Operator Overloading - elegant and easy to compile
Tomasz Sowinski
tomeksowi at gmail.com
Mon Apr 14 16:11:22 PDT 2008
NOTE: I put a more readible version of this post on Zoho:
http://writer.zoho.com/public/tomeksowi/Operator-Overloading
Yet another try to get operator overloading right.
The reason I'm revisiting this issue is that most users are not particularily proud of the way operator overloading is handled in D. The foreach statement, array slicing and concatenation as well as many other features hit the jackpot. Operator overloading did not.
Consider this example:
class Foo
{
int field;
this (int a) { field = a; }
Foo op(+, -, *, /)(Foo value)
{
return new Foo(this.field op value.field);
}
void op(+=, -=, *=, /=)(Foo value)
{
this.field op value.field;
}
bool op(<, <=, >, >=, ==, !=)(Foo value)
{
return (this.field op value.field);
}
Foo op(++op, --op)()
{
op(this.field);
return this;
}
Foo op(op++, op--)()
{
Foo temp = new Foo(this.field);
op(this.field);
return temp;
}
}
You probably have already guessed what this proposal is about by reading the example, but I'm going to explain it anyway:
The idea is to treat operator overloading like a function template. Of course, the above examples are not valid function templates, still it would be good to have an op declaration that would feel like one. For example, if the compiler sees someting like this:
Foo op(+, -, *, /)(Foo value) {...}
It would make operators opAdd, opSub, opMul, opDiv and all the op..._r's as well.
To generalize, the declaration would be:
OperatorDeclaration:
ReturnType op (OperatorSymbolList) (ParameterList) OperatorBlockStatement
The compiler then generates appropriate functions by iterating through OperatorSymbolList and substituting every occurence of the op keyword in the OperatorBlockStatement with an operator symbol from the OperatorSymbolList and then compiling it as any other code.
The reason of having such an approach is that it is very often that operator overloading is done by applying the operator you would apply to a custom type to each (some of) the custom type's fields.
Some pros of this proposal:
* it complies so well with the 'don't write things twice' rule
* elegant syntax - no need to learn all those opQueerNames by heart
* no problem with parsing (no special case needed to prevent from understanding "operator<(...)" as "operator is less than (...)" like in C++)
* is natural, and melts into existing syntax (if one is familiar with function templates, he will easily understand the declaration)
* performance gains of easy replacing opCmp with a set of specific comparison functions
I haven't thought of cons yet, as I just came up with this idea and can't help thinking it's brilliant :) If you think otherwise, discuss, show me how wrong I am.
(btw, it's my first post, so big Hello to everyone)
Tomek
More information about the Digitalmars-d
mailing list