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