Jump to page: 1 2
Thread overview
DIP 1016--ref T accepts r-values--Final Review
Nov 17, 2018
Mike Parker
Nov 17, 2018
Rubn
Nov 17, 2018
kinke
Nov 18, 2018
Rubn
Nov 18, 2018
Manu
Nov 19, 2018
12345swordy
Nov 19, 2018
Nicholas Wilson
Nov 19, 2018
AlCaponeJr
Nov 17, 2018
12345swordy
November 17, 2018
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.
November 17, 2018
    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
November 17, 2018
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).
November 17, 2018
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
November 18, 2018
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.

November 18, 2018
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 :)
November 19, 2018
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
November 19, 2018
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
November 19, 2018
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!
November 19, 2018
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.

« First   ‹ Prev
1 2