Wednesday, April 1, 2015

Why Overload Operators?

Marcel Weiher:

There are two candidates for what the difference might be: the fact that the operation is now written in infix notation and that it’s using special characters.

[…]

To my eyes at least, the binary-message version is no improvement over the keyword message, in fact it seems somewhat worse to me. So the attractiveness of infix notation appears to be a strong candidate for why operator overloading is desirable. Of course, having to use operator overloading to get infix notation is problematic, because special characters generally do not convey the meaning of the operation nearly as well as names, conventional arithmetic aside.

[…]

I’d say that overloaded operators are particularly attractive (to hacker mentalities, but that’s probably most of us) in languages where this boundary between user-defined and built-in stuff exists, and therefore those overloaded operators let you cross that boundary and do things normally reserved for language implementors.

2 Comments RSS · Twitter

I looked through Keyboard Maestro's code (which is all Objective-C++ - I use whatever facilities I think are most appropriate for the task), and I use operator overloading for a number of cases:

* The assignment operator for cases where assigning one object to another needs some bookkeeping
* The equality and inequality operators for cases where it makes sense to compare two objects or sort objects by a canonical means.
* The () operator where an instance needs to be able to act like a function (which is largely a C++ thing).
* The casting operator where an object can behave like another thing
* The indirection operator where it holds a pointer but really is just a representation of that pointer.
* The ++ operator where it makes sense to increment an object
* The ! operator where it makes sense to test if something is false/null/empty
* The [] operator where an object holds an array of things

So what is the common denominator - basically almost all the cases are when using a natural existing standard operation makes sense for the object in question.

We already have a perfectly well defined way of comparing two things for equality (==), and if I have two objects and I want to compare them, its natural to write "a == b" whether the two things are integers or instances (but curiously enough, not if they are floats!). Why would I want to write "a.Equals(b)" - that is more verbose but more importantly it is less clear.

I'd second Peter's example. I've once tried to come up with new binary operators and found it really convenient to write code using these new operators (stuff like >). However, after a week or two this code really became hard to read. Using non-standard operators means that you decide on a meaning for this operator and the meaning may not be obvious later. Using normal word-based method names makes things a whole lot easier to understand.

So if you are tempted to invent a new operator, feel free to do so and try it out. But once everything's done consider to rename the operator to a normal method (that implies that there's a "rename" refactoring because otherwise it'll be too much manual work). That way it's possible to have a speedy way of entering all the code, but also have a readable result.

Leave a Comment