My thoughts & tries with rvalue references

Zach the Mystic reachzach at gggggmail.com
Thu Apr 4 18:01:00 PDT 2013


On Thursday, 4 April 2013 at 16:25:52 UTC, kenji hara wrote:
> I can tell some reasonable points about 'scope ref'.
> - 'in ref' has been allowed from 2.060 (
> http://d.puremagic.com/issues/show_bug.cgi?id=8105)
> - 'scope ref' is still disallowed. ("Error: scope cannot be ref 
> or out")
> - 'scope' means "the reference cannot escape from local scope".
>   And an rvalue reference cannot escape from passed function. 
> There is
> consistent semantics.
> - 'in' is equivalent to 'const scope' ( 
> http://dlang.org/function.html
> )<http://dlang.org/function.html>
>   So, 'in ref' is equivalent to 'const scope ref'.
> - Currently 'scope' affects to delegate parameter. In other 
> cases, 'scope'
> has no meaning.
>
> I recognize that Jonathan had opposed to 'in ref' because it 
> had supported
> just only "const rvalue reference" (like 'cosnt T&' in C++). In 
> D, 'const'
> means physical const, so he has thought that mutable rvalue 
> reference
> should be supported in D.
>
> So, I think 'scope ref' is good proposal against the Jonathan's 
> objection.
>
> Kenji Hara

My argument would be that 'scope ref' and '@temp ref' are two 
different horns of the same devil, really. The problem with 
'@temp ref' is that it's "syntax creep", adding a new storage 
class for limited reward. But 'scope ref' is equally problematic, 
because if it *does* allow returning the parameter by reference 
it will be deceptively different from simply what 'scope' would 
do. So the syntax creep would be replaced by the confusing nature 
of 'ref', 'scope', and 'scope ref':

ref int func(ref int a) { return a; } // Okay

ref int func2(scope int a) {
   return *new int;
   //return a; // No good, error: a is 'scope'
}

// Okay: 'scope ref' means something different from 'scope'
ref int func3(scope ref int a) { return a; }

ref int testFuncs(ref int y) {
   int x;
   return func(x); // Error: ref return assumed local as x
   return func(y); // Okay: y is from outside and returnable
   return func2(x); // Okay: 'scope' ensures x not returned
   return func2(y); // Okay
   return func3(x); // Error: ref return assumed local as x
   return func3(y); // Okay: y outside
   return func3(53); // Error: temp 53 is local
}

If 'scope' were defined as above, 'scope ref' could not be used 
to say that you *also* want the parameter to be 'scope' in 
addition to 'scope ref'. This leads into the remaining issue with 
DIP25, which is that 'scope' would be useful to tell the calling 
function that the passed-in variable will not be 'ref' returned, 
as in func2() above. DIP25 may want 'scope' to help add 
flexibility to what may or may not be returned.

Dicebot's suggestion, that ref int func3(scope ref int a) {} 
above be banned from returning 'a', would solve this problem. In 
this case 'scope ref' would mean both 'scope' *and* '@temp ref'. 
It does however conflate the two features, making it impossible 
to return an rvalue ref parameter by ref.

It may be that the cases where you actually *want* to return an 
rvalue ref parameter by reference are so rare that no one will 
miss that you can't do it. Or, conversely, it may be so rare that 
you want to specify 'scope' on your parameter in addition to 
'scope ref' that no one will miss not being able to do that 
either. But one of these solutions must be accepted is 'scope 
ref' is to mean what is suggested.

The other horn of the devil is to swallow the distasteful pill 
and allow '@temp ref', 'ref&', or some other "syntax creep".


More information about the Digitalmars-d mailing list