Re: operator overloading
On Thu, 8 May 2008, Owen Jacobson wrote:
It might be instructive to think about how foreach was made extensible:
there is an interface which, if implemented properly, can make an
arbitrary class usable in a for(each) loop. The same could be done to
map syntax to operations:
public interface java.lang.Indexed<T> {
public T get (int i);
}
would, hypothetically, be enough to allow arbitrary classes to be used
on the left of array expressions like:
Indexed<String> notAnArray = new MyClass ("foo", "bar");
assert notAnArray[0] == "foo"; // notAnArray.get (0)
assert notAnArray[1] == "bar"; // notAnArray.get (1)
That's a bloody good idea. Well, it might be ...
However, it's not clear whether the core operators (+, *, /, binary -,
unary -, ++, --) should be exposed as a single interface (Arithmetic),
several interfaces (Addable, Multipliable, Dividable/Rational, etc).
Both. The joy of multiple inheritance of interfaces!
You need to be able to have things which you can, say, add and multiply,
but not divide - anything a mathematician would call a ring, like a
three-by-three matrix. Forcing these to have divide methods that just
threw an exception would be pretty poor.
You could even model a little hierarchy on discrete mathematics: Addable,
Multipliable, Ring extends Addable, Multipliable, Dividable, Field extends
Ring, Dividable, etc.
There are also some weird edge cases (like time) where the operands
and result of operations are not the same type.
There are also some distinctly non-weird non-edge cases where this is
true, and where the operands are not the same type, and where you want to
be able to overload the operators according to operand type. An obvious
example would be a Vector3D; i want to be able to add two vectors to make
a third, but also to multiply a vector by a double to get a vector, and a
vector by a vector to get their dot product, which is a double. If i also
have Matrix3D (being a 3 x 3 matrix, to represent linear transformations),
i want to be able to add matrices, to multiply two to make a third
(although i have no idea what the geometric significance of that is!), to
multiply a matrix by a vector to make a transformed vector, etc.
I can't see how you'd do this with interfaces unless they were defined as
taking Object and returning Object, which would be a bit lame. Like how
equals and compareTo work.
tom
--
Got a revolution behind my eyes - We got to get up and organise