www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - structs are now lvalues - what is with "auto ref"?

reply "Namespace" <rswhite4 googlemail.com> writes:
As the title says: In dmd 2.061 structs are lvalues now, but we 
have still no auto ref for none template functions. What should I 
do if I need something like that and don't want to write a ref 
and a none-ref function?
I'm very afraid that "auto ref" will also not work in 2.062 So 
what is the stage of affairs? Or is there any hope that it will 
be fixed in 2.061?
Dec 23 2012
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 12/24/12, Namespace <rswhite4 googlemail.com> wrote:
 As the title says: In dmd 2.061 structs are lvalues now
You mean struct literals? They're rvalues now, this wasn't enforced before but it is now since a recent pull. Can't answer your other question, sorry.
Dec 23 2012
parent "Namespace" <rswhite4 googlemail.com> writes:
On Sunday, 23 December 2012 at 23:53:49 UTC, Andrej Mitrovic 
wrote:
 On 12/24/12, Namespace <rswhite4 googlemail.com> wrote:
 As the title says: In dmd 2.061 structs are lvalues now
You mean struct literals? They're rvalues now, this wasn't enforced before but it is now since a recent pull. Can't answer your other question, sorry.
Yes of course. They was lvalues.
Dec 23 2012
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 00:48:01 Namespace wrote:
 As the title says: In dmd 2.061 structs are lvalues now, but we
 have still no auto ref for none template functions. What should I
 do if I need something like that and don't want to write a ref
 and a none-ref function?
 I'm very afraid that "auto ref" will also not work in 2.062 So
 what is the stage of affairs? Or is there any hope that it will
 be fixed in 2.061?
If you have a templated function, you can use auto ref. If you have a non- templated function, you need to write both a ref and non-ref function (though the non-ref version can forward to the ref one avoiding having to duplicate the entire function). It's a long-standing issue that has yet to be resolved, and it won't be fixed in 2.061 as we're about to start preparing for that release. I think that Kenji was working on trying to get auto ref to work with non- templated functions in some manner at one point but ran into issues with it, and it hasn't really been decided what the correct solution is, so I don't know when it will be fixed. Plenty of folks would simply argue for const ref working like it does in C++, but Andrei is dead set against that, so it hasn't happened. It's not necessarily a good fix anyway though given the fact that const is so much more restrictive in D. auto ref will accept both lvalues and rvalues but will allow for the mutation of the argument, making it somewhat different from what you get with const& in C++, but it also avoids having to restrict yourself with const (and you can still use const with auto ref if you want to). So, we may need a similar fix with non-templated functions. As for struct literals, it never made sense for them to be lvalues. They're temporaries, not variables. And it causes stupidity like S foo() {...} auto bar(ref S) {...} bar(S()); //compiles bar(foo()); //doesn't compile There's no question though that the issue with const ref / auto ref needs to be resolved. But unfortunately, that's still an open issue. - Jonathan M Davis
Dec 23 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
If I remember correctly, the discussion and the fix of "auto ref" 
permanently on dmd since 2.058. But since at least June 2012. Is 
that correct?
That is a very important use case. No one can/will use D 
seriously if D has all the time such big problems.
Dec 23 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 01:19:22 Namespace wrote:
 If I remember correctly, the discussion and the fix of "auto ref"
 permanently on dmd since 2.058. But since at least June 2012. Is
 that correct?
It's been discussed off and on for ages, but it's never been a high enough priority to actually get fixed. I believe that the last major discussion involving both Walter and Andrei was on the Beta list during the beta for 2.060, but there have been a couple of discussions involving other people in the main newsgroup more recently than that.
 That is a very important use case. No one can/will use D
 seriously if D has all the time such big problems.
Plenty of people are using it with the problems that it currently has, but I do agree that it needs to be fixed. Still, it's not like problems aren't being fixed. It's just that other problems have been fixed first. - Jonathan M Davis
Dec 23 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 Plenty of people are using it with the problems that it 
 currently has
But how long? For the moment (or the next 2, 3 releases) it should be enough if I write void foo()(auto ref const Foo f) { instead of void foo(ref const Foo f) { or is there any difficulty? After all it's a template now.
Dec 23 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 02:41:41 Namespace wrote:
 Plenty of people are using it with the problems that it
 currently has
But how long? For the moment (or the next 2, 3 releases) it should be enough if I write void foo()(auto ref const Foo f) { instead of void foo(ref const Foo f) { or is there any difficulty? After all it's a template now.
If you templatize a function, then you can use auto ref with it, and auto ref functions will work with both lvalues and rvalues without copying either. It basically creates two overloads - a ref and non-ref version. The ref version takes lvalues and obviously won't make copies. The non-ref version _might_ copy but shouldn't, because the compiler will generally move rvalues values rather than copying them. - Jonathan M Davis
Dec 23 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Yes that's what I thought. My question was, if it's bad if now a 
lot of my functions/methods are templatized.
Dec 24 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 09:08:09 Namespace wrote:
 Yes that's what I thought. My question was, if it's bad if now a
 lot of my functions/methods are templatized.
That would depend on what you're doing. It's a problem with classes, because templated functions can't be virtual. With everything else, it mostly depends on whether you care about the fact that the function won't exist if it's not use and the fact that if you're putting it in a library, it won't really be compiled into the library unless it's actually used in the library (so it won't save you any disk space). Also, it will have to have its full source code in .di files if you use .di files. You also potentially have to put up with a different set of compiler bugs, since some bugs affect templated functions but not non-templated functions (and probably vice versa), which probably isn't much of an issue, but that would depend on whatever bugs there happen to currently be. So, for the most part, I'd say that it's a non-issue aside from classes, but you might care, depending on what you're doing. - Jonathan M Davis
Dec 24 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Put another way: how long will we probably still wait for a 
solution? Yet another release, or 2? Say, 6 months or even 
longer? When it comes in the near future (ie a maximum of 1-2 
months), then it would be sufficient simply to templatize my 
methods. But if it goes for much longer (which I strongly go out) 
then I probably write both functions by myself.
Dec 24 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
One more thing: Which pull request is for "auto ref" for 
none-template functions?
Dec 24 2012
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 14:01:10 Namespace wrote:
 One more thing: Which pull request is for "auto ref" for
 none-template functions?
There isn't one. - Jonathan M Davis
Dec 24 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 12:16:15 Namespace wrote:
 Put another way: how long will we probably still wait for a
 solution? Yet another release, or 2? Say, 6 months or even
 longer? When it comes in the near future (ie a maximum of 1-2
 months), then it would be sufficient simply to templatize my
 methods. But if it goes for much longer (which I strongly go out)
 then I probably write both functions by myself.
I have no idea. It's a known issue, and we want it solved, but there is no ETA for when it will be solved. It could be soon or it could be quite a while. - Jonathan M Davis
Dec 24 2012
prev sibling parent reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis 
wrote:
 On Monday, December 24, 2012 00:48:01 Namespace wrote:
but Andrei is dead set against
 - Jonathan M Davis
Why?
Dec 24 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 17:55:23 Minas Mina wrote:
 On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis
 
 wrote:
 On Monday, December 24, 2012 00:48:01 Namespace wrote:
but Andrei is dead set against

 - Jonathan M Davis
Why?
He's convinced that it's caused problems for C++ and was a major mistake. You can search the newsgroup for discussions on it. The most recent one which involved Andrei was in the beta group: http://forum.dlang.org/post/4F84D6DD.5090405 digitalmars.com - Jonathan M Davis
Dec 24 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/12 12:11 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 17:55:23 Minas Mina wrote:
 On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis

 wrote:
 On Monday, December 24, 2012 00:48:01 Namespace wrote:
 but Andrei is dead set against

 - Jonathan M Davis
Why?
He's convinced that it's caused problems for C++ and was a major mistake. You can search the newsgroup for discussions on it. The most recent one which involved Andrei was in the beta group: http://forum.dlang.org/post/4F84D6DD.5090405 digitalmars.com - Jonathan M Davis
An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); Andrei
Dec 24 2012
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:
 An important smoking gun is C++'s min(), which is allows writing unsafe
 code without casts.
 
 const int& haveANiceDay = min(4, 5);
But what does that have to do with const& for function parameters? I can agree that it's bad for local variables like that, but such references aren't legal in D anyway - const or not. const& on function paramters merely avoids a copy, and as long as you don't take the reference of that parameter (which you can't do in D) and then assign it to something or return it, it can't survive past the point that it leaves scope. I get the impression that your complaints about rvalue references stem from issues with them that have nothing to do with function parameters, and it's the function parameters that everyone cares about. That being said, I don't think that having const ref take rvalues is a good solution for D given how strict its const is - rather I think that we should figure out how to make auto ref work for non-templated functions - but I fail to see how making const ref accept rvalues would really cause any problems. - Jonathan M Davis
Dec 24 2012
next sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
12/24/2012 9:57 PM, Jonathan M Davis пишет:
 On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:
 An important smoking gun is C++'s min(), which is allows writing unsafe
 code without casts.

 const int& haveANiceDay = min(4, 5);
But what does that have to do with const& for function parameters?
It relates directly as one may then pass the result of min to fun(const ref T);
 I can agree
 that it's bad for local variables like that, but such references aren't legal
 in D anyway - const or not. const& on function paramters merely avoids a copy,
 and as long as you don't take the reference of that parameter (which you can't
 do in D) and then assign it to something or return it, it can't survive past
 the point that it leaves scope.

 I get the impression that your complaints about rvalue references stem from
 issues with them that have nothing to do with function parameters, and it's
 the function parameters that everyone cares about.

 That being said, I don't think that having const ref take rvalues is a good
 solution for D given how strict its const is - rather I think that we should
 figure out how to make auto ref work for non-templated functions - but I fail
 to see how making const ref accept rvalues would really cause any problems.

 - Jonathan M Davis
-- Dmitry Olshansky
Dec 24 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 22:11:58 Dmitry Olshansky wrote:
 12/24/2012 9:57 PM, Jonathan M Davis =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
 On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:
 An important smoking gun is C++'s min(), which is allows writing u=
nsafe
 code without casts.
=20
 const int& haveANiceDay =3D min(4, 5);
=20 But what does that have to do with const& for function parameters?
=20 It relates directly as one may then pass the result of min to fun(con=
st
 ref T);
But the temporary has to be kept in existence for the duration of the=20= statement, so I don't see how that's a problem. The temporary will last= as=20 long as the function call does. Worst case, the function returns a cons= t ref=20 to its parameter, but either that ref is used as part of the same state= ment,=20 and so the temporary continues to exist and there are no problems, or i= t's=20 copied when it's assigned to a variable, and there are no problems. It'= s the=20 fact that you can have a const& local variable that breaks things, and = D=20 doesn't allow that. - Jonathan M Davis
Dec 24 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/12 1:20 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 22:11:58 Dmitry Olshansky wrote:
 12/24/2012 9:57 PM, Jonathan M Davis пишет:
 On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:
 An important smoking gun is C++'s min(), which is allows writing unsafe
 code without casts.

 const int&  haveANiceDay = min(4, 5);
But what does that have to do with const& for function parameters?
It relates directly as one may then pass the result of min to fun(const ref T);
But the temporary has to be kept in existence for the duration of the statement, so I don't see how that's a problem.
The problem occurs of course once haveANiceDay is actually used.
 The temporary will last as
 long as the function call does. Worst case, the function returns a const ref
 to its parameter, but either that ref is used as part of the same statement,
 and so the temporary continues to exist and there are no problems, or it's
 copied when it's assigned to a variable, and there are no problems. It's the
 fact that you can have a const&  local variable that breaks things, and D
 doesn't allow that.
The very binding of rvalues to const ref would allow that breakage. We can't allow that to happen. Andrei
Dec 24 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 13:45:10 Andrei Alexandrescu wrote:
 The very binding of rvalues to const ref would allow that breakage. We
 can't allow that to happen.
But it's only bound for the length of the statement. After that, the binding can no longer exist (as the binding was a function parameter). And as I understand it, temporaries only go out of scope once the statement has completed. So, foo(bar(min(5, 7))); wouldn't be a problem no matter what bar or foo did, because no reference to 5, 7, or the return values of any of the functions could be kept. It's being able to do const int& i = foo(bar(min(5, 7))); which would allow a reference to be kept around, which D disallows. - Jonathan M Davis
Dec 24 2012
next sibling parent reply "anonymous" <anonymous example.com> writes:
On Monday, 24 December 2012 at 18:50:12 UTC, Jonathan M Davis 
wrote:
 const int& i = foo(bar(min(5, 7)));

 which would allow a reference to be kept around, which D 
 disallows.
Does it? const(int)* i = &foo(bar(min(5, 7)));
Dec 24 2012
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 20:46:00 anonymous wrote:
 On Monday, 24 December 2012 at 18:50:12 UTC, Jonathan M Davis
 
 wrote:
 const int& i = foo(bar(min(5, 7)));
 
 which would allow a reference to be kept around, which D
 disallows.
Does it? const(int)* i = &foo(bar(min(5, 7)));
That's a pointer, not a ref. It's completely different. It's also system, whereas ref is safe. - Jonathan M Davis
Dec 24 2012
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/12 2:46 PM, anonymous wrote:
 On Monday, 24 December 2012 at 18:50:12 UTC, Jonathan M Davis wrote:
 const int& i = foo(bar(min(5, 7)));

 which would allow a reference to be kept around, which D disallows.
Does it? const(int)* i = &foo(bar(min(5, 7)));
We plan to forbid that. Andrei
Dec 24 2012
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/12 1:49 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 13:45:10 Andrei Alexandrescu wrote:
 The very binding of rvalues to const ref would allow that breakage. We
 can't allow that to happen.
But it's only bound for the length of the statement. After that, the binding can no longer exist (as the binding was a function parameter). And as I understand it, temporaries only go out of scope once the statement has completed. So, foo(bar(min(5, 7))); wouldn't be a problem no matter what bar or foo did, because no reference to 5, 7, or the return values of any of the functions could be kept.
Actually D's rules are different from C++'s in that regard; Walter mentioned D is more sanguine about destroying data. I'll check with him.
 It's being
 able to do

 const int&  i = foo(bar(min(5, 7)));

 which would allow a reference to be kept around, which D disallows.
I now see what you mean, thanks. We need to disallow taking the address of that ref, but that's already planned. Andrei
Dec 24 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 16:08:36 Andrei Alexandrescu wrote:
 On 12/24/12 1:49 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 13:45:10 Andrei Alexandrescu wrote:
Actually D's rules are different from C++'s in that regard; Walter mentioned D is more sanguine about destroying data. I'll check with him.
Well, that could be a problem.
 It's being
 able to do
 
 const int&  i = foo(bar(min(5, 7)));
 
 which would allow a reference to be kept around, which D disallows.
I now see what you mean, thanks. We need to disallow taking the address of that ref, but that's already planned.
Actually, one problem did occur to me after thinking about this some more. ref int foo(ref int i) { return i; } ref int bar(int j) { return foo(j); } While the ref returned by bar can't be saved without being copied, it's returning a ref which isn't valid once bar has returned, since it was a function parameter which was not ref. The same would occur if you did ref int baz() { int i; return foo(i); } The ref has managed to basically do what happens with & and pointers, and it's essentially the same as int* foo(int* i) { return i; } int* bar(int j) { return foo(&j); } You have an escaping reference. So, while the min example would be valid, because ref was used througout, if any part of the chain passed by value or if it was a local variable inside one of those functions which was returned by ref, then we're in trouble. And auto ref will have exactly the same problem. The fact that you can both pass by ref screws things up. If that were illegal, then we'd be okay, but it's not illegal, and it would be problematic if it were, since we'd end up with lots of unnecessary copies in quite a few cases. I suppose that we could disallow returning by ref unless the value being returned was an actual variable (as opposed to the return value of another function which returned by ref), but I don't know how restrictive that would be. Certainly, as things stand, the code above that uses ref is doing what would currently be considered safe code even though it's actually unsafe. We definitely need to work through this some more and figure out what should and shouldn't be valid and what we can and can't make safe. - Jonathan M Davis
Dec 24 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Quick question: what is the state of things with dmd 2.061 and I 
see that right, that "auto ref" is more complicated than first 
thought? :/
Dec 26 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, December 26, 2012 10:43:53 Namespace wrote:
 Quick question: what is the state of things with dmd 2.061
AFAIK, it's exactly the same as it was in 2.060. - Jonathan M Davis
Dec 26 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 26 December 2012 at 22:33:38 UTC, Jonathan M Davis 
wrote:
 On Wednesday, December 26, 2012 10:43:53 Namespace wrote:
 Quick question: what is the state of things with dmd 2.061
AFAIK, it's exactly the same as it was in 2.060. - Jonathan M Davis
I mean, when it comes out. But that has now done. ;)
Dec 26 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
In consideration that Andrei said that the implementation of 
"auto ref" for none-template functions are relatively easy and 
that until now only the first beta of 2.061 came out: How likely 
is it that "auto ref" will implemented in this release? Maybe an 
official statement would be good.

Purely out of interest, because only then this release would 
really be useful for me (and maybe even for other).
But of course I know, that I am completely irrelevant. ;)
Dec 28 2012
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Namespace:

 How likely is it that "auto ref" will implemented in this 
 release?
Walter wants to release 2.061 "soon". So maybe that's for the successive (unstable?) version of the compiler. Bye, bearophile
Dec 28 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Friday, 28 December 2012 at 12:28:01 UTC, bearophile wrote:
 Namespace:

 How likely is it that "auto ref" will implemented in this 
 release?
Walter wants to release 2.061 "soon". So maybe that's for the successive (unstable?) version of the compiler. Bye, bearophile
As long as it is implemented soon, I'm so satisfied. But an official statement that it will be implemented soon, would be nice. This feature is really very important and useful.
Dec 28 2012
parent reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
On Friday, 28 December 2012 at 12:47:03 UTC, Namespace wrote:
 On Friday, 28 December 2012 at 12:28:01 UTC, bearophile wrote:
 Namespace:

 How likely is it that "auto ref" will implemented in this 
 release?
Walter wants to release 2.061 "soon". So maybe that's for the successive (unstable?) version of the compiler. Bye, bearophile
As long as it is implemented soon, I'm so satisfied. But an official statement that it will be implemented soon, would be nice. This feature is really very important and useful.
+1
Dec 28 2012
parent "Namespace" <rswhite4 googlemail.com> writes:
I wrote a workaround for me: I implement it in Romulus. So for 
these functions:

[code]
void foo(auto ref const Foo f) {
	// do something with f
}

const(int[42]) bar(auto ref const Foo a, auto ref const Foo b) 
pure nothrow {
	// do something with a and b
}

const(int[42]) quatz(auto ref const Foo a, auto ref const Foo b, 
auto ref const Foo c) pure nothrow {
	// do something with a and b
}
[/code]

Romulus generates (if they aren't template functions):

[code]
void foo( const Foo f){
	 return foo(f);
}

void foo(ref const Foo f) {
	// do something with f
}

const(int[42]) bar(ref const Foo a, const Foo b)) pure nothrow{
	 return bar(a,b);
}

const(int[42]) bar(const Foo a, ref const Foo b)) pure nothrow{
	 return bar(a,b);
}

const(int[42]) bar( const Foo a,  const Foo b) pure nothrow{
	 return bar(a,b);
}

const(int[42]) bar(ref const Foo a, ref const Foo b) pure nothrow 
{
	// do something with a and b
}

const(int[42]) quatz(ref const Foo a, const Foo b, const Foo c)) 
pure nothrow{
	 return quatz(a,b,c);
}

const(int[42]) quatz(const Foo a, ref const Foo b, const Foo c)) 
pure nothrow{
	 return quatz(a,b,c);
}

const(int[42]) quatz(const Foo a, const Foo b, ref const Foo c)) 
pure nothrow{
	 return quatz(a,b,c);
}

const(int[42]) quatz(ref const Foo a, ref const Foo b, const Foo 
c)) pure nothrow{
	 return quatz(a,b,c);
}

const(int[42]) quatz(const Foo a, ref const Foo b, ref const Foo 
c)) pure nothrow{
	 return quatz(a,b,c);
}

const(int[42]) quatz(ref const Foo a, const Foo b, ref const Foo 
c)) pure nothrow{
	 return quatz(a,b,c);
}

const(int[42]) quatz( const Foo a,  const Foo b,  const Foo c) 
pure nothrow{
	 return quatz(a,b,c);
}

const(int[42]) quatz(ref const Foo a, ref const Foo b, ref const 
Foo c) pure nothrow {
	// do something with a and b
}
[/code]

I will push it later on my github account. Maybe someone like it.
Dec 28 2012
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, December 28, 2012 13:19:01 Namespace wrote:
 In consideration that Andrei said that the implementation of
 "auto ref" for none-template functions are relatively easy and
 that until now only the first beta of 2.061 came out: How likely
 is it that "auto ref" will implemented in this release? Maybe an
 official statement would be good.
 
 Purely out of interest, because only then this release would
 really be useful for me (and maybe even for other).
 But of course I know, that I am completely irrelevant. ;)
2.061 is beta. I think that the chances of it having something like this in it are very close to zero. - Jonathan M Davis
Dec 28 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 2.061 is beta. I think that the chances of it having something 
 like this in it
 are very close to zero.

 - Jonathan M Davis
You know how to give a suffering hope. :D
Dec 28 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, December 28, 2012 22:21:09 Namespace wrote:
 2.061 is beta. I think that the chances of it having something
 like this in it
 are very close to zero.
 
 - Jonathan M Davis
You know how to give a suffering hope. :D
LOL. Yeah, well. It's not like I'm going to lie about it. I'd love to see this fixed as well, but I can't change reality, and I have lots of other stuff that I need to do (much of which is Phobos-related) and not enough time to do it, so I'm not going to spend the time figuring out enough about the compiler to implement it myself. And the reality of the matter is that even if someone implemented it right now, it's unlikely that it would end up in the next release of the compiler, because it's now in beta. The chances aren't necessarily zero, but they're pretty low, and since no one shows any signs of implementing it right now AFAIK, that pretty much puts the chances at zero. - Jonathan M Davis
Dec 28 2012
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
Spontaneous question: why was the behavior altered from lvalue to 
rvalue if there is still no replacement with "auto ref" and so a 
lot of code becomes invalid?
I know of course that the change was necessary, but as long as 
there is no fix I don't understand such ruthless change.
It meant no offense, I'm just curious.
Dec 28 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, December 28, 2012 23:29:38 Namespace wrote:
 Spontaneous question: why was the behavior altered from lvalue to
 rvalue if there is still no replacement with "auto ref" and so a
 lot of code becomes invalid?
 I know of course that the change was necessary, but as long as
 there is no fix I don't understand such ruthless change.
 It meant no offense, I'm just curious.
Because the code was invalid to begin with. It was a bug that it was ever allowed. Not fixing it would just encourage people to continue writing incorrect code and thus break even more code later. And it's not like the functions that currently work with ref or const ref are going to later when the auto ref situation is sorted out, since it's almost certain that that will be solved with auto ref and not by changing anything with ref or const ref. Also, there's the cost in confusion caused by allowing foo(S(5)) but not foo(bar()). So, in some ways, allowing the broken behavior actually causes more problems than fixing it does. - Jonathan M Davis
Dec 28 2012
parent reply "Minas Mina" <minas_mina1990 hotmail.co.uk> writes:
So when it will be fixed I will be able to write:

void foo(auto ref Vector3 v);

and it will pass copies or references depending on the situation?
Dec 29 2012
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
On Saturday, 29 December 2012 at 18:43:37 UTC, Minas Mina wrote:
 So when it will be fixed I will be able to write:

 void foo(auto ref Vector3 v);

 and it will pass copies or references depending on the 
 situation?
Yes. The compiler generates the function for the specific situation. So you have in the worst case 2^n permutations of the function. See also my implementation in Remus/Romulus. This generates actually _all_ permutations.
Dec 29 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, December 29, 2012 19:43:36 Minas Mina wrote:
 So when it will be fixed I will be able to write:
 
 void foo(auto ref Vector3 v);
 
 and it will pass copies or references depending on the situation?
For templated functions, it currently generates either void foo(ref Vector3 v); or void foo(Vector3 v); depending on whether you pass it an lvalue or an rvalue. The situtation with non-templated functions has not been sorted out yet, but what will probably happen once it has been is that if you declare void foo(auto ref Vector3 v); then underneath the hood, you'll only get void foo(ref Vector3 v); but when it's passed an rvalue, it will get automatically assigned to a local variable first and then that local variable will leave scope after the function call. So, foo(bar()); will turn into something like auto _temp = bar(); foo(_temp); In either case, the idea is that if you declare a parameter to be auto ref, it will accept both rvalues and lvalues and do so without making unnecessary copies, whereas ref will still specifically require an lvalue. So, you use ref when you want to mutate the original, and you use auto ref when you don't care whether it gets mutated or not but don't want a copy to be made if it doesn't have to be (and you use auto ref const if you want to avoid the copy but guarantee that it doesn't get mutated). - Jonathan M Davis
Dec 29 2012
prev sibling parent reply "jerro" <a a.com> writes:
 I'd love to see this fixed as well, but I can't change reality, 
 and I have lots
 of other stuff that I need to do (much of which is 
 Phobos-related) and not
 enough time to do it, so I'm not going to spend the time 
 figuring out enough
 about the compiler to implement it myself. And the reality of 
 the matter is
 that even if someone implemented it right now, it's unlikely 
 that it would end
 up in the next release of the compiler, because it's now in 
 beta. The chances
 aren't necessarily zero, but they're pretty low, and since no 
 one shows any
 signs of implementing it right now AFAIK, that pretty much puts 
 the chances at
 zero.
I've played with this a bit today. The code is at https://github.com/jerro/dmd/tree/auto-ref. I know next to nothing about DMD, so it could be all kinds of wrong, but it does at least seem to work. What do you think should happen in this case: void foo(auto ref int a){} void foo(int a){} ... foo(1); should this be an error, or should the second overload be called? And what about this: void foo(auto ref int a){} void foo(ref int a){} For this to work, the name mangling for auto ref should be different than for ref, but I'm not sure there's value in making it work.
Dec 30 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 I've played with this a bit today. The code is at 
 https://github.com/jerro/dmd/tree/auto-ref. I know next to 
 nothing about DMD, so it could be all kinds of wrong, but it 
 does at least seem to work.

 What do you think should happen in this case:

 void foo(auto ref int a){}
 void foo(int a){}
 ...
 foo(1);

 should this be an error, or should the second overload be 
 called?
IMO the second overload (foo(int a)) should be called and the compiler shouldn't do anymore, because all necessary functions exists.
 And what about this:

 void foo(auto ref int a){}
 void foo(ref int a){}
IMO the auto ref function should be replaced by void foo(int a){ }. Then all necessary functions exists also. Nice work so far, but I don't see any tests for it. I hope it will be merged in this release.
Dec 30 2012
parent reply "jerro" <a a.com> writes:
On Sunday, 30 December 2012 at 13:57:26 UTC, Namespace wrote:
 I've played with this a bit today. The code is at 
 https://github.com/jerro/dmd/tree/auto-ref. I know next to 
 nothing about DMD, so it could be all kinds of wrong, but it 
 does at least seem to work.

 What do you think should happen in this case:

 void foo(auto ref int a){}
 void foo(int a){}
 ...
 foo(1);

 should this be an error, or should the second overload be 
 called?
IMO the second overload (foo(int a)) should be called and the compiler shouldn't do anymore, because all necessary functions exists.
 And what about this:

 void foo(auto ref int a){}
 void foo(ref int a){}
 IMO the auto ref function should be replaced by void foo(int 
 a){ }. Then all necessary functions exists also.
These aren't template functions. They must both be generated, whether they are used or not. And if they are both generated, name mangling for auto ref must be different, or the linker will complain.
 Nice work so far, but I don't see any tests for it.
 I hope it will be merged in this release.
Don't get your hopes up. This could have all kinds of problems, for example, it doesn't work for const auto ref yet. And even if it worked perfectly it's probably to late to merge it in this release.
Dec 30 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Just hope for the best. Did you create a pull request?
Dec 30 2012
parent reply "jerro" <a a.com> writes:
On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:
 Just hope for the best. Did you create a pull request?
No. I need to first make it work correctly with const at the very least.
Dec 30 2012
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:
 On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:
 Just hope for the best. Did you create a pull request?
No. I need to first make it work correctly with const at the very least.
You should hurry up, it seems that Walter will official release soon.
Dec 30 2012
prev sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:
 On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:
 Just hope for the best. Did you create a pull request?
No. I need to first make it work correctly with const at the very least.
Sorry if I seem intrusive, but how does it look? Do you have it so far that it works with const?
Dec 31 2012
parent reply "jerro" <a a.com> writes:
On Tuesday, 1 January 2013 at 01:10:20 UTC, Namespace wrote:
 On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:
 On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:
 Just hope for the best. Did you create a pull request?
No. I need to first make it work correctly with const at the very least.
Sorry if I seem intrusive, but how does it look? Do you have it so far that it works with const?
It does work with const now.
Jan 01 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Tuesday, 1 January 2013 at 11:17:36 UTC, jerro wrote:
 On Tuesday, 1 January 2013 at 01:10:20 UTC, Namespace wrote:
 On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:
 On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:
 Just hope for the best. Did you create a pull request?
No. I need to first make it work correctly with const at the very least.
Sorry if I seem intrusive, but how does it look? Do you have it so far that it works with const?
It does work with const now.
So it is ready to merge?
Jan 01 2013
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
I took over your changes into my current project (which isn't 
that small) and it works very well.
Jan 01 2013
prev sibling parent reply "jerro" <a a.com> writes:
 So it is ready to merge?
I honestly don't know. I don't know enough about the DMD code base to be confident that there aren't some serious problems with my changes. Another problem is that it isn't entirely clear how auto ref is supposed to work. Should auto ref on templates work as it does now or should it be the same as auto ref on non template functions? How should auto ref affect overloading? Maybe it's best to just make a pull request and let others inspect the changes and discuss the semantics of auto ref. Or maybe it would be better to make a thread in digitalmars.D first? But in any case, I strongly doubt this has any chance of being in 2.061.
Jan 01 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 Maybe it's best to just make a pull request and let others 
 inspect the changes and discuss the semantics of auto ref. Or 
 maybe it would be better to make a thread in digitalmars.D 
 first?
In my opinion you should do both, thread and also pull request. I thank you again for your work. I'm using it already.
Jan 01 2013
next sibling parent "jerro" <a a.com> writes:
 In my opinion you should do both, thread and also pull request.
 I thank you again for your work. I'm using it already.
I have opened a pull request now and replied to the thread about auto ref on digitalmars.D.
Jan 02 2013
prev sibling parent reply "jerro" <a a.com> writes:
On Wednesday, 2 January 2013 at 01:05:09 UTC, Namespace wrote:
 Maybe it's best to just make a pull request and let others 
 inspect the changes and discuss the semantics of auto ref. Or 
 maybe it would be better to make a thread in digitalmars.D 
 first?
In my opinion you should do both, thread and also pull request. I thank you again for your work. I'm using it already.
It turns out there already was a pull request that does this: https://github.com/D-Programming-Language/dmd/pull/1019 If you are going to use code that is not merged yet, then maybe it's better to use that one (I've closed my pull request).
Jan 03 2013
next sibling parent reply "Namespace" <rswhite4 googlemail.com> writes:
 It turns out there already was a pull request that does this:

 https://github.com/D-Programming-Language/dmd/pull/1019
The pull request is still unmerged. Isn't this important enough or is the pull invalid?
Jan 13 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
On Sunday, 13 January 2013 at 09:50:37 UTC, Namespace wrote:
 It turns out there already was a pull request that does this:

 https://github.com/D-Programming-Language/dmd/pull/1019
The pull request is still unmerged. Isn't this important enough or is the pull invalid?
The question is still there. Will the pull merged in the near future or not? I'm asking because I'm afraid that it takes several months until D has 'auto ref'.
Jan 14 2013
prev sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 It turns out there already was a pull request that does this:

 https://github.com/D-Programming-Language/dmd/pull/1019

 If you are going to use code that is not merged yet, then maybe 
 it's better to use that one (I've closed my pull request).
Maybe you should reopen your pull, we need definitely a solution for this problem. It seems that the other pull isn't finished in the next two release cycles. We know that your code works partially, that is better than further releases without an auto ref...
Jan 21 2013
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/12 12:57 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:
 An important smoking gun is C++'s min(), which is allows writing unsafe
 code without casts.

 const int&  haveANiceDay = min(4, 5);
But what does that have to do with const& for function parameters?
min takes its parameters by const ref. Andrei
Dec 24 2012
prev sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu 
wrote:
 On 12/24/12 12:11 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 17:55:23 Minas Mina wrote:
 On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis

 wrote:
 On Monday, December 24, 2012 00:48:01 Namespace wrote:
 but Andrei is dead set against

 - Jonathan M Davis
Why?
He's convinced that it's caused problems for C++ and was a major mistake. You can search the newsgroup for discussions on it. The most recent one which involved Andrei was in the beta group: http://forum.dlang.org/post/4F84D6DD.5090405 digitalmars.com - Jonathan M Davis
An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); Andrei
But that example actually works correctly. TBH, most of the "unsafe" code I have been presented regarding the implict "cast + ref problem" comes from msvc accepting code which is not actually legal C++. In "legit" C++, you *can't* bind a rvalue to a (non const) ref. gcc will turn you down if you tried any of those "unsafe" examples.
Dec 24 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/24/12 1:05 PM, monarch_dodra wrote:
 On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu wrote:
 On 12/24/12 12:11 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 17:55:23 Minas Mina wrote:
 On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis

 wrote:
 On Monday, December 24, 2012 00:48:01 Namespace wrote:
 but Andrei is dead set against

 - Jonathan M Davis
Why?
He's convinced that it's caused problems for C++ and was a major mistake. You can search the newsgroup for discussions on it. The most recent one which involved Andrei was in the beta group: http://forum.dlang.org/post/4F84D6DD.5090405 digitalmars.com - Jonathan M Davis
An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); Andrei
But that example actually works correctly.
No. Andrei
Dec 24 2012
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 24 December 2012 at 18:42:31 UTC, Andrei Alexandrescu 
wrote:
 On 12/24/12 1:05 PM, monarch_dodra wrote:
 On Monday, 24 December 2012 at 17:37:54 UTC, Andrei 
 Alexandrescu wrote:
 On 12/24/12 12:11 PM, Jonathan M Davis wrote:
 On Monday, December 24, 2012 17:55:23 Minas Mina wrote:
 On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M 
 Davis

 wrote:
 On Monday, December 24, 2012 00:48:01 Namespace wrote:
 but Andrei is dead set against

 - Jonathan M Davis
Why?
He's convinced that it's caused problems for C++ and was a major mistake. You can search the newsgroup for discussions on it. The most recent one which involved Andrei was in the beta group: http://forum.dlang.org/post/4F84D6DD.5090405 digitalmars.com - Jonathan M Davis
An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); Andrei
But that example actually works correctly.
No. Andrei
Hum... Indeed, it takes by ref *and* returns by ref. Passing in to out a const ref is *the* smoking gun. Working with D has gotten me used to functions that take by value and return by value... Snap. You got me.
Dec 24 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 20:03:24 monarch_dodra wrote:
 Hum... Indeed, it takes by ref *and* returns by ref. Passing in
 to out a const ref is *the* smoking gun. Working with D has
 gotten me used to functions that take by value and return by
 value...
 
 Snap. You got me.
It wouldn't matter if the function accepted its argument by value. You'd still be returning a reference to a variable that doesn't exist anymore. If anything, it would be _worse_ if it took it by value, since the variable definitely doesn't exist anymore once the function returns in that case, whereas with a reference, it will continue to exist for the duration of the statement that the call was made in (and beyond that, if the argument was actually an lvalue - in fact with an lvalue, the code would work as unsafe is it may be). So, it's the returning by reference that's the problem, not passing by reference. - Jonathan M Davis
Dec 24 2012
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 24 December 2012 at 19:09:35 UTC, Jonathan M Davis 
wrote:
 On Monday, December 24, 2012 20:03:24 monarch_dodra wrote:
 Hum... Indeed, it takes by ref *and* returns by ref. Passing in
 to out a const ref is *the* smoking gun. Working with D has
 gotten me used to functions that take by value and return by
 value...
 
 Snap. You got me.
It wouldn't matter if the function accepted its argument by value... - Jonathan M Davis
well, if the function took by value, and returned by ref, then it would be just plain *wrong*, no conditions, so that did not even cross my mind. I *thought* min took by ref, and returned by value, hence my confusion to the example. I'm legitimatly surprised to learn that it works that way, specifically because I've learned to NEVER return by ref an input argument exactly because of this... Side question, is this legal? "int a = min(min(1,2), min(3,4));" How long do those temps last? I like this piece of code, because the previous had that fishy "const int&", which raises eyebrows, but I think this example could blindsind even the most careful programmer. EDIT: In this specific example, those might be statics, so the code would be legal, but what if we replace those ints with "foo()"s ?
Dec 24 2012
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 21:42:09 monarch_dodra wrote:
 Side question, is this legal?
 
 "int a = min(min(1,2), min(3,4));"
 
 How long do those temps last? I like this piece of code, because
 the previous had that fishy "const int&", which raises eyebrows,
 but I think this example could blindsind even the most careful
 programmer.
 
 EDIT: In this specific example, those might be statics, so the
 code would be legal, but what if we replace those ints with
 "foo()"s ?
As I understand it, temporaries last for the duration of the statement that they're used it. So, the example would be legal and completely safe. - Jonathan M Davis
Dec 24 2012
prev sibling parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Monday, 24 December 2012 at 19:09:35 UTC, Jonathan M Davis 
wrote:
 On Monday, December 24, 2012 20:03:24 monarch_dodra wrote:
 Snap. You got me.
It wouldn't matter if the function accepted its argument by value. You'd still be returning a reference to a variable that doesn't exist anymore.
So what if it does exist? Say the temporary lives as long as the current scope lives?
Jan 01 2013
parent "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Tuesday, 1 January 2013 at 08:49:29 UTC, Era Scarecrow wrote:
 On Monday, 24 December 2012 at 19:09:35 UTC, Jonathan M Davis 
 wrote:
 On Monday, December 24, 2012 20:03:24 monarch_dodra wrote:
 Snap. You got me.
It wouldn't matter if the function accepted its argument by value. You'd still be returning a reference to a variable that doesn't exist anymore.
So what if it does exist? Say the temporary lives as long as the current scope lives?
Make that the scope of the variable it's being assigned to...
Jan 01 2013
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 24, 2012 19:05:32 monarch_dodra wrote:
 On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu
 wrote:
 An important smoking gun is C++'s min(), which is allows
 writing unsafe code without casts.
 
 const int& haveANiceDay = min(4, 5);
 
 
 Andrei
But that example actually works correctly.
Um. How? It's created a reference to a temporary, and that temporary will no longer exist once the statement has completed. So, haveANiceDay ensd up pointing to garbage. Sure, there's a decent chance that it'll give you the value of 4 initially, but there's no guarantee whatsoever that it will or that it will continue to do so, as the program is free to reuse that memory for something else. The only thing that _might_ save you is the fact that the temporary is likely higher up on the stack and therefore less likely to have its memory reused as long as haveANiceDay exists lower on the stack. I don't believe that there's any guarantee of that however. Once the statement has completed, haveANiceDay could point to anything. - Jonathan M Davis
Dec 24 2012