Tuesday, July 6, 2010

Why Java Doesn't Need Operator Overloading (and Very Few Languages Do, Really)

Operator overloading is a topic that never fails to generate very passionate responses, and this monster thread on Artima is no exception.

First of all, I’d like to address a common complaint heard from people
who dislike operator overloading, and which usually goes along the
lines of:

In Java, when I see a + b, I know exactly what is going on. If Java supported operator overloading, I would have no idea what + means.

I have very little sympathy for this argument because this example is hardly different from a method call such as o.init(). When you read such code in Java, you don’t necessarily assume that it’s the method init on o’s
class that is being invoked. You know that you will have to look at how
this object is created in order to determine its effective type before
you can find out which method init is being invoked.

Operator overloading is no different, and if you knew that the language
that you are reading supports it, you are just going to extend this
mental path to operations that involve overridable operators.

Very often, I find that operator overloading is being demonized
because its uses in other languages has led to excesses. I have found
that many people who dislike operator overloading can trace it back to
some personal experiences where they once had to deal with code that
was clearly abusing this feature. This is unfortunate, but I still
think that Java is doing fine without it and that overall, it only
leads to clearer code in very few and uncommon cases.

Here are a couple of objections I have with operator overloading:

  • The number of operators that you can overload is very
    small and each of them is attached to very specific semantics that
    makes little sense outside the realm of scalars and of a few other
    specialized mathematical concepts (e.g. matrices).

  • In exchange for infix notation, operator overloading severely restricts my freedom to name my methods in a meaningful way.

The most common operators that people want to overload are + and -,
and they are also the operators that probably make the most sense
outside simple arithmetics. I can see these two operators make sense
for types that represent a collection of elements (java.util.Collection
obviously, but also strings or streams). However, even in this ideal
case in favor of operator overloading, the metaphor quickly breaks down
when you realize that you need to supplement these two methods with
ones that have slightly different meanings, such as addAll(). Would you rather have an interface that contains add() and addAll() or +() and addAll()?

Of course, there are more operators that can be overloaded, such as * or /,
but I find that even strong advocates of operator overloading quickly
run short of arguments when trying to justify why one would even want
to overload them outside of specific algebras.

I am a big fan of clear names, and I dislike the name +
for the simple reason that it doesn’t carry enough meaning to explain
to me what is going on. This operator is very clearly defined when it
is used in a mathmatical sense but it becomes very vague when you start
to extend it to concepts that supports the idea of addition in a more
vague sense. For example, adding to a List is very different from adding to a Map
since the latter can produce an object that’s equal to the one you
started with, even though the object you added is not zero. And what is
zero in the sense of a collection, anyway? Doesn’t it make much more
sense to use add() for a List and put() for a Map?

Overall, I find that code that makes heavy use of operator overloading
is harder to read and harder to maintain because it is severely
restricted syntactically (forced to use specific names taken from a
very small pool) and semantically (since you are using symbols that
have very precise mathematical definitions, it is very unlikely that
your usage will match the mental model that people who read your code
have of their meaning).

I would love to see some good examples of operator overloading, if you have any to share…

From http://beust.com/weblog

No comments:

Post a Comment