Operator Overloading - elegant and easy to compile

Bill Baxter dnewsgroup at billbaxter.com
Mon Apr 14 16:50:21 PDT 2008


Tomasz Sowinski wrote:
> 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)

Howdy!

Can you be more specific on how to deal with the _r variants of operator 
overloads?

The first con that comes to my mind is
* Sometimes you want to explicitly call an overloaded operator by name, 
or get a delegate for it to pass to another function.

Also Walter doesn't like treating the operator symbols as pure symbols. 
  Part of the reason he gave the D operator overloads names like "opAdd" 
was to discourage people from trying to overload "+" to mean anything 
other than addition.  So your proposal will face an uphill battle 
because of that.

Macros also might be able to provide this kind of thing.  Someday, when 
they exist, that is.

--bb



More information about the Digitalmars-d mailing list