Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 11, 2019 D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
In change log of nightly builds I see that: `D1 operator overloads have been deprecated` The major concern about it is that D2 style operators are template functions. And template functions cannot be virtual. Does it mean that we shall not be able to decalare operators in classes and interfaces that could be overloaded in terms of OOP. What is the proposed solution to this problemme? Currently the only way I see is to declare `final` opOpAssign(RHS, string op)(RHS rhs) (for instance). And then dispatch them to `regular` virtual functions. But it shall look the same as these operator that we are trying to deprecate, but with extra `wrapper`. What is the profit of deprecating these D1? Or is it meant that virtual operators in generally a bad practice?! But I don't understand - why? |
July 11, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to uranuz | On 11.07.19 19:58, uranuz wrote: > In change log of nightly builds I see that: > `D1 operator overloads have been deprecated` > The major concern about it is that D2 style operators are template functions. And template functions cannot be virtual. Does it mean that we shall not be able to decalare operators in classes and interfaces that could be overloaded in terms of OOP. What is the proposed solution to this problemme? > > Currently the only way I see is to declare `final` opOpAssign(RHS, string op)(RHS rhs) (for instance). And then dispatch them to `regular` virtual functions. But it shall look the same as these operator that we are trying to deprecate, but with extra `wrapper`. import std.stdio; class C{ int x; this(int x){ this.x=x; } C opAddImpl(C rhs){ return new C(x+rhs.x); } alias opBinary(string op:"+")=opAddImpl; } void main(){ auto a=new C(1),b=new C(2); writeln((a+b).x); } You can probably even write a mixin template that automatically upgrades your class from D1 style operators to D2 style. > What is the profit of deprecating these D1? > ... When designing a language from scratch, probably you wouldn't add two ways to declare operators, especially if one of them subsumes the other. |
July 11, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 11 July 2019 at 19:07:28 UTC, Timon Gehr wrote:
> alias opBinary(string op:"+")=opAddImpl;
Nice workaround. That shouldn't be necessary though. Something so fundamental shouldn't require 'tricks'.
|
July 11, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to uranuz | On Thursday, 11 July 2019 at 17:58:50 UTC, uranuz wrote: > In change log of nightly builds I see that: > `D1 operator overloads have been deprecated` > The major concern about it is that D2 style operators are template functions. And template functions cannot be virtual. Nice catch... > Does it mean that we shall not be able to decalare operators in classes and interfaces that could be overloaded in terms of OOP. It rather looks like a big whoopsie. Nobody has thought to this case during the review stage[1]. I don't know if the change would have been accepted otherwise, even if they were not documented anymore. [1] https://github.com/dlang/dmd/pull/10130 |
July 11, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Thursday, 11 July 2019 at 20:29:19 UTC, Basile B. wrote:
> It rather looks like a big whoopsie. Nobody has thought to this case during the review stage[1]
I remember it coming up, maybe not formally, but the solution of just forwarding the final templates to a virtual implementation, mentioned above, has been around for a while.
|
July 11, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Thu, Jul 11, 2019 at 08:35:13PM +0000, Adam D. Ruppe via Digitalmars-d wrote: > On Thursday, 11 July 2019 at 20:29:19 UTC, Basile B. wrote: > > It rather looks like a big whoopsie. Nobody has thought to this case during the review stage[1] > > I remember it coming up, maybe not formally, but the solution of just forwarding the final templates to a virtual implementation, mentioned above, has been around for a while. If it's a 1-line fix, I doubt it would stop W&A from going ahead anyway, since D1 operators have been deprecated for quite a while now. On a separate note, I think somebody mentioned a while ago that there are ways to make template functions virtual. If this is a really important issue, we should explore that instead of clinging on to old cruft that's supposed to have been gone years ago. T -- An elephant: A mouse built to government specifications. -- Robert Heinlein |
July 11, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | On Thursday, July 11, 2019 2:29:19 PM MDT Basile B. via Digitalmars-d wrote:
> On Thursday, 11 July 2019 at 17:58:50 UTC, uranuz wrote:
> > In change log of nightly builds I see that:
> > `D1 operator overloads have been deprecated`
> > The major concern about it is that D2 style operators are
> > template functions. And template functions cannot be virtual.
>
> Nice catch...
>
> > Does it mean that we shall not be able to decalare operators in classes and interfaces that could be overloaded in terms of OOP.
>
> It rather looks like a big whoopsie. Nobody has thought to this case during the review stage[1]. I don't know if the change would have been accepted otherwise, even if they were not documented anymore.
>
> [1] https://github.com/dlang/dmd/pull/10130
It was decided years ago that the old, non-templated overloaded operators would be removed from the language, and it was well-known that if you then wanted virtual operator overloading, you'd need to forward to a protected, virtual function. Most user-defined types in D are structs anyway, and it's a simple workaround when you need virtual operator overloading with classes. I actually thought that the old operators had been fully removed quite some time ago, but I guess that it's on the list of stuff where we clearly decided that it was going away, but no one got around to actually deprecating it.
- Jonathan M Davis
|
July 12, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 11 July 2019 at 19:07:28 UTC, Timon Gehr wrote:
> On 11.07.19 19:58, uranuz wrote:
>> In change log of nightly builds I see that:
>> `D1 operator overloads have been deprecated`
>> The major concern about it is that D2 style operators are template functions. And template functions cannot be virtual. Does it mean that we shall not be able to decalare operators in classes and interfaces that could be overloaded in terms of OOP. What is the proposed solution to this problemme?
>>
>> Currently the only way I see is to declare `final` opOpAssign(RHS, string op)(RHS rhs) (for instance). And then dispatch them to `regular` virtual functions. But it shall look the same as these operator that we are trying to deprecate, but with extra `wrapper`.
>
>
> import std.stdio;
> class C{
> int x;
> this(int x){ this.x=x; }
> C opAddImpl(C rhs){
> return new C(x+rhs.x);
> }
> alias opBinary(string op:"+")=opAddImpl;
> }
> void main(){
> auto a=new C(1),b=new C(2);
> writeln((a+b).x);
> }
>
> You can probably even write a mixin template that automatically upgrades your class from D1 style operators to D2 style.
>
>> What is the profit of deprecating these D1?
>> ...
>
> When designing a language from scratch, probably you wouldn't add two ways to declare operators, especially if one of them subsumes the other.
um, the OP said "works with virtual functions/inheritance". When are people going to learn that aliases are not virtual and have nothing to do with preserving inheritance structure?
import std.stdio;
class X
{
}
class C : X{
int x;
this(int x){ this.x=x; }
C opAddImpl(C rhs){
return new C(x+rhs.x);
}
alias opBinary(string op:"+")=opAddImpl;
}
void main(){
X a=new C(1),b=new C(2);
writeln((a+b).x);
}
fails.
|
July 12, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bert | On 12.07.19 15:42, Bert wrote:
>
> um, the OP said "works with virtual functions/inheritance". When are people going to learn that aliases are not virtual and have nothing to do with preserving inheritance structure?
>
>
> import std.stdio;
>
> class X
> {
> }
> class C : X{
> int x;
> this(int x){ this.x=x; }
> C opAddImpl(C rhs){
> return new C(x+rhs.x);
> }
> alias opBinary(string op:"+")=opAddImpl;
> }
> void main(){
> X a=new C(1),b=new C(2);
> writeln((a+b).x);
> }
>
> fails.
Please do enlighten us how you would make that work with D1 operators.
|
July 12, 2019 Re: D1 operator overloads have been deprecated. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bert | On Friday, 12 July 2019 at 13:42:35 UTC, Bert wrote:
> um, the OP said "works with virtual functions/inheritance". When are people going to learn that aliases are not virtual and have nothing to do with preserving inheritance structure?
>
You're misunderstanding.
import std.stdio;
abstract class X
{
abstract X opAddImpl(X rhs);
alias opBinary(string op:"+") = opAddImpl;
}
class C : X{
int x;
this(int x){ this.x=x; }
override C opAddImpl(X rhs){
return new C(x+(cast(C) rhs).x);
}
}
void main(){
X a=new C(1),b=new C(2);
writeln((cast(C) (a+b)).x);
}
|
Copyright © 1999-2021 by the D Language Foundation