www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Operator Overloading - elegant and easy to compile

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
Apr 14 2008