March 28, 2019
On Thursday, 28 March 2019 at 14:36:59 UTC, bitwise wrote:
> On Wednesday, 27 March 2019 at 01:38:40 UTC, Andrei Alexandrescu wrote:
>> Here, the DIP Author clearly expresses two reasons why a programmer may choose to declare a function to accept `ref` arguments. The Language Maintainers see this as the core of the proposal and would expect the distinction between the two cases to be maintained throughout. [However, this proposal does not maintain the distinction and instead conflates the two][1] cases. The Language Maintainers insist that any proposal allowing `ref` parameters to accept rvalue references must clearly define how functions which make use of `ref` for side effects will not accept rvalues.
>
> I don't see anything in the new DIP that addresses the above issue. [1]

Thats because it was never an issue with the dip, the conflation was entirely deliberate, It is the review if the dip that was wrong. This issue is resolved by the fact that temporaries created are not usable after the expression they appear in, and things that look like lvalues (e.g. @property functions) are disallowed as candidates for rvalue -> ref conversion.

> It seems like a waste to have a keyword that's just an alias for two others (in = const scope), so why not put 'in' to better use, like to qualify a ref parameter as accepting rvalues, or to outright replace 'ref' for rvalue-ref accepting parameters?

Code breakage.
March 28, 2019
On 3/28/19 10:36 AM, bitwise wrote:
> On Wednesday, 27 March 2019 at 01:38:40 UTC, Andrei Alexandrescu wrote:
>> Work has been underway on redoing DIP 1016. I haven't made a pull request yet as it's a bit early. Looking for high-level observations:
>>
>> https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a
>>
>> Thanks in advance for any feedback.
> 
>  From the response to DIP 1016:
> 
>> Here, the DIP Author clearly expresses two reasons why a programmer may choose to declare a function to accept `ref` arguments. The Language Maintainers see this as the core of the proposal and would expect the distinction between the two cases to be maintained throughout. [However, this proposal does not maintain the distinction and instead conflates the two][1] cases. The Language Maintainers insist that any proposal allowing `ref` parameters to accept rvalue references must clearly define how functions which make use of `ref` for side effects will not accept rvalues.
> 
> I don't see anything in the new DIP that addresses the above issue. [1]

The nonassignability requirement addresses it.


March 28, 2019
On 3/28/19 12:07 PM, Nicholas Wilson wrote:
> things that look like lvalues (e.g. @property functions) are disallowed as candidates for rvalue -> ref conversion

Can you please point to the DIP text that proposes such disallowance? All I see is:

fun(x.prop);   // properties

given as an example of call that should succeed yet fails. The dip is at:

https://github.com/dlang/DIPs/blob/master/DIPs/rejected/DIP1016.md
March 28, 2019
On Thursday, 28 March 2019 at 16:28:47 UTC, Andrei Alexandrescu wrote:
> On 3/28/19 12:07 PM, Nicholas Wilson wrote:
>> things that look like lvalues (e.g. @property functions) are disallowed as candidates for rvalue -> ref conversion
>
> Can you please point to the DIP text that proposes such disallowance? All I see is:
>
> fun(x.prop);   // properties
>
> given as an example of call that should succeed yet fails. The dip is at:
>
> https://github.com/dlang/DIPs/blob/master/DIPs/rejected/DIP1016.md

That was covered in the nonassignability requirement was it not? (it is confusing with multiple documents)
March 28, 2019
On Thursday, 28 March 2019 at 16:14:04 UTC, Andrei Alexandrescu wrote:
> On 3/28/19 10:36 AM, bitwise wrote:
>> On Wednesday, 27 March 2019 at 01:38:40 UTC, Andrei Alexandrescu wrote:
>>> Work has been underway on redoing DIP 1016. I haven't made a pull request yet as it's a bit early. Looking for high-level observations:
>>>
>>> https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a
>>>
>>> Thanks in advance for any feedback.
>> 
>>  From the response to DIP 1016:
>> 
>>> Here, the DIP Author clearly expresses two reasons why a programmer may choose to declare a function to accept `ref` arguments. The Language Maintainers see this as the core of the proposal and would expect the distinction between the two cases to be maintained throughout. [However, this proposal does not maintain the distinction and instead conflates the two][1] cases. The Language Maintainers insist that any proposal allowing `ref` parameters to accept rvalue references must clearly define how functions which make use of `ref` for side effects will not accept rvalues.
>> 
>> I don't see anything in the new DIP that addresses the above issue. [1]
>
> The nonassignability requirement addresses it.

I agree that the nonassignability requirement fills a major pothole, but it doesn't address the issue of expressing your intent as the writer of a function with ref parameters. The caller may have trouble determining if a function will modify the argument passed to it. The issue could be mitigated by function/parameter naming convention, comments, documentation, or providing source code to the caller, but all of these solutions have the potential to be spotty or absent, so I believe something should be done to make the writer's intent clear to the caller.
March 28, 2019
On 3/28/19 3:59 PM, bitwise wrote:
> I agree that the nonassignability requirement fills a major pothole, but it doesn't address the issue of expressing your intent as the writer of a function with ref parameters. The caller may have trouble determining if a function will modify the argument passed to it. The issue could be mitigated by function/parameter naming convention, comments, documentation, or providing source code to the caller, but all of these solutions have the potential to be spotty or absent, so I believe something should be done to make the writer's intent clear to the caller.

A salient point.

Also made in the DIP as "In such cases, w.price is not assignable and calls such as applyDiscount(w.price) or w.price.applyDiscount will succeed but not perform any meaningful update. A maintainer expecting such calls to fail may be surprised. We consider this is an inevitable price to pay for the gained flexibility."

I reckon that there's implied that some sort of @rvalue attribute would be a better solution, a la void fun(@rvalue ref T). I'm afraid this would be widely protested, even more widely than doing nothing or going with the nonassignable requirement. You are of course encouraged to say what you think is right and raise the matter to other folks as well.

The nonassignable requirement is a major improvement, but won't catch all potential misuses. I don't know how to do better.
March 28, 2019
On Thursday, 28 March 2019 at 20:11:26 UTC, Andrei Alexandrescu wrote:
> On 3/28/19 3:59 PM, bitwise wrote:
>> I agree that the nonassignability requirement fills a major pothole, but it doesn't address the issue of expressing your intent as the writer of a function with ref parameters. The caller may have trouble determining if a function will modify the argument passed to it. The issue could be mitigated by function/parameter naming convention, comments, documentation, or providing source code to the caller, but all of these solutions have the potential to be spotty or absent, so I believe something should be done to make the writer's intent clear to the caller.
>
> A salient point.
>
> Also made in the DIP as "In such cases, w.price is not assignable and calls such as applyDiscount(w.price) or w.price.applyDiscount will succeed but not perform any meaningful update. A maintainer expecting such calls to fail may be surprised. We consider this is an inevitable price to pay for the gained flexibility."
>
> I reckon that there's implied that some sort of @rvalue attribute would be a better solution, a la void fun(@rvalue ref T). I'm afraid this would be widely protested, even more widely than doing nothing or going with the nonassignable requirement. You are of course encouraged to say what you think is right and raise the matter to other folks as well.
>
> The nonassignable requirement is a major improvement, but won't catch all potential misuses. I don't know how to do better.

I liked the idea someone else gave in regards to "out". I think it would be too difficult to repurpose out as it is now, but perhaps even just "out ref" would do.


    void foo(out ref int value);

    int v;
    foo(out v);

It would be have the same way as C#, but again how many different type of attributes are there going to be. I honestly think there are too many, and the current way in/out are implement, they should just be deprecated. They don't add that much value.
March 28, 2019
On Thursday, 28 March 2019 at 20:11:26 UTC, Andrei Alexandrescu wrote:
> The nonassignable requirement is a major improvement, but won't catch all potential misuses. I don't know how to do better.

You could be more strict and consider that any call of the form

    applyDiscount(x.price)

is invalid if `price` is a method, whether or not that method is a property. The correct way to pass price's return would then be:

    applyDiscount(x.price())

This syntax is a little surprising to readers because D users don't expect empty parentheses for function calls, but I'd count that as a plus: this situation is a little ambiguous, so code that makes the user wonder about what it does instead of taking it for granted is good.

Additionally, you can probably skip the nonassignable requirement for const references.
March 28, 2019
On Wednesday, 27 March 2019 at 01:38:40 UTC, Andrei Alexandrescu wrote:
> Work has been underway on redoing DIP 1016.

Thanks for the reboot! I just quickly skimmed through, and it seems to be what I hoped for, a more formal DIP1016 with nice binding clarifications.

Things I noted:
* You use types T_k for the arguments in the binding rules, but introduce them as E_k in the 2nd sentence.
* Wrt. binding rule 3, I had to think about the difference of assignability vs. remaining lvalues after the previous rules. If I understand correctly, you're proposing to let a non-assignable `const uint` lvalue bind to a `ref long` param, as opposed to a mutable `uint` lvalue argument. I'd find that a bit counter-intuitive (or more complex than necessary) and would rather disallow all remaining lvalues (+ the remaining assignables), forcing the user to add a clarifying cast regardless of the lvalue mutability.
March 29, 2019
On Thursday, 28 March 2019 at 23:46:34 UTC, kinke wrote:
> I'd find that a bit counter-intuitive (or more complex than necessary)

Just to elaborate - that would allow to quickly summarize the rules as in:

- If the argument is an lvalue, it binds if the types are an exact or qualified match.
- If it's an rvalue, it binds if it's implicitly convertible to the param type *and* the argument expression is not assignable (writable property, opIndex expression with opIndexAssign writability, ...).