www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP 1016--ref T accepts r-values--Final Review

reply Mike Parker <aldacron gmail.com> writes:
DIP 1016, "ref T accepts r-values", is now ready for Final 
Review. This is the last chance for community feedback before the 
DIP is handed off to Walter and Andrei for the Formal Assessment. 
Please read the procedures document for details on what is 
expected in this review stage:

https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#final-review

The current revision of the DIP for this review is located here:

https://github.com/dlang/DIPs/blob/b0de441a7ba3d55f267dc2ab4fce0eebe42c48e6/DIPs/DIP1016.md

In it you'll find a link to and summary of the previous review 
round. This round of review will continue until 11:59 pm ET on 
December 1 unless I call it off before then.

Thanks in advance for your participation.
Nov 17 2018
next sibling parent reply Rubn <where is.this> writes:
     void lval_only(int x)  disable;
     void lval_only(ref int x);

     int x = 10;
     lval_only(x);  // ok: choose by-ref
     lval_only(10); // error: literal matches by-val, which is 
 disabled

For this what about if there are multiple parameters? How many 
overloads do you have to define to get this behavior?

     void lval_only(int x, int y)  disable;
     void lval_only(ref int x, ref int y);

     int x = 10;
     int y = 20;
     lval_only(x, y);  // ok: choose by-ref
     lval_only(10, 20); // error: literal matches by-val, which is 
 disabled
     lval_only(x, 20); // is this an error cause of  disable or 
not ?
     lval_only(10, y); // ditto
Nov 17 2018
parent reply kinke <noone nowhere.com> writes:
On Saturday, 17 November 2018 at 13:01:12 UTC, Rubn wrote:
 For this what about if there are multiple parameters? How many 
 overloads do you have to define to get this behavior?
I'd assume a single one. It should be analogous to this: ``` void lval_only(uint x, short y) disable; void lval_only(int x, int y); void main() { byte y = 1; lval_only(100_000, y); } ``` The disabled function is preferred, so this doesn't compile. As by-value params are to be preferred for rvalue args in overload resolution, the single overload should do in your example. --- I'm a huge fan of this DIP and have been wanting this in the language literally since the day I wrote my first D code, immediately stumbling into this limitation (but fortunately not losing much interest due to numerous advantages and syntax loveliness).
Nov 17 2018
parent reply Rubn <where is.this> writes:
On Saturday, 17 November 2018 at 14:49:26 UTC, kinke wrote:
 On Saturday, 17 November 2018 at 13:01:12 UTC, Rubn wrote:
 For this what about if there are multiple parameters? How many 
 overloads do you have to define to get this behavior?
I'd assume a single one. It should be analogous to this: ``` void lval_only(uint x, short y) disable; void lval_only(int x, int y); void main() { byte y = 1; lval_only(100_000, y); } ``` The disabled function is preferred, so this doesn't compile. As by-value params are to be preferred for rvalue args in overload resolution, the single overload should do in your example. --- I'm a huge fan of this DIP and have been wanting this in the language literally since the day I wrote my first D code, immediately stumbling into this limitation (but fortunately not losing much interest due to numerous advantages and syntax loveliness).
If that's the case then it'll look something like this, for just 3 parameters if you want the old behavior: void lval_only(int x, int y, int z) disable; void lval_only(int x, int y, ref int z) disable; void lval_only(int x, ref int y, ref int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, int z) disable; void lval_only(int x, ref int y, int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, ref int z); Not really ideal, I might be missing one, hard to tell.
Nov 18 2018
next sibling parent Manu <turkeyman gmail.com> writes:
On Sun, Nov 18, 2018 at 8:00 AM Rubn via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Saturday, 17 November 2018 at 14:49:26 UTC, kinke wrote:
 On Saturday, 17 November 2018 at 13:01:12 UTC, Rubn wrote:
 For this what about if there are multiple parameters? How many
 overloads do you have to define to get this behavior?
I'd assume a single one. It should be analogous to this: ``` void lval_only(uint x, short y) disable; void lval_only(int x, int y); void main() { byte y = 1; lval_only(100_000, y); } ``` The disabled function is preferred, so this doesn't compile. As by-value params are to be preferred for rvalue args in overload resolution, the single overload should do in your example. --- I'm a huge fan of this DIP and have been wanting this in the language literally since the day I wrote my first D code, immediately stumbling into this limitation (but fortunately not losing much interest due to numerous advantages and syntax loveliness).
If that's the case then it'll look something like this, for just 3 parameters if you want the old behavior: void lval_only(int x, int y, int z) disable; void lval_only(int x, int y, ref int z) disable; void lval_only(int x, ref int y, ref int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, int z) disable; void lval_only(int x, ref int y, int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, ref int z); Not really ideal, I might be missing one, hard to tell.
Ideas to improve this are welcome; but let's be realistic, the thing you describe has almost certainly *never* been deployed in practise in any code anywhere at any time, and I can't imagine a use case. The value in this DIP shouldn't be called into question because a not-useful thing appears less convenient. Meanwhile, the more-likely and simpler case (one argument, which appears in properties and what not), becomes clearer and more explicit. If you have ideas to improve this multi-arg case, that's useful, but I wouldn't lose sleep over this either way :)
Nov 18 2018
prev sibling next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Sunday, 18 November 2018 at 15:55:11 UTC, Rubn wrote:
 On Saturday, 17 November 2018 at 14:49:26 UTC, kinke wrote:
 [...]
If that's the case then it'll look something like this, for just 3 parameters if you want the old behavior: void lval_only(int x, int y, int z) disable; void lval_only(int x, int y, ref int z) disable; void lval_only(int x, ref int y, ref int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, int z) disable; void lval_only(int x, ref int y, int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, ref int z); Not really ideal, I might be missing one, hard to tell.
How about void lval_only(ref int x, ref int y, ref int z) disable(rvalue)? Would that be easier? Alex
Nov 18 2018
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/18/18 10:55 AM, Rubn wrote:
 On Saturday, 17 November 2018 at 14:49:26 UTC, kinke wrote:
 On Saturday, 17 November 2018 at 13:01:12 UTC, Rubn wrote:
 For this what about if there are multiple parameters? How many 
 overloads do you have to define to get this behavior?
I'd assume a single one. It should be analogous to this: ``` void lval_only(uint x, short y) disable; void lval_only(int x, int y); void main() {     byte y = 1;     lval_only(100_000, y); } ``` The disabled function is preferred, so this doesn't compile. As by-value params are to be preferred for rvalue args in overload resolution, the single overload should do in your example. --- I'm a huge fan of this DIP and have been wanting this in the language literally since the day I wrote my first D code, immediately stumbling into this limitation (but fortunately not losing much interest due to numerous advantages and syntax loveliness).
If that's the case then it'll look something like this, for just 3 parameters if you want the old behavior:     void lval_only(int x, int y, int z) disable;     void lval_only(int x, int y, ref int z) disable;     void lval_only(int x, ref int y, ref int z) disable;     void lval_only(ref int x, int y, ref int z) disable;     void lval_only(ref int x, ref int y, int z) disable;     void lval_only(int x, ref int y, int z) disable;     void lval_only(ref int x, int y, ref int z) disable;     void lval_only(ref int x, ref int y, ref int z); Not really ideal, I might be missing one, hard to tell.
We can reduce to linear growth using auto ref: void lval_only()(int x, auto ref int y, auto ref int z) disable void lval_only()(ref int, int, auto ref int) disable void lval_only(ref int, ref int, int) disable Still not ideal though. I tried auto ref for all 3, but that means it will match both the template and the real function. I tried using a constraint, but not sure how to get the parameter ref-ness in a neat way inside the constraint. This does work: void lval_only()(auto ref int x, auto ref int y, auto ref int z) disable if (!__traits(isRef, x) || !__traits(isRef, y) || !__traits(isRef, z)) But it is a bit ugly. Another option is to use a variadic template, verify the parameters match the lvalue version, and then use some testing on the parameter tuple. Or use a mixin based on the original function. Probably the mixin could work something like: mixin(disableNonRef!lval_only); -Steve
Nov 19 2018
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Monday, 19 November 2018 at 15:23:14 UTC, Steven Schveighoffer 
wrote:
 We can reduce to linear growth using auto ref:

 void lval_only()(int x, auto ref int y, auto ref int z)  disable
 void lval_only()(ref int, int, auto ref int)  disable
 void lval_only(ref int, ref int, int)  disable

 Still not ideal though. I tried auto ref for all 3, but that 
 means it will match both the template and the real function.

 I tried using a constraint, but not sure how to get the 
 parameter ref-ness in a neat way inside the constraint. This 
 does work:

 void lval_only()(auto ref int x, auto ref int y, auto ref int 
 z)  disable if (!__traits(isRef, x) || !__traits(isRef, y) || 
 !__traits(isRef, z))

 But it is a bit ugly.
template isRefX(A...) if (A.length == 1) { enum bool isRefX = __traits(isRef, A[0]); } template allIsRef(A...) { enum allIsRef = allSatisfy!(isRefX, A); } void lval_only()(auto ref int x, auto ref int y, auto ref int z) disable if (!allIsRef!(x, y, z));
 Another option is to use a variadic template, verify the 
 parameters match the lvalue version, and then use some testing 
 on the parameter tuple.
Yuck.
 Or use a mixin based on the original function.

 Probably the mixin could work something like:

 mixin(disableNonRef!lval_only);
That doesn't look too bad.
Nov 19 2018
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/19/18 6:39 PM, Nicholas Wilson wrote:
 On Monday, 19 November 2018 at 15:23:14 UTC, Steven Schveighoffer wrote:
 We can reduce to linear growth using auto ref:

 void lval_only()(int x, auto ref int y, auto ref int z)  disable
 void lval_only()(ref int, int, auto ref int)  disable
 void lval_only(ref int, ref int, int)  disable

 Still not ideal though. I tried auto ref for all 3, but that means it 
 will match both the template and the real function.

 I tried using a constraint, but not sure how to get the parameter 
 ref-ness in a neat way inside the constraint. This does work:

 void lval_only()(auto ref int x, auto ref int y, auto ref int z) 
  disable if (!__traits(isRef, x) || !__traits(isRef, y) || 
 !__traits(isRef, z))

 But it is a bit ugly.
template isRefX(A...) if (A.length == 1) {     enum bool isRefX = __traits(isRef, A[0]); } template allIsRef(A...) {     enum allIsRef = allSatisfy!(isRefX, A); } void lval_only()(auto ref int x, auto ref int y, auto ref int z) disable if (!allIsRef!(x, y, z));
Yep, that is much better. I didn't think of that without making the parameters variadic, lol! I don't think you need the if(A.length == 1) thing, because alias should work there. They are symbols and won't be keywords. -Steve
Nov 19 2018
prev sibling parent AlCaponeJr <a c.com> writes:
On Sunday, 18 November 2018 at 15:55:11 UTC, Rubn wrote:
 On Saturday, 17 November 2018 at 14:49:26 UTC, kinke wrote:
 On Saturday, 17 November 2018 at 13:01:12 UTC, Rubn wrote:
 For this what about if there are multiple parameters? How 
 many overloads do you have to define to get this behavior?
I'd assume a single one. It should be analogous to this: ``` void lval_only(uint x, short y) disable; void lval_only(int x, int y); void main() { byte y = 1; lval_only(100_000, y); } ``` The disabled function is preferred, so this doesn't compile. As by-value params are to be preferred for rvalue args in overload resolution, the single overload should do in your example. --- I'm a huge fan of this DIP and have been wanting this in the language literally since the day I wrote my first D code, immediately stumbling into this limitation (but fortunately not losing much interest due to numerous advantages and syntax loveliness).
If that's the case then it'll look something like this, for just 3 parameters if you want the old behavior: void lval_only(int x, int y, int z) disable; void lval_only(int x, int y, ref int z) disable; void lval_only(int x, ref int y, ref int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, int z) disable; void lval_only(int x, ref int y, int z) disable; void lval_only(ref int x, int y, ref int z) disable; void lval_only(ref int x, ref int y, ref int z); Not really ideal, I might be missing one, hard to tell.
Nice catch!
Nov 19 2018
prev sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Saturday, 17 November 2018 at 12:46:38 UTC, Mike Parker wrote:
 DIP 1016, "ref T accepts r-values", is now ready for Final 
 Review. This is the last chance for community feedback before 
 the DIP is handed off to Walter and Andrei for the Formal 
 Assessment. Please read the procedures document for details on 
 what is expected in this review stage:

 https://github.com/dlang/DIPs/blob/master/PROCEDURE.md#final-review

 The current revision of the DIP for this review is located here:

 https://github.com/dlang/DIPs/blob/b0de441a7ba3d55f267dc2ab4fce0eebe42c48e6/DIPs/DIP1016.md

 In it you'll find a link to and summary of the previous review 
 round. This round of review will continue until 11:59 pm ET on 
 December 1 unless I call it off before then.

 Thanks in advance for your participation.
It's happening Manu Evans! It's Happening! This feature is essential in regards to interfacing c++ code as the meaning of cost is different in the D language. -Alex
Nov 17 2018