www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP 36: Rvalue References

reply "Namespace" <rswhite4 googlemail.com> writes:
http://wiki.dlang.org/DIP36
Apr 09 2013
next sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/4/10 Namespace <rswhite4 googlemail.com>

 http://wiki.dlang.org/DIP36
Typo:
 Similar to "auto ref" but no extra template instantations.
Similar to "auto ref" but no extra template instantiations One question: void test1(scope ref A a) {} test1(A(42)); // safe, this temporary value is valid for mutation and "scope" ensures it does not leak scope A a =3D A(23); // no difference test1(a); void test32(T)(scope ref T id) {} test32(1337); // Prohibited, no address for "1337" test32(a.id); // fine and safe Why test32 does not accept rvalue like test1? I think that "scope ref" should always behave same for rvalue argument - create temporary and take its address to "scope ref" parameter. Consistent behavior with any types is important for the generic programming. Other than comment, looks good. Good work, Randy and =D0=9C=D0=B8=D1=85=D0= =B0=D0=B8=D0=BB! Kenji Hara
Apr 09 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 00:41:54 UTC, kenji hara wrote:
 Why test32 does not accept rvalue like test1? I think that 
 "scope ref"
 should always behave same for rvalue argument - create 
 temporary and take
 its address to "scope ref" parameter. Consistent behavior with 
 any types is
 important for the generic programming.
That is me to blame. I have convinced Namespace that this is the way to go in private conversation and hope to do the same with you ;) Consistent behavior is important but it does not change the fact that there two types of rvalues in the language - raw literals (42, A.init) and constructed temporaries (A()). Accepting rvalues of the first type in as mutable references may be consistent from the point of view of syntax by _extremely_ confusing semantics-wise: void foo(scope ref int x) { x = 32; } void main() { foo(42); // erm, 32 is the new 42 or ref is not actually ref? } Beauty of "in ref" is that in that case user can't use it in any way that may disclose the fact the temporary variable for non-adressable entities is created. For mutable scope ref it is not the case and we must leak implementation details, which is never good. Another concern is that if someone tries to pass "42" as a mutable ref, most likely he does not really wants it to be mutable and "in ref" is a better match. This may not be consistent from the point of view of generic code, but it is now consistent from the point of view of programmer : A(...) construct always create temporaries, raw value literals never do (well, they will for "in ref" but you can't observe it). I think this is much more important. One extra thing to note is that test32 may actually work if it instantiates T as "const int" for 42 (making it "in ref" essentially), but I don't know if D rules allow it.
Apr 10 2013
next sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 07:43:57 UTC, Dicebot wrote:
 ...
Kenji, got any comments/objections on this point of view? It is not that late to change it back ;)
Apr 11 2013
parent reply kenji hara <k.hara.pg gmail.com> writes:
I think 'scope ref' should always pass the address of given argument to the
function body. Because 'ref' always means "pass the address of given
argument". So, if given argument is an rvalue, compiler will allocate a
temporary on stack, save the rvalue in it, and take its address. If
argument is an lvalue, take its address directly. It should be always true,
eve if the parameter type is small int.

Essentially language semantics should not reflect low level implementation
detail. After DIP36 is accepted, we will get a full set of tools for
efficiency - T, ref T, and scope ref T. From the toolbox, you can choose
the most efficient storage class based on the T.

void foo(MostEfficientParameters!(int, string, S, int[1024]) params) { ... }

Kenji Hara

2013/4/11 Dicebot <m.strashun gmail.com>

 On Wednesday, 10 April 2013 at 07:43:57 UTC, Dicebot wrote:

 ...
Kenji, got any comments/objections on this point of view? It is not that late to change it back ;)
Apr 11 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
You don't think exposing creation of temporaries is low level 
implementation
detail?

On Thursday, 11 April 2013 at 08:14:00 UTC, kenji hara wrote:
 ...

 Kenji Hara
Apr 11 2013
parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/4/11 Dicebot <m.strashun gmail.com>

 You don't think exposing creation of temporaries is low level
 implementation
 detail?
No. In this case, it is the purpose of 'scope ref', not is the implementation details. What is the language semantics and what is the implementation detail - that varies depending on what is properly supported in the language. D explicitly distinguishes lvalues and rvalues, and also defines that rvalue cannot be taken its address (== reference). The purpose of 'scope ref' is that the parameter can be received both lvalues and rvalues with one function body. To receive lvalues, scope ref should take the address of them. As a conclusion, to receive rvalues temporary creation is necessary in caller site. Yes, it mostly represents implementation details, but it is still description of language semantics. This confusion is almost inevitable. Because the essential purpose of 'scope ref' is already "efficiency". Furthermore, note that the desired "efficiency" is not "the speed of argument passing". I recognize that it is "to avoid code bloating of function body". If you need "most efficient argument passing", you should choose it from the argument type. 'scope ref' is not a thing to make the choice automatic. Kenji Hara
Apr 11 2013
next sibling parent "Dicebot" <m.strashun gmail.com> writes:
On Thursday, 11 April 2013 at 09:27:11 UTC, kenji hara wrote:
 No. In this case, it is the purpose of 'scope ref', not is the
 implementation details.

 What is the language semantics and what is the implementation 
 detail - that
 varies depending on what is properly supported in the language. 
 D
 explicitly distinguishes lvalues and rvalues, and also defines 
 that rvalue
 cannot be taken its address (== reference).

 The purpose of 'scope ref' is that the parameter can be 
 received both
 lvalues and rvalues with one function body. To receive lvalues, 
 scope ref
 should take the address of them. As a conclusion, to receive 
 rvalues
 temporary creation is necessary in caller site.

 Yes, it mostly represents implementation details, but it is 
 still
 description of language semantics.
 This confusion is almost inevitable. Because the essential 
 purpose of
 'scope ref' is already "efficiency".

 Furthermore, note that the desired "efficiency" is not "the 
 speed of
 argument passing".
 I recognize that it is "to avoid code bloating of function 
 body". If you
 need "most efficient argument passing", you should choose it 
 from the
 argument type. 'scope ref' is not a thing to make the choice 
 automatic.

 Kenji Hara
I trust your judgement then, will update DIP then. But I am still afraid of confusion.
Apr 11 2013
prev sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
Kenji, what do you think, should we / you create a pull request 
for the proposal?
Most seem to be very satisfied with the proposal. In addition, a 
pull request would rather cause that Walter and Andrei join the 
discussion.
Apr 12 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Thanks to Kenji there is now a corresponding pull request:
https://github.com/D-Programming-Language/dmd/pull/1903

Let us hope that it will be quickly merged.

I still hope that Andrei or Walter say something to this topic.
Maybe we have a chance with this pull request. ;)
Apr 17 2013
parent reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
On Wednesday, 17 April 2013 at 17:50:07 UTC, Namespace wrote:
 Thanks to Kenji there is now a corresponding pull request:
 https://github.com/D-Programming-Language/dmd/pull/1903

 Let us hope that it will be quickly merged.

 I still hope that Andrei or Walter say something to this topic.
 Maybe we have a chance with this pull request. ;)
Finally, I'm tired of copy-pasting the same code just to change to "ref". :)
Apr 17 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 Finally, I'm tired of copy-pasting the same code just to change 
 to "ref". :)
What do you mean?
Apr 17 2013
parent reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
On Wednesday, 17 April 2013 at 19:29:51 UTC, Namespace wrote:
 Finally, I'm tired of copy-pasting the same code just to 
 change to "ref". :)
What do you mean?
This: /// dot product of two Vector3 vectors auto dot(T) (Vector3!T u, Vector3!T v) safe pure nothrow { return u.x * v.x + u.y * v.y + u.z * v.z; } /// dot product of two Vector3 vectors auto dot(T) (ref Vector3!T u, ref Vector3!T v) safe pure nothrow { return u.x * v.x + u.y * v.y + u.z * v.z; }
Apr 17 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 17 April 2013 at 20:18:56 UTC, Minas Mina wrote:
 On Wednesday, 17 April 2013 at 19:29:51 UTC, Namespace wrote:
 Finally, I'm tired of copy-pasting the same code just to 
 change to "ref". :)
What do you mean?
This: /// dot product of two Vector3 vectors auto dot(T) (Vector3!T u, Vector3!T v) safe pure nothrow { return u.x * v.x + u.y * v.y + u.z * v.z; } /// dot product of two Vector3 vectors auto dot(T) (ref Vector3!T u, ref Vector3!T v) safe pure nothrow { return u.x * v.x + u.y * v.y + u.z * v.z; }
Oh, I thought you had anything against the DIP. ^^ Yes that annoys me as well. That's why I really hope that we can fix this vexing issue soon. :)
Apr 17 2013
parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 17 April 2013 at 20:27:27 UTC, Namespace wrote:
 Oh, I thought you had anything against the DIP. ^^
 Yes that annoys me as well. That's why I really hope that we 
 can fix this vexing issue soon. :)
Yes, this temp ref issue is far more important than the ref safety issue I've been concerning myself with. I wouldn't mind if the objections I've brought up fall in favor of whatever it takes to get temp ref solved. ref safety is important, but it's nowhere near the shear *annoyingness* factor of rvalue temp refs. But someone besides me would need to evaluate both DIP 35 & 36 to see if there were any real conflicts there.
Apr 17 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 Yes, this temp ref issue is far more important than the ref 
 safety issue I've been concerning myself with. I wouldn't mind 
 if the objections I've brought up fall in favor of whatever it 
 takes to get temp ref solved. ref safety is important, but it's 
 nowhere near the shear *annoyingness* factor of rvalue temp 
 refs.
That is true, but it makes the impression that, with the exception of Kenji, none of the core developers is interested in a solution to this problem. The DIP was not much discussed and the pull request is regularly overlooked / ignored. Also in the discussion on the pull request no comments for Walter or Andrei are found. Although the pull is complete and has passed all the tests and would be ready to merge. Also this thread is completely ignored even though both write in this forum regularly and participate in other discussions. To me this makes the impression that they were not interested in this problem (or in our solution to the problem). Either they want the problem does not solve or try to solve it in their own way and that can take a very long time. At least an annotation what of both is the case or if I see it completely wrong, would be polite.
 But someone besides me would need to evaluate both DIP 35 & 36 
 to see if there were any real conflicts there.
Yes that would be good.
Apr 20 2013
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 20 April 2013 at 14:42:57 UTC, Namespace wrote:
 Yes, this temp ref issue is far more important than the ref 
 safety issue I've been concerning myself with. I wouldn't mind 
 if the objections I've brought up fall in favor of whatever it 
 takes to get temp ref solved. ref safety is important, but 
 it's nowhere near the shear *annoyingness* factor of rvalue 
 temp refs.
That is true, but it makes the impression that, with the exception of Kenji, none of the core developers is interested in a solution to this problem. The DIP was not much discussed and the pull request is regularly overlooked / ignored.
I don't think adding more to the language is the sane thing to do right now.
Apr 20 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 I don't think adding more to the language is the sane thing to 
 do right now.
Why not? Could you explain this? This issue is discussed since more than a year and it is a very annoying issue. And even if Walter and Andrei are of this opinion, it would still only polite when they explain in detail why they think this.
Apr 20 2013
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 20 April 2013 at 15:17:39 UTC, Namespace wrote:
 I don't think adding more to the language is the sane thing to 
 do right now.
Why not? Could you explain this? This issue is discussed since more than a year and it is a very annoying issue. And even if Walter and Andrei are of this opinion, it would still only polite when they explain in detail why they think this.
Listen, this issue is very real, but it is mostly about performance. I'll tell you something : the best performance improvement is the one that bring your program from non working state to working one. And right now, many existing feature are broken. The let's add whatever feature we have in mind is the very cause of the state of the language right now.
Apr 20 2013
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
 Listen, this issue is very real, but it is mostly about 
 performance. I'll tell you something : the best performance 
 improvement is the one that bring your program from non working 
 state to working one. And right now, many existing feature are 
 broken.

 The let's add whatever feature we have in mind is the very 
 cause of the state of the language right now.
As far as I remember, you were in favor of the introduction of the feature "attribute inference for auto functions". Also a new feature but none that would solve problems which are discussed since more than a year. Furthermore this issue should be solved with the introduction of "auto ref" (AFAIK introduced with dmd 2.035?). So this is not like "add whatever feature" but rather "fix an issue, that is often discussed and annoys many people".
Apr 20 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 20 April 2013 at 15:39:42 UTC, Namespace wrote:
 Listen, this issue is very real, but it is mostly about 
 performance. I'll tell you something : the best performance 
 improvement is the one that bring your program from non 
 working state to working one. And right now, many existing 
 feature are broken.

 The let's add whatever feature we have in mind is the very 
 cause of the state of the language right now.
As far as I remember, you were in favor of the introduction of the feature "attribute inference for auto functions". Also a new feature but none that would solve problems which are discussed since more than a year.
Half of the standard lib is broken because it is annotated incorrectly.
 Furthermore this issue should be solved with the introduction 
 of "auto ref" (AFAIK introduced with dmd 2.035?). So this is 
 not like "add whatever feature" but rather "fix an issue, that 
 is often discussed and annoys many people".
DIP36 discuss the addition of new features.
Apr 20 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
You miss quite an important point - DIP36 does not add new 
feature. It partially defines existing feature (scope) to replace 
an existing but broken solution (auto ref). Nothing new is really 
added to the language, only existing stuff better defined.
Apr 20 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/20/2013 05:56 PM, Dicebot wrote:
 You miss quite an important point - DIP36 does not add new feature. It
 partially defines existing feature (scope) to replace an existing but
 broken solution (auto ref). Nothing new is really added to the language,
 only existing stuff better defined.
_New meaning_ is assigned to existing grammar whose original purpose is at most loosely related to the _new_ features. I do not think that making 'scope' indicate an rvalue reference is particularly future proof.
Apr 20 2013
parent reply Manu <turkeyman gmail.com> writes:
On 21 April 2013 06:51, Timon Gehr <timon.gehr gmx.ch> wrote:

 On 04/20/2013 05:56 PM, Dicebot wrote:

 You miss quite an important point - DIP36 does not add new feature. It
 partially defines existing feature (scope) to replace an existing but
 broken solution (auto ref). Nothing new is really added to the language,
 only existing stuff better defined.
_New meaning_ is assigned to existing grammar whose original purpose is a=
t
 most loosely related to the _new_ features.

 I do not think that making 'scope' indicate an rvalue reference is
 particularly future proof.
That's not what scope does. Scope promises that the variables will not escape the scope. And as such, just happens to make passing a temporary by ref safe. It does not implement r-value ref's. It simply allows refs to temporaries to be considered a safe operation. This DIP is actually likely to solve an important source of problems, consider: void func(const ref matrix m); func(x.getMatrix()); // compile error! // ... matrix temp =3D x.getMatrix(); func(temp); // no more compile error! (but equally unsafe/dangerous) In this example, the 'solution', which is what everybody does right now, is exactly as unsafe as the attempted call with the r-value. ref, as in the language right now, is a fundamentally unsafe operation... and not only is it technically unsafe, a programmer can't even know if it is practically unsafe or not. Since they have a habit of using this hack, they may unknowingly use it in a call site where it's not *practically* safe to do it. They can't know, and by habit (and frustration) they're trained to use this hack everywhere. With 'scope ref' (or 'in ref'), the programmer now has a guide to say whether it's safe to pass a temporary or not. In the future, if the function does not receive scope ref, perhaps the programmer will start to presume that it is NOT safe to pass a temporary, and stop doing so via the current local-variable hack. scope was always intended to implement this promise as far as I'm lead to believe(?). <Side rant> the first one that comes up, every time (which really doesn't help with first impressions), and I'm fairly sure every single person I've introduced to D has complained about this. It's kind of embarrassing when I'm saying that D is really cool, and then I have to start making excuses and apologising for this, and assure them that it's a known issue, and it'll be fixed one day.
Apr 20 2013
next sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Sunday, 21 April 2013 at 00:51:31 UTC, Manu wrote:
 That's not what scope does. Scope promises that the variables 
 will not
 escape the scope. And as such, just happens to make passing a 
 temporary by
 ref safe.
 It does not implement r-value ref's. It simply allows refs to 
 temporaries
 to be considered a safe operation.
It's a two-fer! (2 for 1 deal)
 This DIP is actually likely to solve an important source of 
 problems,
 consider:

 void func(const ref matrix m);


 func(x.getMatrix()); // compile error!


 // ...

 matrix temp = x.getMatrix();
 func(temp); // no more compile error! (but equally 
 unsafe/dangerous)
It's hard to fully understand this example without getMatrix() defined, and why func() is unsafe (does it escape the reference?). Help!
 <Side rant>

 complaint. It's
 the first one that comes up, every time (which really doesn't 
 help with
 first impressions), and I'm fairly sure every single person 
 I've introduced
 to D has complained about this.
 It's kind of embarrassing when I'm saying that D is really 
 cool, and then I
 have to start making excuses and apologising for this, and 
 assure them that
 it's a known issue, and it'll be fixed one day.
Yikes.
Apr 20 2013
parent reply Manu <turkeyman gmail.com> writes:
On 21 April 2013 11:36, Zach the Mystic <reachzach gggggmail.com> wrote:

 On Sunday, 21 April 2013 at 00:51:31 UTC, Manu wrote:

 That's not what scope does. Scope promises that the variables will not
 escape the scope. And as such, just happens to make passing a temporary =
by
 ref safe.
 It does not implement r-value ref's. It simply allows refs to temporarie=
s
 to be considered a safe operation.
It's a two-fer! (2 for 1 deal) This DIP is actually likely to solve an important source of problems,
 consider:

 void func(const ref matrix m);


 func(x.getMatrix()); // compile error!


 // ...

 matrix temp =3D x.getMatrix();
 func(temp); // no more compile error! (but equally unsafe/dangerous)
It's hard to fully understand this example without getMatrix() defined, and why func() is unsafe (does it escape the reference?). Help!
definition: matrix getMatrix(T x); // this is all you know That's the point of the example. You _don't know_ if func() is unsafe, does it escape the reference? But you need to pass a temp anyway, you have no bearing on whether you should just hack it to work, or reconsider the problem. And when 99 times out of 100, the correct answer is 'hack it to work', you're basically asking for a spectacular bug in that other 1% of cases. <Side rant>

 the first one that comes up, every time (which really doesn't help with
 first impressions), and I'm fairly sure every single person I've
 introduced
 to D has complained about this.
 It's kind of embarrassing when I'm saying that D is really cool, and the=
n
 I
 have to start making excuses and apologising for this, and assure them
 that
 it's a known issue, and it'll be fixed one day.
Yikes.
Apr 20 2013
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 21 April 2013 at 02:13:54 UTC, Manu wrote:
 definition:
   matrix getMatrix(T x); // this is all you know

 That's the point of the example. You _don't know_ if func() is 
 unsafe, does
 it escape the reference? But you need to pass a temp anyway, 
 you have no
 bearing on whether you should just hack it to work, or 
 reconsider the
 problem.
 And when 99 times out of 100, the correct answer is 'hack it to 
 work',
 you're basically asking for a spectacular bug in that other 1% 
 of cases.
If that is your concern then the DIP36 is a very bad answer to it : - It require extra anotation, which wont be added most of the time. - It is inferior, and impair the introduction of lifetime. This isn't even discussed.
Apr 20 2013
next sibling parent "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 21 April 2013 at 02:50:02 UTC, deadalnix wrote:
 If that is your concern then the DIP36 is a very bad answer to 
 it :
  - It require extra anotation, which wont be added most of the 
 time.
Automatic annotations are indicators of broken language. If someone will forget this one, he won't be able to use rvalues, no problem.
  - It is inferior, and impair the introduction of lifetime. 
 This isn't even discussed.
Scope is the absolute minimal lifetime which is needed for this DIP. Any other lifetime options are simply irrelevant.
Apr 21 2013
prev sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Sunday, 21 April 2013 at 02:50:02 UTC, deadalnix wrote:
 If that is your concern then the DIP36 is a very bad answer to 
 it :
  - It require extra anotation, which wont be added most of the 
 time.
It's possible to make it an error to pass a stack variable to a non-'scope' ref parameter. Or to make it an error in safe code only. But those may be extreme measures. This also raises the issue that some types of escape are more dangerous than others. ref T func(ref T a) { return a; // Escape by return, safe if tracked at call site T* p = &a; // Escape to local pointer, safe? if *p is tracked static T* s = &a; // Escape by global pointer, system } In this sense, 'scope' is a blunt instrument, because you might want to say, 'returnable, but not globally assignable'. 'scope' is also the kind of thing which might be better as the default than as something you must specifically add. But then we'd need an attribute ' noscope' or something like that. Ugh.
  - It is inferior, and impair the introduction of lifetime. 
 This isn't even discussed.
You've mentioned lifetime a couple times. Can you show what lifetime is and show how it contrasts with the current proposal, particularly DIP25?
Apr 21 2013
parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 21 April 2013 at 16:02:35 UTC, Zach the Mystic wrote:
 On Sunday, 21 April 2013 at 02:50:02 UTC, deadalnix wrote:
 If that is your concern then the DIP36 is a very bad answer to 
 it :
 - It require extra anotation, which wont be added most of the 
 time.
It's possible to make it an error to pass a stack variable to a non-'scope' ref parameter. Or to make it an error in safe code only. But those may be extreme measures.
No they aren't.
 This also raises the issue that some types of escape are more 
 dangerous than others.
This is why the notion of lifetime is needed.
 'scope' is also the kind of thing which might be better as the 
 default than as something you must specifically add. But then 
 we'd need an attribute ' noscope' or something like that. Ugh.
Inference is always a solution.
 - It is inferior, and impair the introduction of lifetime. 
 This isn't even discussed.
You've mentioned lifetime a couple times. Can you show what lifetime is and show how it contrasts with the current proposal, particularly DIP25?
Here is a good link to start : http://smallcultfollowing.com/babysteps/blog/2012/07/17/borrowed-pointer-tutorial/
Apr 21 2013
prev sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Sunday, 21 April 2013 at 02:13:54 UTC, Manu wrote:
  This DIP is actually likely to solve an important source of 
 problems,
 consider:

 void func(const ref matrix m);


 func(x.getMatrix()); // compile error!


 // ...

 matrix temp = x.getMatrix();
 func(temp); // no more compile error! (but equally 
 unsafe/dangerous)
It's hard to fully understand this example without getMatrix() defined, and why func() is unsafe (does it escape the reference?). Help!
definition: matrix getMatrix(T x); // this is all you know That's the point of the example. You _don't know_ if func() is unsafe, does it escape the reference? But you need to pass a temp anyway, you have no bearing on whether you should just hack it to work, or reconsider the problem. And when 99 times out of 100, the correct answer is 'hack it to work', you're basically asking for a spectacular bug in that other 1% of cases.
Yeah, that's kind of what I meant when I said it's a two-for-one deal. You get to pass temps, and you get safety checking too.
Apr 20 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/21/2013 06:27 AM, Zach the Mystic wrote:
 ...
 Yeah, that's kind of what I meant when I said it's a two-for-one deal.
 You get to pass temps, and you get safety checking too.
I prefer to buy separate products separately.
Apr 21 2013
parent Manu <turkeyman gmail.com> writes:
On 22 April 2013 04:23, Timon Gehr <timon.gehr gmx.ch> wrote:

 On 04/21/2013 06:27 AM, Zach the Mystic wrote:

 ...

 Yeah, that's kind of what I meant when I said it's a two-for-one deal.
 You get to pass temps, and you get safety checking too.
I prefer to buy separate products separately.
I'm confused, what 2 products are you getting? Which of said products do you actually object to?
Apr 21 2013
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/21/2013 02:51 AM, Manu wrote:
 On 21 April 2013 06:51, Timon Gehr <timon.gehr gmx.ch
 <mailto:timon.gehr gmx.ch>> wrote:

     On 04/20/2013 05:56 PM, Dicebot wrote:

         You miss quite an important point - DIP36 does not add new
         feature. It
         partially defines existing feature (scope) to replace an
         existing but
         broken solution (auto ref). Nothing new is really added to the
         language,
         only existing stuff better defined.


     _New meaning_ is assigned to existing grammar whose original purpose
     is at most loosely related to the _new_ features.

     I do not think that making 'scope' indicate an rvalue reference is
     particularly future proof.


 That's not what scope does. Scope promises that the variables will not
 escape the scope.
That is the intention, but this formulation is awfully imprecise. Hence nothing has been implemented. void foo(scope ref int x){ ... } void foo(scope int* x){ ... } void foo(scope ref int* x){ ... } // ??? struct S{ scope S* x; // ??? }
 And as such, just happens to make passing a temporary
 by ref safe.
 ...
But this is not about safety! Passing an rvalue by ref is disallowed even in system code. Hence 'scope' is assigned a meaning different from its intention. The DIP also aims to add more special behaviour to built-in literals.
Apr 21 2013
parent reply Manu <turkeyman gmail.com> writes:
On 22 April 2013 03:39, Timon Gehr <timon.gehr gmx.ch> wrote:

 On 04/21/2013 02:51 AM, Manu wrote:

 On 21 April 2013 06:51, Timon Gehr <timon.gehr gmx.ch
 <mailto:timon.gehr gmx.ch>> wrote:

     On 04/20/2013 05:56 PM, Dicebot wrote:

         You miss quite an important point - DIP36 does not add new
         feature. It
         partially defines existing feature (scope) to replace an
         existing but
         broken solution (auto ref). Nothing new is really added to the
         language,
         only existing stuff better defined.


     _New meaning_ is assigned to existing grammar whose original purpose
     is at most loosely related to the _new_ features.

     I do not think that making 'scope' indicate an rvalue reference is
     particularly future proof.


 That's not what scope does. Scope promises that the variables will not
 escape the scope.
That is the intention, but this formulation is awfully imprecise. Hence nothing has been implemented. void foo(scope ref int x){ ... } void foo(scope int* x){ ... } void foo(scope ref int* x){ ... }
What's the problem here? // ???
 struct S{
     scope S* x; // ???
 }
I don't think scope on a struct member makes a lot of sense. scope on a local variable declaration makes sense though, it would be able to be assigned from another scope variable. Although I would say the same about ref on a local variable declaration, which is disallowed for completely unknown reasons. And as such, just happens to make passing a temporary
 by ref safe.
 ...
But this is not about safety! Passing an rvalue by ref is disallowed even in system code. Hence 'scope' is assigned a meaning different from its intention. The DIP also aims to add more special behaviour to built-in literals.
Passing an r-value by ref is disallowed for arbitrary reasons. It can easily create a temporary on the spot, but it doesn't, because it's not considered good form to pass a temp to a function by ref. This offers the possibility to pass a temp safely, and consequently, the compiler may generate the temp for you. Explain to me what meaning 'scope' has been assigned that is different from it's intention? And what 'special behaviour'? I honestly can't understand the objections, by you or deadalnix. Can someone actually explain the problem clearly?
Apr 21 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/21/2013 10:38 PM, Manu wrote:
 ...

         That's not what scope does. Scope promises that the variables
         will not
         escape the scope.


     That is the intention, but this formulation is awfully imprecise.
     Hence nothing has been implemented.

     void foo(scope ref int x){ ... }
     void foo(scope int* x){ ... }
     void foo(scope ref int* x){ ... }


 What's the problem here?
What does 'scope' bind to? How to make it bind to something else (if at all)? Does the proposal lock down 'scope' to always refer to every single pointer in the argument?
     // ???

     struct S{
          scope S* x; // ???
     }


 I don't think scope on a struct member makes a lot of sense.
void main() safe{ S s; auto t = S(&t); }
 scope on a local variable declaration makes sense though, it would be
 able to be assigned from another scope variable.
'scope' shouldn't restrict the abstraction capability of structs.
 Although I would say the same about ref on a local variable declaration,
 which is disallowed for completely unknown reasons.


         And as such, just happens to make passing a temporary
         by ref safe.
         ...


     But this is not about safety! Passing an rvalue by ref is disallowed
     even in  system code. Hence 'scope' is assigned a meaning different
     from its intention. The DIP also aims to add more special behaviour
     to built-in literals.


 Passing an r-value by ref is disallowed for arbitrary reasons.
Reasons not closely related to lack of 'scope'. So why bind the new rule to scope?
 It can easily create a temporary on the spot, but it doesn't, because it's not
 considered good form to pass a temp to a function by ref.  ...
Yet this is what everyone appears to want to do.
 Explain to me what meaning 'scope' has been assigned that is different
 from it's intention?
Implicit binding of (some) rvalues to ref.
 And what 'special behaviour'?
If I read the ambiguous wording of the proposal correctly, the following code will be disallowed: void foo1(scope ref int x) { } void main(){ foo1(1); // error } But this will be fine: void foo1(scope ref int x) { } int bar(){ return 1; } void main(){ foo1(bar()); }
 I honestly can't understand the objections, by you or deadalnix. Can
 someone actually explain the problem clearly?
Having a lot of ad-hoc programming language rules leads to a clumsy design. Eg. see the evolution of C++.
Apr 21 2013
next sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Sunday, 21 April 2013 at 22:16:14 UTC, Timon Gehr wrote:
 What does 'scope' bind to? How to make it bind to something 
 else (if at all)?
I agree this is an issue. We need to enumerate the use cases. Is 'scope' transitive or does it only apply to the first thing it hits?
 Passing an r-value by ref is disallowed for arbitrary reasons.
Reasons not closely related to lack of 'scope'. So why bind the new rule to scope?
I think that it's possible to consider binding it as a convenient benefit of what 'scope' is generally meant to do anyway. I think the crossover of the two features is quite high. But it is a judgment call. Sometimes you may want to allow rvalue refs without prohibiting escaping them, or prohibit escaping them without allowing rvalues refs. But the point of 'scope' is that it safely takes stack references, which is exactly what rvalue temps are. Maybe getting the two features separate is good, but since it will require another parameter attribute, it suggests a need for increased reliance on attribute inference to spare the programmer the trouble. The main reason to consider combining is that it saves on syntax.
 If I read the ambiguous wording of the proposal correctly, the 
 following code will be disallowed:

 void foo1(scope ref int x) { }

 void main(){
     foo1(1); // error
 }
My impression is that this would be allowed, not disallowed.
 But this will be fine:

 void foo1(scope ref int x) { }
 int bar(){ return 1; }

 void main(){
     foo1(bar());
 }
I think this would also be allowed.
Apr 21 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 If I read the ambiguous wording of the proposal correctly, the 
 following code will be disallowed:

 void foo1(scope ref int x) { }

 void main(){
    foo1(1); // error
 }
My impression is that this would be allowed, not disallowed.
 But this will be fine:

 void foo1(scope ref int x) { }
 int bar(){ return 1; }

 void main(){
    foo1(bar());
 }
I think this would also be allowed.
Yes, both cases are allowed. Dicebot initially wanted that scope ref does not accept literals (only in ref should this do), but Kenji has convinced him that this is unnecessary. In the current pull of Kenji both cases works fine. I also have taken the time and added the overload rules to the DIP.
Apr 22 2013
parent reply "Diggory" <diggsey googlemail.com> writes:
I realise I'm new here but this seems to be suggesting a whole 
load of changes and special cases for something that can be done 
in (IMHO) a much simpler way:

Why not simply make escaping a "ref" pointer an unsafe operation. 
The compiler should be able to detect this and report it without 
any changes to the syntax.

This should cover 99% of cases with no extra attributes required 
and no limitations on what you can do with a "ref" within the 
function. In the 1% of cases that a pointer needs to be escaped 
safely you can add an attribute (maybe "heap ref" or something, 
although perhaps some existing syntax could be used) that 
requires the input to have been allocated on the heap.

In the case that a stack variable is passed as a "heap ref" 
parameter the compiler can automatically promote it where 
possible, or if that's not possible, such as the variable being 
marked "scope" (existing meaning) then it should complain.

All values (including literals and temporaries) should then be 
able to be passed to a "ref const" parameter.

As far as I'm aware the only real purpose for R-value references 
is to implement move semantics. This could already be done using 
"ref in" syntax, as that makes no guarantees that the value is 
not going to be destroyed, only says that the value should be 
initialised prior to it being passed in. The only change would be 
to allow passing temporaries as "ref in".

To promise that the variable is not going to be modified "ref 
const" or "ref const in" can be used.
Apr 22 2013
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Monday, 22 April 2013 at 12:22:14 UTC, Diggory wrote:
 I realise I'm new here but this seems to be suggesting a whole 
 load of changes and special cases for something that can be 
 done in (IMHO) a much simpler way:

 Why not simply make escaping a "ref" pointer an unsafe 
 operation. The compiler should be able to detect this and 
 report it without any changes to the syntax.

 This should cover 99% of cases with no extra attributes 
 required and no limitations on what you can do with a "ref" 
 within the function. In the 1% of cases that a pointer needs to 
 be escaped safely you can add an attribute (maybe "heap ref" or 
 something, although perhaps some existing syntax could be used) 
 that requires the input to have been allocated on the heap.

 In the case that a stack variable is passed as a "heap ref" 
 parameter the compiler can automatically promote it where 
 possible, or if that's not possible, such as the variable being 
 marked "scope" (existing meaning) then it should complain.

 All values (including literals and temporaries) should then be 
 able to be passed to a "ref const" parameter.

 As far as I'm aware the only real purpose for R-value 
 references is to implement move semantics. This could already 
 be done using "ref in" syntax, as that makes no guarantees that 
 the value is not going to be destroyed, only says that the 
 value should be initialised prior to it being passed in. The 
 only change would be to allow passing temporaries as "ref in".

 To promise that the variable is not going to be modified "ref 
 const" or "ref const in" can be used.
This DIP already suggest 'in ref' besides 'scope ref'. 'in' is a shortcut for const scope. And Andrei already reject variants which _only_ consist of non-mutable rvalue ref's (like const ref), because the const system in D is physical. But this could be read on the wiki. You should read the DIP before you write here. ;)
Apr 22 2013
parent reply "Diggory" <diggsey googlemail.com> writes:
On Monday, 22 April 2013 at 13:17:36 UTC, Namespace wrote:
 On Monday, 22 April 2013 at 12:22:14 UTC, Diggory wrote:
 I realise I'm new here but this seems to be suggesting a whole 
 load of changes and special cases for something that can be 
 done in (IMHO) a much simpler way:

 Why not simply make escaping a "ref" pointer an unsafe 
 operation. The compiler should be able to detect this and 
 report it without any changes to the syntax.

 This should cover 99% of cases with no extra attributes 
 required and no limitations on what you can do with a "ref" 
 within the function. In the 1% of cases that a pointer needs 
 to be escaped safely you can add an attribute (maybe "heap 
 ref" or something, although perhaps some existing syntax could 
 be used) that requires the input to have been allocated on the 
 heap.

 In the case that a stack variable is passed as a "heap ref" 
 parameter the compiler can automatically promote it where 
 possible, or if that's not possible, such as the variable 
 being marked "scope" (existing meaning) then it should 
 complain.

 All values (including literals and temporaries) should then be 
 able to be passed to a "ref const" parameter.

 As far as I'm aware the only real purpose for R-value 
 references is to implement move semantics. This could already 
 be done using "ref in" syntax, as that makes no guarantees 
 that the value is not going to be destroyed, only says that 
 the value should be initialised prior to it being passed in. 
 The only change would be to allow passing temporaries as "ref 
 in".

 To promise that the variable is not going to be modified "ref 
 const" or "ref const in" can be used.
This DIP already suggest 'in ref' besides 'scope ref'. 'in' is a shortcut for const scope. And Andrei already reject variants which _only_ consist of non-mutable rvalue ref's (like const ref), because the const system in D is physical.
The definition was somewhat hidden in the language reference and the first reference I found on the forum said that "in" simply meant that the value should be initialised by the caller (in the same way that "out" means that the callee initialises the value).
 But this could be read on the wiki. You should read the DIP 
 before you write here. ;)
I have but the DIP isn't consistent, for example in test1 it says R-value temporaries are allowed:
 void test1(scope ref A a)
And in test32 it says they are not "Only adressable parameters are valid, not temporaries, no extra template instances.":
 void test32(T)(scope ref T id)
And then:
 test32(1337); // Fine, temporary mutable int variable is 
 created with value 1337
Some other problems: - Taking the address of a "scope ref" variable is prohibited even if the compiler can prove that it's safe. - Implementing "forward" in the following is impossible: doSomething(forward(<temporary/literal>)) Obviously a function that simply returns what is passed in seems pointless but it may be very useful if sometimes that function should do something else. All the restrictions on "scope ref" are exactly the same as the restrictions on "ref" if DIP25 is implemented, except that "scope ref" variables can't be returned (why is this the case when by following the same rules as DIP25 it can be safe?) In which case why not allow passing R-value references as normal "ref" parameters? Why the need for "scope" when the only new restriction it introduces can (and should) be avoided. DIP25 says that the return value of a ref function must not be assumed to have a lifetime longer than the shortest lifetime of any of its ref parameters. This formulation works just as well for an R-value reference as it does for a reference to a local variable, just that the first is slightly shorter.
Apr 22 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
 I have but the DIP isn't consistent
I must have overlooked this all the time. I will clean up this inconsistency. The statement that only adressable elements are taken by scope ref is not true anymore. Both, scope ref and in ref can take any values. If it is an rvalue, a temporary is created and this is passed to the function. Thanks for the hint.
 In which case why not allow passing R-value references as 
 normal "ref" parameters? Why the need for "scope" when the only 
 new restriction it introduces can (and should) be avoided.
 DIP25 says that the return value of a ref function must not be 
 assumed to have a lifetime longer than the shortest lifetime of 
 any of its ref parameters. This formulation works just as well 
 for an R-value reference as it does for a reference to a local 
 variable, just that the first is slightly shorter.
You should search for "rvalue references". 'ref' that takes both, lvalues and revalues was suggested and AFAIK rejected. Otherwise you could open a new DIP or first a thread and ask for this. I'm curious of the answers. This issue is very old (Exactly one year ago it was officially discussed for the first time). But the core problem exist since 2.038. There was 'auto ref' introduced. This was the first attempt to solve this problem. Long long time ago and it annoys us still today.
Apr 22 2013
prev sibling parent "Zach the Mystic" <reachzach gggggmail.com> writes:
On Monday, 22 April 2013 at 12:22:14 UTC, Diggory wrote:
 Why not simply make escaping a "ref" pointer an unsafe 
 operation. The compiler should be able to detect this and 
 report it without any changes to the syntax.
In other words, 'scope' would be the default and require no explicit attribute. The first thing about this is the question of how much code it would break. I don't know the answer. Maybe a mockup of this idea could be used to create a sense of how badly it breaks existing code. The second question is how desirable is it as a feature. I think it may be quite desirable to have all refs be 'scope' by default, because the most common case will be the default, that refs will not be assigned to globals. Since there is a difference between the safety of returning by ref and the safety of assigning to heap or global addresses, there may need to be a distinction made between these two types of 'escape'.
 This should cover 99% of cases with no extra attributes 
 required and no limitations on what you can do with a "ref" 
 within the function. In the 1% of cases that a pointer needs to 
 be escaped safely you can add an attribute (maybe "heap ref" or 
 something, although perhaps some existing syntax could be used) 
 that requires the input to have been allocated on the heap.
' noscope ref' has also been suggested, since the reference in question would also need to include static global data.
 In the case that a stack variable is passed as a "heap ref" 
 parameter the compiler can automatically promote it where 
 possible, or if that's not possible, such as the variable being 
 marked "scope" (existing meaning) then it should complain.
This is interesting to me. The only drawback I can think of is the aversion people have to introducing code which could secretly allocate, since many people want to avoid the garbage collector. It would only be an issue if the automatic promotion looked so much like a normal function call that it was extraordinarily difficult to distinguish it.
 As far as I'm aware the only real purpose for R-value 
 references is to implement move semantics. This could already 
 be done using "ref in" syntax, as that makes no guarantees that 
 the value is not going to be destroyed, only says that the 
 value should be initialised prior to it being passed in. The 
 only change would be to allow passing temporaries as "ref in".
The only existing definition of 'in' is that it means 'const scope', so it already means scope. I don't know if that is a good definition or not. I think that there remains a significant fear in this community of introducing changes which will break existing code. I don't myself know how justified this fear is, but it is nonetheless something to take very seriously when proposing new ideas.
 I realise I'm new here
I'm new too. I'm glad to be able to have this discussion with you despite both of our being new. :-)
Apr 22 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 21 April 2013 at 22:16:14 UTC, Timon Gehr wrote:
 Passing an r-value by ref is disallowed for arbitrary reasons.
Reasons not closely related to lack of 'scope'. So why bind the new rule to scope?
I had quite an impression this was prohibited mostly because of safe issues.
Apr 23 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/23/2013 10:10 AM, Dicebot wrote:
 On Sunday, 21 April 2013 at 22:16:14 UTC, Timon Gehr wrote:
 Passing an r-value by ref is disallowed for arbitrary reasons.
Reasons not closely related to lack of 'scope'. So why bind the new rule to scope?
I had quite an impression this was prohibited mostly because of safe issues.
It is disallowed in system code.
Apr 23 2013
parent "Dicebot" <m.strashun gmail.com> writes:
On Tuesday, 23 April 2013 at 08:19:43 UTC, Timon Gehr wrote:
 It is disallowed in  system code.
Ye, I know and always took it as yet another "we care mostly for safe" issue. What is the real rationale for this restriction?
Apr 23 2013
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Saturday, 20 April 2013 at 15:23:35 UTC, deadalnix wrote:
 On Saturday, 20 April 2013 at 15:17:39 UTC, Namespace wrote:
 I don't think adding more to the language is the sane thing 
 to do right now.
Why not? Could you explain this? This issue is discussed since more than a year and it is a very annoying issue. And even if Walter and Andrei are of this opinion, it would still only polite when they explain in detail why they think this.
Listen, this issue is very real, but it is mostly about performance. I'll tell you something : the best performance improvement is the one that bring your program from non working state to working one. And right now, many existing feature are broken. The let's add whatever feature we have in mind is the very cause of the state of the language right now.
Sadly, I have to agree on this. As nice as many new feature ideas are, they are far from priorities when there are multiple core mechanics that are broken.
Apr 20 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 Sadly, I have to agree on this. As nice as many new feature 
 ideas are, they are far from priorities when there are multiple 
 core mechanics that are broken.
There is no reason to prioritize DIP 36. Kenji, Dicebot and I did most of the work. The DIP is written and all necessary information are described in detail there with examples. The code also exists and there is even a pull request which has passed all the tests. Thus, this proposal is linked with not much work. Most of it was taken over by others. Due to this, it really is not asking too much to get a note if this pull is accepted or rejected. Of course, with detailed justification.
Apr 20 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Saturday, 20 April 2013 at 16:11:49 UTC, Namespace wrote:
 Sadly, I have to agree on this. As nice as many new feature 
 ideas are, they are far from priorities when there are 
 multiple core mechanics that are broken.
There is no reason to prioritize DIP 36. Kenji, Dicebot and I did most of the work. The DIP is written and all necessary information are described in detail there with examples. The code also exists and there is even a pull request which has passed all the tests. Thus, this proposal is linked with not much work. Most of it was taken over by others. Due to this, it really is not asking too much to get a note if this pull is accepted or rejected. Of course, with detailed justification.
How about "on hold"? (Not that I have any say in it at all) The fact is, there's much more to any change than simply implementing it. Changes break unexpected things. There are always extra corner cases not considered. There are always bugs and inconsistencies. Although it's great that you and some others have done the legwork to implement this proposal, it may have to wait until other more urgent problems have been fixed.
Apr 20 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 How about "on hold"? (Not that I have any say in it at all)
As long as it is implemented in the near future and we must not wait another year (not even a half) it is ok. But the fact is, that we don't know what state it has, because we get no response.
 The fact is, there's much more to any change than simply 
 implementing it. Changes break unexpected things. There are 
 always extra corner cases not considered. There are always bugs 
 and inconsistencies.
Could be, but I don't see what could be broken by this DIP. All contingencies are listed also in the DIP (and that are not many). And it passed all tests what is crucial.
 Although it's great that you and some others have done the 
 legwork to implement this proposal, it may have to wait until 
 other more urgent problems have been fixed.
Could be, but I don't know why. Which other fix is necessary for this pull? But also this would be ok, as long as we know, _which_ problems must be fixed.
Apr 20 2013
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 20 April 2013 at 18:00:50 UTC, Namespace wrote:
 The fact is, there's much more to any change than simply 
 implementing it. Changes break unexpected things. There are 
 always extra corner cases not considered. There are always 
 bugs and inconsistencies.
Could be, but I don't see what could be broken by this DIP. All contingencies are listed also in the DIP (and that are not many). And it passed all tests what is crucial.
The DIP for instance, consider that const scope ref is semantically equivalent to pass by value, when it isn't (and not only for performance reasons, but for aliasing reasons). Nothing is considered about it.
Apr 20 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 21 April 2013 at 01:04:04 UTC, deadalnix wrote:
 On Saturday, 20 April 2013 at 18:00:50 UTC, Namespace wrote:
 The fact is, there's much more to any change than simply 
 implementing it. Changes break unexpected things. There are 
 always extra corner cases not considered. There are always 
 bugs and inconsistencies.
Could be, but I don't see what could be broken by this DIP. All contingencies are listed also in the DIP (and that are not many). And it passed all tests what is crucial.
The DIP for instance, consider that const scope ref is semantically equivalent to pass by value, when it isn't (and not only for performance reasons, but for aliasing reasons). Nothing is considered about it.
At least some objections that make sense and I'd love to see in the very first announcement. If you see any issues that prevent treating "const scope int" as "const scope ref int", please tell about them and they will be addressed in DIP. Because it is the intention. I don't understand what aliasing are you speaking about.
Apr 21 2013
parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Sunday, 21 April 2013 at 10:55:37 UTC, Dicebot wrote:
 The DIP for instance, consider that const scope ref is 
 semantically equivalent to pass by value, when it isn't (and 
 not only for performance reasons, but for aliasing reasons). 
 Nothing is considered about it.
At least some objections that make sense and I'd love to see in the very first announcement. If you see any issues that prevent treating "const scope int" as "const scope ref int", please tell about them and they will be addressed in DIP. Because it is the intention. I don't understand what aliasing are you speaking about.
The only thing I could think of was if you want to 'ref' a reference type. void func(ref Object o, scope Object o2, scope ref Object o3) {} Would there be a difference between the type of o and o2, or of o2 and o3? There is inconsistency, but it would be nice to find use cases which make this inconsistency truly unworkable with other things in the language.
Apr 21 2013
next sibling parent "Zach the Mystic" <reachzach gggggmail.com> writes:
On Sunday, 21 April 2013 at 16:08:55 UTC, Zach the Mystic wrote:
 Would there be a difference between the type of o and o2, or of 
 o2 and o3? There is inconsistency, but it would be nice to find 
 use cases which make this inconsistency truly unworkable with 
 other things in the language.
('nice' in the sense that it would prove the suggestion to be unworkable as opposed to nice that it actually is unworkable...)
Apr 21 2013
prev sibling parent "Dicebot" <m.strashun gmail.com> writes:
On Sunday, 21 April 2013 at 16:08:55 UTC, Zach the Mystic wrote:
 The only thing I could think of was if you want to 'ref' a 
 reference type.

 void func(ref Object o, scope Object o2, scope ref Object o3) {}

 Would there be a difference between the type of o and o2, or of 
 o2 and o3? There is inconsistency, but it would be nice to find 
 use cases which make this inconsistency truly unworkable with 
 other things in the language.
Taking consistent approach with "ref", they all should have same type but bpth "ref" and "scope" differences are mangled into func name so that caller can take notion of proper behavior. I don't see an issue here.
Apr 23 2013
prev sibling parent reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
On Saturday, 20 April 2013 at 15:23:35 UTC, deadalnix wrote:
 On Saturday, 20 April 2013 at 15:17:39 UTC, Namespace wrote:
 I don't think adding more to the language is the sane thing 
 to do right now.
Why not? Could you explain this? This issue is discussed since more than a year and it is a very annoying issue. And even if Walter and Andrei are of this opinion, it would still only polite when they explain in detail why they think this.
Listen, this issue is very real, but it is mostly about performance. I'll tell you something : the best performance improvement is the one that bring your program from non working state to working one. And right now, many existing feature are broken. The let's add whatever feature we have in mind is the very cause of the state of the language right now.
I thought D was driven by its community.
Apr 20 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/20/2013 07:34 PM, Minas Mina wrote:
 ...

 I thought D was driven by its community.
(This is its community.)
Apr 20 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/20/13 11:17 AM, Namespace wrote:
 I don't think adding more to the language is the sane thing to do
 right now.
Why not? Could you explain this? This issue is discussed since more than a year and it is a very annoying issue. And even if Walter and Andrei are of this opinion, it would still only polite when they explain in detail why they think this.
In a way I wish my not being polite would be the main bottleneck for this. I've been extremely busy at work, then preparing for DConf 2013, and last week has been quite distracting what with the Boston bombings three miles away from where we live and all that. It strikes me as odd to be obligated to spend time on something just because someone else did, and framed as impolite if I don't. That being said, I have made a pass through this DIP and I have the following concerns about it. 1. It defines a new language feature instead of improving the existing ones. At this point in the development of the language, our preference should be putting the existing features in good order. 2. The proposal is sketchy and does not give many details, such as the lifetime of temporaries bound to scope ref objects. 3. The relationship with auto ref is insufficiently described, e.g. there should be clarification on why auto ref cannot be improved to fulfill the desired role. 4. Above all this is a new language feature and again we want to resort to adding new feature only if it is clear that the existing features are insufficient and cannot be made sufficient. In particular we are much more inclined to impart real, demonstrable safety to "ref" and to make "auto ref" work as a reference that can bind to rvalues as well as lvalues. Andrei
Apr 22 2013
next sibling parent "Tove" <tove fransson.se> writes:
On Monday, 22 April 2013 at 20:02:12 UTC, Andrei Alexandrescu 
wrote:
 4. Above all this is a new language feature and again we want 
 to resort to adding new feature only if it is clear that the 
 existing features are insufficient and cannot be made 
 sufficient. In particular we are much more inclined to impart 
 real, demonstrable safety to "ref" and to make "auto ref" work 
 as a reference that can bind to rvalues as well as lvalues.
Why isn't DIP36 "scope ref" be future compatible with a future safe "auto ref"? ... and if in the future the compiler would be able to infer "scope ref" from "auto ref", this entire DIP could be reused, with the benefit that people could start using this functionality already today(there is a full pull request with a very small delta), before the auto inference is in place.
Apr 22 2013
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 In a way I wish my not being polite would be the main 
 bottleneck for this. I've been extremely busy at work, then 
 preparing for DConf 2013, and last week has been quite 
 distracting what with the Boston bombings three miles away from 
 where we live and all that. It strikes me as odd to be 
 obligated to spend time on something just because someone else 
 did, and framed as impolite if I don't.

 That being said, I have made a pass through this DIP and I have 
 the following concerns about it.

 1. It defines a new language feature instead of improving the 
 existing ones. At this point in the development of the 
 language, our preference should be putting the existing 
 features in good order.

 2. The proposal is sketchy and does not give many details, such 
 as the lifetime of temporaries bound to scope ref objects.

 3. The relationship with auto ref is insufficiently described, 
 e.g. there should be clarification on why auto ref cannot be 
 improved to fulfill the desired role.

 4. Above all this is a new language feature and again we want 
 to resort to adding new feature only if it is clear that the 
 existing features are insufficient and cannot be made 
 sufficient. In particular we are much more inclined to impart 
 real, demonstrable safety to "ref" and to make "auto ref" work 
 as a reference that can bind to rvalues as well as lvalues.


 Andrei
I'm sorry that you take it so personally, but I know from experience that some topics often get forgotten or ignored if you don't ask about it more then once. And that we have made so much effort should show that we work for D and not against it and that we don't want to annoy you. But you are right, scope ref is in comparison to auto ref a new feature, but it is one with little sideeffects and minimized implementation effort. And Jonathan described here (http://forum.dlang.org/thread/uswucstsooghescofycp forum.dlang.org?page=2#post-mailman.293.1364249651.4724.digitalmars-d-le rn:40puremagic.com) very well and in detail why auto ref is no solution for non-templates. In short: It cannot work the same way for non-templates as it does for template functions, because that would mean that non-templates are also doubled 2^n times. And the way scope ref would work, would mean, that auto ref works different for templates and non-template functions. But you'd better read Jonathan's answer.
Apr 22 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Monday, 22 April 2013 at 20:02:12 UTC, Andrei Alexandrescu 
wrote:
 In a way I wish my not being polite would be the main 
 bottleneck for this. I've been extremely busy at work, then 
 preparing for DConf 2013, and last week has been quite 
 distracting what with the Boston bombings three miles away from 
 where we live and all that. It strikes me as odd to be 
 obligated to spend time on something just because someone else 
 did, and framed as impolite if I don't.
Thanks for your time. Sometimes even simple "Have seen it, will answer later / after DConf is priceless".
 That being said, I have made a pass through this DIP and I have 
 the following concerns about it.

 1. It defines a new language feature instead of improving the 
 existing ones. At this point in the development of the 
 language, our preference should be putting the existing 
 features in good order.
You consider "scope" a new language feature? And consider "auto ref" improvable solution. The very point of this DIP is to not create syntax-driven features, instead better define existing ones that make sense on their own so they can be used for same purpose.
 2. The proposal is sketchy and does not give many details, such 
 as the lifetime of temporaries bound to scope ref objects.
It can't because lifetime of temporaries is not defined in D at all and suck stuff needs to be consistent. It is not really different from a lifetime of struct literal temporary used for pass-by-value.
 3. The relationship with auto ref is insufficiently described, 
 e.g. there should be clarification on why auto ref cannot be 
 improved to fulfill the desired role.
auto ref is a template-world entity. If by "improved" you mean "completely reworked" than sure, I can add this rationale. Will do today.
 4. Above all this is a new language feature and again we want 
 to resort to adding new feature only if it is clear that the 
 existing features are insufficient and cannot be made 
 sufficient. In particular we are much more inclined to impart 
 real, demonstrable safety to "ref" and to make "auto ref" work 
 as a reference that can bind to rvalues as well as lvalues.
Can't agree. "scope" is defined (but not implemented, a pity). Creating temporaries already exists for some cases. No really new language feature is added. No special syntax created. "scope ref" is still "scope" and "ref" with all semantics this imposes, rvalue references are just a side-effect. Contrary to this, "auto ref" IS a new feature created specifically for syntax hack. That is a very problem you are speaking about - introducing new concepts instead of making use of ones that exist for ages.
Apr 23 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/23/13 4:08 AM, Dicebot wrote:
 You consider "scope" a new language feature?
Yes.
 And consider "auto ref"
 improvable solution.
Yes.
 The very point of this DIP is to not create
 syntax-driven features, instead better define existing ones that make
 sense on their own so they can be used for same purpose.
It's a new feature, no two ways about it. It overlaps ref and auto ref without any palpable benefit and defines yet another way to achieve the same thing as auto ref. On this ground alone the proposal has a large problem.
 2. The proposal is sketchy and does not give many details, such as the
 lifetime of temporaries bound to scope ref objects.
It can't because lifetime of temporaries is not defined in D at all and suck stuff needs to be consistent. It is not really different from a lifetime of struct literal temporary used for pass-by-value.
A proposal aimed at binding rvalues to references must address lifetime of temporaries as a central concern.
 3. The relationship with auto ref is insufficiently described, e.g.
 there should be clarification on why auto ref cannot be improved to
 fulfill the desired role.
auto ref is a template-world entity. If by "improved" you mean "completely reworked" than sure, I can add this rationale. Will do today.
I think we should focus on http://d.puremagic.com/issues/show_bug.cgi?id=9238 and on making ref safe.
 4. Above all this is a new language feature and again we want to
 resort to adding new feature only if it is clear that the existing
 features are insufficient and cannot be made sufficient. In particular
 we are much more inclined to impart real, demonstrable safety to "ref"
 and to make "auto ref" work as a reference that can bind to rvalues as
 well as lvalues.
Can't agree. "scope" is defined (but not implemented, a pity). Creating temporaries already exists for some cases. No really new language feature is added. No special syntax created. "scope ref" is still "scope" and "ref" with all semantics this imposes, rvalue references are just a side-effect. Contrary to this, "auto ref" IS a new feature created specifically for syntax hack. That is a very problem you are speaking about - introducing new concepts instead of making use of ones that exist for ages.
You are of course to disagree, but that would make you wrong. Andrei
Apr 23 2013
next sibling parent "Dicebot" <m.strashun gmail.com> writes:
On Tuesday, 23 April 2013 at 14:24:06 UTC, Andrei Alexandrescu 
wrote:
 On 4/23/13 4:08 AM, Dicebot wrote:
 You consider "scope" a new language feature?
Yes.
Well, ok, that explains everything. Thank you.
Apr 23 2013
prev sibling parent reply Manu <turkeyman gmail.com> writes:
On 24 April 2013 00:24, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org>wrote:

 The very point of this DIP is to not create
 syntax-driven features, instead better define existing ones that make
 sense on their own so they can be used for same purpose.
It's a new feature, no two ways about it. It overlaps ref and auto ref without any palpable benefit and defines yet another way to achieve the same thing as auto ref. On this ground alone the proposal has a large problem.
How does it overlap ref? It simply justifies the argument with an extra constraint and isn't tied to 'ref' at all, it's just useful in conjunction. I can't agree that it overlaps auto-ref at all. They're fundamentally different concepts. auto-ref is a template concept; it selects the ref-ness based on the received arg. 'auto ref', ie, 'automatic ref-ness'. It makes no sense on a non-template situation. I'm still completely amazed that the very reason this DIP makes perfect sense to me(/us) is the same reason you have a problem with it. 2. The proposal is sketchy and does not give many details, such as the
 lifetime of temporaries bound to scope ref objects.
It can't because lifetime of temporaries is not defined in D at all and suck stuff needs to be consistent. It is not really different from a lifetime of struct literal temporary used for pass-by-value.
A proposal aimed at binding rvalues to references must address lifetime of temporaries as a central concern.
It's not an r-value, it's a standard stack-allocated temporary. It's lifetime is identical to any other local. The reason it's not detailed in the proposal is because it adds no such new feature, and makes no changes. The lifetime of a local is well understood. 3. The relationship with auto ref is insufficiently described, e.g.
 there should be clarification on why auto ref cannot be improved to
 fulfill the desired role.
auto ref is a template-world entity. If by "improved" you mean "completely reworked" than sure, I can add this rationale. Will do today.
I think we should focus on http://d.puremagic.com/issues/** show_bug.cgi?id=9238 <http://d.puremagic.com/issues/show_bug.cgi?id=9238>and on making ref safe.
I don't believe it's possible to make ref safe. Can you suggest any vision for this? It's unsafe by definition... you are passing a pointer of unknown origin to a function that could do anything with that pointer. Hence 'scope ref', which appropriately restricts what the callee is able to do with it. 4. Above all this is a new language feature and again we want to
 resort to adding new feature only if it is clear that the existing
 features are insufficient and cannot be made sufficient. In particular
 we are much more inclined to impart real, demonstrable safety to "ref"
 and to make "auto ref" work as a reference that can bind to rvalues as
 well as lvalues.
Can't agree. "scope" is defined (but not implemented, a pity). Creating temporaries already exists for some cases. No really new language feature is added. No special syntax created. "scope ref" is still "scope" and "ref" with all semantics this imposes, rvalue references are just a side-effect. Contrary to this, "auto ref" IS a new feature created specifically for syntax hack. That is a very problem you are speaking about - introducing new concepts instead of making use of ones that exist for ages.
You are of course to disagree, but that would make you wrong.
Explain why? Proclaiming he is simply wrong when he presents sound reason isn't helpful.
Apr 23 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/23/13 12:04 PM, Manu wrote:
 On 24 April 2013 00:24, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org <mailto:SeeWebsiteForEmail erdani.org>>
 wrote:


         The very point of this DIP is to not create
         syntax-driven features, instead better define existing ones that
         make
         sense on their own so they can be used for same purpose.


     It's a new feature, no two ways about it. It overlaps ref and auto
     ref without any palpable benefit and defines yet another way to
     achieve the same thing as auto ref. On this ground alone the
     proposal has a large problem.


 How does it overlap ref? It simply justifies the argument with an extra
 constraint and isn't tied to 'ref' at all, it's just useful in conjunction.
The best setup would be: 1. To take lvalues by reference, write "ref". 2. To take lvalues and rvalues by reference, write "auto ref". Everything else is superfluous and puts the burden of justification on the proposer. With DIP36, the setup would be: 1. To take lvalues by reference, write "ref". 2. To take lvalues and rvalues by reference: 2.1. Is it a template? Then write "auto ref". 2.2. Is it a non-template? Then write "scope ref".
 I can't agree that it overlaps auto-ref at all. They're fundamentally
 different concepts. auto-ref is a template concept; it selects the
 ref-ness based on the received arg. 'auto ref', ie, 'automatic
 ref-ness'. It makes no sense on a non-template situation.
 I'm still completely amazed that the very reason this DIP makes perfect
 sense to me(/us) is the same reason you have a problem with it.
I don't know how to respond to this. To me is it painfully obvious DIP 36 is poor language design and fails to solve a variety of issues, such as clarifying lifetime of temporaries, safety, and returning ref from functions.
             2. The proposal is sketchy and does not give many details,
             such as the
             lifetime of temporaries bound to scope ref objects.


         It can't because lifetime of temporaries is not defined in D at
         all and
         suck stuff needs to be consistent. It is not really different from a
         lifetime of struct literal temporary used for pass-by-value.


     A proposal aimed at binding rvalues to references must address
     lifetime of temporaries as a central concern.


 It's not an r-value, it's a standard stack-allocated temporary. It's
 lifetime is identical to any other local.
 The reason it's not detailed in the proposal is because it adds no such
 new feature, and makes no changes. The lifetime of a local is well
 understood.
Currently rvalues are destroyed immediately after the call they are passed into. DIP 36 would need to change that, but fails to specify it.
             3. The relationship with auto ref is insufficiently
             described, e.g.
             there should be clarification on why auto ref cannot be
             improved to
             fulfill the desired role.


         auto ref is a template-world entity. If by "improved" you mean
         "completely reworked" than sure, I can add this rationale. Will
         do today.


     I think we should focus on
     http://d.puremagic.com/issues/__show_bug.cgi?id=9238
     <http://d.puremagic.com/issues/show_bug.cgi?id=9238> and on making
     ref safe.


 I don't believe it's possible to make ref safe. Can you suggest any
 vision for this?
http://d.puremagic.com/issues/show_bug.cgi?id=9238
 It's unsafe by definition... you are passing a pointer of unknown origin
 to a function that could do anything with that pointer.
 Hence 'scope ref', which appropriately restricts what the callee is able
 to do with it.
Our intent is to make "ref" always scoped and reserve non-scoped uses to pointers. We consider this good language design: we have unrestricted pointers for code that doesn't care much about safety, and we have "ref" which is almost as powerful but sacrifices a teeny bit of that power for the sake of guaranteed safety. Safety is guaranteed by making sure "ref" is always scoped (references can be passed down but never escape their bound value).
             4. Above all this is a new language feature and again we want to
             resort to adding new feature only if it is clear that the
             existing
             features are insufficient and cannot be made sufficient. In
             particular
             we are much more inclined to impart real, demonstrable
             safety to "ref"
             and to make "auto ref" work as a reference that can bind to
             rvalues as
             well as lvalues.


         Can't agree. "scope" is defined (but not implemented, a pity).
         Creating
         temporaries already exists for some cases. No really new language
         feature is added. No special syntax created. "scope ref" is still
         "scope" and "ref" with all semantics this imposes, rvalue
         references are
         just a side-effect. Contrary to this, "auto ref" IS a new feature
         created specifically for syntax hack. That is a very problem you are
         speaking about - introducing new concepts instead of making use
         of ones
         that exist for ages.


     You are of course to disagree, but that would make you wrong.


 Explain why? Proclaiming he is simply wrong when he presents sound
 reason isn't helpful.
I assumed it was obvious from what I'd already written. The claim has been made that "scope ref" is not a new language feature. I don't know how to reply to that other than, well, it is. Andrei
Apr 23 2013
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 23 Apr 2013 13:33:31 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Our intent is to make "ref" always scoped and reserve non-scoped uses to  
 pointers.
So no more returning ref? Because if you allow returning ref, you lose any notion of safety, unless you plan on changing the entire compilation model?
 We consider this good language design: we have unrestricted pointers for  
 code that doesn't care much about safety, and we have "ref" which is  
 almost as powerful but sacrifices a teeny bit of that power for the sake  
 of guaranteed safety. Safety is guaranteed by making sure "ref" is  
 always scoped (references can be passed down but never escape their  
 bound value).
Not being able to return ref is a large loss of power. Not arguing in favor of DIP36, but it seems there is a misunderstanding as to what it does. -Steve
Apr 23 2013
next sibling parent reply "Diggory" <diggsey googlemail.com> writes:
 So no more returning ref?  Because if you allow returning ref, 
 you lose any notion of safety, unless you plan on changing the 
 entire compilation model?
The rules from DIP25/35 show how you can return refs while still maintaining safety.
Apr 23 2013
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 23 Apr 2013 14:01:14 -0400, Diggory <diggsey googlemail.com> wrote:

 So no more returning ref?  Because if you allow returning ref, you lose  
 any notion of safety, unless you plan on changing the entire  
 compilation model?
The rules from DIP25/35 show how you can return refs while still maintaining safety.
Those rules disallow the following valid code: struct S { int x; ref S opOpAssign(string op : "+")(ref S other) { x += other.x; return this;} } ref S add5(ref S s) { auto o = S(5); return s += o; } void main() { auto s = S(5); S s2 = add5(s); } Because opOpAssign takes two refs to S, and in add5, we bind one parameter to a local, we cannot return the result, even though it's perfectly safe and valid. The point is simply that there exist valid and safe cases which will be disallowed by these rules. While maybe it's OK in your mind to restrict the above code from validity, it's currently valid and compiling code. You will be breaking existing code for pretty much no reason. -Steve
Apr 23 2013
parent "Diggory" <diggsey googlemail.com> writes:
In that example you could make opOpAssign take a "const ref" and 
then the compiler could see that it could not return that 
parameter, but this is slightly hacky and I can see how there may 
be obscure corner cases where the rules are not sufficient.

Actually this could also be solved by using the (original) 
meaning of "scope" to mark parameters that are not going to be 
returned. (I still think both "ref" and "scope ref" should accept 
rvalues)
Apr 23 2013
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/23/13 1:57 PM, Steven Schveighoffer wrote:
 On Tue, 23 Apr 2013 13:33:31 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 Our intent is to make "ref" always scoped and reserve non-scoped uses
 to pointers.
So no more returning ref?
If we can't return ref, ref has failed. (This is what makes the entire thing difficult btw.) Andrei
Apr 23 2013
parent reply Manu <turkeyman gmail.com> writes:
On 24 April 2013 04:01, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org>wrote:

 On 4/23/13 1:57 PM, Steven Schveighoffer wrote:

 On Tue, 23 Apr 2013 13:33:31 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org**> wrote:

  Our intent is to make "ref" always scoped and reserve non-scoped uses
 to pointers.
So no more returning ref?
If we can't return ref, ref has failed. (This is what makes the entire thing difficult btw.)
I think the key that's not in this DIP is that it should also return 'scope ref' to maintain the safety. This brings the proposal in-line with your plans, except the safety is explicit, and the option is available to the programmer. Making 'safe' ref the default is a major breaking change.
Apr 23 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/23/13 2:32 PM, Manu wrote:
 On 24 April 2013 04:01, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org <mailto:SeeWebsiteForEmail erdani.org>>
 wrote:

     On 4/23/13 1:57 PM, Steven Schveighoffer wrote:

         On Tue, 23 Apr 2013 13:33:31 -0400, Andrei Alexandrescu
         <SeeWebsiteForEmail erdani.org
         <mailto:SeeWebsiteForEmail erdani.org>__> wrote:

             Our intent is to make "ref" always scoped and reserve
             non-scoped uses
             to pointers.


         So no more returning ref?


     If we can't return ref, ref has failed. (This is what makes the
     entire thing difficult btw.)


 I think the key that's not in this DIP is that it should also return
 'scope ref' to maintain the safety.
 This brings the proposal in-line with your plans, except the safety is
 explicit, and the option is available to the programmer.
We prefer to simplify. Use ref safely for scoped pass-down of resources, use pointers for unrestricted escapes. What you see as "offering an option" I see as "adding a burden".
 Making 'safe' ref the default is a major breaking change.
How do you assess the size of the breakage? Andrei
Apr 23 2013
parent "Mehrdad" <wfunction hotmail.com> writes:
On Tuesday, 23 April 2013 at 18:41:07 UTC, Andrei Alexandrescu 
wrote:
 Making 'safe' ref the default is a major breaking change.
How do you assess the size of the breakage?
I think it's fairly well-understood, probably with the same meaning that you used in your own post somewhere else: http://forum.dlang.org/thread/hlh4g2$1tn0$2 digitalmars.com#post-hlh753:24270m:241:40digitalmars.com
Apr 23 2013
prev sibling next sibling parent reply Manu <turkeyman gmail.com> writes:
On 24 April 2013 03:33, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org>wrote:

 On 4/23/13 12:04 PM, Manu wrote:

 On 24 April 2013 00:24, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org
<mailto:SeeWebsiteForEmail **erdani.org<SeeWebsiteForEmail erdani.org>

wrote: The very point of this DIP is to not create syntax-driven features, instead better define existing ones that make sense on their own so they can be used for same purpose. It's a new feature, no two ways about it. It overlaps ref and auto ref without any palpable benefit and defines yet another way to achieve the same thing as auto ref. On this ground alone the proposal has a large problem. How does it overlap ref? It simply justifies the argument with an extra constraint and isn't tied to 'ref' at all, it's just useful in conjunction.
The best setup would be: 1. To take lvalues by reference, write "ref". 2. To take lvalues and rvalues by reference, write "auto ref".
That's not a good setup at all. It still doesn't make sense. There's nothing 'automatic' about it, I've specified ref, it is ref, there's no other choice. And it relies on a major breaking change to ref, which restricts the functionality of ref by default. Everything else is superfluous and puts the burden of justification on the
 proposer. With DIP36, the setup would be:

 1. To take lvalues by reference, write "ref".

 2. To take lvalues and rvalues by reference:

 2.1. Is it a template? Then write "auto ref".

 2.2. Is it a non-template? Then write "scope ref".
Stop talking about r-values, rather, consider safety of passing temporaries. This problem has nothing to do with r-values, this is equally unsafe: void f(ref int x); int x; f(x); It's precisely the same problem, and should be fixed with the same solution. I would rewrite your list as such: 1. 'un-safely' pass a value (may not be a local), write 'ref' 2. safely pass a value (may be a local), write 'scope ref' 3. if you are concerned with templates do you: 3.a. want unsafe auto-ref, type 'auto ref' (only non-locals would generate 'ref') 3.b. want safe auto-ref, type 'scope auto ref' The automatic selection of ref for templates is fairly unrelated to this issue. I can't agree that it overlaps auto-ref at all. They're fundamentally
 different concepts. auto-ref is a template concept; it selects the
 ref-ness based on the received arg. 'auto ref', ie, 'automatic
 ref-ness'. It makes no sense on a non-template situation.
 I'm still completely amazed that the very reason this DIP makes perfect
 sense to me(/us) is the same reason you have a problem with it.
I don't know how to respond to this. To me is it painfully obvious DIP 36 is poor language design and fails to solve a variety of issues, such as clarifying lifetime of temporaries, safety, and returning ref from functions.
Lifetime of temporaries is the most basic of principles. A local lives the life of the function in which it is defined. Safety is the whole point, and intrinsic to the proposal; safety by explicit specification, thus the programmer retains the option. If a function receives 'scope ref', and wants to return it, I think it should also return 'scope ref' (I guess this wasn't defined in the DIP), otherwise it would be considered an escape. 2. The proposal is sketchy and does not give many details,
             such as the
             lifetime of temporaries bound to scope ref objects.


         It can't because lifetime of temporaries is not defined in D at
         all and
         suck stuff needs to be consistent. It is not really different
 from a
         lifetime of struct literal temporary used for pass-by-value.


     A proposal aimed at binding rvalues to references must address
     lifetime of temporaries as a central concern.


 It's not an r-value, it's a standard stack-allocated temporary. It's
 lifetime is identical to any other local.
 The reason it's not detailed in the proposal is because it adds no such
 new feature, and makes no changes. The lifetime of a local is well
 understood.
Currently rvalues are destroyed immediately after the call they are passed into. DIP 36 would need to change that, but fails to specify it.
Again, I think it was presumed (I can't conceive any other approach), and certainly Kenji read it that way, because his code appears to do just that. 3. The relationship with auto ref is insufficiently
             described, e.g.
             there should be clarification on why auto ref cannot be
             improved to
             fulfill the desired role.


         auto ref is a template-world entity. If by "improved" you mean
         "completely reworked" than sure, I can add this rationale. Will
         do today.


     I think we should focus on
     http://d.puremagic.com/issues/**__show_bug.cgi?id=9238<http://d.puremagic.com/issues/__show_bug.cgi?id=9238>

     <http://d.puremagic.com/**issues/show_bug.cgi?id=9238<http://d.puremagic.com/issues/show_bug.cgi?id=9238>>
 and on making
     ref safe.


 I don't believe it's possible to make ref safe. Can you suggest any
 vision for this?
http://d.puremagic.com/issues/**show_bug.cgi?id=9238<http://d.puremagic.com/issues/show_bug.cgi?id=9238> It's unsafe by definition... you are passing a pointer of unknown origin
 to a function that could do anything with that pointer.
 Hence 'scope ref', which appropriately restricts what the callee is able
 to do with it.
Our intent is to make "ref" always scoped and reserve non-scoped uses to pointers. We consider this good language design: we have unrestricted pointers for code that doesn't care much about safety, and we have "ref" which is almost as powerful but sacrifices a teeny bit of that power for the sake of guaranteed safety. Safety is guaranteed by making sure "ref" is always scoped (references can be passed down but never escape their bound value).
That's a massive breaking change... [response in other thread, we need to stop repeating in 2 threads I think]
Apr 23 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/23/13 2:29 PM, Manu wrote:
 On 24 April 2013 03:33, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org <mailto:SeeWebsiteForEmail erdani.org>>
 wrote:
     The best setup would be:

     1. To take lvalues by reference, write "ref".

     2. To take lvalues and rvalues by reference, write "auto ref".


 That's not a good setup at all. It still doesn't make sense.
 There's nothing 'automatic' about it,
There is - it means ref is inferred.
 I've specified ref, it is ref,
 there's no other choice.
Well "auto ref" means "I don't care whether this is ref or not".
 And it relies on a major breaking change to ref, which restricts the
 functionality of ref by default.
This is a confusion. There's no reliance on any change to ref. The breaking changes are related to adding safety. If safety weren't a concern, a lot of things would be simple.
 Stop talking about r-values, rather, consider safety of passing
 temporaries. This problem has nothing to do with r-values, this is
 equally unsafe:
    void f(ref int x);
    int x;
    f(x);

 It's precisely the same problem, and should be fixed with the same solution.
We should make the code above safe as is.
 I would rewrite your list as such:

 1. 'un-safely' pass a value (may not be a local), write 'ref'
 2. safely pass a value (may be a local), write 'scope ref'
 3. if you are concerned with templates do you:
 3.a. want unsafe auto-ref, type 'auto ref' (only non-locals would
 generate 'ref')
 3.b. want safe auto-ref, type 'scope auto ref'
This a terrible, terrible list. I'd be ashamed to have to explain this with a straight face.
     I don't know how to respond to this. To me is it painfully obvious
     DIP 36 is poor language design and fails to solve a variety of
     issues, such as clarifying lifetime of temporaries, safety, and
     returning ref from functions.


 Lifetime of temporaries is the most basic of principles. A local lives
 the life of the function in which it is defined.
 Safety is the whole point, and intrinsic to the proposal; safety by
 explicit specification, thus the programmer retains the option.
The missing point here is inflicting more complexity on the user. Andrei
Apr 23 2013
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/23/2013 07:33 PM, Andrei Alexandrescu wrote:
 On 4/23/13 12:04 PM, Manu wrote:
 On 24 April 2013 00:24, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org <mailto:SeeWebsiteForEmail erdani.org>>
 wrote:


         The very point of this DIP is to not create
         syntax-driven features, instead better define existing ones that
         make
         sense on their own so they can be used for same purpose.


     It's a new feature, no two ways about it. It overlaps ref and auto
     ref without any palpable benefit and defines yet another way to
     achieve the same thing as auto ref. On this ground alone the
     proposal has a large problem.


 How does it overlap ref? It simply justifies the argument with an extra
 constraint and isn't tied to 'ref' at all, it's just useful in
 conjunction.
The best setup would be: 1. To take lvalues by reference, write "ref". 2. To take lvalues and rvalues by reference, write "auto ref". Everything else is superfluous and puts the burden of justification on the proposer. With DIP36, the setup would be: 1. To take lvalues by reference, write "ref". 2. To take lvalues and rvalues by reference: 2.1. Is it a template? Then write "auto ref".
or "scope ref", to be fair. scope ref on a template would behave differently than auto ref on a template.
 2.2. Is it a non-template? Then write "scope ref".

 I can't agree that it overlaps auto-ref at all. They're fundamentally
 different concepts. auto-ref is a template concept; it selects the
 ref-ness based on the received arg. 'auto ref', ie, 'automatic
 ref-ness'. It makes no sense on a non-template situation.
 I'm still completely amazed that the very reason this DIP makes perfect
 sense to me(/us) is the same reason you have a problem with it.
I don't know how to respond to this. To me is it painfully obvious DIP 36 is poor language design and fails to solve a variety of issues, such as clarifying lifetime of temporaries, safety, and returning ref from functions.
+1.
 ...

 Our intent is to make "ref" always scoped and reserve non-scoped uses to
 pointers. We consider this good language design: we have unrestricted
 pointers for code that doesn't care much about safety, and we have "ref"
 which is almost as powerful but sacrifices a teeny bit of that power for
 the sake of guaranteed safety. Safety is guaranteed by making sure "ref"
 is always scoped (references can be passed down but never escape their
 bound value).
 ...
Safety should be guaranteed in safe code. There is no point in conservatively disallowing perfectly fine system code on the basis of safety concerns, unless, of course, the type system is advanced enough to prove safe all relevant use cases.
Apr 23 2013
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 23 Apr 2013 15:40:35 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:


 Safety should be guaranteed in  safe code. There is no point in  
 conservatively disallowing perfectly fine  system code on the basis of  
 safety concerns, unless, of course, the type system is advanced enough  
 to prove safe all relevant use cases.
I agree with this. If safe code is all that is affected, we will be well off. We can also disallow known bad cases in non- safe code. -Steve
Apr 23 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/23/2013 09:51 PM, Steven Schveighoffer wrote:
 On Tue, 23 Apr 2013 15:40:35 -0400, Timon Gehr <timon.gehr gmx.ch> wrote:


 Safety should be guaranteed in  safe code. There is no point in
 conservatively disallowing perfectly fine  system code on the basis of
 safety concerns, unless, of course, the type system is advanced enough
 to prove safe all relevant use cases.
I agree with this. If safe code is all that is affected, we will be well off. We can also disallow known bad cases in non- safe code. -Steve
Another possibility I consider fine is to implement what Andrei suggests and then allow system code to cast around the conservative escape checks using something like eg. cast(scope). struct CodeGen{ struct Label{ CodeGen* outer; } Label makeLabel(){ return Label(&this); } // error } struct CodeGen{ struct Label{ CodeGen* outer; } Label makeLabel(){ return Label(cast(scope)&this); } // ok } The best way to fix this would of course be to introduce lifetimes as an explicit type system feature. (Though if I was allowed to add that kind of complexity to the type system, I'd do many things very differently.)
Apr 23 2013
prev sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
First of all, we should define words for the discussion.

1. Let's name current `auto ref` "parameterized-ref", which works only with
template functions and the `auto ref` parameter is instantiated to both
ref/non-ref by the actual function argument.
2. Let's call it "rvalue-ref(erence)", which currently discussed, that can
receive both lvalues and rvalues by one function body.

2013/4/24 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>

 The best setup would be:

 1. To take lvalues by reference, write "ref".

 2. To take lvalues and rvalues by reference, write "auto ref".

 Everything else is superfluous and puts the burden of justification on the
 proposer. With DIP36, the setup would be:

 1. To take lvalues by reference, write "ref".

 2. To take lvalues and rvalues by reference:

 2.1. Is it a template? Then write "auto ref".

 2.2. Is it a non-template? Then write "scope ref".
The difference between 2.1 and 2.2 is not superfluous. Because: 1. "parameterized-ref" is already there with the syntax `auto ref`. Removing it introduces breaking language change. 2. If we remove "parameterized-ref" from D, we will lose the ability to write certain kind of template functions. For example: auto ref forward(T)(auto ref T arg) { return arg; } The parameter `arg` is instantiated with both ref/non-ref, and forward `function` returns also both ref/non-ref value. In such case, you cannot replace "parameterized-ref" to "rvalue-ref". These are why DIP36 is necessary. Repeatedly, I think removing current `auto ref` is not good.
 Currently rvalues are destroyed immediately after the call they are passed
 into. DIP 36 would need to change that, but fails to specify it.
DIP36 does not change it.
 Our intent is to make "ref" always scoped and reserve non-scoped uses to
 pointers. We consider this good language design: we have unrestricted
 pointers for code that doesn't care much about safety, and we have "ref"
 which is almost as powerful but sacrifices a teeny bit of that power for
 the sake of guaranteed safety. Safety is guaranteed by making sure "ref" is
 always scoped (references can be passed down but never escape their bound
 value).
I'm basically agreeing with the DIP25. Making `ref` more safety is possible and should. I can guess that you are intended applying DIP25 to "rvalue-ref" concept. It is sane design, but DIP36 also accepts such applying DIP25. There is no issue.
 Andrei
Kenji Hara
Apr 23 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04/24/2013 02:41 AM, kenji hara wrote:
 ...

 1. "parameterized-ref" is already there with the syntax `auto ref`.
 Removing it introduces breaking language change.

 2. If we remove "parameterized-ref" from D, we will lose the ability to
 write certain kind of template functions. For example:

      auto ref forward(T)(auto ref T arg) { return arg; }

 The parameter `arg` is instantiated with both ref/non-ref, and forward
 `function` returns also both ref/non-ref value. In such case, you cannot
 replace "parameterized-ref" to "rvalue-ref".

 These are why DIP36 is necessary. Repeatedly, I think removing current
 `auto ref` is not good.
...
We could specify that if there is no influence (to be made more precise) of the actual ref-ness for the function semantics, the second copy is elided. It is then illegal for non-templated functions to require multiple copies. This would merge the two features under the name auto ref.
Apr 24 2013
prev sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Saturday, 20 April 2013 at 14:42:57 UTC, Namespace wrote:
 That is true, but it makes the impression that, with the 
 exception of Kenji, none of the core developers is interested 
 in a solution to this problem.
I don't think that's true.
 The DIP was not much discussed and the pull request is 
 regularly overlooked / ignored.
Patience!
 Also in the discussion on the pull request no comments for 
 Walter or Andrei are found. Although the pull is complete and 
 has passed all the tests and would be ready to merge.
 Also this thread is completely ignored even though both write 
 in this forum regularly and participate in other discussions.
 To me this makes the impression that they were not interested 
 in this problem (or in our solution to the problem). Either 
 they want the problem does not solve or try to solve it in 
 their own way and that can take a very long time.
 At least an annotation what of both is the case or if I see it 
 completely wrong, would be polite.

 But someone besides me would need to evaluate both DIP 35 & 36 
 to see if there were any real conflicts there.
Yes that would be good.
I think you've done a good job with the feature and the presentation. But I personally don't feel like it's my job to rush D's development. Part of the reason is that D is already way ahead of most if not all of the competition in terms of sheer language design. When you extend into unknown territory, it's sometimes wise just to stay where you are for a bit, to give yourself time to adapt and build up a foundation. I don't think your work will go unnoticed or unappreciated. Most of the time when people don't get back to you, it's because they're busy with other things. Probably the best thing you can do is say, well, my work on this feature is done, what else can I improve around here? This feature and this issue won't go away, IMO.
Apr 20 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
Well perhaps I am too hasty. I'll wait and see what is happening.

BTW: Thanks for the support. ;)
Apr 21 2013
prev sibling parent "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 10 April 2013 at 07:43:57 UTC, Dicebot wrote:
 Consistent behavior is important but it does not change the 
 fact that there two types of rvalues in the language - raw 
 literals (42, A.init) and constructed temporaries (A()). 
 Accepting rvalues of the first type in as mutable references 
 may be consistent from the point of view of syntax by 
 _extremely_ confusing semantics-wise:

 void foo(scope ref int x)
 {
     x = 32;
 }

 void main()
 {
     foo(42); // erm, 32 is the new 42 or ref is not actually 
 ref?
 }

 Beauty of "in ref" is that in that case user can't use it in 
 any way that may disclose the fact the temporary variable for 
 non-adressable entities is created. For mutable scope ref it is 
 not the case and we must leak implementation details, which is 
 never good.

 Another concern is that if someone tries to pass "42" as a 
 mutable ref, most likely he does not really wants it to be 
 mutable and "in ref" is a better match.

 This may not be consistent from the point of view of generic 
 code, but it is now consistent from the point of view of 
 programmer : A(...) construct always create temporaries, raw 
 value literals never do (well, they will for "in ref" but you 
 can't observe it). I think this is much more important.

 One extra thing to note is that test32 may actually work if it 
 instantiates T as "const int" for 42 (making it "in ref" 
 essentially), but I don't know if D rules allow it.
I think this is another case of two different features which may or may not be paired up together. If it is always okay to have A accompany B, and B accompany A, it's good from a syntax point of view because you only need one syntax for both of them. But if you pair them up and later think, I wish I could do A without having to do B, or B without having to do A, then you'll regret pairing them up because you'll either have to break code or live with what you've got. When you say we shouldn't be able to return an rvalue temporaries, even if they're safe, I think it's reasonable, not a life or death issue. But if 'scope ref' is used to mean that, you're also saying that any *other* feature which wants 'scope', such as 'ref' safety (why I created DIP35, to highlight this), will automatically also have to take rvalue temps because they're bound up with it, it's more risky. Some of these will be a judgment call - A and B are sometimes so similar that it's better to save on syntax than differentiate them. 'const scope' might be the same way.
Apr 11 2013
prev sibling next sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:
 http://wiki.dlang.org/DIP36
// Does not pretend to be safe any more void test2(ref A a) { } I believe 'ref' still *can* be safe. The unsafe action is really when you assign it to a global pointer. void test2(ref A a) { static A* p; p = &a; // <-- This is really the only unsafe thing } I think for convenience the function must only be considered unsafe if it does the above. Even returning the 'ref' is safe so long as the *caller* keeps track of what it passes in, according to DIP25. "Following limitation apply to scope ref function parameters (including in ref): ...3. Parameter can only be used as an argument for other function if it also accepts scope ref, no implicit casting away." The DIP fails to mention that 'scope' by itself implies 'ref', and (presumably) can be reserved for cases where the caller specifically does not want to allow rvalue temps. 'scope' implies 'ref' because value types are inherently safe and need no attributes. I'm not sure what's so bad about allowing 'scope ref' arguments to be passed to 'scope' parameters also. It passes the ref it receives, but since it's still 'scope', it's not going anywhere. Also, given that 'scope' implies 'ref', there may be significant advantage in simply allowing *all* scope parameters to accept rvalue temps. It would be helpful to have a use case where 'scope' was clearly desired but rvalue temps clearly *not* desired. In most cases, it seems, anything marked 'scope' could easily accept an rvalue temp no problem. The 'scope ref' syntax does have a slight conflict with DIP25 and my suggested addition DIP35, in that if other means are found to making returning 'ref' safe, 'scope ref' as a syntax means that no rvalue temporary can ever be returned. Since this may be perfectly acceptable from a 'bad practices' point of view, 'scope ref' may still be a good syntax. But if it were seen as okay to return even a an rvalue temporary, since it is made safe by other means, 'scope ref' would either not be usable for this or would actually be (confusingly) returnable.
Apr 09 2013
next sibling parent reply kenji hara <k.hara.pg gmail.com> writes:
2013/4/10 Zach the Mystic <reachzach gggggmail.com>

 On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:

 http://wiki.dlang.org/DIP36
// Does not pretend to be safe any more void test2(ref A a) { } I believe 'ref' still *can* be safe. The unsafe action is really when you assign it to a global pointer. void test2(ref A a) { static A* p; p = &a; // <-- This is really the only unsafe thing } I think for convenience the function must only be considered unsafe if it does the above. Even returning the 'ref' is safe so long as the *caller* keeps track of what it passes in, according to DIP25. "Following limitation apply to scope ref function parameters (including in ref): ...3. Parameter can only be used as an argument for other function if it also accepts scope ref, no implicit casting away." The DIP fails to mention that 'scope' by itself implies 'ref', and (presumably) can be reserved for cases where the caller specifically does not want to allow rvalue temps. 'scope' implies 'ref' because value types are inherently safe and need no attributes. I'm not sure what's so bad about allowing 'scope ref' arguments to be passed to 'scope' parameters also. It passes the ref it receives, but since it's still 'scope', it's not going anywhere. Also, given that 'scope' implies 'ref', there may be significant advantage in simply allowing *all* scope parameters to accept rvalue temps. It would be helpful to have a use case where 'scope' was clearly desired but rvalue temps clearly *not* desired. In most cases, it seems, anything marked 'scope' could easily accept an rvalue temp no problem. The 'scope ref' syntax does have a slight conflict with DIP25 and my suggested addition DIP35, in that if other means are found to making returning 'ref' safe, 'scope ref' as a syntax means that no rvalue temporary can ever be returned. Since this may be perfectly acceptable from a 'bad practices' point of view, 'scope ref' may still be a good syntax. But if it were seen as okay to return even a an rvalue temporary, since it is made safe by other means, 'scope ref' would either not be usable for this or would actually be (confusingly) returnable.
I think having both 'ref' and 'scope ref' is still reasonable, because: 1. According to DIP25, escaping ref parameter is always safe. But, for rvalue reference, it allows meaningless code. // Even if this is allowed, it is safe. BUT will introduce bad practice. ref int foo(scope ref int x) { return x; } // safe ref int bar(ref int x) { return x; } void test() { int x; foo(x) = 10; // may useful but... foo(1) = 10; // completely useless! bar(x) = 10; // may useful, and bar(1) = 10; // disallowed. } 2. Certainly 'scope' by itself _can_ imply 'ref'. BUT, currently a function parameter without 'ref' storage class implies having value semantics (== copy). If we change the 'scope' meaning to 'implicit ref', it will break the consistency. And, 'scope' is alredy used for delegate parameter. int opApply(scope int delegate(ref int) dg); Such a semantic modification will silently change the meaning of existing code. It's not good to me. Kenji Hara
Apr 09 2013
parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 10 April 2013 at 02:41:10 UTC, kenji hara wrote:
 I think having both 'ref' and 'scope ref' is still reasonable, 
 because:

 1. According to DIP25, escaping ref parameter is always safe.  
 But, for
 rvalue reference, it allows meaningless code.

 // Even if this is allowed, it is safe. BUT will introduce bad 
 practice.
 ref int foo(scope ref int x) { return x; }

 // safe
 ref int bar(ref int x) { return x; }

 void test() {
     int x;
     foo(x) = 10;    // may useful but...
     foo(1) = 10;    // completely useless!

     bar(x) = 10;    // may useful, and
     bar(1) = 10;    // disallowed.
 }
'foo(1) = 10' is indeed completely useless, but I don't think all uses are completely useless. But I will concede that allowing things like 'foo(1)' may be useless *enough* to disallow it without anyone feeling bad. I have made DIP35, http://wiki.dlang.org/DIP35 , which utilizes 'scope' to actually make DIP25 more flexible, which I think is probably good. The example I used was the 'copy' function. 'foo' above, rewritten as the copy function would be: ref int foo(scope ref int x) { int* y = new int; *y = x; return y; } DIP25 may *need* to use 'scope' in this way to know that foo() will always give a fresh value - so it can treat it like a global safely. Thus 'foo(1)' will return a fresh heap allocated copy of "1". ref int test() { return foo(1); // allowed return bar(1); // disallowed! } Without the 'scope' parameter, there would be no way the compiler could know. Therefore, it is not completely useless.
 2. Certainly 'scope' by itself _can_ imply 'ref'. BUT,  
 currently a function
 parameter without 'ref' storage class implies having value 
 semantics (== copy).
This is slightly wrong, I suspect. 'out' parameters are implicitly references.
 If we change the 'scope' meaning to 'implicit ref', it will 
 break the
 consistency.

 And, 'scope' is already used for delegate parameter.

 int opApply(scope int delegate(ref int) dg);

 Such a semantic modification will silently change the meaning 
 of existing code. It's not good to me.
Generally, I agree. My argument is for a small convenience of not having to type 'ref' when not necessary. It would mean that when the type was implicitly a reference, such as a delegate or object, 'ref' was *not* implied, whereas it *was* implied with a value type. This may or may not wreak havoc on the generic type system. I thought there might be an off-chance that it would actually be a *convenience* for the type system, since it would get the right level of referencing for the type involved. I believe that the 'scope' keyword may be a necessary addition to DIP25 to make 'ref' fully safe and flexible (DIP35). If so, then there may be a conflict with using it only to mean rvalue temporaries. They are two separate features. I believe that if they are to be used together, it will be because it was decided that whenever you want to stop a reference from escaping, you *always* want to allow rvalue temporaries, and whenever you want to allow rvalue temporaries, you *never* want them to be returned. Right now, returning an rvalue temporary might seem dangerous, but sealed references *are* part of the plan for D, and there may be no need to see them as dangerous.
Apr 09 2013
parent "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 10 April 2013 at 04:46:43 UTC, Zach the Mystic 
wrote:
 ref int bar(ref int x) { return x; }

 ref int foo(scope ref int x) {
   int* y = new int;
   *y = x;
   return y;
 }

 ref int test() {
   return foo(1); // allowed
   return bar(1); // disallowed!
 }
When said 'bar(1)' was disallowed, I meant that it was considered local and not disallowed because it doesn't accept rvalue temps. Fix: ref int test() { int y; return foo(y); // allowed return bar(y); // disallowed! }
Apr 09 2013
prev sibling next sibling parent reply Manu <turkeyman gmail.com> writes:
On 10 April 2013 12:40, kenji hara <k.hara.pg gmail.com> wrote:

 2013/4/10 Zach the Mystic <reachzach gggggmail.com>

 On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:

 http://wiki.dlang.org/DIP36
// Does not pretend to be safe any more void test2(ref A a) { } I believe 'ref' still *can* be safe. The unsafe action is really when you assign it to a global pointer. void test2(ref A a) { static A* p; p = &a; // <-- This is really the only unsafe thing } I think for convenience the function must only be considered unsafe if it does the above. Even returning the 'ref' is safe so long as the *caller* keeps track of what it passes in, according to DIP25. "Following limitation apply to scope ref function parameters (including in ref): ...3. Parameter can only be used as an argument for other function if it also accepts scope ref, no implicit casting away." The DIP fails to mention that 'scope' by itself implies 'ref', and (presumably) can be reserved for cases where the caller specifically does not want to allow rvalue temps. 'scope' implies 'ref' because value types are inherently safe and need no attributes. I'm not sure what's so bad about allowing 'scope ref' arguments to be passed to 'scope' parameters also. It passes the ref it receives, but since it's still 'scope', it's not going anywhere. Also, given that 'scope' implies 'ref', there may be significant advantage in simply allowing *all* scope parameters to accept rvalue temps. It would be helpful to have a use case where 'scope' was clearly desired but rvalue temps clearly *not* desired. In most cases, it seems, anything marked 'scope' could easily accept an rvalue temp no problem. The 'scope ref' syntax does have a slight conflict with DIP25 and my suggested addition DIP35, in that if other means are found to making returning 'ref' safe, 'scope ref' as a syntax means that no rvalue temporary can ever be returned. Since this may be perfectly acceptable from a 'bad practices' point of view, 'scope ref' may still be a good syntax. But if it were seen as okay to return even a an rvalue temporary, since it is made safe by other means, 'scope ref' would either not be usable for this or would actually be (confusingly) returnable.
I think having both 'ref' and 'scope ref' is still reasonable, because: 1. According to DIP25, escaping ref parameter is always safe. But, for rvalue reference, it allows meaningless code. // Even if this is allowed, it is safe. BUT will introduce bad practice. ref int foo(scope ref int x) { return x; } // safe ref int bar(ref int x) { return x; } void test() { int x; foo(x) = 10; // may useful but... foo(1) = 10; // completely useless! bar(x) = 10; // may useful, and bar(1) = 10; // disallowed. } 2. Certainly 'scope' by itself _can_ imply 'ref'. BUT, currently a function parameter without 'ref' storage class implies having value semantics (== copy). If we change the 'scope' meaning to 'implicit ref', it will break the consistency.
Why are you suggesting changing scope to imply ref? This seems wrong. scope and ref are separate, should remain that way. Arguments would be scope ref, or in ref, thus allowing rvalues. Without ref, I would imagine that the meaning is such that, even though the argument is a copy, it, or members thereof are not allowed to escape. struct X { int *p; } int* global; void func(scope X x) // note: is not ref { global = x.p; // <- error! scope prevents any part of x escaping, even though it's a copy. } This way, scope has meaning with or without ref. And, 'scope' is alredy used for delegate parameter.
 int opApply(scope int delegate(ref int) dg);

 Such a semantic modification will silently change the meaning of existing
 code. It's not good to me.
What does scope mean in this case? Is this a conflict in some way?
Apr 09 2013
next sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 10 April 2013 at 05:21:40 UTC, Manu wrote:
 Why are you suggesting changing scope to imply ref? This seems 
 wrong. scope
 and ref are separate, should remain that way.
To be clear, I suggested it, not Kenji. The reason scope could imply ref is that no value type is ever unsafe. If you copy the value you're passing, there's no way the reference could escape the scope, because there's no reference! A delegate has an implicit pointer and is inherently a reference type, which is why it can work with 'scope'. In all likelihood 'scope' implying 'ref' would needlessly complicate the type system, in exchange for the convenience of only having to type either 'scope' or 'ref' depending on what you wanted. But I suggested it because I at least wanted it to be discussed.
Apr 09 2013
next sibling parent Manu <turkeyman gmail.com> writes:
On 10 April 2013 16:11, Zach the Mystic <reachzach gggggmail.com> wrote:

 On Wednesday, 10 April 2013 at 05:21:40 UTC, Manu wrote:

 Why are you suggesting changing scope to imply ref? This seems wrong.
 scope
 and ref are separate, should remain that way.
To be clear, I suggested it, not Kenji. The reason scope could imply ref is that no value type is ever unsafe.
It is though, in the case I demonstrated. A value type can aggregate a reference type, and by-val scope would prohibit any part of the copy from escaping in turn. This is tricky, but I think it would be an important enhancement for non-ref scope variables and safe-ty. It might be impractical, but it's something to think about anyway... If you copy the value you're passing, there's no way the reference could
 escape the scope, because there's no reference! A delegate has an implicit
 pointer and is inherently a reference type, which is why it can work with
 'scope'. In all likelihood 'scope' implying 'ref' would needlessly
 complicate the type system, in exchange for the convenience of only having
 to type either 'scope' or 'ref' depending on what you wanted. But I
 suggested it because I at least wanted it to be discussed.
Fair enough.
Apr 09 2013
prev sibling parent reply "Mehrdad" <wfunction hotmail.com> writes:
On Wednesday, 10 April 2013 at 06:11:29 UTC, Zach the Mystic 
wrote:
 no value type is ever unsafe.
Delegates?
Apr 23 2013
parent "Zach the Mystic" <reachzach gggggmail.com> writes:
On Tuesday, 23 April 2013 at 08:13:28 UTC, Mehrdad wrote:
 On Wednesday, 10 April 2013 at 06:11:29 UTC, Zach the Mystic 
 wrote:
 no value type is ever unsafe.
Delegates?
Well, I don't know the formal definition of a delegate, but I believe it is a pointer to a function, plus a pointer to a data frame for the function. Since it contains a pointer, it qualifies to me as a reference type. Arrays too.
Apr 23 2013
prev sibling parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 10 April 2013 at 05:21:40 UTC, Manu wrote:
 struct X { int *p; }
 int* global;

 void func(scope X x) // note: is not ref
 {
   global = x.p; // <- error! scope prevents any part of x 
 escaping, even
 though it's a copy.
 }

 This way, scope has meaning with or without ref.
I think this is a subtle point, but I don't think it's correct. I think there's a difference between 'x.p' above, and what '&x.p' or '&x' would give. I think 'scope' should guarantee that you won't assign the *address* of the passed-in parameter: void func(scope X x, ref X y) { static X* xx = &x; // Error static int** xpp = &x.p; // Error xx = &y; // unsafe, but pass xpp = &y.p; // same } I don't think it should guarantee that you won't copy something that is *already* a pointer. Copying the pointer may be dangerous, but I don't think 'scope' will be very useful if it's supposed to track the internal pointers of aggregate types like that. I think somebody else has to make sure that pointer is safe. I could be wrong.
Apr 10 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 07:39:25 UTC, Zach the Mystic 
wrote:
 ...
Kind of. I am thinking that scope is best when transitive for aggregation but not for indirection: struct S { int a; int *b; } void foo(scope S s) { static int *x1 = &(s.a); // error static int *x2 = s.b; // fine }
Apr 23 2013
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 04/23/2013 10:16 AM, Dicebot wrote:
 On Wednesday, 10 April 2013 at 07:39:25 UTC, Zach the Mystic wrote:
 ...
Kind of. I am thinking that scope is best when transitive for aggregation but not for indirection: struct S { int a; int *b; } void foo(scope S s) { static int *x1 = &(s.a); // error static int *x2 = s.b; // fine }
(Both of these are in error because static variables are initialized at compile time, but I get what you mean.) Why would 'scope' have any effect on the validity of the first? s.a belongs to the callee exclusively. Adding modular annotations to prevent taking its address has no point.
Apr 23 2013
parent "Dicebot" <m.strashun gmail.com> writes:
On Tuesday, 23 April 2013 at 08:25:18 UTC, Timon Gehr wrote:
 (Both of these are in error because static variables are 
 initialized at compile time, but I get what you mean.)
Shame on me! (blush)
 Why would 'scope' have any effect on the validity of the first? 
 s.a belongs to the callee exclusively. Adding modular 
 annotations to prevent taking its address has no point.
Because it is an attempt to take/store address of a scope variable, which is prohibited by scope definition. I think (but I am not sure!) that it makes sense to make scope transitive for aggregation, because automatic destruction upon leaving the scope happens for aggregated entities. Thus, nothing can be known about s.a lifetime, same as s lifetime. This is one step towards consistent "scope" behavior that will allow safety desired by this DIP.
Apr 23 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
2013/4/10 Manu <turkeyman gmail.com>
 Why are you suggesting changing scope to imply ref? This seems wrong.
 scope and ref are separate, should remain that way.
I say that 'scope' itself should not imply 'ref'. It is *possible* but would break existing code meaning, so it should not be applied.
 Arguments would be scope ref, or in ref, thus allowing rvalues. Without
 ref, I would imagine that the meaning is such that, even though the
 argument is a copy, it, or members thereof are not allowed to escape.

 struct X { int *p; }
 int* global;

 void func(scope X x) // note: is not ref
 {
   global = x.p; // <- error! scope prevents any part of x escaping, even
 though it's a copy.
 }

 This way, scope has meaning with or without ref.
That is an enhancement. Similar things is now in my mind, but it is not yet output.
 And, 'scope' is alredy used for delegate parameter.
 int opApply(scope int delegate(ref int) dg);

 Such a semantic modification will silently change the meaning of existing
 code. It's not good to me.
What does scope mean in this case? Is this a conflict in some way?
Compiler guarantees that given delegate to the scope parameter never make a closure. It would avoid heap allocation. Kenji Hara
Apr 09 2013
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
On 10 April 2013 15:30, kenji hara <k.hara.pg gmail.com> wrote:

 2013/4/10 Manu <turkeyman gmail.com>
 Why are you suggesting changing scope to imply ref? This seems wrong.
 scope and ref are separate, should remain that way.
I say that 'scope' itself should not imply 'ref'. It is *possible* but would break existing code meaning, so it should not be applied.
Right. Absolutely agree then! :)
 Arguments would be scope ref, or in ref, thus allowing rvalues. Without
 ref, I would imagine that the meaning is such that, even though the
 argument is a copy, it, or members thereof are not allowed to escape.

 struct X { int *p; }
 int* global;

 void func(scope X x) // note: is not ref
 {
   global = x.p; // <- error! scope prevents any part of x escaping, even
 though it's a copy.
 }

 This way, scope has meaning with or without ref.
That is an enhancement. Similar things is now in my mind, but it is not yet output.
I think this is a tool that will greatly enhance working with safe in the future. I look forward to it. And, 'scope' is alredy used for delegate parameter.
 int opApply(scope int delegate(ref int) dg);

 Such a semantic modification will silently change the meaning of
 existing code. It's not good to me.
What does scope mean in this case? Is this a conflict in some way?
Compiler guarantees that given delegate to the scope parameter never make a closure. It would avoid heap allocation.
Do you have any ideas/solutions that still fit this proposal? I tend to think the value of this proposal is of extreme significance to D. It is, without doubt, the single biggest complaint I've heard by virtually every programmer I've introduced D to, and the future implications for safe improvements are valuable too.
Apr 09 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 01:40:49 UTC, Zach the Mystic 
wrote:
 I think for convenience the function must only be considered 
 unsafe if it does the above. Even returning the 'ref' is  safe 
 so long as the *caller* keeps track of what it passes in, 
 according to DIP25.
Safety of "ref" is not problem that this DIP tries to solve. It should be solved with DIP25. Now ref is not safe (despite the fact it pretends to) and it still won't be after DIP36 approval, not until issue is addressed in DIP25. No need to mix it.
Apr 10 2013
parent reply "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 10 April 2013 at 07:46:41 UTC, Dicebot wrote:
 On Wednesday, 10 April 2013 at 01:40:49 UTC, Zach the Mystic 
 wrote:
 I think for convenience the function must only be considered 
 unsafe if it does the above. Even returning the 'ref' is  safe 
 so long as the *caller* keeps track of what it passes in, 
 according to DIP25.
Safety of "ref" is not problem that this DIP tries to solve. It should be solved with DIP25. Now ref is not safe (despite the fact it pretends to) and it still won't be after DIP36 approval, not until issue is addressed in DIP25. No need to mix it.
My proposed DIP35 uses 'scope' to enhance DIP25. I don't believe DIP25 is really complete. 'scope' would help it a lot, but that would give more meanings to 'scope' which are potentially in conflict with it just meaning rvalue temp.
Apr 10 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 09:26:38 UTC, Zach the Mystic 
wrote:
 On Wednesday, 10 April 2013 at 07:46:41 UTC, Dicebot wrote:
 On Wednesday, 10 April 2013 at 01:40:49 UTC, Zach the Mystic 
 wrote:
 I think for convenience the function must only be considered 
 unsafe if it does the above. Even returning the 'ref' is 
  safe so long as the *caller* keeps track of what it passes 
 in, according to DIP25.
Safety of "ref" is not problem that this DIP tries to solve. It should be solved with DIP25. Now ref is not safe (despite the fact it pretends to) and it still won't be after DIP36 approval, not until issue is addressed in DIP25. No need to mix it.
My proposed DIP35 uses 'scope' to enhance DIP25. I don't believe DIP25 is really complete. 'scope' would help it a lot, but that would give more meanings to 'scope' which are potentially in conflict with it just meaning rvalue temp.
And how it is relevant to DIP36? It solves specific issue. It provides some hints how other DIP may use new opportunities. It is up to DIP25 and DIP35 to be built on top if this gets accepted first. Or other way around. DIPs are built in context for current language implementation, not some potential other DIPs.
Apr 10 2013
parent "Zach the Mystic" <reachzach gggggmail.com> writes:
On Wednesday, 10 April 2013 at 09:31:22 UTC, Dicebot wrote:
 Safety of "ref" is not problem that this DIP tries to solve. 
 It should be solved with DIP25. Now ref is not safe (despite 
 the fact it pretends to) and it still won't be after DIP36 
 approval, not until issue is addressed in DIP25.

 No need to mix it.
My proposed DIP35 uses 'scope' to enhance DIP25. I don't believe DIP25 is really complete. 'scope' would help it a lot, but that would give more meanings to 'scope' which are potentially in conflict with it just meaning rvalue temp.
And how it is relevant to DIP36? It solves specific issue. It provides some hints how other DIP may use new opportunities. It is up to DIP25 and DIP35 to be built on top if this gets accepted first. Or other way around. DIPs are built in context for current language implementation, not some potential other DIPs.
I would say, if you are going to use a keyword ('scope' in this case) to mean something, and there are other uses of the keyword which are also useful, you have to decide first if there is a conflict, and second how it should be resolved. In my opinion there is a conflict. The only existing definition of 'scope' parameters we have suggets that it means the parameter may not be escaped. It turns out that such a parameter is possibly necessary to successfully seal references in D. If a different proposal wants to use the word to mean something else, then it's important to decide either that two different features require two different parameter attributes (DIP36 understands this, and proposes several alternate possibilities to use), or that each feature can always automatically include the other feature without any problems (possible but see my other responses), or that only one feature is truly important enough to be included in the language, allowing you to disregard the other feature entirely.
Apr 10 2013
prev sibling next sibling parent reply Manu <turkeyman gmail.com> writes:
YES PLEASE!!
I've been saying precisely this for years, I'm glad someone took the time
to write it down all nice and proposal-like :)


On 10 April 2013 03:06, Namespace <rswhite4 googlemail.com> wrote:

 http://wiki.dlang.org/DIP36
Apr 09 2013
parent "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 05:01:12 UTC, Manu wrote:
 YES PLEASE!!
 I've been saying precisely this for years, I'm glad someone 
 took the time
 to write it down all nice and proposal-like :)
When I initially volunteered to help formalize it I had no strong feelings about this proposal but after taking care of all details I really like how it naturally fits into existing D type system, with no ugly hacks or weird behavior changes.
Apr 10 2013
prev sibling next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:
 http://wiki.dlang.org/DIP36
I see no point in adding that much complexity for something that can mostly be automated.
Apr 10 2013
next sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 11:36:22 UTC, deadalnix wrote:
 On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:
 http://wiki.dlang.org/DIP36
I see no point in adding that much complexity for something that can mostly be automated.
Can you explain this a bit more extensively, probably with some sort of counter-proposal? I can't see where complexity comes from, this DIP introduces literally zero special cases.
Apr 10 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 10 April 2013 at 11:37:43 UTC, Dicebot wrote:
 On Wednesday, 10 April 2013 at 11:36:22 UTC, deadalnix wrote:
 On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:
 http://wiki.dlang.org/DIP36
I see no point in adding that much complexity for something that can mostly be automated.
Can you explain this a bit more extensively, probably with some sort of counter-proposal? I can't see where complexity comes from, this DIP introduces literally zero special cases.
I think he means that the Compiler could/should decide, if something should passed by ref or by value. But I think that would be far more complex than scope ref/in ref.
Apr 10 2013
parent reply Manu <turkeyman gmail.com> writes:
On 10 April 2013 22:27, Namespace <rswhite4 googlemail.com> wrote:

 On Wednesday, 10 April 2013 at 11:37:43 UTC, Dicebot wrote:

 On Wednesday, 10 April 2013 at 11:36:22 UTC, deadalnix wrote:

 On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:

 http://wiki.dlang.org/DIP36
I see no point in adding that much complexity for something that can mostly be automated.
Can you explain this a bit more extensively, probably with some sort of counter-proposal? I can't see where complexity comes from, this DIP introduces literally zero special cases.
I think he means that the Compiler could/should decide, if something should passed by ref or by value. But I think that would be far more complex than scope ref/in ref.
Right. Yeah, seems more complex for sure. It's also unreliable/unpredictable. Same as with the pure conversation, I really prefer explicit control of things to at least be an option. I really don't want to be guessing about things that I may be depending on.
Apr 10 2013
next sibling parent "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
I hope this proposal gets implemented soon :)
Apr 10 2013
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Wednesday, 10 April 2013 at 12:40:57 UTC, Manu wrote:
 On 10 April 2013 22:27, Namespace <rswhite4 googlemail.com> 
 wrote:

 On Wednesday, 10 April 2013 at 11:37:43 UTC, Dicebot wrote:

 On Wednesday, 10 April 2013 at 11:36:22 UTC, deadalnix wrote:

 On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:

 http://wiki.dlang.org/DIP36
I see no point in adding that much complexity for something that can mostly be automated.
Can you explain this a bit more extensively, probably with some sort of counter-proposal? I can't see where complexity comes from, this DIP introduces literally zero special cases.
I think he means that the Compiler could/should decide, if something should passed by ref or by value. But I think that would be far more complex than scope ref/in ref.
Right. Yeah, seems more complex for sure. It's also unreliable/unpredictable. Same as with the pure conversation, I really prefer explicit control of things to at least be an option. I really don't want to be guessing about things that I may be depending on.
It is certainly more complex on the compiler implementation side. But the ends result can be much better, and any program would benefit from it. Plus, do you know that depending on the ABI, some pass by value are already transformed as pass by ref ? This is already in place in some cases, and have been proven to work well. Back to the DIP, it fail to define how and where lvalue are implicitely created, what are their lifetime, etc . . . Finally, ref and scope would benefit much more from the introduction of lifetime into D than hacking around.
Apr 10 2013
parent "Dicebot" <m.strashun gmail.com> writes:
On Wednesday, 10 April 2013 at 13:51:59 UTC, deadalnix wrote:
 It is certainly more complex on the compiler implementation 
 side. But the ends result can be much better, and any program 
 would benefit from it.

 Plus, do you know that depending on the ABI, some pass by value 
 are already transformed as pass by ref ? This is already in 
 place in some cases, and have been proven to work well.

 Back to the DIP, it fail to define how and where lvalue are 
 implicitely created, what are their lifetime, etc . . .

 Finally, ref and scope would benefit much more from the 
 introduction of lifetime into D than hacking around.
DIP36 was intentionally tweaked in such way so that compiler is free to do any implementation and swap pass by values with pass by ref if needed - until it preserves the semantics guarantees. Introduction of lifetime is very beneficial but not really relevant to _this_ DIP. If lifetime is well defined, idea of making struct literal lvalues may be discussed, but that is a different story. I don't care about how complex compiler implementation is but behavior needs to be predictable by programmer, no observable magic. Scope happens to have exactly the semantics needed to make stuff work right here and right now, with no relation to possible improvements of ref and rvalue/lvalue system.
Apr 10 2013
prev sibling parent Manu <turkeyman gmail.com> writes:
On 10 April 2013 21:36, deadalnix <deadalnix gmail.com> wrote:

 On Tuesday, 9 April 2013 at 17:06:47 UTC, Namespace wrote:

 http://wiki.dlang.org/DIP36
I see no point in adding that much complexity for something that can mostly be automated.
Where's the complexity? I find it intuitive and super useful. I personally see this DIP as just fleshing out the functionality of scope that I imagined/assumed from the moment I learned about the scope keyword. I was actually quite surprised to learn it wasn't already like this :)
Apr 10 2013
prev sibling parent "Jonas Drewsen" <nospam4321 hotmail.com > writes:
Isn's it too strict? The following example would not work because 
you cannot take the address of the parameter. But it would still 
be nice to have it passed by ref and scoped:

struct Item
{
    int data;
    Item* next;
}

void printThem(const scope ref Item first)
{
     auto it = &first;
     while (it)
     {
         std.stdio.writeln(*it);
         it = it.next;
     }
}


/Jonas
Apr 11 2013