digitalmars.D - DIP25 draft available for destruction
- Andrei Alexandrescu (5/5) Feb 05 2013 Probably it'll need a fair amount of tweaking. Anyhow it's in
- kenji hara (26/29) Feb 06 2013 Hmm, this is much reasonable.
- Johannes Pfau (10/19) Feb 06 2013 Sounds good.
- Chad Joan (10/15) Feb 06 2013 This is probably reasonably, but I'm having trouble fully comprehending ...
- Chad Joan (3/7) Feb 06 2013 I should be more clear myself: I mean "Typechecking rules" and
- Andrei Alexandrescu (5/14) Feb 06 2013 Yah, we need more examples. As for what's disallowed, in a way it's
- Andrei Alexandrescu (6/9) Feb 06 2013 Hmm, I need to make things clearer. That's covered plainly in 1.1. You
- Zach the Mystic (64/69) Feb 06 2013 All of the 'fine' ones are fine. Which leaves how one might
- Benjamin Thaut (6/11) Feb 06 2013 What I don't get is, why is it better to have a function
- Andrei Alexandrescu (5/18) Feb 06 2013 A good part of that is the recent debate on what &func should do (take
- Benjamin Thaut (9/28) Feb 06 2013 Ok that makes sense, you might want to add that as a explanation to the
- Andrei Alexandrescu (3/7) Feb 06 2013 I don't think that would work without adding new keywords.
- Benjamin Thaut (14/21) Feb 06 2013 Whats so bad about adding a new keyword for this?
- Andrei Alexandrescu (10/32) Feb 06 2013 This is an ill-posed question. A keyword should justify its utility, not...
- Timon Gehr (11/43) Feb 06 2013 So you are saying this should compile?:
- Andrei Alexandrescu (4/19) Feb 06 2013 Yah, it should, and it also should detect the escape and allocate foo's
- Timon Gehr (7/29) Feb 06 2013 I see. Generally?
- Andrei Alexandrescu (3/9) Feb 06 2013 I think I'm starting to see what you're doing there :o).
- deadalnix (3/12) Feb 06 2013 I have to admit this was a big puzzling point to me as well.
- Rob T (7/32) Feb 06 2013 I thought we wanted to minimize allocations, especially silent
- Andrei Alexandrescu (3/21) Feb 06 2013 Added a dedicated section to the DIP: http://goo.gl/xkIXb
- Zach the Mystic (4/11) Feb 06 2013 As per your encouragement to me, I suggest using 'opAddress'
- Regan Heath (36/39) Feb 07 2013 &X takes the address of X.
- Andrei Alexandrescu (4/7) Feb 06 2013 Updated with a section dedicated to address taking:
- Steven Schveighoffer (14/17) Feb 06 2013 First reaction:
- Andrej Mitrovic (22/25) Feb 06 2013 Originally I thought addressOf was only planned for safe functions,
- Andrei Alexandrescu (11/36) Feb 06 2013 I think there's no way to have it both ways. You'll have to get used to
- Andrej Mitrovic (4/6) Feb 06 2013 But we're talking about @system here. I would probably be fine with
- Walter Bright (2/8) Feb 06 2013 One reason why @safe is not the default.
- Marco Leise (6/18) Feb 10 2013 It would also be very very nice, if we could at least write
- Tove (12/22) Feb 10 2013 struct S
- Jakob Ovrum (12/17) Feb 06 2013 I'm not sure why it's trying to safe-up pointers.
- Andrei Alexandrescu (4/23) Feb 06 2013 I think it stands to reason that we should pull back a little bit and
- Robert (14/23) Feb 06 2013 What happened to the scope storage class for parameters.
- Johannes Pfau (21/28) Feb 06 2013 This is an important question. How would this new proposal interact with
- deadalnix (3/19) Feb 07 2013 scope in not enough, as you can alias parameters (for instance
- Johannes Pfau (7/30) Feb 07 2013 Can you give an example?
- deadalnix (9/13) Feb 06 2013 Seems like a good DIP overall.
- Walter Bright (9/15) Feb 06 2013 Properties are always going to be subsets of fields. For example,
- deadalnix (10/31) Feb 06 2013 Obviously it is not going to work in that case.
- deadalnix (3/8) Feb 06 2013 Reformulating : it helps on the grammatical perspective, but the
- Walter Bright (11/18) Feb 06 2013 Ok, why should "as much as possible" be the goal? There are other consid...
- deadalnix (23/45) Feb 07 2013 I don't think anyone have interest to get back on that. If you
- Walter Bright (20/59) Feb 07 2013 The point is, there must always be a balance of competing interests. Tha...
- deadalnix (34/58) Feb 07 2013 C# don't have address of. It isn't a system language. Even if you
- Walter Bright (14/56) Feb 07 2013 Try designing anything by using one overriding principle - you won't get...
- deadalnix (46/106) Feb 07 2013 Ho yeah, I'm not arguing against that. But what is seen as
- Walter Bright (7/33) Feb 07 2013 They won't behave any differently than they would outside of being passe...
- deadalnix (17/62) Feb 07 2013 That isn't what I read. It is clearly written void function()
- Zach the Mystic (5/15) Feb 07 2013 Can you tell me if you consider my proposal with regard to making
- Walter Bright (3/7) Feb 07 2013 I don't know if it's complete and safe. It's not something that can be
- Zach the Mystic (22/33) Feb 07 2013 Okay. But at least that's a 'check' on simple and intuitive?
- Robert (7/16) Feb 07 2013 The solution to this problem has been posted already many times, simply
- Steven Schveighoffer (13/16) Feb 07 2013 Thinking about this, I don't know that I like the idea of disallowing
- deadalnix (3/20) Feb 07 2013 Exactly.
- Marco Leise (17/26) Feb 06 2013 At first I was skeptical about how this would work with binary
- Walter Bright (7/13) Feb 06 2013 I think C++ missed an opportunity with reference types. All they are in ...
- H. S. Teoh (8/23) Feb 06 2013 D ref types are currently highly crippled because of the inability to
- Andrei Alexandrescu (6/26) Feb 06 2013 Unfortunately type qualifiers have very high complexity costs. I think
- deadalnix (3/11) Feb 07 2013 My heart say yes, but my brain doesn't really any way to make
- Johannes Pfau (19/28) Feb 07 2013 Regarding the questions about scope parameters and allowing & in system
- Chad Joan (118/123) Feb 07 2013 A single delegate (closure) can be used to defer both reads and writes
- deadalnix (16/147) Feb 07 2013 The cost of passing a delegate is way higher than the cost of
- Chad Joan (4/22) Feb 08 2013 Fair enough.
- Michael (4/4) Feb 09 2013 Two more things:
- Jonathan M Davis (29/33) Feb 11 2013 Overall, the ref part seems good, but I'm highly skeptical of the part o...
Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, Andrei
Feb 05 2013
2013/2/6 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25Hmm, this is much reasonable. In recent, I had wrote and post a compiler extension to reinforce a kind of trait which related to pure function. I call the trait "isolated", and that means "Whether any reachable indirections from parameters does not appear in the returned value". https://github.com/D-Programming-Language/dmd/pull/1519 With my patch, such as following cases can be detected. struct S { int* ptr; } S foo(int* ptr) pure; S bar(const int* ptr) pure; void main() { int n; immutable S s = foo(&n); // implicit conversion from S to immutable S is _diallowed_. // Because &n may appear in foo's returned value. immutable S s = bar(&n); // implicit conversion from S to immutable S is _allowed_. // Because &n never appear in bar's returned value. // (compiler assumes that bar doesn't do any un- safe operations, e.g. cast(int*)ptr) } As far as I see, the contained essence in the DIP is much similar to the "isolated" traits. So I can say that it is *implementable*. Kenji Hara
Feb 06 2013
Am Wed, 06 Feb 2013 02:38:17 -0500 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiSounds good. Regarding rule 2.2: I think somebody already said that classes could be allocated on the stack but I guess we can't do anything about that. At least in safe code placing a class on the stack should be illegal though, so we can partially avoid the problem there. If we have such a special rule for classes would it also make sense to have a similar rule for struct*?
Feb 06 2013
On 02/06/2013 02:38 AM, Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiThis is probably reasonably, but I'm having trouble fully comprehending it. Once I get to the "Typechecking rules" section and dig into the nitty-gritty, it seems to be written in a way that discusses what is allowed, but only briefly hints at what is disallowed. It is not immediately clear to me how this would impact my code. My interpretation so far is that the only difference between DIP25 and current D code is that we won't be allowed to pass stack variables (including by-value/copied parameters) into ref parameters. HTH
Feb 06 2013
On 02/06/2013 09:48 AM, Chad Joan wrote:Once I get to the "Typechecking rules" section and dig into the nitty-gritty, it seems to be written in a way that discusses what is allowed, but only briefly hints at what is disallowed. It is not immediately clear to me how this would impact my code.I should be more clear myself: I mean "Typechecking rules" and everything that follows it.
Feb 06 2013
On 2/6/13 9:49 AM, Chad Joan wrote:On 02/06/2013 09:48 AM, Chad Joan wrote:Yah, we need more examples. As for what's disallowed, in a way it's "simple" - everything that's not allowed is disallowed :o). We definitely should add discussion of disallowed uses. AndreiOnce I get to the "Typechecking rules" section and dig into the nitty-gritty, it seems to be written in a way that discusses what is allowed, but only briefly hints at what is disallowed. It is not immediately clear to me how this would impact my code.I should be more clear myself: I mean "Typechecking rules" and everything that follows it.
Feb 06 2013
On 2/6/13 9:48 AM, Chad Joan wrote:My interpretation so far is that the only difference between DIP25 and current D code is that we won't be allowed to pass stack variables (including by-value/copied parameters) into ref parameters.Hmm, I need to make things clearer. That's covered plainly in 1.1. You get to pass down stack variables and by-value parameters down to functions taking ref. You won't be able to return them up, no matter what you (safely) try. Andrei
Feb 06 2013
On Wednesday, 6 February 2013 at 07:38:17 UTC, Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiAll of the 'fine' ones are fine. Which leaves how one might invoke the 'unfine' ones. The language must make a choice between restricted simplicity and flexible complexity. If it chooses flexibility, the function signature must give a clue as to what the return value contains. 'out' return values and 'scope' parameters will give the clues it needs. Here are all the 'unfine' functions listed: ref T gun(ref T); struct S { int a; T b; } ref S iun(ref S); ref T caller(bool condition, ref T v1, ref S v2, T v3, S v4) { T v5; S v6; // Not fine, bound to locals // if (condition) return gun(v3); // if (condition) return gun(v4.b); // if (condition) return gun(v5); // if (condition) return gun(v6.b); // Not fine, bound to locals // if (condition) return iun(v4); // if (condition) return iun(v6); } Say gun's actual implementation is: ref T gun(ref T a) { auto noo = new T; noo = a; return noo; } You can' tell from the function signature that the return value of this function is good to go, so the call 'return gun(v3);' above would be disallowed even though it didn't need to be. If you marked the signature with 'out', the caller knows it's good to go, and the compiler can statically prevent the function from returning one of its ref parameters. 'out' can be made to imply 'ref' in any case where the type is not inherently a reference anyway. out T gun(ref T a) { return new T; // Pass return a; // Error } This will solve all problems, except for the very rare corner case when you need to assert fined-grained control over exactly which ref parameters are safe and which are not. 'scope' comes to the rescue here. ref int fud(ref int a, scope int b) { a += b; return a; // Pass return b; // Error } ref int elmer(ref int f) { int v; return fud(f, v); // Passes return fud(v, f); // Fails } An 'out' return value simply marks all its 'ref' parameters 'scope' underneath the hood, so there will never be a need for both 'out' and 'scope' in the same signature. Since 'scope' is useless if its not a reference, it implies 'ref' also. I'm pretty sure this is the best way to make the language completely flexible. I don't anticipate an easier way to get it done, and therefore, to my mind at least, the choice is between simple-but-limited and flexible-and-complicated.
Feb 06 2013
Am 06.02.2013 08:38, schrieb Andrei Alexandrescu:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiWhat I don't get is, why is it better to have a function "addressOf(value)" that does exactly the same as &value? Expect that it is more text to type? Why is addressOf(value) more explicit then &value? Kind Regards Benjamin Thaut
Feb 06 2013
On 2/6/13 12:33 PM, Benjamin Thaut wrote:Am 06.02.2013 08:38, schrieb Andrei Alexandrescu:A good part of that is the recent debate on what &func should do (take the address of the function vs. the address of its result). With the unsafe meaning out of the way, only the safe one is eligible. AndreiProbably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiWhat I don't get is, why is it better to have a function "addressOf(value)" that does exactly the same as &value? Expect that it is more text to type? Why is addressOf(value) more explicit then &value?
Feb 06 2013
Am 06.02.2013 18:36, schrieb Andrei Alexandrescu:On 2/6/13 12:33 PM, Benjamin Thaut wrote:Ok that makes sense, you might want to add that as a explanation to the DIP. So the &value expression would only be left for taking addresses of functions? Wouldn't it make more sense to do it the other way around? E.g. create some utilty function that is only there for taking the address of functions and disallowing to do so by using &func? Kind Regards Benjamin ThautAm 06.02.2013 08:38, schrieb Andrei Alexandrescu:A good part of that is the recent debate on what &func should do (take the address of the function vs. the address of its result). With the unsafe meaning out of the way, only the safe one is eligible. AndreiProbably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiWhat I don't get is, why is it better to have a function "addressOf(value)" that does exactly the same as &value? Expect that it is more text to type? Why is addressOf(value) more explicit then &value?
Feb 06 2013
On 2/6/13 12:40 PM, Benjamin Thaut wrote:So the &value expression would only be left for taking addresses of functions? Wouldn't it make more sense to do it the other way around? E.g. create some utilty function that is only there for taking the address of functions and disallowing to do so by using &func?I don't think that would work without adding new keywords. Andrei
Feb 06 2013
Am 06.02.2013 18:50, schrieb Andrei Alexandrescu:On 2/6/13 12:40 PM, Benjamin Thaut wrote:Whats so bad about adding a new keyword for this? I fear that newcomers will find taking addresses pretty inconsistens if we implement this proposal. Because the language will have the take address operator "&" they know from c++, but it only works in some special cases. For all other cases addressOf has to be used. It would be much more consistent if you could use the "&" operator for everything but taking the address of a function. That would be more consistent in my opinion. Lately I'm getting the feeling that D 2.0 is becoming a collection of hacks to workaround issues which could be solved by adding new keywords or doing other major changes. (like all the stuff that starts with __) Kind Regards Benjamin ThautSo the &value expression would only be left for taking addresses of functions? Wouldn't it make more sense to do it the other way around? E.g. create some utilty function that is only there for taking the address of functions and disallowing to do so by using &func?I don't think that would work without adding new keywords. Andrei
Feb 06 2013
On 2/6/13 1:39 PM, Benjamin Thaut wrote:Am 06.02.2013 18:50, schrieb Andrei Alexandrescu:This is an ill-posed question. A keyword should justify its utility, not prove it doesn't harm.On 2/6/13 12:40 PM, Benjamin Thaut wrote:Whats so bad about adding a new keyword for this?So the &value expression would only be left for taking addresses of functions? Wouldn't it make more sense to do it the other way around? E.g. create some utilty function that is only there for taking the address of functions and disallowing to do so by using &func?I don't think that would work without adding new keywords. AndreiI fear that newcomers will find taking addresses pretty inconsistens if we implement this proposal. Because the language will have the take address operator "&" they know from c++, but it only works in some special cases. For all other cases addressOf has to be used. It would be much more consistent if you could use the "&" operator for everything but taking the address of a function. That would be more consistent in my opinion.It would be more consistent with C++, but less so with the notion of safety. I find it very consistent that all uses of &expression are safe, and this is the kind of consistency Walter and I believe is worth aiming for.Lately I'm getting the feeling that D 2.0 is becoming a collection of hacks to workaround issues which could be solved by adding new keywords or doing other major changes. (like all the stuff that starts with __)I can't help how you feel, but I think you're wrong here and I don't know what other cases you're referring to. Andrei
Feb 06 2013
On 02/06/2013 08:12 PM, Andrei Alexandrescu wrote:On 2/6/13 1:39 PM, Benjamin Thaut wrote:So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }Am 06.02.2013 18:50, schrieb Andrei Alexandrescu:This is an ill-posed question. A keyword should justify its utility, not prove it doesn't harm.On 2/6/13 12:40 PM, Benjamin Thaut wrote:Whats so bad about adding a new keyword for this?So the &value expression would only be left for taking addresses of functions? Wouldn't it make more sense to do it the other way around? E.g. create some utilty function that is only there for taking the address of functions and disallowing to do so by using &func?I don't think that would work without adding new keywords. AndreiI fear that newcomers will find taking addresses pretty inconsistens if we implement this proposal. Because the language will have the take address operator "&" they know from c++, but it only works in some special cases. For all other cases addressOf has to be used. It would be much more consistent if you could use the "&" operator for everything but taking the address of a function. That would be more consistent in my opinion.It would be more consistent with C++, but less so with the notion of safety. I find it very consistent that all uses of &expression are safe, and this is the kind of consistency Walter and I believe is worth aiming for.+1.Lately I'm getting the feeling that D 2.0 is becoming a collection of hacks to workaround issues which could be solved by adding new keywords or doing other major changes. (like all the stuff that starts with __)I can't help how you feel, but I think you're wrong here and I don't know what other cases you're referring to.
Feb 06 2013
On 2/6/13 5:05 PM, Timon Gehr wrote:On 02/06/2013 08:12 PM, Andrei Alexandrescu wrote:Yah, it should, and it also should detect the escape and allocate foo's frame on the heap. AndreiIt would be more consistent with C++, but less so with the notion of safety. I find it very consistent that all uses of &expression are safe, and this is the kind of consistency Walter and I believe is worth aiming for.So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }
Feb 06 2013
On 02/06/2013 11:14 PM, Andrei Alexandrescu wrote:On 2/6/13 5:05 PM, Timon Gehr wrote:I see. Generally? Eg. this detects the escape and allocates as well?: S* foo() safe{ S s; return &s; }On 02/06/2013 08:12 PM, Andrei Alexandrescu wrote:Yah, it should, and it also should detect the escape and allocate foo's frame on the heap. AndreiIt would be more consistent with C++, but less so with the notion of safety. I find it very consistent that all uses of &expression are safe, and this is the kind of consistency Walter and I believe is worth aiming for.So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }
Feb 06 2013
On 2/6/13 5:22 PM, Timon Gehr wrote:I see. Generally? Eg. this detects the escape and allocates as well?: S* foo() safe{ S s; return &s; }I think I'm starting to see what you're doing there :o). Andrei
Feb 06 2013
On Wednesday, 6 February 2013 at 22:33:57 UTC, Andrei Alexandrescu wrote:On 2/6/13 5:22 PM, Timon Gehr wrote:I have to admit this was a big puzzling point to me as well.I see. Generally? Eg. this detects the escape and allocates as well?: S* foo() safe{ S s; return &s; }I think I'm starting to see what you're doing there :o).
Feb 06 2013
On Wednesday, 6 February 2013 at 22:14:42 UTC, Andrei Alexandrescu wrote:On 2/6/13 5:05 PM, Timon Gehr wrote:I thought we wanted to minimize allocations, especially silent ones. In the quoted example, I'd rather the address taking be disallowed at compile time unless the programmer explicitly allocated S on the heap. --rtOn 02/06/2013 08:12 PM, Andrei Alexandrescu wrote:Yah, it should, and it also should detect the escape and allocate foo's frame on the heap. AndreiIt would be more consistent with C++, but less so with the notion of safety. I find it very consistent that all uses of &expression are safe, and this is the kind of consistency Walter and I believe is worth aiming for.So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }
Feb 06 2013
On Thursday, 7 February 2013 at 05:37:44 UTC, Rob T wrote:On Wednesday, 6 February 2013 at 22:14:42 UTC, Andrei Alexandrescu wrote:In other words safe should explicitly mean "I hereby verify that the code is safe" not "I will silently re-write your code in unknown ways to make it safe". PLEASE reconsider! --rtOn 2/6/13 5:05 PM, Timon Gehr wrote:I thought we wanted to minimize allocations, especially silent ones. In the quoted example, I'd rather the address taking be disallowed at compile time unless the programmer explicitly allocated S on the heap. --rtOn 02/06/2013 08:12 PM, Andrei Alexandrescu wrote:Yah, it should, and it also should detect the escape and allocate foo's frame on the heap. AndreiIt would be more consistent with C++, but less so with the notion of safety. I find it very consistent that all uses of &expression are safe, and this is the kind of consistency Walter and I believe is worth aiming for.So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }
Feb 06 2013
On Thursday, 7 February 2013 at 05:43:24 UTC, Rob T wrote:In other words safe should explicitly mean "I hereby verify that the code is safe" not "I will silently re-write your code in unknown ways to make it safe".safe never meant that and Andrei never suggested that.
Feb 06 2013
On Thursday, 7 February 2013 at 05:54:29 UTC, deadalnix wrote:On Thursday, 7 February 2013 at 05:43:24 UTC, Rob T wrote:I must have misunderstood something. What did he mean by this? ------------In other words safe should explicitly mean "I hereby verify that the code is safe" not "I will silently re-write your code in unknown ways to make it safe".safe never meant that and Andrei never suggested that.So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }Yah, it should, and it also should detect the escape and allocate foo's frame on the heap. Andrei ------------ What is being allocated on the heap? --rt
Feb 07 2013
On Thursday, 7 February 2013 at 08:48:30 UTC, Rob T wrote:On Thursday, 7 February 2013 at 05:54:29 UTC, deadalnix wrote:The frame pointer is, and it isn't dependent of system or safe .On Thursday, 7 February 2013 at 05:43:24 UTC, Rob T wrote:I must have misunderstood something. What did he mean by this? ------------In other words safe should explicitly mean "I hereby verify that the code is safe" not "I will silently re-write your code in unknown ways to make it safe".safe never meant that and Andrei never suggested that.So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }Yah, it should, and it also should detect the escape and allocate foo's frame on the heap. Andrei ------------ What is being allocated on the heap?
Feb 07 2013
On Thursday, 7 February 2013 at 09:21:38 UTC, deadalnix wrote:On Thursday, 7 February 2013 at 08:48:30 UTC, Rob T wrote:S* foo() safe{ S s; return &s; } In the above example, will s be silently allocated on the heap? --rtOn Thursday, 7 February 2013 at 05:54:29 UTC, deadalnix wrote:The frame pointer is, and it isn't dependent of system or safe .On Thursday, 7 February 2013 at 05:43:24 UTC, Rob T wrote:I must have misunderstood something. What did he mean by this? ------------In other words safe should explicitly mean "I hereby verify that the code is safe" not "I will silently re-write your code in unknown ways to make it safe".safe never meant that and Andrei never suggested that.So you are saying this should compile?: struct S{ int x; int foo() safe{ return x; } } int delegate() safe foo() safe{ S s; return &s.foo; }Yah, it should, and it also should detect the escape and allocate foo's frame on the heap. Andrei ------------ What is being allocated on the heap?
Feb 07 2013
On 2/6/13 12:36 PM, Andrei Alexandrescu wrote:On 2/6/13 12:33 PM, Benjamin Thaut wrote:Added a dedicated section to the DIP: http://goo.gl/xkIXb AndreiAm 06.02.2013 08:38, schrieb Andrei Alexandrescu:A good part of that is the recent debate on what &func should do (take the address of the function vs. the address of its result). With the unsafe meaning out of the way, only the safe one is eligible.Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiWhat I don't get is, why is it better to have a function "addressOf(value)" that does exactly the same as &value? Expect that it is more text to type? Why is addressOf(value) more explicit then &value?
Feb 06 2013
On Wednesday, 6 February 2013 at 17:50:06 UTC, Andrei Alexandrescu wrote:As per your encouragement to me, I suggest using 'opAddress' instead of 'addressOf' to allow future compatibility with structs.A good part of that is the recent debate on what &func should do (take the address of the function vs. the address of its result). With the unsafe meaning out of the way, only the safe one is eligible.Added a dedicated section to the DIP: http://goo.gl/xkIXb Andrei
Feb 06 2013
On Wed, 06 Feb 2013 17:36:24 -0000, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:A good part of that is the recent debate on what &func should do (take the address of the function vs. the address of its result). With the unsafe meaning out of the way, only the safe one is eligible.&X takes the address of X. If X is a symbol which represents an 'int' you get the address of the int itself, not the address of the int's value. If X is a symbol which represents a 'function' you should get the address of the function itself, not the address of that functions value (AKA the result). That seems the most logical thing to implement, to me. I think the confusion arises because ppl conflate the symbol/variable/thing and that thing's value. If we implement this we then have to ask how to get the address of the value. I reckon; if you want the address of the value of the function then call the function and take the address of that i.e. &func(). Here, brackets are not optional because they indicate the function is being called. Alternately if you don't like that, perhaps &*func. So, if func is "ref int func()" then this syntax makes it analogous to an int* e.g. int i = 5; int *p = &i; &p // takes the address of the variable 'p' &*p // takes the address of the variable 'i' int i = 5; ref int func() { return i; } &func // takes the address of func &*func // takes the address of i I prefer: &func() // takes the address of i because to me that is clearer and nicer looking. This seems the most logical thing to do, and seems the most flexible to me. If &func were to take the address of the value of func (result) then we'd need to invent a new syntax to take the address of func itself and why do that when we don't really need to. IMO. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Feb 07 2013
On 2/6/13 2:38 AM, Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25Updated with a section dedicated to address taking: http://wiki.dlang.org/DIP25#Taking_address Andrei
Feb 06 2013
On Wed, 06 Feb 2013 02:38:17 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25First reaction: It should be GUARANTEED that addressOf is a simple load of the underlying pointer that ref represents. That is, the library/compiler should be compelled not to call a specific function or otherwise execute anything but a simple load (if not already in a register). If that can't be implemented, this whole DIP falls apart. The reason being, that although we want to make it clear the intentions of the code (by using the knowingly unsafe addressOf and not &), we don't want to penalize code for doing so. The D compiler and library should be neutral on performance, even if it is overly nanny-ish when it comes to safety. -Steve
Feb 06 2013
On 2/6/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25Originally I thought addressOf was only planned for safe functions, but for system too? This will likely break almost every library in existence. And interfacing with C will become severely handicapped. Btw, using pointers can actually lead to code which is clearer in its intention: void foo(int* x, int* y) { } void test(int x, int y) { foo(&x, &y); // we know foo might modify these parameters } Since we don't have "ref" at the call site, using ref parameters can lead to code which isn't immediately understood at the call site: void foo(ref int x, ref int y) { } void test(int x, int y) { foo(x, y); // can the parameters be modified? it's not clear from the call site } Also the DIP argues that addressOf solves the property issue w.r.t. return values. I've proposed we use an .addressOf property which only works on property functions, and I saw no arguments against it.
Feb 06 2013
On 2/6/13 3:02 PM, Andrej Mitrovic wrote:On 2/6/13, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:That's a good point.Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25Originally I thought addressOf was only planned for safe functions, but for system too? This will likely break almost every library in existence. And interfacing with C will become severely handicapped.Btw, using pointers can actually lead to code which is clearer in its intention: void foo(int* x, int* y) { } void test(int x, int y) { foo(&x,&y); // we know foo might modify these parameters } Since we don't have "ref" at the call site, using ref parameters can lead to code which isn't immediately understood at the call site: void foo(ref int x, ref int y) { } void test(int x, int y) { foo(x, y); // can the parameters be modified? it's not clear from the call site }I think there's no way to have it both ways. You'll have to get used to the new style and make it a requirement instead of a stylistic preference. Pointers are what they are, and they're not appropriate for code that offers guarantees. We could define a bunch of special rules for pointers in safe mode, but I think it's cleaner this way: ref is for safe code, if you want to mess with things use pointers.Also the DIP argues that addressOf solves the property issue w.r.t. return values. I've proposed we use an .addressOf property which only works on property functions, and I saw no arguments against it.There aren't, but a library approach is better than a magic work, all other things being equal. Andrei
Feb 06 2013
On 2/6/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Pointers are what they are, and they're not appropriate for code that offers guarantees.But we're talking about system here. I would probably be fine with these rules if they only applied to safe. I feel like someone is trying to put training wheels on my mountain bike.
Feb 06 2013
On 2/6/2013 4:23 PM, Andrej Mitrovic wrote:On 2/6/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:One reason why safe is not the default.Pointers are what they are, and they're not appropriate for code that offers guarantees.But we're talking about system here. I would probably be fine with these rules if they only applied to safe. I feel like someone is trying to put training wheels on my mountain bike.
Feb 06 2013
Am Wed, 06 Feb 2013 22:11:40 -0800 schrieb Walter Bright <newshound2 digitalmars.com>:On 2/6/2013 4:23 PM, Andrej Mitrovic wrote:It would also be very very nice, if we could at least write "Hello, world!" in safe D. -- MarcoOn 2/6/13, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:One reason why safe is not the default.Pointers are what they are, and they're not appropriate for code that offers guarantees.But we're talking about system here. I would probably be fine with these rules if they only applied to safe. I feel like someone is trying to put training wheels on my mountain bike.
Feb 10 2013
On Wednesday, 6 February 2013 at 21:40:00 UTC, Andrei Alexandrescu wrote:On 2/6/13 3:02 PM, Andrej Mitrovic wrote:struct S { property int var(); property void var(int); } The .addressOf property gave me the idea of solving the getter/setter issue, by having two properties... var.getter var.setter maybe it could be added to your library approach though?Also the DIP argues that addressOf solves the property issue w.r.t. return values. I've proposed we use an .addressOf property which only works on property functions, and I saw no arguments against it.There aren't, but a library approach is better than a magic work, all other things being equal. Andrei
Feb 10 2013
On Wednesday, 6 February 2013 at 07:38:17 UTC, Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiI'm not sure why it's trying to safe-up pointers. Disallowing the & operator on stack variables is going to cause code breakage of unprecedented proportions (probably biggest since strings where made immutable), I know I use it a LOT in my projects, particularly when interfacing with C libraries or making slices to stack memory. Also, shoving the burden of performance onto the GC for the common case seems like a particularly bad choice considering the current state of the art. Pointers are relatively rare in D; when users take the address of a local variable, it's for a good reason.
Feb 06 2013
On 2/6/13 5:26 PM, Jakob Ovrum wrote:On Wednesday, 6 February 2013 at 07:38:17 UTC, Andrei Alexandrescu wrote:I think it stands to reason that we should pull back a little bit and only tighten that particular screw in safe code. AndreiProbably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiI'm not sure why it's trying to safe-up pointers. Disallowing the & operator on stack variables is going to cause code breakage of unprecedented proportions (probably biggest since strings where made immutable), I know I use it a LOT in my projects, particularly when interfacing with C libraries or making slices to stack memory. Also, shoving the burden of performance onto the GC for the common case seems like a particularly bad choice considering the current state of the art. Pointers are relatively rare in D; when users take the address of a local variable, it's for a good reason.
Feb 06 2013
What happened to the scope storage class for parameters. Wouldn't this solve the problems, with the simple rule that you are not allowed to pass transient objects by reference if the parameter was not declared with scope? And if I understood correctly, the compiler is already capable of locally ensuring that the address does not escape (to ensure the scope requirement), so we are all set? Maybe even simpler, so that the approach also works with variadic template functions: All ref/pointer parameters of a trusted/safe method are automatically scope. For the addressOf method, I think it would be needed far too often. Think about std.stdio.readf() for example. It would really be annoying. Best regards, Robert On Wed, 2013-02-06 at 02:38 -0500, Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, Andrei
Feb 06 2013
Am Wed, 06 Feb 2013 23:45:51 +0100 schrieb Robert <jfanatiker gmx.at>:What happened to the scope storage class for parameters. Wouldn't this solve the problems, with the simple rule that you are not allowed to pass transient objects by reference if the parameter was not declared with scope? And if I understood correctly, the compiler is already capable of locally ensuring that the address does not escape (to ensure the scope requirement), so we are all set?This is an important question. How would this new proposal interact with scope parameters? Scope parameters could at least: * Allow some otherwise trusted code to be safe: --------- trusted bool parse1(ref double v) { // Use C's scanf return scanf("%f", addressOf(v)) == 1; // Fine } --------- can be safe if scanf parameters are scope parameters. Ditto for the parse2 example with addressOf. * Taking the address of a stack variable or a ref parameter could be allowed and safe as long as it's only passed as scope parameters. (All examples in "Taking address" could work if scanf were using scope parameters) IIRC the main problem with scope parameters was that escape analysis isn't implemented yet. http://d.puremagic.com/issues/show_bug.cgi?id=6931
Feb 06 2013
On Thursday, 7 February 2013 at 07:41:57 UTC, Johannes Pfau wrote:Am Wed, 06 Feb 2013 23:45:51 +0100 schrieb Robert <jfanatiker gmx.at>:scope in not enough, as you can alias parameters (for instance swap).What happened to the scope storage class for parameters. Wouldn't this solve the problems, with the simple rule that you are not allowed to pass transient objects by reference if the parameter was not declared with scope? And if I understood correctly, the compiler is already capable of locally ensuring that the address does not escape (to ensure the scope requirement), so we are all set?This is an important question. How would this new proposal interact with scope parameters?
Feb 07 2013
Am Thu, 07 Feb 2013 09:04:29 +0100 schrieb "deadalnix" <deadalnix gmail.com>:On Thursday, 7 February 2013 at 07:41:57 UTC, Johannes Pfau wrote:Can you give an example? I understand the scope is not enough to completely replace the rules in the proposal, but shouldn't it be legal to pass addresses of stack variables in safe code as a scope parameter? Could this cause issues as well?Am Wed, 06 Feb 2013 23:45:51 +0100 schrieb Robert <jfanatiker gmx.at>:scope in not enough, as you can alias parameters (for instance swap).What happened to the scope storage class for parameters. Wouldn't this solve the problems, with the simple rule that you are not allowed to pass transient objects by reference if the parameter was not declared with scope? And if I understood correctly, the compiler is already capable of locally ensuring that the address does not escape (to ensure the scope requirement), so we are all set?This is an important question. How would this new proposal interact with scope parameters?
Feb 07 2013
On Wednesday, 6 February 2013 at 07:38:17 UTC, Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks,Seems like a good DIP overall. The limitation on address taking seriously impair the possibility of implementing property properly to emulate a field. It seems like a solvable problem, as scope can be explicited. But then, some address taking are back, and so the syntax problem around previous DIP isn't solved (But that is arguably a good thing as we should solve problems themselves, not symptoms).
Feb 06 2013
On 2/6/2013 7:30 PM, deadalnix wrote:The limitation on address taking seriously impair the possibility of implementing property properly to emulate a field.Properties are always going to be subsets of fields. For example, property int foo() { return 3; } is never going to work with trying to get the address of 3. Trying to make it work would be a quixotic quest of dubious utility. I.e. I disagree that it is a serious impairment.It seems like a solvable problem, as scope can be explicited. But then, some address taking are back, and so the syntax problem around previous DIP isn't solved (But that is arguably a good thing as we should solve problems themselves, not symptoms).The only time (now) that you can take the address of function return value is if that is a return by ref. So, if taking the address of a ref is disallowed, then the syntax is no longer ambiguous.
Feb 06 2013
On Thursday, 7 February 2013 at 06:06:56 UTC, Walter Bright wrote:On 2/6/2013 7:30 PM, deadalnix wrote:Obviously it is not going to work in that case. You'll find a huge difference between it will not work in case XXX and it is impossible to make it work. It is a given that properties can't 100M emulate field, but the goal should be to close he gap as much as possible.The limitation on address taking seriously impair the possibility of implementing property properly to emulate a field.Properties are always going to be subsets of fields. For example, property int foo() { return 3; } is never going to work with trying to get the address of 3. Trying to make it work would be a quixotic quest of dubious utility. I.e. I disagree that it is a serious impairment.It doesn't change anything in many cases. Especially for template alias parameters. It doesn't change the intrinsic complexity of the proposal that conflate a function (as first class object), its return value, and the useless C/C++ entity that is a function.It seems like a solvable problem, as scope can be explicited. But then, some address taking are back, and so the syntax problem around previous DIP isn't solved (But that is arguably a good thing as we should solve problems themselves, not symptoms).The only time (now) that you can take the address of function return value is if that is a return by ref. So, if taking the address of a ref is disallowed, then the syntax is no longer ambiguous.
Feb 06 2013
On Thursday, 7 February 2013 at 06:13:44 UTC, deadalnix wrote:It doesn't change anything in many cases. Especially for template alias parameters. It doesn't change the intrinsic complexity of the proposal that conflate a function (as first class object), its return value, and the useless C/C++ entity that is a function.Reformulating : it helps on the grammatical perspective, but the semantic is still broken.
Feb 06 2013
On 2/6/2013 10:13 PM, deadalnix wrote:It is a given that properties can't 100M emulate field, but the goal should be to close he gap as much as possible.Ok, why should "as much as possible" be the goal? There are other considerations - what merit should they have? For example, I consider having an easily understood mental model of how things work to be very important. Having the language doing mysterious heroic things under the hood trying to implement someone else's idea of human intuition impairs anyone's ability to understand a language.It doesn't change anything in many cases. Especially for template alias parameters.Why? foo seems straightforward as a template alias parameter, meaning the function foo. Alias parameters do not take expressions as arguments - so the expression rules do not apply.It doesn't change the intrinsic complexity of the proposal that conflate a function (as first class object), its return value, and the useless C/C++ entity that is a function.Removing an ambiguous case does reduce the intrinsic complexity.
Feb 06 2013
On Thursday, 7 February 2013 at 06:23:10 UTC, Walter Bright wrote:On 2/6/2013 10:13 PM, deadalnix wrote:I don't think anyone have interest to get back on that. If you have another answer to that question, please share.It is a given that properties can't 100M emulate field, but the goal should be to close he gap as much as possible.Ok, why should "as much as possible" be the goal? There are other considerations - what merit should they have?For example, I consider having an easily understood mental model of how things work to be very important. Having the language doing mysterious heroic things under the hood trying to implement someone else's idea of human intuition impairs anyone's ability to understand a language.Ease come from 2 main things : - Fit the mental model that an user have in realted area (ie other programing languages) - Simplicity (which is very different from ease). The current proposal seems easy to you because it is close o YOUR mental model, working on D. But on a larger scale, it fails at both criteria mentioned above : it is different from what exists in any languages mentioned in this NG, and a same identifier can refers to 3 different distinct (however related) concepts. DIP25 aim to solve the ref issue. Which is clearly useful. Conflating that goal with making previous DIP on function call is only going to export the mess in another area of the language. This is the very example of why simplicity in semantic is key.An alias template parameter bind to a symbol. A symbol can be either a first-class function or a the other entity that have no name (the symbol resulting of a function declaration).It doesn't change anything in many cases. Especially for template alias parameters.Why? foo seems straightforward as a template alias parameter, meaning the function foo. Alias parameters do not take expressions as arguments - so the expression rules do not apply.I'm sure that, as a developer that specialized itself in compilers, you perfectly know the difference between syntax and semantic. And that solving a syntax issue that is symptom of a semantic issue will not fix the semantic issue.It doesn't change the intrinsic complexity of the proposal that conflate a function (as first class object), its return value, and the useless C/C++ entity that is a function.Removing an ambiguous case does reduce the intrinsic complexity.
Feb 07 2013
On 2/7/2013 12:22 AM, deadalnix wrote:The point is, there must always be a balance of competing interests. That's certainly true here.Ok, why should "as much as possible" be the goal? There are other considerations - what merit should they have?I don't think anyone have interest to get back on that. If you have another answer to that question, please share.know, but I'd be surprised if it did.For example, I consider having an easily understood mental model of how things work to be very important. Having the language doing mysterious heroic things under the hood trying to implement someone else's idea of human intuition impairs anyone's ability to understand a language.Ease come from 2 main things : - Fit the mental model that an user have in realted area (ie other programing languages) - Simplicity (which is very different from ease). The current proposal seems easy to you because it is close o YOUR mental model, working on D. But on a larger scale, it fails at both criteria mentioned above : it is different from what exists in any languages mentioned in this NG,and a same identifier can refers to 3 different distinct (however related) concepts.It is not unusual for an identifier to mean different things in different constructs.DIP25 aim to solve the ref issue. Which is clearly useful. Conflating that goal with making previous DIP on function call is only going to export the mess in another area of the language. This is the very example of why simplicity in semantic is key.Simplicity is great, but it does not always trump everything else. It's also possible for reasonable people to disagree on what is simple or intuitive.Yes.An alias template parameter bind to a symbol. A symbol can be either a first-class functionIt doesn't change anything in many cases. Especially for template alias parameters.Why? foo seems straightforward as a template alias parameter, meaning the function foo. Alias parameters do not take expressions as arguments - so the expression rules do not apply.or a the other entity that have no name (the symbol resulting of a function declaration).Yes. But I don't see the issue. &foo cannot bind to an alias parameter, nor can foo().What &foo means is a semantic issue, not a syntactic one. It's not an ambiguous grammar. Semantic ambiguity issues are resolved by creating rules (which one may consider intuitive or arbitrary) and applying them, which is what we're doing here. There are several such ambiguities in D that are resolved by applying semantic disambiguation rules. This is done because although it makes the spec (and the compiler) more complex, it is actually simpler for the user. Saying that one cannot take the address of a return value solves the semantic ambiguity problem with &foo.I'm sure that, as a developer that specialized itself in compilers, you perfectly know the difference between syntax and semantic. And that solving a syntax issue that is symptom of a semantic issue will not fix the semantic issue.It doesn't change the intrinsic complexity of the proposal that conflate a function (as first class object), its return value, and the useless C/C++ entity that is a function.Removing an ambiguous case does reduce the intrinsic complexity.
Feb 07 2013
On Thursday, 7 February 2013 at 09:23:20 UTC, Walter Bright wrote:The point is, there must always be a balance of competing interests. That's certainly true here.That is an assertion not an argument.value? I don't know, but I'd be surprised if it did.consider the whole stuff without the address problem, the D way cause syntax problem issue with address of, where D does.Usually not when they resolve to the same symbol. And it has to be proven that this is a good thing.and a same identifier can refers to 3 different distinct (however related) concepts.It is not unusual for an identifier to mean different things in different constructs.Simplicity is great, but it does not always trump everything else. It's also possible for reasonable people to disagree on what is simple or intuitive.Here we have a more complex solution, and more problem with it. Conclude whatever you want, but each time I choose the complex path in my programmer life, I ended up with that kind of effect. You also seems to conflate simple and intuitive, which are really unrelated. Simplicity is mostly objective, when intuition is mostly subjective. Both combined usually lead to ease.Yes.void function() foo can.or a the other entity that have no name (the symbol resulting of a function declaration).Yes. But I don't see the issue. &foo cannot bind to an alias parameter, nor can foo().What &foo means is a semantic issue, not a syntactic one. It's not an ambiguous grammar. Semantic ambiguity issues are resolved by creating rules (which one may consider intuitive or arbitrary) and applying them, which is what we're doing here.You should hear ambiguous as ambiguous for the parser here. This is possible to make any crazy insane syntax unambiguous for the parser.There are several such ambiguities in D that are resolved by applying semantic disambiguation rules. This is done because although it makes the spec (and the compiler) more complex, it is actually simpler for the user.I don't think it is, and looking at other languages choices, I'm not alone. This kind of thing always seems simple of some cases, but ends up creating a huge minefield of special case when you start to combine feature together. And this is something that most D users experiences. It result in users not using advanced D features (see HIGGS topic for instance, or many codebases on github in general) or user having trouble. It is often advised to stay away form advanced features of D for production quality stuff and I have to say I share the observation. Working on large codebase (well large . . . for a personal project, but clearly ridiculous compared to many companies codebase : ~25 000LOC) using advanced features of D, I run in such troubles almost on a daily basis, and have developed some knowledge of area of the language I should not even try to go in.
Feb 07 2013
On 2/7/2013 2:05 AM, deadalnix wrote:On Thursday, 7 February 2013 at 09:23:20 UTC, Walter Bright wrote:Try designing anything by using one overriding principle - you won't get a useful result. Designs are always tradeoffs, always.The point is, there must always be a balance of competing interests. That's certainly true here.That is an assertion not an argument.It's a different language, with a different view of things. Direct comparisonsknow, but I'd be surprised if it did.of, where D does.I don't understand this sentence.How does one prove anything is a "good thing"?Usually not when they resolve to the same symbol. And it has to be proven that this is a good thing.and a same identifier can refers to 3 different distinct (however related) concepts.It is not unusual for an identifier to mean different things in different constructs.Not really, I said "simple OR intuitive" :-)Simplicity is great, but it does not always trump everything else. It's also possible for reasonable people to disagree on what is simple or intuitive.Here we have a more complex solution, and more problem with it. Conclude whatever you want, but each time I choose the complex path in my programmer life, I ended up with that kind of effect. You also seems to conflate simple and intuitive,Sure. But I'm lost at what your point is with that example.Yes. But I don't see the issue. &foo cannot bind to an alias parameter, nor can foo().void function() foo can.Given the vast variety and complexity of languages out there, for every example of A you can find, I can find examples of !A. It's not really useful, after all, if other languages got it all right, there's no point to D.There are several such ambiguities in D that are resolved by applying semantic disambiguation rules. This is done because although it makes the spec (and the compiler) more complex, it is actually simpler for the user.I don't think it is, and looking at other languages choices, I'm not alone.This kind of thing always seems simple of some cases, but ends up creating a huge minefield of special case when you start to combine feature together. And this is something that most D users experiences.I believe that Andrei's proposal resolves these.It result in users not using advanced D features (see HIGGS topic for instance, or many codebases on github in general) or user having trouble. It is often advised to stay away form advanced features of D for production quality stuff and I have to say I share the observation. Working on large codebase (well large . . . for a personal project, but clearly ridiculous compared to many companies codebase : ~25 000LOC) using advanced features of D, I run in such troubles almost on a daily basis, and have developed some knowledge of area of the language I should not even try to go in.This is exactly why we're going through this exercise with the properties.
Feb 07 2013
On Thursday, 7 February 2013 at 10:32:38 UTC, Walter Bright wrote:On 2/7/2013 2:05 AM, deadalnix wrote:Ho yeah, I'm not arguing against that. But what is seen as conflicting goal often aren't.On Thursday, 7 February 2013 at 09:23:20 UTC, Walter Bright wrote:Try designing anything by using one overriding principle - you won't get a useful result. Designs are always tradeoffs, always.The point is, there must always be a balance of competing interests. That's certainly true here.That is an assertion not an argument.what is called in D a delegate. foo.bar() execute that delegate. It remove the need for &foo.bar altogether, so with that mechanism in D, no problem with & operator. Scala does even one step further by executing the method, or not, depending on what is expected, proving that optional () are compatible with. Back to D, we have void function() foo; foo is declared as a function here. However, void bar() {} will also be called a function, even if the entity represented by foo and bar are completely different. When you do foo = &bar, you get a pointer on foo's instruction. Here foo isn't a function in the D sense, but an Array of CPU instruction, or something like that. This entity, coming from C/C++ hasn't ANY useful usage except taking the address of to get a function. Wanting to keep that useless entity is the source of most trouble with the & syntax, and also on previous DIP (not that one).It's a different language, with a different view of things. account.value? I don't know, but I'd be surprised if it did.you consider the whole stuff without the address problem, the D way isissue with address of, where D does.I don't understand this sentence.How does one prove anything is a "good thing"?Proven may be strong, but you can't refute that some things are better than others.Now you can pass several object to templates alias parameters, that will behave differently in slightly different subtle ways. For no real good reason.Sure. But I'm lost at what your point is with that example.Yes. But I don't see the issue. &foo cannot bind to an alias parameter, nor can foo().void function() foo can.If A is the instruction pack entity type mentionned above, you'll find pretty hard to find a !A if we exclude C and C++ (well and D, but it is kind of excluded if look for references). I don't pretend none exists, but it seems pretty hard to find one. Because the idea is bad for everybody : it make the language more complex, harder to implement compiler/tooling for, can conflict with other features, and worse, have no benefice. This is a bad idea in all possible way. Actually so bad that even PHP don't implement it.I don't think it is, and looking at other languages choices, I'm not alone.Given the vast variety and complexity of languages out there, for every example of A you can find, I can find examples of !A. It's not really useful, after all, if other languages got it all right, there's no point to D.He does so by adding special cases. That is the problem with special cases, they multiply themselves faster than rabbits.This kind of thing always seems simple of some cases, but ends up creating a huge minefield of special case when you start to combine feature together. And this is something that most D users experiences.I believe that Andrei's proposal resolves these.It is clear that the property improvement proposed by Andrei is a great step forward. However, the &foo.bar that return the delegate when bar is a property is exactly the kind of stuff that are waiting to explode. Yes, this DIP remove the syntactic ambiguity (does this take the delegate or the address of the result ?) but that is barely it. I'd say that the fact that & have a meaning is way more problematic than the fact that it is not possible to take the resulting address.It result in users not using advanced D features (see HIGGS topic for instance, or many codebases on github in general) or user having trouble. It is often advised to stay away form advanced features of D for production quality stuff and I have to say I share the observation. Working on large codebase (well large . . . for a personal project, but clearly ridiculous compared to many companies codebase : ~25 000LOC) using advanced features of D, I run in such troubles almost on a daily basis, and have developed some knowledge of area of the language I should not even try to go in.This is exactly why we're going through this exercise with the properties.
Feb 07 2013
On 2/7/2013 3:16 AM, deadalnix wrote:No, that declares foo as a "pointer to function".D a delegate. foo.bar() execute that delegate. It remove the need for &foo.bar altogether, so with that mechanism in D, no problem with & operator. Scala does even one step further by executing the method, or not, depending on what is expected, proving that optional () are compatible with. Back to D, we have void function() foo; foo is declared as a function here.of, where D does.I don't understand this sentence.Now you can pass several object to templates alias parameters, that will behave differently in slightly different subtle ways. For no real good reason.They won't behave any differently than they would outside of being passed as aliases. I don't see a special problem added with alias parameters.There are few languages in the systems programming category (languages that give one full access to pointers), so excluding C and C++ seems rather draconian.If A is the instruction pack entity type mentionned above, you'll find pretty hard to find a !A if we exclude C and C++ (well and D, but it is kind of excluded if look for references). I don't pretend none exists, but it seems pretty hard to find one.I don't think it is, and looking at other languages choices, I'm not alone.Given the vast variety and complexity of languages out there, for every example of A you can find, I can find examples of !A. It's not really useful, after all, if other languages got it all right, there's no point to D.He does so by adding special cases. That is the problem with special cases, they multiply themselves faster than rabbits.Taking the address of a ref was already problematic.
Feb 07 2013
On Thursday, 7 February 2013 at 19:57:50 UTC, Walter Bright wrote:On 2/7/2013 3:16 AM, deadalnix wrote:That isn't what I read. It is clearly written void function() foo; And if in int a; a is an int and in int* b, b is a pointer on int, foo must be a function. The fact that this very entity type is called function pointer is C is irrelevant. The distinction between the 2 is a problem in the first place, as it create new entities with different behavior, for a benefice that is unclear to me.No, that declares foo as a "pointer to function".what is called in D a delegate. foo.bar() execute that delegate. It remove the need for &foo.bar altogether, so with that mechanism in D, no problem with & operator. Scala does even one step further by executing the method, or not, depending on what is expected, proving that optional () are compatible with. Back to D, we have void function() foo; foo is declared as a function here.issue with address of, where D does.I don't understand this sentence.Because the same syntax have different meanings, so suddenly, you have to special case everything. That is never done in practice, not even in phobos.Now you can pass several object to templates alias parameters, that will behave differently in slightly different subtle ways. For no real good reason.They won't behave any differently than they would outside of being passed as aliases. I don't see a special problem added with alias parameters.I don't see why this should be limited to system languages. This is about function and most languages have functions (and most modern languages have first class functions). language often do not conflict with pointer access.If A is the instruction pack entity type mentionned above, you'll find pretty hard to find a !A if we exclude C and C++ (well and D, but it is kind of excluded if look for references). I don't pretend none exists, but it seems pretty hard to find one.There are few languages in the systems programming category (languages that give one full access to pointers), so excluding C and C++ seems rather draconian.Yes indeed. I never argued against that.He does so by adding special cases. That is the problem with special cases, they multiply themselves faster than rabbits.Taking the address of a ref was already problematic.
Feb 07 2013
On Thursday, 7 February 2013 at 09:23:20 UTC, Walter Bright wrote:Can you tell me if you consider my proposal with regard to making ref safe and complete simple and intuitive both for compiler and user, and if not, why? (I don't have an opinion about '&' yet.) http://forum.dlang.org/thread/ket199$2c27$1 digitalmars.com#post-bsgrtofehxfjmzkaedfr:40forum.dlang.orgDIP25 aim to solve the ref issue. Which is clearly useful. Conflating that goal with making previous DIP on function call is only going to export the mess in another area of the language. This is the very example of why simplicity in semantic is key.Simplicity is great, but it does not always trump everything else. It's also possible for reasonable people to disagree on what is simple or intuitive.
Feb 07 2013
On 2/7/2013 6:15 AM, Zach the Mystic wrote:Can you tell me if you consider my proposal with regard to making ref safe and complete simple and intuitive both for compiler and user, and if not, why? (I don't have an opinion about '&' yet.) http://forum.dlang.org/thread/ket199$2c27$1 digitalmars.com#post-bsgrtofehxfjmzkaedfr:40forum.dlang.orgI don't know if it's complete and safe. It's not something that can be determined with a quick read.
Feb 07 2013
On Thursday, 7 February 2013 at 19:49:27 UTC, Walter Bright wrote:On 2/7/2013 6:15 AM, Zach the Mystic wrote:Okay. But at least that's a 'check' on simple and intuitive? As far as why I think it's safe, my investigation led me to conclude that the key question was, how do I know whether to treat the return value of a ref function which accept a ref as local or global? I pass a value into a mysterious box, how do I know whether what comes out the other end is related to what I passed in, or something completely different? All the cases DIP25 takes care of are the ones which can be known just by the peculiarities of the call and signature, but many cases just leave you in the dark. The only way the compiler can know for sure without help from the function signature is by dipping into the function's code to take a look, which seems like too high a price to pay. About a month ago Jonathan M Davis brought this up and pointed out that the PIMPL idiom occasionally banishes altogether that opportunity for the compiler. After a few tries, I realized that 'out' was actually still available to use for this purpose, which is either pure luck (possible) or a hidden byproduct of the fact that 1) it's a good keyword to begin with or 2) there's a secret truth to its interchangeability with 'ref' which applies to return values as well as to parameter tags.Can you tell me if you consider my proposal with regard to making ref safe and complete simple and intuitive both for compiler and user, and if not, why? (I don't have an opinion about '&' yet.) http://forum.dlang.org/thread/ket199$2c27$1 digitalmars.com#post-bsgrtofehxfjmzkaedfr:40forum.dlang.orgI don't know if it's complete and safe. It's not something that can be determined with a quick read.
Feb 07 2013
The solution to this problem has been posted already many times, simply allow fields to be marked with property too, having the compiler lower it to a private field with trivial setter/getter method. As I already mentioned, I don't really see the point of properties at all, if they are not interchangeable with fields. We could as well use setXXX/getXXX as in Java. On Wed, 2013-02-06 at 22:06 -0800, Walter Bright wrote:Properties are always going to be subsets of fields. For example, property int foo() { return 3; } is never going to work with trying to get the address of 3. Trying to make it work would be a quixotic quest of dubious utility. I.e. I disagree that it is a serious impairment.
Feb 07 2013
On Thu, 07 Feb 2013 01:06:34 -0500, Walter Bright <newshound2 digitalmars.com> wrote:The only time (now) that you can take the address of function return value is if that is a return by ref. So, if taking the address of a ref is disallowed, then the syntax is no longer ambiguous.Thinking about this, I don't know that I like the idea of disallowing taking the address of ref. One major usage of taking the address of ref returns is the opIndex operator: int *ptr = &arr[0]; Or, more generally, the front property of a range: int *ptr = &arr.front; What I am concerned about is that this is not going to have the desired effect. Instead of grudgingly switching to a new style of coding, people will simply return pointers instead of ref. -Steve
Feb 07 2013
On Thursday, 7 February 2013 at 14:43:38 UTC, Steven Schveighoffer wrote:On Thu, 07 Feb 2013 01:06:34 -0500, Walter Bright <newshound2 digitalmars.com> wrote:Exactly.The only time (now) that you can take the address of function return value is if that is a return by ref. So, if taking the address of a ref is disallowed, then the syntax is no longer ambiguous.Thinking about this, I don't know that I like the idea of disallowing taking the address of ref. One major usage of taking the address of ref returns is the opIndex operator: int *ptr = &arr[0]; Or, more generally, the front property of a range: int *ptr = &arr.front; What I am concerned about is that this is not going to have the desired effect. Instead of grudgingly switching to a new style of coding, people will simply return pointers instead of ref.
Feb 07 2013
Am Wed, 06 Feb 2013 02:38:17 -0500 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiAt first I was skeptical about how this would work with binary operator overloads where you have a lot of ref returns. (Think vector * matrix.) But as it seems, only stack local variables underly new restrictions. So anything that operates only on 'this' stays valid code. I'd still like to see some actual code that will break, since its bad to rely on lack of imagination and contrived examples. As for the address taking, I hope it doesn't end up in being nannied to much by the language. Like in the case with printf, it could really piss people off that don't understand the reasoning behind it. Make the error message informative for that: "Potential escape of pointer to stack local" or similar. -- Marco
Feb 06 2013
On 2/6/2013 8:16 PM, Marco Leise wrote:As for the address taking, I hope it doesn't end up in being nannied to much by the language. Like in the case with printf, it could really piss people off that don't understand the reasoning behind it. Make the error message informative for that: "Potential escape of pointer to stack local" or similar.I think C++ missed an opportunity with reference types. All they are in C++ are just another way to express a pointer. They don't really offer any semantic improvement - you can even have null references. In D, we have an opportunity to define reference types as a kind of "safe" pointer type - where we can get much of the advantages of pointers without the potential for memory corruption.
Feb 06 2013
On Wed, Feb 06, 2013 at 10:09:48PM -0800, Walter Bright wrote:On 2/6/2013 8:16 PM, Marco Leise wrote:D ref types are currently highly crippled because of the inability to declare ref variables, which mandates ugly workarounds. It should be a first-class type qualifier IMO. (Yes I know it's currently a *function* qualifier, not a type qualifier... which makes it all the more ugly.) T -- Дерево держится корнями, а человек - друзьями.As for the address taking, I hope it doesn't end up in being nannied to much by the language. Like in the case with printf, it could really piss people off that don't understand the reasoning behind it. Make the error message informative for that: "Potential escape of pointer to stack local" or similar.I think C++ missed an opportunity with reference types. All they are in C++ are just another way to express a pointer. They don't really offer any semantic improvement - you can even have null references. In D, we have an opportunity to define reference types as a kind of "safe" pointer type - where we can get much of the advantages of pointers without the potential for memory corruption.
Feb 06 2013
On 2/7/13 1:34 AM, H. S. Teoh wrote:On Wed, Feb 06, 2013 at 10:09:48PM -0800, Walter Bright wrote:Unfortunately type qualifiers have very high complexity costs. I think it's very neat that we managed to keep ref the way it is. Yes, I, too, would like to have a ref variable sometimes, but overall I'm please with the way it's working (post DIP25 especially). AndreiOn 2/6/2013 8:16 PM, Marco Leise wrote:D ref types are currently highly crippled because of the inability to declare ref variables, which mandates ugly workarounds. It should be a first-class type qualifier IMO. (Yes I know it's currently a *function* qualifier, not a type qualifier... which makes it all the more ugly.)As for the address taking, I hope it doesn't end up in being nannied to much by the language. Like in the case with printf, it could really piss people off that don't understand the reasoning behind it. Make the error message informative for that: "Potential escape of pointer to stack local" or similar.I think C++ missed an opportunity with reference types. All they are in C++ are just another way to express a pointer. They don't really offer any semantic improvement - you can even have null references. In D, we have an opportunity to define reference types as a kind of "safe" pointer type - where we can get much of the advantages of pointers without the potential for memory corruption.
Feb 06 2013
On Thursday, 7 February 2013 at 06:36:22 UTC, H. S. Teoh wrote:D ref types are currently highly crippled because of the inability to declare ref variables, which mandates ugly workarounds. It should be a first-class type qualifier IMO. (Yes I know it's currently a *function* qualifier, not a type qualifier... which makes it all the more ugly.)My heart say yes, but my brain doesn't really any way to make that work :/
Feb 07 2013
Am Wed, 06 Feb 2013 02:38:17 -0500 schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiRegarding the questions about scope parameters and allowing & in system code, wouldn't it make sense to change the rules to the following: * Taking the address in system code is allowed. You can do everything with the returned address just as right now. * Taking the address in safe code is also allowed, but you can't do anything with it: You can't assign it to anything, can't return it and can't dereference it. ** Once full escape analysis and scope parameters are implemented, those rule will be relaxed a little and passing such pointers to some functions (e.g. as scope parameters) will be allowed in safe code. ** addressOf isn't necessary as you can take addresses in system code anyway This makes more sense than disallowing the & operator completely as we'd have to reintroduce it anyway once scope is implemented. This way we start with a strict, conservative way and relax the rules when the compiler can prove that the operations are really safe.
Feb 07 2013
On 02/06/2013 02:38 AM, Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiA single delegate (closure) can be used to defer both reads and writes on an arbitrary expression. This works on naked variables, references, pointers, properties, and probably a number of other things I haven't thought of yet. Here's the relevance to DIP25: closures already have well-defined escape semantics. The downside is that they probably allocate heap way too aggressively in the current implementation. The upshot is that they are always memory-safe. This makes optimization a quality-of-implementation issue: a sufficiently intelligent compiler should be able to remove many allocations for non-escaping closures. Perhaps ref parameters should be delegates under the hood instead of pointers? The longterm disadvantage I see with this is the extra pointer that must be passed/returned. I wonder how hard it would be for the compiler to instantiate specialized oldschool-pointer versions of functions with ref parameters whenever calls are made that do not require the guarantees that closures provide. A working demonstration is given below. Destroy! import std.traits; import std.stdio; struct Option(T) { bool hasValue = false; union { ubyte nope; T value; } this( T value ) { hasValue = true; this.value = value; } } Option!T none(T)() { Option!T result; return result; } /* For some reason we need to cast to this to make template deduction work on any functions it gets passed into. */ template DelegateRef(T) { alias T delegate(Option!T intake) DelegateRef; } template isDelegateRef(T) { static if ( isDelegate!T ) { alias ReturnType!T R; static if ( is( T == R delegate(Option!R) ) ) enum isDelegateRef = true; else enum isDelegateRef = false; } else enum isDelegateRef = false; } string accessor(string expr) { return `cast(DelegateRef!(typeof(`~expr~`))) (`~ `delegate typeof(`~expr~`)(Option!(typeof(`~expr~`)) intake) {`~ ` if ( intake.hasValue )`~ ` return (`~expr~` = intake.value);`~ ` else`~ ` return `~expr~`;`~ `})`; } // Function that accepts a reference. auto someFunc(Q)(Q qux) if ( isDelegateRef!Q ) { alias ReturnType!Q T; auto x = qux(none!T); x |= 0xF00D; qux(Option!T(x)); return qux(none!T); } struct MyStruct { private int m_q; property int q() { writefln("get q (%x)",m_q); return m_q; } property int q(int v) { writefln("set q (%x = %x)", m_q, v); return m_q = v; } } void testRef( ref int foo ) { assert(someFunc(mixin(accessor("foo"))) == 0xF00D); } void testPtr( int* foo ) { assert(someFunc(mixin(accessor("*foo"))) == 0xF00D); } void main() { int abc = 0; assert(someFunc(mixin(accessor("abc"))) == 0xF00D); assert(abc == 0xF00D); int foo = 0; testRef(foo); assert(foo == 0xF00D); int bar = 0; testPtr(&bar); assert(bar == 0xF00D); MyStruct s; s.q = 0; assert(someFunc(mixin(accessor("s.q"))) == 0xF00D); assert(s.q == 0xF00D); }
Feb 07 2013
On Friday, 8 February 2013 at 06:28:54 UTC, Chad Joan wrote:On 02/06/2013 02:38 AM, Andrei Alexandrescu wrote:The cost of passing a delegate is way higher than the cost of passing the extra pointer. Delegate cause an opaque function call so : - All registers that the callee is allowed to trash must be saved preventively (even if the callee don't trash them). - CPU cannot really use branch prediction. - The compiler must assume that the delegate call may have arbitrary side effects so have to commit everything to memory and then take everything back afterward. This prevent many instruction reordering, register promotions, dead read/write elimination, constant propagation and so on. Considering passing by ref is sometime done to fasten things, this defeat the whole point. Note that the operation above are not dying slow, but clearly not a good fit for ref.Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25 Thanks, AndreiA single delegate (closure) can be used to defer both reads and writes on an arbitrary expression. This works on naked variables, references, pointers, properties, and probably a number of other things I haven't thought of yet. Here's the relevance to DIP25: closures already have well-defined escape semantics. The downside is that they probably allocate heap way too aggressively in the current implementation. The upshot is that they are always memory-safe. This makes optimization a quality-of-implementation issue: a sufficiently intelligent compiler should be able to remove many allocations for non-escaping closures. Perhaps ref parameters should be delegates under the hood instead of pointers? The longterm disadvantage I see with this is the extra pointer that must be passed/returned. I wonder how hard it would be for the compiler to instantiate specialized oldschool-pointer versions of functions with ref parameters whenever calls are made that do not require the guarantees that closures provide. A working demonstration is given below. Destroy!import std.traits; import std.stdio; struct Option(T) { bool hasValue = false; union { ubyte nope; T value; } this( T value ) { hasValue = true; this.value = value; } } Option!T none(T)() { Option!T result; return result; } /* For some reason we need to cast to this to make template deduction work on any functions it gets passed into. */ template DelegateRef(T) { alias T delegate(Option!T intake) DelegateRef; } template isDelegateRef(T) { static if ( isDelegate!T ) { alias ReturnType!T R; static if ( is( T == R delegate(Option!R) ) ) enum isDelegateRef = true; else enum isDelegateRef = false; } else enum isDelegateRef = false; } string accessor(string expr) { return `cast(DelegateRef!(typeof(`~expr~`))) (`~ `delegate typeof(`~expr~`)(Option!(typeof(`~expr~`)) intake) {`~ ` if ( intake.hasValue )`~ ` return (`~expr~` = intake.value);`~ ` else`~ ` return `~expr~`;`~ `})`; } // Function that accepts a reference. auto someFunc(Q)(Q qux) if ( isDelegateRef!Q ) { alias ReturnType!Q T; auto x = qux(none!T); x |= 0xF00D; qux(Option!T(x)); return qux(none!T); } struct MyStruct { private int m_q; property int q() { writefln("get q (%x)",m_q); return m_q; } property int q(int v) { writefln("set q (%x = %x)", m_q, v); return m_q = v; } } void testRef( ref int foo ) { assert(someFunc(mixin(accessor("foo"))) == 0xF00D); } void testPtr( int* foo ) { assert(someFunc(mixin(accessor("*foo"))) == 0xF00D); } void main() { int abc = 0; assert(someFunc(mixin(accessor("abc"))) == 0xF00D); assert(abc == 0xF00D); int foo = 0; testRef(foo); assert(foo == 0xF00D); int bar = 0; testPtr(&bar); assert(bar == 0xF00D); MyStruct s; s.q = 0; assert(someFunc(mixin(accessor("s.q"))) == 0xF00D); assert(s.q == 0xF00D); }
Feb 07 2013
On 02/08/2013 02:06 AM, deadalnix wrote:On Friday, 8 February 2013 at 06:28:54 UTC, Chad Joan wrote:Fair enough. I wonder if we can learn something from it though. It does seem to provide a conceptual model that's very desirable.Destroy!The cost of passing a delegate is way higher than the cost of passing the extra pointer. Delegate cause an opaque function call so : - All registers that the callee is allowed to trash must be saved preventively (even if the callee don't trash them). - CPU cannot really use branch prediction. - The compiler must assume that the delegate call may have arbitrary side effects so have to commit everything to memory and then take everything back afterward. This prevent many instruction reordering, register promotions, dead read/write elimination, constant propagation and so on. Considering passing by ref is sometime done to fasten things, this defeat the whole point. Note that the operation above are not dying slow, but clearly not a good fit for ref.
Feb 08 2013
Two more things: Disable a read/write propa like int getSetSomeInteger(int). int getSomeInteger() and void setSomeIntger(int) only allowed. And disable default parameter for setter.
Feb 09 2013
On Wednesday, February 06, 2013 02:38:17 Andrei Alexandrescu wrote:Probably it'll need a fair amount of tweaking. Anyhow it's in destroyable form. http://wiki.dlang.org/DIP25Overall, the ref part seems good, but I'm highly skeptical of the part on addresses. The main point I'd raise about the ref portion is that module-level variables need to be grouped in with the static variables. You seem to have marked some module-level variables as scope in the examples, but static has no effect on module-level variables. As for the addresses, it seems very bizarre to create a function for doing what & does and then make & legal only in very restricted circumstances. Having a safeAddressOf for some set of restricted circumstances might make sense, but couldn't the compiler just detect that & was safe under those circumstances? If the compiler can determine that it's safe using the function, it should be possible for it to determine it without. And disallowing & even in system code is _way_ overkill. The compiler is already able to detect at least some unsafe cases (e.g. taking the address of a local variable), and it's incredibly common to need to do some of those when interacting with C code (e.g. taking the address of a local variable and passing it to a C function). If the problem is ambiguities between taking the address of a function and the address of its return value, then I'd think that it would be much cleaner to just create a __trait for getting the address of a function. It's needed far less than taking the address of a variable, and the difference between & and addressOf is just going to sow confusion. It definitely seems like overkill to me to introduce a function for doing what & already does just to deal with the difference between taking the address of a function and taking the address of its return value. So, I'm in favor of the changes to ref, but I definitely don't like what this DIP does with &. - Jonathan M Davis
Feb 11 2013