Daniel Pitts’ Tech Blog

Posts Tagged ‘operator overloading’

More Discussion On Operator Overloading

Wednesday, December 5th, 2007

Updated: See notes below.

I was surprised to see that within one day of posting my previous entry on Operator Overloading, I received several comments. Aviad Ben Dov from Chaotic Java even took my idea and ran with it. Ricky Clarkson suggested using Haskell’s approach of allowing anything that is of the “Num” type to define +,-,/,*, etc…. I have a few things to add to this discussion.

Aviad’s idea for operators by interface is not a bad one; it works well for overloading “[]” but it breaks down on a few use cases (such as ‘+’, ‘*’, etc..) that are important (to me). Ricky’s idea for subtypes of a specific class getting to have operator overloading isn’t bad either, but for physical unit manipulation it is too inflexible. The core concept that both of them seem to have suggest is that a limited selection of types can have overloaded operators, but the operations that are possible aren’t limited to the scalar quantities that this would limit the operators to.

Suppose I have the classes Distance, Area, and the built-in “Scalar” type Double I would expect at least these sets of operations:
Distance * Distance => Area
Distance * Double => Distance

If I had to implement the Multipliable<T> interface, I wouldn’t be able to handle Distance * Distance and Distance * Double. You can’t implement an interface twice, even with different type parameters. I don’t know if this is something that Reified generics would fix, but it feels like it might be. Maybe someone could comment on that.

Also, if Distance had to extend Number, what would doubleValue return? Meters? Inches? Smoots? There might be some way to solve these problems, but I can’t think of a way to prevent abuse while allow good use.

Actually, now that I have thought a little about it…

The semantics of plus (+), minus (-), times (*), dividedBy (/), moduloOf (%), shiftLeft(<<), shiftRight(>>), unsignedShiftRight(>>>), or(|), and(&), xor (^), negative(-), and inverse(~), are all well-defined enough for so many not-necessarily-numeric types that allowing, even if only through naming conventions, the overloading of those operations seems like a good idea.

I think a good way to go would be to convert at compile time a * b to the method call a.times(b). Assignment operators like a += b would be replaced with a = a.plus(b). This would help reduce abuse while creating a more expressive language. The assignment operator rule is important, as it will help prevent the “clever” idiom of using += for appending elements to a collection.

Note on updates: I previously misspelled Aviad as “Avaid”. I also have added clarification for which use-cases Aviad’s Indexer doesn’t work for me, namely for algebraic operators.

Almost Useful: Operator overloading

Tuesday, December 4th, 2007

On suns site, there is an open bug for operator overloading. Many people have pointed out that Java has one special case of operator overloading (String + String), so why not allow the programmer to overload operators?

Operator overloading would become especially useful when the addition of the units and measures API, or other custom libraries that are similar. It becomes especially useful when trying to avoid primitive obsession, and create numeric-like types.

Imagine this case:

Speed s = endDistance.minus(startDistance).divide(duration);

could be simplified to

Speed s = (endDistance - startDistance) / duration;

This of course is a simple example, and yet one that I would love to use in some of my existing code-bases.

Another use case would be a cleaner syntax for lists/maps:

myMap["Hey"] = "There";
System.out.println(myList[10]);

And hey, what about a special case for compareTo? Although it might be too dangerous to overload =/==, I could see overloading <, > <=, and >=. It might be nice to add a couple of operators to the mix. I’m officially suggesting “#” for concatenation. Maybe “:=” for shortand to .equals().