Wednesday, December 29, 2004

Java Operator Overloading

I saw this comment somewhere...

Even if it is trivial to add operator overloading to Java and to make it simple to use, are you absolutely sure its a good idea?

Operator overloading violates one of the central tenets of the Java language design; transparency. If you look at any piece of Java code (no matter who wrote it or where its from) you can easily figure out exactly what it does. There is no "hidden" information; everything is stated explicitly. This philosophy makes Java an ideal language for Open Source and business programming where there may be many different contributors over a long period of time. It is easy to dive into a class, see what's going on and make any modifications necessary.

With operator overloading (and many of the dubious "improvements" made to the Java language in Java 1.5) we lose this transparency. External declarations not referred to internally can completely alter the meaning of a section of code.

That's bad.

Of course, some people don't agree that this emphasis on transparency is useful, so they program in (or at least advocate) other languages (like for example Lisp, Nice, or C++) where the language can be modified and transformed willy nilly. This kind of thing makes an interesting intellectual exercise; it does not however make for a good social environment to program in. For these people, Java must seem limited. However, the vast majority of programmers have rejected this approach (with some relief!) and now program in Java (or its evil twin C#)

The String concatenation argument is often brought up by advocates of operator overloading in Java, and in a way they do have a point; that operator overloading can be useful. That is, it WOULD be useful if it didn't compromise code transparency so flagrantly! There is one big difference between String operator overloading and arbitrary operator overloading. When I sit down to maintain your code, I know what the String "+" operator does; it's in the Java Language Specification. On the other hand, I have no idea what your overriding of the "+" operator does on your "CustomerRecord" class. That is, if I can Without prior knowledge, I can't even tell if an operator is overridden or not!

Operator overloading is indeed not high on Java programmers list of desires (at least those that understand the design philosophy of the language). Rather, the very mention of it provokes feelings of fear and disgust. And rightly so! To those who would like to return to the days where every day was an obfuscated C contest, and where knowledge of the actual language didn't translate into ability to understand and maintain code, I say go elsewhere; to the lands of C++, Perl, Python and their ilk where you will find yourself in eerily familiar territory. Or if you hang around Java long enough you will probably see it ruined by people such as yourself screaming at Sun for more "improvements" along the same lines as Tiger.

I agree with his point of transparency. When you're reading someone else's code or even your own code after some gap, trying to make sense of it is difficult. That's why trying to write "clean" self documenting code is important. And it's the reason why "simple" languages like Java and C# are becoming more popular. There are limited (often only one) ways to do things. It's one of the reasons I don't like the C/C++ typedef statement. Most of the time you can't make sense of what the underlying type is.

In the case of operator overloading I disagree with him. I don't think it destroys transperency. If anything I think it makes the code more understandable. Operator overloading is just an abstraction over methods. And it's not like you can overload any operator. There are only a limited and well know operators that have a standard universal meaning that can be overloaded. Yeah, there is potential for abuse, for example, by overloading + to subtract instead of add, but there is nothing stopping anyone from subtracting in an Add() method either.

1 comment:

matt said...

He makes a good point, Operator overloading is a very important feature to fully implement abstraction and encapsulation. For example two vectors vecA and vecB could be added with vecA + vecB just as humans assume it would be. Rather that vecA.add(vecB) or vecA.addVec(vecB) which is less clear (and ugly).