Thread overview
Not allowed to globally overload operators?
Jul 20, 2021
Tejas
Jul 20, 2021
Mike Parker
Jul 20, 2021
Tejas
Jul 20, 2021
vit
Jul 20, 2021
Tejas
Jul 20, 2021
Ali Çehreli
Jul 20, 2021
H. S. Teoh
Jul 20, 2021
Paul Backus
Jul 20, 2021
Ali Çehreli
Jul 21, 2021
Tejas
July 20, 2021

The following doesn't work:

import std;
int opBinary(string s:"+")(int a, int b){
    int result;
    a<b?(result = -1):a>b? (result = 1): (result = 0);
    return result;
}
void main(){
    int f = 1 + 5;
    writeln(f);
}

It outputs 6

But if I manually write it as

int f = opBinary!"+"(1,5);

It works as expected.

Why isn't it working by default?

Initially, I was trying to create the spaceship operator of C++, but we aren't allowed to create new operators, it seems. Then I just wanted to verify whether we can even overload an operator globally, but even that seems to be failing, atleast for me.

July 20, 2021

On Tuesday, 20 July 2021 at 06:20:34 UTC, Tejas wrote:

>

Why isn't it working by default?

Initially, I was trying to create the spaceship operator of C++, but we aren't allowed to create new operators, it seems. Then I just wanted to verify whether we can even overload an operator globally, but even that seems to be failing, atleast for me.

From the docs:

>

Operator overloading is accomplished by rewriting operators whose operands are class or struct objects into calls to specially named members.

https://dlang.org/spec/operatoroverloading.html

Note the word "members".

See also:

https://dlang.org/articles/rationale.html#why-no-global-operator-functions

July 20, 2021

On Tuesday, 20 July 2021 at 06:20:34 UTC, Tejas wrote:

>

...
Initially, I was trying to create the spaceship operator of C++, but we aren't allowed to create new operators
...

D has spaceship operator: opCmp (https://dlang.org/spec/operatoroverloading.html#compare).

July 20, 2021

On Tuesday, 20 July 2021 at 06:30:56 UTC, Mike Parker wrote:

>

On Tuesday, 20 July 2021 at 06:20:34 UTC, Tejas wrote:

>

Why isn't it working by default?

Initially, I was trying to create the spaceship operator of C++, but we aren't allowed to create new operators, it seems. Then I just wanted to verify whether we can even overload an operator globally, but even that seems to be failing, atleast for me.

From the docs:

>

Operator overloading is accomplished by rewriting operators whose operands are class or struct objects into calls to specially named members.

https://dlang.org/spec/operatoroverloading.html

Note the word "members".

Ack. I remember reading the spec but have forgotten that detail multiple times now.

>

See also:

https://dlang.org/articles/rationale.html#why-no-global-operator-functions

Well, this is new. sigh Guess I'll have to find another way to implement spaceship then. I don't disagree with the rationale, but it is a little inconvenient in my case.

July 20, 2021

On Tuesday, 20 July 2021 at 06:34:45 UTC, vit wrote:

>

On Tuesday, 20 July 2021 at 06:20:34 UTC, Tejas wrote:

>

...
Initially, I was trying to create the spaceship operator of C++, but we aren't allowed to create new operators
...

D has spaceship operator: opCmp (https://dlang.org/spec/operatoroverloading.html#compare).

I know, but I just really wanted the <=> :(

July 20, 2021
On 7/19/21 11:20 PM, Tejas wrote:

> trying to create the spaceship operator of C++

Just to make sure, D's opCmp returns an int. That new C++ operator was added to provide the same semantics.

Ali

July 20, 2021
On Tue, Jul 20, 2021 at 11:32:26AM -0700, Ali Çehreli via Digitalmars-d-learn wrote:
> On 7/19/21 11:20 PM, Tejas wrote:
> 
> > trying to create the spaceship operator of C++
> 
> Just to make sure, D's opCmp returns an int. That new C++ operator was added to provide the same semantics.
[...]

FYI, opCmp *may* return float, which may be useful sometimes for implementing partial orders (return float.nan when two elements are incomparable).


T

-- 
"Outlook not so good." That magic 8-ball knows everything! I'll ask about Exchange Server next. -- (Stolen from the net)
July 20, 2021

On Tuesday, 20 July 2021 at 18:49:07 UTC, H. S. Teoh wrote:

>

On Tue, Jul 20, 2021 at 11:32:26AM -0700, Ali Çehreli via Digitalmars-d-learn wrote:

>

On 7/19/21 11:20 PM, Tejas wrote:

>

trying to create the spaceship operator of C++

Just to make sure, D's opCmp returns an int. That new C++ operator was added to provide the same semantics.
[...]

FYI, opCmp may return float, which may be useful sometimes for implementing partial orders (return float.nan when two elements are incomparable).

To be precise about it: opCmp must return a value that can be compared with 0 using < and >. Any integer or floating-point type will satisfy this requirement.

July 20, 2021
On 7/20/21 11:49 AM, H. S. Teoh wrote:

> On Tue, Jul 20, 2021 at 11:32:26AM -0700, Ali Çehreli via Digitalmars-d-learn wrote:
>> On 7/19/21 11:20 PM, Tejas wrote:
>>
>>> trying to create the spaceship operator of C++
>>
>> Just to make sure, D's opCmp returns an int. That new C++ operator was
>> added to provide the same semantics.
> [...]
>
> FYI, opCmp *may* return float, which may be useful sometimes for
> implementing partial orders (return float.nan when two elements are
> incomparable).

Thanks. For that matter, opCmp can return a UDT (and bool as well as demonstarted below) but then the UDT cannot know what to do in its opCmp: :)

import std.stdio;

void main() {
  S a, b;
  auto result = a < b;
  // The operator above is reduced to the following:
  //
  //   a.opCmp(b) < 0;
  //
  // (It would be 'a.opCmp(b) >= 0' if we used the >= operator, etc.)
  //
  // But because the result of opCmp is an O object in this code
  // (let's call it 'o'), the reduction is applied to 'o < 0' as well:
  //
  //   o.opCmp(0);
  //
  // where, O.opCmp will receive a 0 'int' value but will never know
  // operator context we are in. (<, >=, etc.)
}

struct S {
  // Weirdly returns an O.
  O opCmp(const S that) {
    return O();
  }
}

struct O {
  bool opCmp(int result) {
    // result will always be '0' in the case of reduction because it
    // will be the 0 used in code reduction by dmd.

    // We might be able to do something here but we don't know the
    // operator context. Are we inside <, >=, etc?

    // Extra credit: This is similar to being able to return float.nan
    // but I can't decipher the semantics at this time. :)
    return true;
  }
}

Ali


July 21, 2021

On Tuesday, 20 July 2021 at 18:32:26 UTC, Ali Çehreli wrote:

>

On 7/19/21 11:20 PM, Tejas wrote:

>

trying to create the spaceship operator of C++

Just to make sure, D's opCmp returns an int. That new C++ operator was added to provide the same semantics.

Ali

I know. As I already mentioned, I just wanted the <=> symbol :(