This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.

Anomaly ~ G. Wade Johnson Anomaly Home G. Wade Home

July 15, 2006

Operator Overloading and Naming

One of the things Java programmers seem to really like to hate in C++ is the concept of operator overloading. I have heard this from many Java programmers and seen it written by others. According to many, operator overloading makes C++ impossible to understand because you can't tell what a piece of code is doing just by looking at it.

When looking for this statement on-line, the first example I found was Joel Spolsky's article, Making Wrong Code Look Wrong - Joel on Software under the section A General Rule. I'll pick on Joel for two reasons here. The first is that the comment has very little to do with the topic of an extremely good article. Second, that I usually agree with Joel on the big things, but often disagree on smaller issues.

Joel uses the following example to prove his point:
i = j * 5;

He states, with complete conviction, that if you see that same snippet of code in C++, you don’t know anything. Nothing.

I believe that the operator overloading issue is a red herring. To prove this, I will transform the code a little.

assign( i, multiply( j, 5 ) );

This would be perfectly legal code in C++, Java, or a number of other common general purpose languages. I could easily define this code to do exactly the same as the original code when i and j are integers.

Now, when you see this snippet of code, what do you know? Even without operator overloading, you don't really know anything. If the programmer used good naming conventions, however, you could infer that j is multiplied by 5 where the multiplication is something appropriate for an object of j's type. You could further infer that the result of this operation is assigned to i using whatever conversions are appropriate for this assignment.

Furthermore, if we used a more object oriented syntax:

i.assign( j.multiply( 5 ) );

Although we now know that both i and j are object types, we still don't know any more than we did from the previous two examples. But, we still don't know what those methods do. For example, multiply could make a call to a relational database with the supplied parameter to give a string that i.assign() uses to make an HTTP request to a web server to update its current state.

If you found that this was the case, you would probably abuse the original programmer about using extremely bad naming. You probably wouldn't ban the use of the method names multiply and assign.

The issue, as I see it, is not that operator overloading is a problem. It's that some programmers name methods, variables, and/or classes badly. The fix is not to ban certain names, but to educate those programmers.

In my experience, most of the bad uses of operator overloading happen when programmers are new to the idea and they think it will be clever or cool to use an operator when a method name works better. Education and experience usually fixes that. (Others may have had different experiences, but that is what I saw.)

Maybe we should stop beating the operator overloading dead horse, and spend more time educating junior programmers about the importance of good names and the Principle of Least Surprise. In fact, the advice cited in Joel's article above is a good start for this kind of education.

Posted by GWade at July 15, 2006 11:43 PM. Email comments