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

rikki cattermole rikki at cattermole.co.nz
Fri Jan 25 21:06:44 UTC 2019


On 26/01/2019 10:00 AM, Rubn wrote:
> On Friday, 25 January 2019 at 11:56:58 UTC, Walter Bright wrote:
>> On 1/24/2019 11:53 PM, Nicholas Wilson wrote:
>>> That the conflation of pass by reference to avoid copying and 
>>> mutation is not only deliberate but also mitigated by @disable.
>>
>> The first oddity about @disable is it is attached to the foo(int), not 
>> the foo(ref int). If I wanted to know if foo(ref int) takes rvalue 
>> references, I'd have to go looking for the existence of another 
>> function. This is one of those cases where it's hard to prove a 
>> negative, as other functions can be introduced by mixins. This is a 
>> strong usability negative.
>>
>> Next, the @disable applies to the entire parameter list. However, 
>> overload selection is done by looking at each parameter. The DIP says:
>>
>> "The DIP author responded that ideas to improve this are welcome, but 
>> that he cannot imagine a use case."
>>
>> I can guarantee that the use case of more than one reference parameter 
>> will come up. The workarounds the DIP suggests are simply awful.
>>
>> Let's look at what C++ does for rvalue references:
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html
>>
>> The syntax is attached to the parameter declaration of the function it 
>> applies to, not some other function, and not every parameter:
>>
>>     int foo(T&& t);  // C++ rvalue ref
>>
>> There are no weird workarounds, at least for that aspect. There are 
>> indeed unlikable things about the C++ rules, but the DIP needs to pay 
>> more attention to how C++ does this, and justify why D differs. 
>> Particularly because D will likely have to have some mechanism of ABI 
>> compatibility with C++ functions that take rvalue references.
>>
>> This is not a small problem.
>>
>> A further problem is implicit conversions, which the DIP ignores by 
>> only talking about ints.
>>
>>     void bar(int);
>>     void foo(ref int);
>>     enum short s = 10;
>>     bar(s); // compiles
>>     foo(s); // currently fails to compile
>>
>> Should `s` be promoted to an int temporary, then pass the temporary by 
>> reference? I can find no guidance in the DIP. What if `s` is a uint 
>> (i.e. the implicit conversion is a type paint and involves no temporary)?
>>
>> Here's a discussion of Rust and rvalue references which may offer 
>> insight:
>>
>> https://www.reddit.com/r/rust/comments/3ko5pm/explaining_cs_rvalue_references_from_a_rust/ 
>>
>>
>>
>>> That the DIP applies to statements, not expressions.
>>
>> The DIP should not invent its own syntax, give no explanation of it, 
>> and have the reader guess. (It did explain the :=, but not the use of 
>> { } and statements.) And, even if one did a mental rewrite, the 
>> semantics of the statement version are simply wrong. (For example, if 
>> 'fun' was actually a function pointer returned by another function, 
>> and that other function threw an exception - then the destructor would 
>> be run on an uninitialized variable.)
>>
>>
>>> That the construction order issue is trivially fixable, by specifying 
>>> the same behaviour as the non ref case modulo ref.
>>
>> It should never have gotten this far without giving a precise 
>> explanation of how exception safety is achieved when faced with 
>> multiple parameters. In the past I've done a lot of work on exception 
>> safety, and it isn't trivial once one goes beyond trivial cases.
>>
>> All that criticism aside, I'd like to see rvalue references in D. But 
>> the DIP needs significant work.
> 
> For future reference, this is what a formal review should be. I'd also 
> rather your exact words than some summarization of them.

So in other words, a formal review should include somebody acting as an 
'interviewer' prompting questions. If that is the case, I do think it 
would be a good idea.


More information about the Digitalmars-d-announce mailing list