DIP 1016--ref T accepts r-values--Formal Assessment

kinke noone at nowhere.com
Wed Jan 30 21:15:38 UTC 2019


On Monday, 28 January 2019 at 19:58:24 UTC, Andrei Alexandrescu 
wrote:
> On 1/28/19 1:00 PM, Andrei Alexandrescu wrote:
>> It seems to me that a proposal adding the "@rvalue" attribute 
>> in function signatures to each parameter that would accept 
>> either an rvalue or an lvalue would be easy to argue.
>> 
>> - No exposing existing APIs to wrong uses
>> - The function's writer makes the decision ("I'm fine with 
>> this function taking an rvalue")
>> - Appears in the function's documentation
>> - Syntax is light and localized where it belongs
>> - Scales well with number of parameters
>> - Transparent to callers

The inverse, the @norval attribute, would feature all but the 
first advantages, at least once people get used to normal ref 
allowing (some) rvalues too. I can't think of many good reasons 
for a callee to disallow rvalues (with matching type at least); 
your example wrt. interlockedIncrement() is a good one, as 
synchronization overhead clearly isn't required for an rvalue. 
But my usages of (mutable) ref are >99% of the time something 
like:

Header readHeader(ref Stream stream)
{
     // read from & advance stream, return parsed header
}

where I'd like to be able put everything into one line if trivial 
(stream not required later on):

readHeader(Stream("file")).doSomething();

(And const ref is mostly used for performance with bigger 
structs, where rvalues are absolutely fine).

TLDR: I'd guess that I'd need to type `@rvalue` about 1000 times 
as often as `@norval`. I'm not kidding.

> TL;DR: it could be argued that the only dangerous conversions 
> are lvalue -> temp rvalue -> ref, so only disable those. The 
> conversion rvalue -> temp rvalue -> ref is not dangerous 
> because the starting value on the caller side could not be 
> inspected after the call anyway.

I agree that the DIP needs to be clearer wrt. rvalues resulting 
from implicit conversions. I also agree with the above point. I'm 
just not sure we need to allow implicit conversions from rvalue 
argument expressions at all. To minimize the changes for overload 
resolution, it might be enough to allow rvalue argument 
expressions of matching type only, i.e., the types which are 
allowed for current ref semantics. After all, I don't plan to use 
the proposed ref semantics for primitive types where that might 
come in handy (something silly like `modf(x, 123.456)` if the 
second param is a `ref real`), and explicit casts would IMO be an 
acceptable price to pay for safety and visibility in the 
remaining cases.


More information about the Digitalmars-d-announce mailing list