digitalmars.D.learn - structs are now lvalues - what is with "auto ref"?
- Namespace (7/7) Dec 23 2012 As the title says: In dmd 2.061 structs are lvalues now, but we
- Andrej Mitrovic (4/5) Dec 23 2012 You mean struct literals? They're rvalues now, this wasn't enforced
- Namespace (3/10) Dec 23 2012 Yes of course. They was lvalues.
- Jonathan M Davis (27/34) Dec 23 2012 If you have a templated function, you can use auto ref. If you have a no...
- Namespace (5/5) Dec 23 2012 If I remember correctly, the discussion and the fix of "auto ref"
- Jonathan M Davis (10/15) Dec 23 2012 It's been discussed off and on for ages, but it's never been a high enou...
- Namespace (7/9) Dec 23 2012 But how long?
- Jonathan M Davis (8/20) Dec 23 2012 If you templatize a function, then you can use auto ref with it, and aut...
- Namespace (2/2) Dec 24 2012 Yes that's what I thought. My question was, if it's bad if now a
- Jonathan M Davis (15/17) Dec 24 2012 That would depend on what you're doing. It's a problem with classes, bec...
- Namespace (6/6) Dec 24 2012 Put another way: how long will we probably still wait for a
- Namespace (2/2) Dec 24 2012 One more thing: Which pull request is for "auto ref" for
- Jonathan M Davis (3/5) Dec 24 2012 There isn't one.
- Jonathan M Davis (4/10) Dec 24 2012 I have no idea. It's a known issue, and we want it solved, but there is ...
- Minas Mina (3/6) Dec 24 2012 Why?
- Jonathan M Davis (6/15) Dec 24 2012 He's convinced that it's caused problems for C++ and was a major mistake...
- Andrei Alexandrescu (5/20) Dec 24 2012 An important smoking gun is C++'s min(), which is allows writing unsafe
- Jonathan M Davis (15/19) Dec 24 2012 But what does that have to do with const& for function parameters? I can...
- Dmitry Olshansky (5/25) Dec 24 2012 It relates directly as one may then pass the result of min to fun(const
- Jonathan M Davis (18/29) Dec 24 2012 st
- Andrei Alexandrescu (5/26) Dec 24 2012 The very binding of rvalues to const ref would allow that breakage. We
- Jonathan M Davis (12/14) Dec 24 2012 But it's only bound for the length of the statement. After that, the bin...
- anonymous (4/7) Dec 24 2012 Does it?
- Jonathan M Davis (4/15) Dec 24 2012 That's a pointer, not a ref. It's completely different. It's also @syste...
- Andrei Alexandrescu (3/9) Dec 24 2012 We plan to forbid that.
- Andrei Alexandrescu (6/20) Dec 24 2012 Actually D's rules are different from C++'s in that regard; Walter
- Jonathan M Davis (45/58) Dec 24 2012 Actually, one problem did occur to me after thinking about this some mor...
- Namespace (3/3) Dec 26 2012 Quick question: what is the state of things with dmd 2.061 and I
- Jonathan M Davis (3/4) Dec 26 2012 AFAIK, it's exactly the same as it was in 2.060.
- Namespace (3/7) Dec 26 2012 I mean, when it comes out. But that has now done. ;)
- Namespace (8/8) Dec 28 2012 In consideration that Andrei said that the implementation of
- bearophile (5/7) Dec 28 2012 Walter wants to release 2.061 "soon". So maybe that's for the
- Namespace (5/12) Dec 28 2012 As long as it is implemented soon, I'm so satisfied. But an
- Minas Mina (2/17) Dec 28 2012 +1
- Namespace (70/70) Dec 28 2012 I wrote a workaround for me: I implement it in Romulus. So for
- Jonathan M Davis (4/13) Dec 28 2012 2.061 is beta. I think that the chances of it having something like this...
- Namespace (1/5) Dec 28 2012 You know how to give a suffering hope. :D
- Jonathan M Davis (12/19) Dec 28 2012 LOL. Yeah, well. It's not like I'm going to lie about it.
- Namespace (6/6) Dec 28 2012 Spontaneous question: why was the behavior altered from lvalue to
- Jonathan M Davis (11/17) Dec 28 2012 Because the code was invalid to begin with. It was a bug that it was eve...
- Minas Mina (3/3) Dec 29 2012 So when it will be fixed I will be able to write:
- Namespace (6/10) Dec 29 2012 Yes. The compiler generates the function for the specific
- Jonathan M Davis (26/31) Dec 29 2012 For templated functions, it currently generates either
- jerro (16/33) Dec 30 2012 I've played with this a bit today. The code is at
- Namespace (7/21) Dec 30 2012 IMO the second overload (foo(int a)) should be called and the
- jerro (9/34) Dec 30 2012 These aren't template functions. They must both be generated,
- Namespace (1/1) Dec 30 2012 Just hope for the best. Did you create a pull request?
- jerro (3/4) Dec 30 2012 No. I need to first make it work correctly with const at the very
- Namespace (3/7) Dec 30 2012 You should hurry up, it seems that Walter will official release
- Namespace (3/7) Dec 31 2012 Sorry if I seem intrusive, but how does it look? Do you have it
- jerro (2/10) Jan 01 2013 It does work with const now.
- Namespace (2/13) Jan 01 2013 So it is ready to merge?
- Namespace (2/2) Jan 01 2013 I took over your changes into my current project (which isn't
- jerro (12/13) Jan 01 2013 I honestly don't know. I don't know enough about the DMD code
- Andrei Alexandrescu (3/9) Dec 24 2012 min takes its parameters by const ref.
- monarch_dodra (9/34) Dec 24 2012 But that example actually works correctly.
- Andrei Alexandrescu (3/34) Dec 24 2012 No.
- monarch_dodra (7/47) Dec 24 2012 Hum... Indeed, it takes by ref *and* returns by ref. Passing in
- Jonathan M Davis (11/17) Dec 24 2012 It wouldn't matter if the function accepted its argument by value. You'd...
- monarch_dodra (18/29) Dec 24 2012 well, if the function took by value, and returned by ref, then it
- Jonathan M Davis (4/16) Dec 24 2012 As I understand it, temporaries last for the duration of the statement t...
- Era Scarecrow (4/9) Jan 01 2013 So what if it does exist? Say the temporary lives as long as the
- Era Scarecrow (2/12) Jan 01 2013 Make that the scope of the variable it's being assigned to...
- Jonathan M Davis (13/24) Dec 24 2012 Um. How?
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
On 12/24/12, Namespace <rswhite4 googlemail.com> wrote:As the title says: In dmd 2.061 structs are lvalues nowYou 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
On Sunday, 23 December 2012 at 23:53:49 UTC, Andrej Mitrovic wrote:On 12/24/12, Namespace <rswhite4 googlemail.com> wrote:Yes of course. They was lvalues.As the title says: In dmd 2.061 structs are lvalues nowYou 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
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
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
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
Plenty of people are using it with the problems that it currently hasBut 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
On Monday, December 24, 2012 02:41:41 Namespace wrote: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 DavisPlenty of people are using it with the problems that it currently hasBut 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
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
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
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
One more thing: Which pull request is for "auto ref" for none-template functions?
Dec 24 2012
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
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
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 DavisWhy?
Dec 24 2012
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: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 DavisOn Monday, December 24, 2012 00:48:01 Namespace wrote: but Andrei is dead set against - Jonathan M DavisWhy?
Dec 24 2012
On 12/24/12 12:11 PM, Jonathan M Davis wrote:On Monday, December 24, 2012 17:55:23 Minas Mina wrote:An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); AndreiOn Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis wrote: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 DavisOn Monday, December 24, 2012 00:48:01 Namespace wrote: but Andrei is dead set against - Jonathan M DavisWhy?
Dec 24 2012
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
12/24/2012 9:57 PM, Jonathan M Davis пишет:On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:It relates directly as one may then pass the result of min to fun(const ref T);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-- Dmitry Olshansky
Dec 24 2012
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:nsafeOn Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:An important smoking gun is C++'s min(), which is allows writing u=st=20 It relates directly as one may then pass the result of min to fun(con=code without casts. =20 const int& haveANiceDay =3D min(4, 5);=20 But what does that have to do with const& for function parameters?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
On 12/24/12 1:20 PM, Jonathan M Davis wrote:On Monday, December 24, 2012 22:11:58 Dmitry Olshansky wrote:The problem occurs of course once haveANiceDay is actually used.12/24/2012 9:57 PM, Jonathan M Davis пишет: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.On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:It relates directly as one may then pass the result of min to fun(const ref T);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?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
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
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
On Monday, December 24, 2012 20:46:00 anonymous wrote:On Monday, 24 December 2012 at 18:50:12 UTC, Jonathan M Davis wrote:That's a pointer, not a ref. It's completely different. It's also system, whereas ref is safe. - Jonathan M Davisconst 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
On 12/24/12 2:46 PM, anonymous wrote:On Monday, 24 December 2012 at 18:50:12 UTC, Jonathan M Davis wrote:We plan to forbid that. Andreiconst 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
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.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.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
On Monday, December 24, 2012 16:08:36 Andrei Alexandrescu wrote:On 12/24/12 1:49 PM, Jonathan M Davis wrote:Well, that could be a problem.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.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 DavisIt'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.
Dec 24 2012
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
On Wednesday, December 26, 2012 10:43:53 Namespace wrote:Quick question: what is the state of things with dmd 2.061AFAIK, it's exactly the same as it was in 2.060. - Jonathan M Davis
Dec 26 2012
On Wednesday, 26 December 2012 at 22:33:38 UTC, Jonathan M Davis wrote:On Wednesday, December 26, 2012 10:43:53 Namespace wrote:I mean, when it comes out. But that has now done. ;)Quick question: what is the state of things with dmd 2.061AFAIK, it's exactly the same as it was in 2.060. - Jonathan M Davis
Dec 26 2012
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
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
On Friday, 28 December 2012 at 12:28:01 UTC, bearophile wrote:Namespace: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.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
On Friday, 28 December 2012 at 12:47:03 UTC, Namespace wrote:On Friday, 28 December 2012 at 12:28:01 UTC, bearophile wrote:+1Namespace: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.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
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
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
2.061 is beta. I think that the chances of it having something like this in it are very close to zero. - Jonathan M DavisYou know how to give a suffering hope. :D
Dec 28 2012
On Friday, December 28, 2012 22:21:09 Namespace wrote: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 Davis2.061 is beta. I think that the chances of it having something like this in it are very close to zero. - Jonathan M DavisYou know how to give a suffering hope. :D
Dec 28 2012
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
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
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
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
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
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
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
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
Just hope for the best. Did you create a pull request?
Dec 30 2012
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
On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:You should hurry up, it seems that Walter will official release soon.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
On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:Sorry if I seem intrusive, but how does it look? Do you have it so far that it works with const?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 31 2012
On Tuesday, 1 January 2013 at 01:10:20 UTC, Namespace wrote:On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:It does work with const now.On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:Sorry if I seem intrusive, but how does it look? Do you have it so far that it works with const?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.
Jan 01 2013
On Tuesday, 1 January 2013 at 11:17:36 UTC, jerro wrote:On Tuesday, 1 January 2013 at 01:10:20 UTC, Namespace wrote:So it is ready to merge?On Sunday, 30 December 2012 at 16:11:44 UTC, jerro wrote:It does work with const now.On Sunday, 30 December 2012 at 16:00:22 UTC, Namespace wrote:Sorry if I seem intrusive, but how does it look? Do you have it so far that it works with const?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.
Jan 01 2013
I took over your changes into my current project (which isn't that small) and it works very well.
Jan 01 2013
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
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
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
On Wednesday, 2 January 2013 at 01:05:09 UTC, Namespace wrote: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 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 03 2013
It turns out there already was a pull request that does this: https://github.com/D-Programming-Language/dmd/pull/1019The pull request is still unmerged. Isn't this important enough or is the pull invalid?
Jan 13 2013
On Sunday, 13 January 2013 at 09:50:37 UTC, Namespace wrote: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'.It turns out there already was a pull request that does this: https://github.com/D-Programming-Language/dmd/pull/1019The pull request is still unmerged. Isn't this important enough or is the pull invalid?
Jan 14 2013
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
On 12/24/12 12:57 PM, Jonathan M Davis wrote:On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:min takes its parameters by const ref. AndreiAn 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?
Dec 24 2012
On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu wrote:On 12/24/12 12:11 PM, Jonathan M Davis wrote: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.On Monday, December 24, 2012 17:55:23 Minas Mina wrote:An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); AndreiOn Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis wrote: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 DavisOn Monday, December 24, 2012 00:48:01 Namespace wrote: but Andrei is dead set against - Jonathan M DavisWhy?
Dec 24 2012
On 12/24/12 1:05 PM, monarch_dodra wrote:On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu wrote:No. AndreiOn 12/24/12 12:11 PM, Jonathan M Davis wrote:But that example actually works correctly.On Monday, December 24, 2012 17:55:23 Minas Mina wrote:An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); AndreiOn Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis wrote: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 DavisOn Monday, December 24, 2012 00:48:01 Namespace wrote: but Andrei is dead set against - Jonathan M DavisWhy?
Dec 24 2012
On Monday, 24 December 2012 at 18:42:31 UTC, Andrei Alexandrescu wrote:On 12/24/12 1:05 PM, 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.On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu wrote:No. AndreiOn 12/24/12 12:11 PM, Jonathan M Davis wrote:But that example actually works correctly.On Monday, December 24, 2012 17:55:23 Minas Mina wrote:An important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); AndreiOn Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis wrote: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 DavisOn Monday, December 24, 2012 00:48:01 Namespace wrote: but Andrei is dead set against - Jonathan M DavisWhy?
Dec 24 2012
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
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: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 ?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
Dec 24 2012
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
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:So what if it does exist? Say the temporary lives as long as the current scope lives?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.
Jan 01 2013
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:Make that the scope of the variable it's being assigned to...On Monday, December 24, 2012 20:03:24 monarch_dodra wrote:So what if it does exist? Say the temporary lives as long as the current scope lives?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.
Jan 01 2013
On Monday, December 24, 2012 19:05:32 monarch_dodra wrote:On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu wrote: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 DavisAn important smoking gun is C++'s min(), which is allows writing unsafe code without casts. const int& haveANiceDay = min(4, 5); AndreiBut that example actually works correctly.
Dec 24 2012