Thread overview
static / global operator overload
Aug 18, 2013
Namespace
Aug 18, 2013
Ali Çehreli
Aug 18, 2013
monarch_dodra
Aug 18, 2013
Namespace
Aug 19, 2013
monarch_dodra
August 18, 2013
I can't find anything so I ask here: what was the decision to disallow static or global operator overloads?
In C++ you can declare operator overloads inside and outside of classes (the latter is more popular), so why wasn't this introduced in D also?

Thanks in advance. :)
August 18, 2013
On 08/18/2013 07:34 AM, Namespace wrote:

> In C++ you can declare operator overloads inside and outside of classes
> (the latter is more popular)

The latter is popular because a global operator takes advantage of implicit type conversions. A global operator+ allows using an int even on the left-hand side of the operator.

As a result, assuming that MyInt can be constructed from an int, when there is

    // Assume this is defined outside of MyInt definition
    MyInt operator+(MyInt lhs, MyInt rhs);

the expression

    1 + MyInt(2)

is lowered to

    operator+(MyInt(1), MyInt(2))

> so why wasn't this introduced in D also?

My guess is that there is no implicit construction of objects in D anyway so there wouldn't be that benefit.

Ali

August 18, 2013
On Sunday, 18 August 2013 at 15:29:26 UTC, Ali Çehreli wrote:
> On 08/18/2013 07:34 AM, Namespace wrote:
>
> > In C++ you can declare operator overloads inside and outside
> of classes
> > (the latter is more popular)
>
> The latter is popular because a global operator takes advantage of implicit type conversions. A global operator+ allows using an int even on the left-hand side of the operator.
>
> As a result, assuming that MyInt can be constructed from an int, when there is
>
>     // Assume this is defined outside of MyInt definition
>     MyInt operator+(MyInt lhs, MyInt rhs);
>
> the expression
>
>     1 + MyInt(2)
>
> is lowered to
>
>     operator+(MyInt(1), MyInt(2))
>
> > so why wasn't this introduced in D also?
>
> My guess is that there is no implicit construction of objects in D anyway so there wouldn't be that benefit.
>
> Ali

D defines the member "opBinaryRight", which makes global operators un-needed.

//====
struct S
{
    void opBinary(alias s)(int i)
    if (s == "+")
    {
        writeln(s);
    }
    void opBinaryRight(alias s)(int i)
    if (s == "+")
    {
        return this + i;
    }
}

void main()
{
    S s;
    s + 5;
    5 + s;
}
//====

Doing this also helps avoid poluting the global name-space with operators.
August 18, 2013
On Sunday, 18 August 2013 at 15:29:26 UTC, Ali Çehreli wrote:
> On 08/18/2013 07:34 AM, Namespace wrote:
>
> > In C++ you can declare operator overloads inside and outside
> of classes
> > (the latter is more popular)
>
> The latter is popular because a global operator takes advantage of implicit type conversions. A global operator+ allows using an int even on the left-hand side of the operator.
>
> As a result, assuming that MyInt can be constructed from an int, when there is
>
>     // Assume this is defined outside of MyInt definition
>     MyInt operator+(MyInt lhs, MyInt rhs);
>
> the expression
>
>     1 + MyInt(2)
>
> is lowered to
>
>     operator+(MyInt(1), MyInt(2))
>
> > so why wasn't this introduced in D also?
>
> My guess is that there is no implicit construction of objects in D anyway so there wouldn't be that benefit.
>
> Ali

It's also preferred (at least by me) because such methods don't have to be in a class/struct and blows it up. They don't effect the class/struct and thanks to UFCS we still could call them like member methods.
So IMO because they have no effect in a class/struct they shouldn't be there.

Compare:

bool opEquals(ref const A a) { ... } inside of struct A

versus:

bool opEquals(ref const A lhs, ref const A rhs) { ... }

I would prefer the last one.

But I would like to see an official thread for this, if any exist. Do you know one? I'm just startled that D follows this way. :)
August 19, 2013
On Sunday, 18 August 2013 at 21:23:05 UTC, Namespace wrote:
> On Sunday, 18 August 2013 at 15:29:26 UTC, Ali Çehreli wrote:
>> On 08/18/2013 07:34 AM, Namespace wrote:
>>
>> > In C++ you can declare operator overloads inside and outside
>> of classes
>> > (the latter is more popular)
>>
>> The latter is popular because a global operator takes advantage of implicit type conversions. A global operator+ allows using an int even on the left-hand side of the operator.
>>
>> As a result, assuming that MyInt can be constructed from an int, when there is
>>
>>    // Assume this is defined outside of MyInt definition
>>    MyInt operator+(MyInt lhs, MyInt rhs);
>>
>> the expression
>>
>>    1 + MyInt(2)
>>
>> is lowered to
>>
>>    operator+(MyInt(1), MyInt(2))
>>
>> > so why wasn't this introduced in D also?
>>
>> My guess is that there is no implicit construction of objects in D anyway so there wouldn't be that benefit.
>>
>> Ali
>
> It's also preferred (at least by me) because such methods don't have to be in a class/struct and blows it up. They don't effect the class/struct and thanks to UFCS we still could call them like member methods.
> So IMO because they have no effect in a class/struct they shouldn't be there.
>
> Compare:
>
> bool opEquals(ref const A a) { ... } inside of struct A
>
> versus:
>
> bool opEquals(ref const A lhs, ref const A rhs) { ... }
>
> I would prefer the last one.
>
> But I would like to see an official thread for this, if any exist. Do you know one? I'm just startled that D follows this way. :)

The possibility of static operator was raised, specifically for opDollar, in std.range, for the possibility of it automatically resolving to length.

Reception for *just* this was kind of cold. I remember it being downright hostile for UFCS operators in general.

The full conversation is here:
http://d.puremagic.com/issues/show_bug.cgi?id=7177
Note that while UFCS was discussed, it wasn't the root of the discussion :/