View mode: basic / threaded / horizontal-split · Log in · Help
April 04, 2013
Re: My thoughts & tries with rvalue references
2013/4/5 Namespace <rswhite4@googlemail.com>

> Hmm, I don't know if I could write a long and good text for the DIP. My
> english is very limited and not free of failures.
> I still had hoped that Kenji or some other find the time, to see over my
> code and to make a DIP/Pull Request.
>

Timely guess. I roughly implemented it in my experimental branch.

https://github.com/9rnsr/dmd/commits/new_inref

I need more cleanup for it, but it would work as we expected.

Kenji Hara
April 04, 2013
Re: My thoughts & tries with rvalue references
On Thursday, 4 April 2013 at 16:21:50 UTC, Namespace wrote:
>> I don't know. My opinion has no value here.
> I know. But I wanted to hear just your personal opinion about 
> the code and if you have any suggestions or anything.
>
>> I may advice to write a DIP that makes more accent on 
>> theoretical side of problem - what "scope" currently is, how 
>> it combines with ref now, how it should combine, how Andrei's 
>> DIP fits in the picture, how it fits overall type system, what 
>> are possible code breakage scenarios, what are typical use 
>> cases for this feature etc. If such DIP and matching pull 
>> request do exist, it is only matter of agreement (with 
>> Andrei/Walter) about points stated in DIP.
>
> Hmm, I don't know if I could write a long and good text for the 
> DIP. My english is very limited and not free of failures.
> I still had hoped that Kenji or some other find the time, to 
> see over my code and to make a DIP/Pull Request.

Well, I doubt there are that many native speakers here which will 
be shocked by bad English :) But if you gather all data mentioned 
(see also Kenji's comment), I can write DIP itself for you. Type 
system changes should be studied in smallest details as those 
have have very long term consequences and incredibly hard to 
replace with better solutions later.
April 04, 2013
Re: My thoughts & tries with rvalue references
> Well, I doubt there are that many native speakers here which 
> will be shocked by bad English :) But if you gather all data 
> mentioned (see also Kenji's comment), I can write DIP itself 
> for you. Type system changes should be studied in smallest 
> details as those have have very long term consequences and 
> incredibly hard to replace with better solutions later.

That sounds good. Then I will try over the weekend to collect all 
the necessary data and post them here. Then you can take a quick 
look, whether you have enough information or if I need a little 
late filing.
April 04, 2013
Re: My thoughts & tries with rvalue references
On Thursday, 4 April 2013 at 16:31:06 UTC, kenji hara wrote:
> 2013/4/5 Namespace <rswhite4@googlemail.com>
>
>> Hmm, I don't know if I could write a long and good text for 
>> the DIP. My
>> english is very limited and not free of failures.
>> I still had hoped that Kenji or some other find the time, to 
>> see over my
>> code and to make a DIP/Pull Request.
>>
>
> Timely guess. I roughly implemented it in my experimental 
> branch.
>
> https://github.com/9rnsr/dmd/commits/new_inref
>
> I need more cleanup for it, but it would work as we expected.
>
> Kenji Hara

That works well. Thanks for your efforts.
April 05, 2013
Re: My thoughts & tries with rvalue references
On Thursday, 4 April 2013 at 07:52:51 UTC, Dicebot wrote:
> After some thinking on topic I come to conclusion that rvalue 
> refs _should_ be "scope ref" and stuff like "ref int f(@temp 
> ref int x) { return x; }" is invalid. I can see no valid use 
> case for such an error-prone case.

Perhaps they should, but at least I will give the use case I was 
thinking of.

If you've got a large struct, you don't want to pass it by value. 
Say you've got two functions which process and return a Large, 
and they accept rvalue refs. It might not be too much to ask that 
a Large always be an lvalue, but let's say you want to pass it 
directly by value for some reason.

struct Large { ... }
ref Large process1(@temp ref Large a) { return a; }
ref Large process2(@temp ref Large a) { return a; }

Large* lar = &process2(process1(Large("Pass"," a ", "Large", 
"here")));

The use case would allow this to work. And with the kind of error 
checking suggested in DIP25, this kind of construction would not 
actually be error prone. 'lar' would be understood as locally 
derived and could not escape the function it was defined in.

But to speak to your point, this kind of single expression 
chaining of ref functions might be so rare that there's no great 
reason to allow it in tandem with rvalues.
April 05, 2013
Re: My thoughts & tries with rvalue references
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".
April 05, 2013
Re: My thoughts & tries with rvalue references
On Friday, 5 April 2013 at 00:12:33 UTC, Zach the Mystic wrote:
> struct Large { ... }
> ref Large process1(@temp ref Large a) { return a; }
> ref Large process2(@temp ref Large a) { return a; }
>
> Large* lar = &process2(process1(Large("Pass"," a ", "Large", 
> "here")));

This is exactly type of code I consider to be bad style and want 
to see banned. Function that gets rvalue ref should never return 
it as it knows nothing about its lifetime. Actually, I can't even 
find scope definition for temporaries in dlang.org, but it is 
hardly a good thing to rely on anyway. Best is to assume that 
when function is gone, so is rvalue temporary.

Your code begs for using plain refs and storing Large in a stack 
variable before calling function chain. May look a bit less 
convenient but much more reliable and understandable.
April 05, 2013
Re: My thoughts & tries with rvalue references
On Thursday, 4 April 2013 at 16:25:52 UTC, kenji hara wrote:
> I also think writing DIP would be better.
> ...

Btw, Kenji, what do you think about redefining "in" to "const 
scope ref" and allowing compiler to chose how variable exactly is 
passed ("auto ref" with no template bloat)? Within those 
restrictions plain values should be indistinguishable from const 
rvalue refs.

Will make "in" also much more meaningful as a separate entity.
April 05, 2013
Re: My thoughts & tries with rvalue references
On Friday, 5 April 2013 at 07:48:38 UTC, Dicebot wrote:
> On Thursday, 4 April 2013 at 16:25:52 UTC, kenji hara wrote:
>> I also think writing DIP would be better.
>> ...
>
> Btw, Kenji, what do you think about redefining "in" to "const 
> scope ref" and allowing compiler to chose how variable exactly 
> is passed ("auto ref" with no template bloat)? Within those 
> restrictions plain values should be indistinguishable from 
> const rvalue refs.
>
> Will make "in" also much more meaningful as a separate entity.

To change "in" from "const scope" to "const scope ref" is IMO a 
bad idea. It will break code and it's not intuitive.
In my opinion we should use "ref" in combination with something 
else (in this case "scope").
But that is my personal opinion.
April 05, 2013
Re: My thoughts & tries with rvalue references
On Friday, 5 April 2013 at 08:35:03 UTC, Namespace wrote:
> On Friday, 5 April 2013 at 07:48:38 UTC, Dicebot wrote:
>> On Thursday, 4 April 2013 at 16:25:52 UTC, kenji hara wrote:
>>> I also think writing DIP would be better.
>>> ...
>>
>> Btw, Kenji, what do you think about redefining "in" to "const 
>> scope ref" and allowing compiler to chose how variable exactly 
>> is passed ("auto ref" with no template bloat)? Within those 
>> restrictions plain values should be indistinguishable from 
>> const rvalue refs.
>>
>> Will make "in" also much more meaningful as a separate entity.
>
> To change "in" from "const scope" to "const scope ref" is IMO a 
> bad idea. It will break code and it's not intuitive.
> In my opinion we should use "ref" in combination with something 
> else (in this case "scope").
> But that is my personal opinion.

How so? It does not break anything, as all "const scope" cases 
can be processed with "const scope ref", in fact, compiler should 
be allowed to degrade first to latter. Regarding meaning - if 
"scope ref" means permissive rvalues (mutable ones), then "const 
scope ref" means closer match for C++ "const &" - constant 
references that can't escape scope. I actually have an impression 
you do really want exactly "const scope ref" considering frequent 
references to C++.

Tricky part as far as I can see is ABI - one needs to be able to 
accept both value and ref parameters within same function 
signature. Possible but may be too hacky to implement.
1 2 3 4 5 6
Top | Discussion index | About this forum | D home