www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Not allowed to globally overload operators?

reply Tejas <notrealemail gmail.com> writes:
The following doesn't work:
```d
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
```d
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.
Jul 19 2021
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
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
Jul 19 2021
parent Tejas <notrealemail gmail.com> writes:
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.
Jul 19 2021
prev sibling next sibling parent reply vit <vit vit.vit> writes:
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).
Jul 19 2021
parent Tejas <notrealemail gmail.com> writes:
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 ```<=>``` :(
Jul 19 2021
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Jul 20 2021
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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)
Jul 20 2021
next sibling parent Paul Backus <snarwin gmail.com> writes:
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.
Jul 20 2021
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 7/20/21 11:49 AM, H. S. Teoh wrote:

 On Tue, Jul 20, 2021 at 11:32:26AM -0700, Ali =C3=87ehreli via=20
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 wa=
s
 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=20 demonstarted below) but then the UDT cannot know what to do in its opCmp:= :) import std.stdio; void main() { S a, b; auto result =3D a < b; // The operator above is reduced to the following: // // a.opCmp(b) < 0; // // (It would be 'a.opCmp(b) >=3D 0' if we used the >=3D 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. (<, >=3D, 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 <, >=3D, 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
Jul 20 2021
prev sibling parent Tejas <notrealemail gmail.com> writes:
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 :(
Jul 20 2021