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

Rubn where at is.this
Fri Jan 25 21:00:53 UTC 2019


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.


More information about the Digitalmars-d-announce mailing list