digitalmars.D - auto, var, raii,scope, banana
- kris (26/26) Jul 25 2006 Don has a good point: changing to "var" would cause conflict with
- Nils Hensel (15/17) Jul 25 2006 I'm sorry but I don't believe there are many programmers out there
- kris (8/32) Jul 25 2006 Well, it would have notable impact on existing code to change auto to
- Regan Heath (12/27) Jul 25 2006 I don't use "var" specifically but I have been known to use tmp, x, y, i...
- Nils Hensel (17/27) Jul 25 2006 I don't either as there will never be a one letter keyword. As for "tmp"...
- Don Clugston (3/34) Jul 26 2006 It does. When I use it, 'var' is not an abbreviation of 'variable', it's...
- Andrei Khropov (4/11) Jul 27 2006 Agreed ( it's also one letter shorter :-) )
- Don Clugston (16/32) Jul 25 2006 Maybe my first impression of the google search yourself -- the data is
- Nils Hensel (24/52) Jul 27 2006 I guess there are regular "var" users then but when I said "programmers"
- Don Clugston (25/75) Jul 27 2006 No, the idea is *not* to have a type inference keyword, but instead only...
- Nils Hensel (19/50) Jul 28 2006 I agree on that. "const x = 5;" is expressive enough in its own way. But...
- Sean Kelly (9/23) Jul 28 2006 So long as the storage class is required, I'm all for it. This seems
- Regan Heath (15/41) Jul 25 2006 I say lets keep 'auto' for auto type inference (for the reasons you and ...
- Chad J (24/92) Jul 25 2006 I disagree.
- Regan Heath (36/112) Jul 25 2006 You miss-understand. I don't want stack allocation at all. I'm saying 2 ...
- Chris Miller (7/8) Jul 25 2006 Except when it doesn't. I'm talking about overloaded 'new'
- Regan Heath (25/34) Jul 25 2006 You're describing 'placement' new, yes?
- Chris Miller (17/40) Jul 27 2006 =
- Sean Kelly (4/12) Jul 27 2006 This is placement new--the parameter to new specifies the location where...
- Chad J (49/201) Jul 26 2006 That's actually what I thought you meant, though I am probably creating
- Regan Heath (88/194) Jul 26 2006 I've already said.. I think it's intuitive because it 'looks' like a cla...
- Chad J (136/333) Jul 28 2006 ...
- Regan Heath (86/370) Jul 28 2006 Err.. oops.. my example was in fact assuming the new "omit 'new'" syntax...
- Chad J (31/404) Aug 02 2006 When reading other people's code, I find that most often I don't know or...
- Regan Heath (33/64) Aug 02 2006 True.. however not being a C++ programmer "on a daily basis" I can't say...
- Bruno Medeiros (23/36) Jul 29 2006 Uh, scopes and stack "frames" do not exist only for function frames.
- Chad J (2/45) Aug 02 2006 Ah. Thanks for the info.
- Bruno Medeiros (8/16) Jul 29 2006 Are you saying it is intuitive because *it is the same syntax as C++* ??...
- Regan Heath (30/42) Jul 31 2006 I was in fact wrong about the syntax being the same.
- xs0 (17/33) Jul 26 2006 Why would you want to deal with where the object is allocated? Besides
- Regan Heath (16/42) Jul 26 2006 My post _must_ have been missleading (more than one person thinks I want...
- Tommie Gannert (4/14) Jul 26 2006 I haven't been following this, but static opCall sounds an awful lot
- Sean Kelly (5/18) Jul 27 2006 Support for static operator functions can be useful for refactoring code...
- xs0 (18/58) Jul 27 2006 'new' doesn't imply/require that heap allocation actually be done, it
- Regan Heath (11/65) Jul 27 2006 Exactly. I never suggested otherwise :)
- xs0 (32/85) Jul 28 2006 You did - you propose that using "new" forces the allocation on the
- Regan Heath (33/116) Jul 31 2006 I'm arguing semantics perhaps but all I did was say that it 'implied' he...
- Bruno Medeiros (15/71) Jul 29 2006 I don't like the no-allocator-keyword proposal. There are the problems:
- Regan Heath (4/10) Jul 31 2006 Good point. That's a big problem.
- Chris Miller (14/40) Jul 25 2006 I vote for banana!
- Jarrett Billingsley (5/8) Jul 27 2006 banana++
- Bruno Medeiros (5/11) Jul 29 2006 No!! I often use banana as an identifier in many of my programs! :P
- Hasan Aljudy (3/42) Jul 26 2006 vote++;
- John Reimer (7/9) Jul 27 2006 I am sympathetic to the "scope" suggestion also. People have to remembe...
- Sean Kelly (10/21) Jul 27 2006 Given the suggested placement, I assume it would be illegal to reassign
- Kirk McDonald (26/55) Jul 27 2006 Maybe we could decide that based on the keyword's placement:
- Chris Nicholson-Sauls (11/38) Jul 28 2006 Sounds reasonable to me, and potentially quite useful (even if often pri...
- Juan Jose Comellas (3/36) Jul 27 2006 I think "local" may be a better name. At least I don't think I have ever
- Andrew Fedoniouk (19/26) Jul 27 2006 Conceptually 'auto' as a scope variable indicator is redundant.
- Kirk McDonald (14/25) Jul 27 2006 I've argued in the past about being able to elide the 'new' keyword
- Andrei Khropov (19/46) Jul 27 2006 Looks ok to me, but should be in the reverse order I think:
- kris (20/73) Jul 28 2006 Someone noted that
- Andrei Khropov (13/26) Jul 28 2006 Yes, that's an essential flaw in this proposal.
-
Andrei Khropov
(34/34)
Jul 28 2006
- Bruno Medeiros (24/52) Jul 29 2006 Up to now, I favored the following keyword proposals:
Don has a good point: changing to "var" would cause conflict with existing variable-names. Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature. I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; } class Foo {} class Bar {} scope class Wumpus {}
Jul 25 2006
kris schrieb:Don has a good point: changing to "var" would cause conflict with existing variable-names.I'm sorry but I don't believe there are many programmers out there actually using something as undescriptive as "var" as a regular identifier. I also strongly believe that no one should. It's the implication of a maintenance nightmare. I don't intend to insult Don in any way but it's a horrible practice IMNSHO that should not be preserved. So let's not focus on some odd minority but rather on the wide use of "var" in the context of type inference and dynamic typing. Also I don't think that it's a good habit to be looking at how C++ does something unless one is looking for a bad example. My main reason for interest in D is because personally I'm fed up with C++ and consider it an abomination and a major PITA. Just my 0.02 EUROs, Nils
Jul 25 2006
Nils Hensel wrote:kris schrieb:Well, it would have notable impact on existing code to change auto to var. They're at least equally clear in my view, so it would come down to a question of impact upon existing code. What's more important is the clarification of what "auto" means. Right now, it's somewhat confused (with raii). If we instead use "scope" to indicate raii, that confusion just goes away. Besides, "scope" is a fine attribute for things that are "scoped" :)Don has a good point: changing to "var" would cause conflict with existing variable-names.I'm sorry but I don't believe there are many programmers out there actually using something as undescriptive as "var" as a regular identifier. I also strongly believe that no one should. It's the implication of a maintenance nightmare. I don't intend to insult Don in any way but it's a horrible practice IMNSHO that should not be preserved. So let's not focus on some odd minority but rather on the wide use of "var" in the context of type inference and dynamic typing. Also I don't think that it's a good habit to be looking at how C++ does something unless one is looking for a bad example. My main reason for interest in D is because personally I'm fed up with C++ and consider it an abomination and a major PITA. Just my 0.02 EUROs, Nils
Jul 25 2006
On Tue, 25 Jul 2006 20:14:52 +0200, Nils Hensel <nils.hensel web.de> wrote:kris schrieb:I don't use "var" specifically but I have been known to use tmp, x, y, i, j, p, s, n, .. for all my temporary and/or meaningless variables. They typically have a short scope life and I can't see a problem with this practice.Don has a good point: changing to "var" would cause conflict with existing variable-names.I'm sorry but I don't believe there are many programmers out there actually using something as undescriptive as "var" as a regular identifier. I also strongly believe that no one should. It's the implication of a maintenance nightmare. I don't intend to insult Don in any way but it's a horrible practice IMNSHO that should not be preserved.So let's not focus on some odd minority but rather on the wide use of "var" in the context of type inference and dynamic typing.I think Kris's point is that of the two choices 'var' and 'auto' the latter is less likely to annoy someone by colliding with existing user variables. The point is valid so long as the group of 'var' users is bigger than the group of 'auto' users, even if both groups are small.Also I don't think that it's a good habit to be looking at how C++ does something unless one is looking for a bad example. My main reason for interest in D is because personally I'm fed up with C++ and consider it an abomination and a major PITA.C++ may be an abomination but it does have 'market' dominance. You have to ask 'why'. You should learn from your 'enemies' ;) Regan
Jul 25 2006
Regan Heath schrieb:I don't use "var" specifically but I have been known to use tmp, x, y, i, j, p, s, n, .. for all my temporary and/or meaningless variables. They typically have a short scope life and I can't see a problem with this practice.I don't either as there will never be a one letter keyword. As for "tmp" it is a lot more descriptive than "var". Not all variables are holding temporary values but all are "variable" as their name already implies. Even i(=index) or n(=number of) bear a meaning in a mathematical context. I'm not all against short variable names (though I try to usually be more expressive) but their name should hint at their content or use. "var" doesn't hint at anything.I think Kris's point is that of the two choices 'var' and 'auto' the latter is less likely to annoy someone by colliding with existing user variables. The point is valid so long as the group of 'var' users is bigger than the group of 'auto' users, even if both groups are small.One should also consider future users of D since we haven't even reached 1.0 yet. Since no one else already uses "auto" for this purpose but a lot of languages use "var" I believe it to be the more intuitive option.C++ may be an abomination but it does have 'market' dominance. You have to ask 'why'. You should learn from your 'enemies' ;)But those reasons are mainly historical and may be summed up by "it's the least of all evils". This does not even hold true anymore. At least not when you look at language constructs and elegance. It's clearly "grown" not designed. Regards, Nils
Jul 25 2006
Nils Hensel wrote:Regan Heath schrieb:It does. When I use it, 'var' is not an abbreviation of 'variable', it's an abbreviation of 'variant'.I don't use "var" specifically but I have been known to use tmp, x, y, i, j, p, s, n, .. for all my temporary and/or meaningless variables. They typically have a short scope life and I can't see a problem with this practice.I don't either as there will never be a one letter keyword. As for "tmp" it is a lot more descriptive than "var". Not all variables are holding temporary values but all are "variable" as their name already implies. Even i(=index) or n(=number of) bear a meaning in a mathematical context. I'm not all against short variable names (though I try to usually be more expressive) but their name should hint at their content or use. "var" doesn't hint at anything.I think Kris's point is that of the two choices 'var' and 'auto' the latter is less likely to annoy someone by colliding with existing user variables. The point is valid so long as the group of 'var' users is bigger than the group of 'auto' users, even if both groups are small.One should also consider future users of D since we haven't even reached 1.0 yet. Since no one else already uses "auto" for this purpose but a lot of languages use "var" I believe it to be the more intuitive option.C++ may be an abomination but it does have 'market' dominance. You have to ask 'why'. You should learn from your 'enemies' ;)But those reasons are mainly historical and may be summed up by "it's the least of all evils". This does not even hold true anymore. At least not when you look at language constructs and elegance. It's clearly "grown" not designed. Regards, Nils
Jul 26 2006
Nils Hensel wrote:Agreed ( it's also one letter shorter :-) ) -- AKhropovI think Kris's point is that of the two choices 'var' and 'auto' the latter is less likely to annoy someone by colliding with existing user variables. The point is valid so long as the group of 'var' users is bigger than the group of 'auto' users, even if both groups are small.One should also consider future users of D since we haven't even reached 1.0 yet. Since no one else already uses "auto" for this purpose but a lot of languages use "var" I believe it to be the more intuitive option.
Jul 27 2006
Nils Hensel wrote:kris schrieb:Maybe my first impression of the google search yourself -- the data is there. I also strongly believe that no one should. It's theDon has a good point: changing to "var" would cause conflict with existing variable-names.I'm sorry but I don't believe there are many programmers out there actually using something as undescriptive as "var" as a regular identifier.implication of a maintenance nightmare.I don't intend to insult Don in any way but it's a horrible practice IMNSHO that should not be preserved.I don't understand. I can't see the difference between 'var' and 'x'. Do you also dislike use of 'i' as a counter variable in a for loop? (And if not, what is the difference?)So let's not focus on some odd minority but rather on the wide use of "var" in the context of type inference and dynamic typing.'var' is inappropriate in a statically typed language. Remember that 'static's are variables too. Note that 'auto' was one of the original C keywords, and was chosen without any constraint (no legacy code whatsoever, they could have chosen any name, including 'var'). Every variable was classed into either: static auto registerAlso I don't think that it's a good habit to be looking at how C++ does something unless one is looking for a bad example. My main reason for interest in D is because personally I'm fed up with C++ and consider it an abomination and a major PITA.Agreed, but the 'auto' thing ultimately comes from C, not C++.
Jul 25 2006
Don Clugston schrieb:Nils Hensel wrote:I guess there are regular "var" users then but when I said "programmers" I was thinking of professionals used to the idiosyncrasies of medium to large software projects, where you're often faced with working on and maintaining someone elses code. I guess if the best description of a variable's intended meaning this somebody could come up with was "var" I'd be pretty pissed pretty soon.I'm sorry but I don't believe there are many programmers out there actually using something as undescriptive as "var" as a regular identifier.Maybe my first impression of the google search yourself -- the data is there.'x' and 'i' are often used in mathematical formulas and contexts so they already bear a meaning even if they look indescriptive. OTOH if someone uses 'i' as a string or a boolean variable I WOULD consider it a bad practice as well.I don't intend to insult Don in any way but it's a horrible practice IMNSHO that should not be preserved.I don't understand. I can't see the difference between 'var' and 'x'. Do you also dislike use of 'i' as a counter variable in a for loop? (And if not, what is the difference?)'var' is inappropriate in a statically typed language. Remember that 'static's are variables too. Note that 'auto' was one of the original C keywords, and was chosen without any constraint (no legacy code whatsoever, they could have chosen any name, including 'var'). Every variable was classed into either: static auto registerTo be frank I don't get your point here. "static", "auto" and "register" are storage classes in these contexts (as they are originally in D). C has no concept of type inference. "auto" just means that the memory management for these variables is dealt with automatically because these variables exist on the stack. D just uses the fact that "auto" signifies the declaration of a variable which allows the compiler to identify the type automatically through the initializing value. The same holds true for "static" and "const". So actually D doesn't have an explicit type inference keyword yet.Yes, but not in the context of type inference. So the C "auto" is totally different from it's current D counterpart. Regards, NilsAlso I don't think that it's a good habit to be looking at how C++ does something unless one is looking for a bad example. My main reason for interest in D is because personally I'm fed up with C++ and consider it an abomination and a major PITA.Agreed, but the 'auto' thing ultimately comes from C, not C++.
Jul 27 2006
Nils Hensel wrote:Don Clugston schrieb:They're normally in trivial one-line functions.Nils Hensel wrote:I guess there are regular "var" users then but when I said "programmers" I was thinking of professionals used to the idiosyncrasies of medium to large software projects, where you're often faced with working on and maintaining someone elses code. I guess if the best description of a variable's intended meaning this somebody could come up with was "var" I'd be pretty pissed pretty soon.I'm sorry but I don't believe there are many programmers out there actually using something as undescriptive as "var" as a regular identifier.Maybe my first impression of the google search yourself -- the data is there.'x' and 'i' are often used in mathematical formulas and contexts so they already bear a meaning even if they look indescriptive. OTOH if someone uses 'i' as a string or a boolean variable I WOULD consider it a bad practice as well.I don't intend to insult Don in any way but it's a horrible practice IMNSHO that should not be preserved.I don't understand. I can't see the difference between 'var' and 'x'. Do you also dislike use of 'i' as a counter variable in a for loop? (And if not, what is the difference?)'var' is inappropriate in a statically typed language. Remember that 'static's are variables too. Note that 'auto' was one of the original C keywords, and was chosen without any constraint (no legacy code whatsoever, they could have chosen any name, including 'var'). Every variable was classed into either: static auto registerTo be frank I don't get your point here. "static", "auto" and "register" are storage classes in these contexts (as they are originally in D). C has no concept of type inference. "auto" just means that the memory management for these variables is dealt with automatically because these variables exist on the stack.D just uses the fact that "auto" signifies the declaration of a variable which allows the compiler to identify the type automatically through the initializing value. The same holds true for "static" and "const". So actually D doesn't have an explicit type inference keyword yet.No, the idea is *not* to have a type inference keyword, but instead only specify the storage class: static a = 7; const b = 7; auto c = 7; Now 'a' is a variable, just as much 'c' is. Are you proposing that you'd have to type: static var x = func(7); ? Surely not. 'const var' would be an abomination! The problem is, there's no storage class for local variables. In C/C++, there is, and it's called 'auto', but it's extremely rarely used in normal code. 'local' is perhaps the most natural name. I just don't like the idea that 'var' would mean "local non-static variable". "Variable" is a much broader category than "local variable". I hope that one day D also gets explicit thread-local variables. They would need a seperate storage class.No, it's not. It's a storage class in C++, *not* a type inference keyword. It's just that it's a storage class that in modern times is only used in the context of type inference. I think 'var' makes much more sense for dynamically typed languages. inference of constants?Yes, but not in the context of type inference. So the C "auto" is totally different from it's current D counterpart.Also I don't think that it's a good habit to be looking at how C++ does something unless one is looking for a bad example. My main reason for interest in D is because personally I'm fed up with C++ and consider it an abomination and a major PITA.Agreed, but the 'auto' thing ultimately comes from C, not C++.
Jul 27 2006
Don Clugston schrieb:No, the idea is *not* to have a type inference keyword, but instead only specify the storage class: static a = 7; const b = 7; auto c = 7; Now 'a' is a variable, just as much 'c' is. Are you proposing that you'd have to type: static var x = func(7);Actually yes. I find it to be clearer than just static x.? Surely not. 'const var' would be an abomination!I agree on that. "const x = 5;" is expressive enough in its own way. But I never said variables and constants should be treated the same.The problem is, there's no storage class for local variables. In C/C++, there is, and it's called 'auto', but it's extremely rarely used in normal code. 'local' is perhaps the most natural name.Also agreed. I find "local" much better than "auto". But I'm afraid we have to carry this ugly legacy. The unexpressiveness of "auto" might be my whole problem with type inference as it is. Using storage classes for detection is a rather clever idea.I just don't like the idea that 'var' would mean "local non-static variable". "Variable" is a much broader category than "local variable".You have a point. But it is definitely the most often used type and what I believe most people think of when they hear "variable".I hope that one day D also gets explicit thread-local variables. They would need a seperate storage class.Sounds good to me.I think that's the same ugly legacy. I think D should drop things that are better expressed in a different way.No, it's not. It's a storage class in C++, *not* a type inference keyword. It's just that it's a storage class that in modern times is only used in the context of type inference.Agreed, but the 'auto' thing ultimately comes from C, not C++.Yes, but not in the context of type inference. So the C "auto" is totally different from it's current D counterpart.I think 'var' makes much more sense for dynamically typed languages. inference of constants?Good question. But my guess is that for variables it's something like what you described above and that "const" does not get a "var". But it's just a guess. Regards, Nils
Jul 28 2006
Don Clugston wrote:No, the idea is *not* to have a type inference keyword, but instead only specify the storage class: static a = 7; const b = 7; auto c = 7; Now 'a' is a variable, just as much 'c' is.So long as the storage class is required, I'm all for it. This seems more consistent than what we have now.I hope that one day D also gets explicit thread-local variables. They would need a seperate storage class.I proposed this a while back and no one responded, so I went and added thread-local storage to Ares. But it would be much nicer to have this as a language feature.No, it's not. It's a storage class in C++, *not* a type inference keyword. It's just that it's a storage class that in modern times is only used in the context of type inference.The things you learn. I don't think I've ever seen 'auto' used in a C or C++ program, though I've come across 'register' quite a bit. Sean
Jul 28 2006
On Tue, 25 Jul 2006 10:17:13 -0700, kris <foo bar.com> wrote:Don has a good point: changing to "var" would cause conflict with existing variable-names. Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature. I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; } class Foo {} class Bar {} scope class Wumpus {}I say lets keep 'auto' for auto type inference (for the reasons you and Don mention) I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes. I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful. Regan
Jul 25 2006
Regan Heath wrote:I say lets keep 'auto' for auto type inference (for the reasons you and Don mention) I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.I disagree. If you want the compiler to be able to optimize by using stack allocation instead of heap allocation, then let it do that with the new keyword. I'm assuming the program's behaviour would be the same in either case, so it wouldn't matter to me. If you want stack allocation then how about scope A a = A(); It keeps the concepts of scope and allocation seperate. Scope is not allocation. For instance, if the function is inlined then something allocated on the stack should live longer than the scope of the function. The only exceptions I can think of are if the compiler forbids inlining of such functions (possibly inefficient) or there is a scope guarantee, in which case you want scope AND stack alloc. Or maybe I just don't understand inlining (hope not!).I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful. ReganPlease don't abolish/remove it. At least not until you have convinced me that it is totally useless. I really don't like the idea of dropping a language feature just for the sake of having a particular syntax that, IMO, is not intuitive. As I said in the 1.0 thread, A a = A(); looks to me like anything but a scoped instanciation; I'd rather have a keyword (like scope) to indicate what it is in an explicit way. From my previous post about this:I like being able to use types as functions. Here's one example where I do something similar to what you'd use nested functions for, but better - my forward referencing woes go away. class F { int result; int tempVar1; static int opCall( int x ) { F f = new F(x); int result = f.result; delete f; return result; } this( int x ) { internalFunc1(); // do stuff } private void internalFunc1() { if ( maybe ) internalFunc2(); else return; } private void internalFunc2() { if ( maybe ) internalFunc1(); else return; } } void main() { int x = 42; x = F(x); } Under the hood, it may also behave differently than nested functions, which could be advantageous. I'm not sure that it is advantageous, but options are always nice. That and you can make nice syntax sugars for alternative memory management methods like freelists, without messing with overriding 'new()'.I do like using the scope keyword for this btw. It seems quite consistant with D's meaning of 'scope'.
Jul 25 2006
On Tue, 25 Jul 2006 23:28:24 -0400, Chad J <gamerChad _spamIsBad_gmail.com> wrote:Regan Heath wrote:You miss-understand. I don't want stack allocation at all. I'm saying 2 things: 1. 'new' implies heap allocation 2. lack of 'new' implies _nothing_ about allocation. The result of which is that the compiler is not _required_ to heap allocate but can allocate in some other fashion.I say lets keep 'auto' for auto type inference (for the reasons you and Don mention) I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.I disagree. If you want the compiler to be able to optimize by using stack allocation instead of heap allocation, then let it do that with the new keyword.I'm assuming the program's behaviour would be the same in either case, so it wouldn't matter to me. If you want stack allocation then how about scope A a = A(); It keeps the concepts of scope and allocation seperate.It's no different to this: A a = A(); which says _nothing_ about allocation. It implies only that 'a' will be collected at the end of scope. The compiler is FREE to allocate however it wants. That _may_ be stack allocation, it _may_ not. In comparison this: A a = new A(); currently 'implies' heap allocation. That's all I was saying. I'm not suggesting stack allocation, I'm suggesting that removing 'new' allows the compiler to allocate however it wants. You're suggesting 'new' could allocate on the stack, I think that would be unexpected to say the least.Scope is not allocation.Correct. I never said it was. The ability to stack allocate is a by product of removing 'new' nothing else.Convince you.. I don't have to convince you, only Walter. Likewise you have to convince Walter. ;0)I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful. ReganPlease don't abolish/remove it. At least not until you have convinced me that it is totally useless.I really don't like the idea of dropping a language feature just for the sake of having a particular syntax that, IMO, is not intuitive.It's the same syntax you see in C++ for a class that has it's destructor called at the end of the scope. That, to me, makes it intuitive. For what reason do you find it un-intuitive?From my previous post about this:What's the point of using static opCall here, as opposed to a normal static method or even a free function? What problem does it solve? What new technique or method does it allow?I like being able to use types as functions. Here's one example where I do something similar to what you'd use nested functions for, but better - my forward referencing woes go away. class F { int result; int tempVar1; static int opCall( int x ) { F f = new F(x); int result = f.result; delete f; return result; } this( int x ) { internalFunc1(); // do stuff } private void internalFunc1() { if ( maybe ) internalFunc2(); else return; } private void internalFunc2() { if ( maybe ) internalFunc1(); else return; } } void main() { int x = 42; x = F(x); } Under the hood, it may also behave differently than nested functions, which could be advantageous. I'm not sure that it is advantageous, but options are always nice. That and you can make nice syntax sugars for alternative memory management methods like freelists, without messing with overriding 'new()'.I do like using the scope keyword for this btw. It seems quite consistant with D's meaning of 'scope'.It's not bad but it's my 2nd choice currently. Regan
Jul 25 2006
On Wed, 26 Jul 2006 00:13:53 -0400, Regan Heath <regan netwin.co.nz> wrote:1. 'new' implies heap allocationExcept when it doesn't. I'm talking about overloaded 'new' If Object`s were given 2 default new() implmentations, one that does the current allocation, and another that allows you to specify a buffer (also so that every Joe who wants this doesn't have to derive from the class to provide it). When RAII is involved, it can choose which version of new() to use (implementaion defined), using stack or not.
Jul 25 2006
On Wed, 26 Jul 2006 00:23:41 -0400, Chris Miller <chris dprogramming.com> wrote:On Wed, 26 Jul 2006 00:13:53 -0400, Regan Heath <regan netwin.co.nz> wrote:You're describing 'placement' new, yes? http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=160&rl=1 I dont think D has placement new, at least not a syntax for it like C++. I could be wrong. You're right in that if D were to get placement new using the C++ syntax then the suggested RAII syntax (removing 'new') would make it impossible to declare an RAII class using placement new. But, it appears that placement new in D is done with a custom allocator and not a special syntax? http://www.digitalmars.com/d/memory.html#newdelete You coud write a custom allocator which would calculate offsets into pre-allocated memory returning that address for each allocation. Essentially placement new without the special syntax. Has this topic come up before? What was Walters comment on it? I don't recall a discussion on it, I did a quick search and didn't turn up anything specific. I wonder, does placement new in D have the same restrictions as in C++? i.e. cannot use stack memory, requires explicit 'delete'. I wonder what constraints the RAII implementation in D puts on how objects are allocated. It's possible they can't be allocated on the stack .. I seem to recall Walter saying he'd like to go there, eventually, but I might be imagining things. Regan1. 'new' implies heap allocationExcept when it doesn't. I'm talking about overloaded 'new' If Object`s were given 2 default new() implmentations, one that does the current allocation, and another that allows you to specify a buffer (also so that every Joe who wants this doesn't have to derive from the class to provide it). When RAII is involved, it can choose which version of new() to use (implementaion defined), using stack or not.
Jul 25 2006
On Wed, 26 Jul 2006 01:23:53 -0400, Regan Heath <regan netwin.co.nz> wro= te:On Wed, 26 Jul 2006 00:23:41 -0400, Chris Miller =<chris dprogramming.com> wrote:=On Wed, 26 Jul 2006 00:13:53 -0400, Regan Heath <regan netwin.co.nz> ==wrote:1. 'new' implies heap allocationExcept when it doesn't. I'm talking about overloaded 'new' If Object`s were given 2 default new() implmentations, one that does =er =the current allocation, and another that allows you to specify a buff=e =(also so that every Joe who wants this doesn't have to derive from th=class to provide it). When RAII is involved, it can choose which =rl=3D1version of new() to use (implementaion defined), using stack or not.You're describing 'placement' new, yes? http://www.informit.com/guides/content.asp?g=3Dcplusplus&seqNum=3D160&=I dont think D has placement new, at least not a syntax for it like C+=+. =I could be wrong. You're right in that if D were to get placement new using the C++ synt=ax =then the suggested RAII syntax (removing 'new') would make it impossib=le =to declare an RAII class using placement new. But, it appears that =placement new in D is done with a custom allocator and not a special =syntax? http://www.digitalmars.com/d/memory.html#newdeleteI hadn't thought of 'placement' new but this page is what I was referrin= g = to. Scroll down to "Allocating Class Instances On The Stack" to see what= I = meant. Different uses of 'new' (RAII/regular) could call different new()= s, = which doesn't imply heap.
Jul 27 2006
Chris Miller wrote:On Wed, 26 Jul 2006 01:23:53 -0400, Regan Heath <regan netwin.co.nz> wrote:This is placement new--the parameter to new specifies the location where the object will be constructed. Seanhttp://www.digitalmars.com/d/memory.html#newdeleteI hadn't thought of 'placement' new but this page is what I was referring to. Scroll down to "Allocating Class Instances On The Stack" to see what I meant. Different uses of 'new' (RAII/regular) could call different new()s, which doesn't imply heap.
Jul 27 2006
Regan Heath wrote:On Tue, 25 Jul 2006 23:28:24 -0400, Chad J <gamerChad _spamIsBad_gmail.com> wrote:That's actually what I thought you meant, though I am probably creating a false dichotomy - stack vs heap.Regan Heath wrote:You miss-understand. I don't want stack allocation at all. I'm saying 2 things: 1. 'new' implies heap allocation 2. lack of 'new' implies _nothing_ about allocation. The result of which is that the compiler is not _required_ to heap allocate but can allocate in some other fashion.I say lets keep 'auto' for auto type inference (for the reasons you and Don mention) I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.I disagree. If you want the compiler to be able to optimize by using stack allocation instead of heap allocation, then let it do that with the new keyword.I did intend to convey that the 'new' keyword could have this ambiguity, but under one condition - that it not change the behaviour of the program. If you need something more hardcore than that, something that causes undefined behaviour, I ask that it not be at the expense of current features.I'm assuming the program's behaviour would be the same in either case, so it wouldn't matter to me. If you want stack allocation then how about scope A a = A(); It keeps the concepts of scope and allocation seperate.It's no different to this: A a = A(); which says _nothing_ about allocation. It implies only that 'a' will be collected at the end of scope. The compiler is FREE to allocate however it wants. That _may_ be stack allocation, it _may_ not. In comparison this: A a = new A(); currently 'implies' heap allocation. That's all I was saying. I'm not suggesting stack allocation, I'm suggesting that removing 'new' allows the compiler to allocate however it wants. You're suggesting 'new' could allocate on the stack, I think that would be unexpected to say the least.True, you are not required to convince me of anything. It was a request. You seem to have some good reasons for prefering this syntax, so please enlighten me. It's kind of a helpfulness thing; saves me some grief from having a feature removed that I like. If I agree with you, there is no grief, only joy :).Scope is not allocation.Correct. I never said it was. The ability to stack allocate is a by product of removing 'new' nothing else.Convince you.. I don't have to convince you, only Walter. Likewise you have to convince Walter. ;0)I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful. ReganPlease don't abolish/remove it. At least not until you have convinced me that it is totally useless.though, and most of my experiences with it have been frustrating bad ones. Anyhow, before I go on that tangent, not everyone is a C++ programmer. I say it's unintuitive because it is implicit - it provides no explicit information to the reader. Since the absence of anything explicit gives no information, you might as well use the keyword asdfqwertok. Even that gives more information than a blank space. For a D newbie reading code, having a keyword is good because it gives them a keyword to search the spec for. Better yet if it is 'scope', because that gives them an idea of where to look. This is also one of those things that is used seldom enough that the succinctness gained from implicit things is only slightly helpful. In a nutshell: assume a programmer of undefined language background, and I believe 'scope' will be much more informative (and therefore intuitive) than a blank space.I really don't like the idea of dropping a language feature just for the sake of having a particular syntax that, IMO, is not intuitive.It's the same syntax you see in C++ for a class that has it's destructor called at the end of the scope. That, to me, makes it intuitive. For what reason do you find it un-intuitive?Why not a normal static method? - implementation hiding. Why not a free function? - I'm assuming you mean a normal function declared at module scope. It allows you to have multiple functions with access to the same non-static variables (member variables). I suppose this is usually accomplished with nested functions, or OOP that can't do implementation hiding. Doing it this way allows me to avoid forward referencing issues and also gives me more options about how my code behaves.From my previous post about this:What's the point of using static opCall here, as opposed to a normal static method or even a free function?I like being able to use types as functions. Here's one example where I do something similar to what you'd use nested functions for, but better - my forward referencing woes go away. class F { int result; int tempVar1; static int opCall( int x ) { F f = new F(x); int result = f.result; delete f; return result; } this( int x ) { internalFunc1(); // do stuff } private void internalFunc1() { if ( maybe ) internalFunc2(); else return; } private void internalFunc2() { if ( maybe ) internalFunc1(); else return; } } void main() { int x = 42; x = F(x); } Under the hood, it may also behave differently than nested functions, which could be advantageous. I'm not sure that it is advantageous, but options are always nice. That and you can make nice syntax sugars for alternative memory management methods like freelists, without messing with overriding 'new()'.What problem does it solve?Annoyance from forward referencing in nested functions, but that's just one. Maybe a small degree of implementation hiding for memory management, though I haven't tried this enough to demonstrate it. It is not really a solution. It is a technique, a syntax sugar, or just an easy way to get D to do things you would not ordinarily make it do.What new technique or method does it allow?Multiple functions using the same non-static variables with no need for forward referencing and possible code behaviour tweaks, etc yadda yadda. I admit it's not horribly important, but I don't think that this choice of syntax is either. Most of all, I like it. *sigh* those were long winded answers, sorry about that.Care to explain why static opCall is a hack and/or not useful outside of RAII or struct constructors?I do like using the scope keyword for this btw. It seems quite consistant with D's meaning of 'scope'.It's not bad but it's my 2nd choice currently. Regan
Jul 26 2006
I've already said.. I think it's intuitive because it 'looks' like a class declared on the stack, as in C++ and like those it will be destroyed at the end of scope. Your counter argument is that not everyone is a C++ programmer, correct? In which case, read on..True, you are not required to convince me of anything. It was a request. You seem to have some good reasons for prefering this syntax, so please enlighten me.Please don't abolish/remove it. At least not until you have convinced me that it is totally useless.Convince you.. I don't have to convince you, only Walter. Likewise you have to convince Walter. ;0)I come from a C background. I have done a little C++, a little Java andthough, and most of my experiences with it have been frustrating bad ones. Anyhow, before I go on that tangent, not everyone is a C++ programmer.I really don't like the idea of dropping a language feature just for the sake of having a particular syntax that, IMO, is not intuitive.It's the same syntax you see in C++ for a class that has it's destructor called at the end of the scope. That, to me, makes it intuitive. For what reason do you find it un-intuitive?I say it's unintuitive because it is implicit - it provides no explicit information to the reader. Since the absence of anything explicit gives no information, you might as well use the keyword asdfqwertok. Even that gives more information than a blank space.The absence of 'new' gives us the required information. You are required to know what the absense of 'new' _means_ just like you are required to know what keyword X means in any given context. In short, some knowledge of programming in D is required to program in D. To expand on why I think it's intuitive let look at 2 scenarios, first the C++ programmer trying D. Likely their first program involving classes will look like this: class A { int a; } void main() { A a = A(); writefln(a.a); } currently, this crashes with an access violation. Add the new RAII syntax and not only does it not crash, but it behaves just like a C++ program would with A being destroyed at the end of scope. class A { int a; } void main() { A a = new A(); writefln(a.a); } No crash, and the behaviour they expect. Then imagine the same programmers looking at each others code, the C++ programmer will understand 'new' to indicate heap allocation and the 'new' means, he'll reply that the class is destroyed at the end of scope. He might also say it's stack allocated, but that's fine, both of them have something to learn, and it has no effect on the way the program behaves. Simple, intuitive and elegant no matter what your background. Of course, 'new' means. Both have to learn that D might not stack allocate the RAII class instance. If we use a 'scope' keyword then both sets of programmers have some learning to do. It's not much worse, but this makes it my 2nd choice.For a D newbie reading code, having a keyword is good because it gives them a keyword to search the spec for. Better yet if it is 'scope', because that gives them an idea of where to look. This is also one of those things that is used seldom enough that the succinctness gained from implicit things is only slightly helpful.The C++ programmer will already know what it does. The Java/C++ programmer will search for 'new' (because it's absent). In either case they'll find the docs on RAII at the same time as they find the docs on 'new'.In a nutshell: assume a programmer of undefined language background, and I believe 'scope' will be much more informative (and therefore intuitive) than a blank space.I've assumed programmers from 2 types of background above, I still think removing 'new' is better than adding 'scope'.I'm assuming this defintion: http://en.wikipedia.org/wiki/Information_hiding I'm not sure I follow your logic, did you mean "encapsulation" instead? If you did mean "information hiding" then it seems to me that using opCall is a design decision, just as using a method called "Bob" would be. The advantage to using "Bob" is that you can define an 'stable' interface eg. interface MyImplementation { int Bob(int x); } and in that way protect your code against changes in implementation. In short, this is a better "information hiding" solution than using static opCall.Why not a normal static method? - implementation hiding.From my previous post about this:What's the point of using static opCall here, as opposed to a normal static method or even a free function?I like being able to use types as functions. Here's one example where I do something similar to what you'd use nested functions for, but better - my forward referencing woes go away. class F { int result; int tempVar1; static int opCall( int x ) { F f = new F(x); int result = f.result; delete f; return result; } this( int x ) { internalFunc1(); // do stuff } private void internalFunc1() { if ( maybe ) internalFunc2(); else return; } private void internalFunc2() { if ( maybe ) internalFunc1(); else return; } } void main() { int x = 42; x = F(x); } Under the hood, it may also behave differently than nested functions, which could be advantageous. I'm not sure that it is advantageous, but options are always nice. That and you can make nice syntax sugars for alternative memory management methods like freelists, without messing with overriding 'new()'.Why not a free function? - I'm assuming you mean a normal function declared at module scope.Yes.It allows you to have multiple functions with access to the same non-static variables (member variables).What does? _static_ opCall does *not* have access to non-static variables, it can only access static variables. Static methods and variables are very similar to module level variables. The difference being how to access them (class name prefix) and where they are declared (inside the class instead of at module level). You can replace static methods and variables with module level ones quite easily.I suppose this is usually accomplished with nested functions, or OOP that can't do implementation hiding.I'm obviously not following your point here.. can you elaborate, perhaps another example?Doing it this way allows me to avoid forward referencing issuesWhat forward referencing issues does the code above have?and also gives me more options about how my code behaves.What options? example?So far: - I'm not seeing the forward reference issue(s) - It seems like a worse way to implement information hiding (than an interface and method).What problem does it solve?Annoyance from forward referencing in nested functions, but that's just one. Maybe a small degree of implementation hiding for memory management, though I haven't tried this enough to demonstrate it. It is not really a solution. It is a technique, a syntax sugar, or just an easy way to get D to do things you would not ordinarily make it do.I *like* non-static opCall, I can see benefits to that. But, so far, static opCall seems to be fairly useless to me.What new technique or method does it allow?Multiple functions using the same non-static variables with no need for forward referencing and possible code behaviour tweaks, etc yadda yadda. I admit it's not horribly important, but I don't think that this choice of syntax is either. Most of all, I like it.*sigh* those were long winded answers, sorry about that.No worries. Long winded tends to imply more information and that's not a bad thing.I'm trying, by learning when, where and why you use it. I can't think of a place where _I_ would use it (which is why I think it's not useful). It's only a 'hack' when used with a struct to emulate a constructor. Strangely that 'hack' is the only vaguely good use I've seen for a *static* opCall. ReganCare to explain why static opCall is a hack and/or not useful outside of RAII or struct constructors?I do like using the scope keyword for this btw. It seems quite consistant with D's meaning of 'scope'.It's not bad but it's my 2nd choice currently. Regan
Jul 26 2006
Regan Heath wrote:...I've already said.. I think it's intuitive because it 'looks' like a class declared on the stack, as in C++ and like those it will be destroyed at the end of scope. Your counter argument is that not everyone is a C++ programmer, correct? In which case, read on.....I come from a C background. I have done a little C++, a little Java and The absence of 'new' gives us the required information. You are required to know what the absense of 'new' _means_ just like you are required to know what keyword X means in any given context. In short, some knowledge of programming in D is required to program in D.I agree, the point is to make it easier to obtain that knowledge while learning.To expand on why I think it's intuitive let look at 2 scenarios, first the C++ programmer trying D. Likely their first program involving classes will look like this: class A { int a; } void main() { A a = A(); writefln(a.a); } currently, this crashes with an access violation.Actually, it doesn't compile. main.d(6): function expected before (), not A of type main.A main.d(6): cannot implicitly convert expression ((A)()) of type int to main.A Maybe not the best error messages for this case, but better than an access violation.Add the new RAII syntax and not only does it not crash, but it behaves just like a C++ program would with A being destroyed at the end of scope.I hear that such syntax, in C++, means that 'A' will be stack allocated, which AFAIK does not imply RAII. One example I can think of that would break RAII is if the function gets inlined, then the stack allocated object may not be deleted until some point outside of the scope's end. It will /probably/ be deleted at the end of the function that the enclosing function was inlined into. I could be wrong about that though. Also, does that C++ syntax allow class references to leak into code that is executed after the class is deleted?class A { int a; } void main() { A a = new A(); writefln(a.a); } No crash, and the behaviour they expect. Then imagine the same programmers looking at each others code, the C++ programmer will understand 'new' to indicate heap allocation and the of 'new' means, he'll reply that the class is destroyed at the end of scope. He might also say it's stack allocated, but that's fine, both of them have something to learn, and it has no effect on the way the program behaves.That learning process would be nice, but it assumes an extra programmer being around. As I learn D, I am alone. Either I go to the spec or I ask on the newsgroup. I'm not sure how many others are in the same situation. I've explained below why I still don't think it's very obvious, which means more potential newsgroup asking. That doesn't bug me too much though.Simple, intuitive and elegant no matter what your background. Of absense of 'new' means. Both have to learn that D might not stack allocate the RAII class instance. If we use a 'scope' keyword then both sets of programmers have some learning to do. It's not much worse, but this makes it my 2nd choice."Both have to learn that D might not stack allocate the RAII class instance." "If we use a 'scope' keyword then both sets of programmers have some learning to do." If they both have learning to do anyways, why not just have them learn 'scope'? I suppose it wouldn't be too bad otherwise, except for one problem: The unfortunate C++ programmer's program worked as expected. I say problem and unfortunate, because they may just assume that D behaves like C++ in all of the corner cases, and if I'm correct about the RAII vs stack alloc above, it may not.Searching for 'new' is a good idea. What if they don't think of that? The only reason I would associate the absence of 'new' with allocation is because of the talk from C++ programmers on this newsgroup. Otherwise it's some kind of wacky cool feature of D that they have not read about yet (as it is now!). This is why I prefer 'scope' - it would make scope, unambiguously, THE keyword to search for to find out what's going on.For a D newbie reading code, having a keyword is good because it gives them a keyword to search the spec for. Better yet if it is 'scope', because that gives them an idea of where to look. This is also one of those things that is used seldom enough that the succinctness gained from implicit things is only slightly helpful.The C++ programmer will already know what it does. The Java/C++ programmer will search for 'new' (because it's absent). In either case they'll find the docs on RAII at the same time as they find the docs on 'new'.That's fine as long as you clear up the two things: - What tells a non-C++ coder to look up 'new'? (besides another coder) - The possible assumption by a C++ coder that RAII syntax means stack allocation. (and subsequent whammy when they hit a pointy corner case) Proving that there are no corner cases in 'stack allocation implies RAII' or me being wrong about that meaning in C++ should clear up that second one.In a nutshell: assume a programmer of undefined language background, and I believe 'scope' will be much more informative (and therefore intuitive) than a blank space.I've assumed programmers from 2 types of background above, I still think removing 'new' is better than adding 'scope'.OK I think I have not explained my example very well. First I'll simplify my original example and try harder to explain. I've added comments this time. Here it is: import std.stdio; // class used as a function class f { int result; int tempVar1; // this is your non-static variable static int opCall( int x ) { // what do you know, not so 'static' after all! f instance = new f(x); int result = instance.result; // cleanup delete instance; return result; } this( int x ) { // If this were a function with nested functions, // then the main execution would occur here. result = x + internalFunc(); } // this is a non-static function int internalFunc() { return 314; } } void main() { int x = 42; x = f(x); writefln(x); } Now I'll rewrite it into a free function: import std.stdio; int f( int x ) { // Error! internalFunc is not defined. return x + internalFunc(); // oh but here it is... nested functions don't allow this int internalFunc() { return 314; } } void main() { int x = 42; x = f(x); writefln(x); } In a trivial case like this all you have to do is move the nested function internalFunc to the top. In other cases though, where you want to be able to places the functions where they intuitively belong, this becomes annoying. This is that forward referencing issue I was talking about. Also, if 'f' were derived from another class, then the code executed in f's constructor would have access to the super class's members. That's more to do with OOP, but it's all hidden behind a static opCall. I suppose you could use a module function to construct and delete a private class that gets used for it's own scope and inheritance. I worry that I am missing some detail that stopped me from just doing that before. Sean, perhaps you could share some of your uses for static opCall since I'm doing such a bad job at this? Only slightly related - I wonder if D's 'new' even implies heap allocation as it is. That might just be a dmd thing, but I am looking in the spec at Classes -> ctors/dtors, and it doesn't say where they get allocated. Maybe someone who is good at searching the spec can find if it says where classes get allocated? My thought, as xs0 has mentioned as well, is that 'new' could be defined independant of those implementation details. For example, just say that 'new' will allocate a class instance, and that the instance will be cleaned up only after there are no more references to that class. The only exception being explicit deletion. Since RAII gaurantees, AFAIK, that there are no references leaked into code that gets executed after the scope is exited, then stack allocation would work here. I'm finding it hard to imagine code that would require an object to be in the heap's address range or in the stack's address range. xs0 says there are other cases in which a class can be allocated on the stack without breaking the gaurantees of no premature deletion, and I wonder what they are.I'm assuming this defintion: http://en.wikipedia.org/wiki/Information_hiding I'm not sure I follow your logic, did you mean "encapsulation" instead? If you did mean "information hiding" then it seems to me that using opCall is a design decision, just as using a method called "Bob" would be. The advantage to using "Bob" is that you can define an 'stable' interface eg. interface MyImplementation { int Bob(int x); } and in that way protect your code against changes in implementation. In short, this is a better "information hiding" solution than using static opCall.What's the point of using static opCall here, as opposed to a normal static method or even a free function?Why not a normal static method? - implementation hiding.Why not a free function? - I'm assuming you mean a normal function declared at module scope.Yes.It allows you to have multiple functions with access to the same non-static variables (member variables).What does? _static_ opCall does *not* have access to non-static variables, it can only access static variables. Static methods and variables are very similar to module level variables. The difference being how to access them (class name prefix) and where they are declared (inside the class instead of at module level). You can replace static methods and variables with module level ones quite easily.I suppose this is usually accomplished with nested functions, or OOP that can't do implementation hiding.I'm obviously not following your point here.. can you elaborate, perhaps another example?Doing it this way allows me to avoid forward referencing issuesWhat forward referencing issues does the code above have?and also gives me more options about how my code behaves.What options? example?So far: - I'm not seeing the forward reference issue(s) - It seems like a worse way to implement information hiding (than an interface and method).What problem does it solve?Annoyance from forward referencing in nested functions, but that's just one. Maybe a small degree of implementation hiding for memory management, though I haven't tried this enough to demonstrate it. It is not really a solution. It is a technique, a syntax sugar, or just an easy way to get D to do things you would not ordinarily make it do.I *like* non-static opCall, I can see benefits to that. But, so far, static opCall seems to be fairly useless to me.What new technique or method does it allow?Multiple functions using the same non-static variables with no need for forward referencing and possible code behaviour tweaks, etc yadda yadda. I admit it's not horribly important, but I don't think that this choice of syntax is either. Most of all, I like it.*sigh* those were long winded answers, sorry about that.No worries. Long winded tends to imply more information and that's not a bad thing.I'm trying, by learning when, where and why you use it. I can't think of a place where _I_ would use it (which is why I think it's not useful). It's only a 'hack' when used with a struct to emulate a constructor. Strangely that 'hack' is the only vaguely good use I've seen for a *static* opCall. ReganCare to explain why static opCall is a hack and/or not useful outside of RAII or struct constructors?I do like using the scope keyword for this btw. It seems quite consistant with D's meaning of 'scope'.It's not bad but it's my 2nd choice currently. Regan
Jul 28 2006
On Fri, 28 Jul 2006 04:44:44 -0400, Chad J <gamerChad _spamIsBad_gmail.com> wrote:Regan Heath wrote:Err.. oops.. my example was in fact assuming the new "omit 'new'" syntax was added, then I went and confused it with: A a; writefln(a.a); which is actually what a C++ programmer would write to allocate a class on the stack and have it destroyed at end of scope. The syntax: A a; writefln(a.a); will crash, the new syntax isn't invloved at all, sorry....I've already said.. I think it's intuitive because it 'looks' like a class declared on the stack, as in C++ and like those it will be destroyed at the end of scope. Your counter argument is that not everyone is a C++ programmer, correct? In which case, read on.....I come from a C background. I have done a little C++, a little Java The absence of 'new' gives us the required information. You are required to know what the absense of 'new' _means_ just like you are required to know what keyword X means in any given context. In short, some knowledge of programming in D is required to program in D.I agree, the point is to make it easier to obtain that knowledge while learning.To expand on why I think it's intuitive let look at 2 scenarios, first the C++ programmer trying D. Likely their first program involving classes will look like this: class A { int a; } void main() { A a = A(); writefln(a.a); } currently, this crashes with an access violation.Actually, it doesn't compile. main.d(6): function expected before (), not A of type main.A main.d(6): cannot implicitly convert expression ((A)()) of type int to main.A Maybe not the best error messages for this case, but better than an access violation.No, but the resulting behaviour is almost identical. In C++ the syntax: A a; causes 'a' to be allocated on the stack and the destructor called at end of scope. Apart from being allocated on the stack (which Walter indicates in the docs is something he plans to implement at a later date for 'auto') it's identical to the behaviour of D's 'auto'. http://www.digitalmars.com/d/memory.html#stackclass "To have a class allocated on the stack that has a destructor, this is the same as a declaration with the auto attribute. Although the current implementation does not put such objects on the stack, future ones can."Add the new RAII syntax and not only does it not crash, but it behaves just like a C++ program would with A being destroyed at the end of scope.I hear that such syntax, in C++, means that 'A' will be stack allocated, which AFAIK does not imply RAII.One example I can think of that would break RAII is if the function gets inlined, then the stack allocated object may not be deleted until some point outside of the scope's end. It will /probably/ be deleted at the end of the function that the enclosing function was inlined into. I could be wrong about that though.I'm not sure what happens when something is inlined either.Also, does that C++ syntax allow class references to leak into code that is executed after the class is deleted?I would expect not. They should be destroyed when the scope ends and the stack space is released.In the case where you're not looking at someone elses code you'll never write: A a = A(); so you will not learn about it until you go looking for RAII. There you'll find the syntax, learn it, and carry on. It's no harder to learn than a keyword 'local'.be: class A { int a; } void main() { A a = new A(); writefln(a.a); } No crash, and the behaviour they expect. Then imagine the same programmers looking at each others code, the C++ programmer will understand 'new' to indicate heap allocation and absense of 'new' means, he'll reply that the class is destroyed at the end of scope. He might also say it's stack allocated, but that's fine, both of them have something to learn, and it has no effect on the way the program behaves.That learning process would be nice, but it assumes an extra programmer being around. As I learn D, I am alone. Either I go to the spec or I ask on the newsgroup. I'm not sure how many others are in the same situation.I've explained below why I still don't think it's very obvious, which means more potential newsgroup asking. That doesn't bug me too much though.I'm not especially bothered which syntax is chosen, I just like discussing stuff.Right back at ya.. why not have them both learn to omit 'new'?Simple, intuitive and elegant no matter what your background. Of absense of 'new' means. Both have to learn that D might not stack allocate the RAII class instance. If we use a 'scope' keyword then both sets of programmers have some learning to do. It's not much worse, but this makes it my 2nd choice."Both have to learn that D might not stack allocate the RAII class instance." "If we use a 'scope' keyword then both sets of programmers have some learning to do." If they both have learning to do anyways, why not just have them learn 'scope'?I suppose it wouldn't be too bad otherwise, except for one problem: The unfortunate C++ programmer's program worked as expected.Actually, my example was wrong and it doesn't. This poor guy still gets an access violation. Perhaps the new 'auto' syntax should just be: A a; then, my previous example and point would be valid.I say problem and unfortunate, because they may just assume that D behaves like C++ in all of the corner cases, and if I'm correct about the RAII vs stack alloc above, it may not.One of the things Walter tends to do (which bothers some D users) is to emulate C/C++ where appropriate. This makes porting C/C++ to D easier because there aren't corner cases where it does something subtley different. Of course I may be wrong, there may be a corner case, but I believe Walter intentionally tries to reduce these. In our case, I believe the D syntax: auto A a = new A(); and the C++ syntax: A a; behave almost identically. The difference being that D current does not allocate on the stack, but, that may change and if it does they will behave identically.Then they'll look for the section on variables, or class references, or declaring variables in function, or .. It shouldn't be all that hard to find, assuming half decent documentation.Searching for 'new' is a good idea. What if they don't think of that?For a D newbie reading code, having a keyword is good because it gives them a keyword to search the spec for. Better yet if it is 'scope', because that gives them an idea of where to look. This is also one of those things that is used seldom enough that the succinctness gained from implicit things is only slightly helpful.The C++ programmer will already know what it does. The Java/C++ programmer will search for 'new' (because it's absent). In either case they'll find the docs on RAII at the same time as they find the docs on 'new'.The only reason I would associate the absence of 'new' with allocation is because of the talk from C++ programmers on this newsgroup. Otherwise it's some kind of wacky cool feature of D that they have not read about yet (as it is now!). This is why I prefer 'scope' - it would make scope, unambiguously, THE keyword to search for to find out what's going on.Have you tried searching for an existing D keyword in the docs? First you have to decide which section to go to; is it a declaration, is it a type, is it a property, is it .. Sure it could be made easier with different documentation but that's all this boils down to, ensuring the information is in a logical place, if that's the case it makes no difference whether your searching for a specific keyword or 'RAII' or 'new' or 'class' etc. In an ideal world whatever you search for should find the results you need.See above. This is a documentation issue.That's fine as long as you clear up the two things: - What tells a non-C++ coder to look up 'new'? (besides another coder)In a nutshell: assume a programmer of undefined language background, and I believe 'scope' will be much more informative (and therefore intuitive) than a blank space.I've assumed programmers from 2 types of background above, I still think removing 'new' is better than adding 'scope'.- The possible assumption by a C++ coder that RAII syntax means stack allocation. (and subsequent whammy when they hit a pointy corner case) Proving that there are no corner cases in 'stack allocation implies RAII' or me being wrong about that meaning in C++ should clear up that second one.See above. I believe the behaviour is almost identical (and may become identical in the future). I believe Walter intentionally avoids corner cases WRT C++ behavior. That's the best I can do.. if I knew of a corner case I'd let you know ;)Err.. you've re-written your constructor as a free function? not the static opCall. Why? I would have expected this free function: int free_function( int x ) { // what do you know, not so 'static' after all! f instance = new f(x); int result = instance.result; // cleanup delete instance; return result; } void main() { int x = 42; x = free_function(x); writefln(x); } I've gotta go.. so, I'll just post what I've said so far and see what you respond with.. I may reply again to the stuff below.. :) ReganOK I think I have not explained my example very well. First I'll simplify my original example and try harder to explain. I've added comments this time. Here it is: import std.stdio; // class used as a function class f { int result; int tempVar1; // this is your non-static variable static int opCall( int x ) { // what do you know, not so 'static' after all! f instance = new f(x); int result = instance.result; // cleanup delete instance; return result; } this( int x ) { // If this were a function with nested functions, // then the main execution would occur here. result = x + internalFunc(); } // this is a non-static function int internalFunc() { return 314; } } void main() { int x = 42; x = f(x); writefln(x); } Now I'll rewrite it into a free function: import std.stdio; int f( int x ) { // Error! internalFunc is not defined. return x + internalFunc(); // oh but here it is... nested functions don't allow this int internalFunc() { return 314; } }I'm assuming this defintion: http://en.wikipedia.org/wiki/Information_hiding I'm not sure I follow your logic, did you mean "encapsulation" instead? If you did mean "information hiding" then it seems to me that using opCall is a design decision, just as using a method called "Bob" would be. The advantage to using "Bob" is that you can define an 'stable' interface eg. interface MyImplementation { int Bob(int x); } and in that way protect your code against changes in implementation. In short, this is a better "information hiding" solution than using static opCall.What's the point of using static opCall here, as opposed to a normal static method or even a free function?Why not a normal static method? - implementation hiding.Why not a free function? - I'm assuming you mean a normal function declared at module scope.Yes.It allows you to have multiple functions with access to the same non-static variables (member variables).What does? _static_ opCall does *not* have access to non-static variables, it can only access static variables. Static methods and variables are very similar to module level variables. The difference being how to access them (class name prefix) and where they are declared (inside the class instead of at module level). You can replace static methods and variables with module level ones quite easily.I suppose this is usually accomplished with nested functions, or OOP that can't do implementation hiding.I'm obviously not following your point here.. can you elaborate, perhaps another example?Doing it this way allows me to avoid forward referencing issuesWhat forward referencing issues does the code above have?and also gives me more options about how my code behaves.What options? example?So far: - I'm not seeing the forward reference issue(s) - It seems like a worse way to implement information hiding (than an interface and method).What problem does it solve?Annoyance from forward referencing in nested functions, but that's just one. Maybe a small degree of implementation hiding for memory management, though I haven't tried this enough to demonstrate it. It is not really a solution. It is a technique, a syntax sugar, or just an easy way to get D to do things you would not ordinarily make it do.I *like* non-static opCall, I can see benefits to that. But, so far, static opCall seems to be fairly useless to me.What new technique or method does it allow?Multiple functions using the same non-static variables with no need for forward referencing and possible code behaviour tweaks, etc yadda yadda. I admit it's not horribly important, but I don't think that this choice of syntax is either. Most of all, I like it.*sigh* those were long winded answers, sorry about that.No worries. Long winded tends to imply more information and that's not a bad thing.I'm trying, by learning when, where and why you use it. I can't think of a place where _I_ would use it (which is why I think it's not useful). It's only a 'hack' when used with a struct to emulate a constructor. Strangely that 'hack' is the only vaguely good use I've seen for a *static* opCall. ReganCare to explain why static opCall is a hack and/or not useful outside of RAII or struct constructors?I do like using the scope keyword for this btw. It seems quite consistant with D's meaning of 'scope'.It's not bad but it's my 2nd choice currently. ReganIn a trivial case like this all you have to do is move the nested function internalFunc to the top. In other cases though, where you want to be able to places the functions where they intuitively belong, this becomes annoying. This is that forward referencing issue I was talking about. Also, if 'f' were derived from another class, then the code executed in f's constructor would have access to the super class's members. That's more to do with OOP, but it's all hidden behind a static opCall. I suppose you could use a module function to construct and delete a private class that gets used for it's own scope and inheritance. I worry that I am missing some detail that stopped me from just doing that before. Sean, perhaps you could share some of your uses for static opCall since I'm doing such a bad job at this? Only slightly related - I wonder if D's 'new' even implies heap allocation as it is. That might just be a dmd thing, but I am looking in the spec at Classes -> ctors/dtors, and it doesn't say where they get allocated. Maybe someone who is good at searching the spec can find if it says where classes get allocated? My thought, as xs0 has mentioned as well, is that 'new' could be defined independant of those implementation details. For example, just say that 'new' will allocate a class instance, and that the instance will be cleaned up only after there are no more references to that class. The only exception being explicit deletion. Since RAII gaurantees, AFAIK, that there are no references leaked into code that gets executed after the scope is exited, then stack allocation would work here. I'm finding it hard to imagine code that would require an object to be in the heap's address range or in the stack's address range. xs0 says there are other cases in which a class can be allocated on the stack without breaking the gaurantees of no premature deletion, and I wonder what they are.
Jul 28 2006
Regan Heath wrote:On Fri, 28 Jul 2006 04:44:44 -0400, Chad J <gamerChad _spamIsBad_gmail.com> wrote:When reading other people's code, I find that most often I don't know or work with the other people. I'd have to contact them to learn from them. The easier option, for me, and probably them too, is to do a search in the spec, even if that is a bit difficult as-is.Regan Heath wrote:Err.. oops.. my example was in fact assuming the new "omit 'new'" syntax was added, then I went and confused it with: A a; writefln(a.a); which is actually what a C++ programmer would write to allocate a class on the stack and have it destroyed at end of scope. The syntax: A a; writefln(a.a); will crash, the new syntax isn't invloved at all, sorry.To expand on why I think it's intuitive let look at 2 scenarios, first the C++ programmer trying D. Likely their first program involving classes will look like this: class A { int a; } void main() { A a = A(); writefln(a.a); } currently, this crashes with an access violation.Actually, it doesn't compile. main.d(6): function expected before (), not A of type main.A main.d(6): cannot implicitly convert expression ((A)()) of type int to main.A Maybe not the best error messages for this case, but better than an access violation.No, but the resulting behaviour is almost identical. In C++ the syntax: A a; causes 'a' to be allocated on the stack and the destructor called at end of scope. Apart from being allocated on the stack (which Walter indicates in the docs is something he plans to implement at a later date for 'auto') it's identical to the behaviour of D's 'auto'. http://www.digitalmars.com/d/memory.html#stackclass "To have a class allocated on the stack that has a destructor, this is the same as a declaration with the auto attribute. Although the current implementation does not put such objects on the stack, future ones can."Add the new RAII syntax and not only does it not crash, but it behaves just like a C++ program would with A being destroyed at the end of scope.I hear that such syntax, in C++, means that 'A' will be stack allocated, which AFAIK does not imply RAII.One example I can think of that would break RAII is if the function gets inlined, then the stack allocated object may not be deleted until some point outside of the scope's end. It will /probably/ be deleted at the end of the function that the enclosing function was inlined into. I could be wrong about that though.I'm not sure what happens when something is inlined either.Also, does that C++ syntax allow class references to leak into code that is executed after the class is deleted?I would expect not. They should be destroyed when the scope ends and the stack space is released.In the case where you're not looking at someone elses code you'll never write: A a = A(); so you will not learn about it until you go looking for RAII. There you'll find the syntax, learn it, and carry on. It's no harder to learn than a keyword 'local'.will be: class A { int a; } void main() { A a = new A(); writefln(a.a); } No crash, and the behaviour they expect. Then imagine the same programmers looking at each others code, the C++ programmer will understand 'new' to indicate heap allocation and absense of 'new' means, he'll reply that the class is destroyed at the end of scope. He might also say it's stack allocated, but that's fine, both of them have something to learn, and it has no effect on the way the program behaves.That learning process would be nice, but it assumes an extra programmer being around. As I learn D, I am alone. Either I go to the spec or I ask on the newsgroup. I'm not sure how many others are in the same situation.Point being it doesn't give you the win-lose, you're still stuck with a lose-lose. If both coders have to learn, then we lose the advantage of chosing this syntax to make it so C++ coders don't have to learn. You still have a point wrt similarity, though I dislike subtly different behaviours as it can lead to bad assumptions.I've explained below why I still don't think it's very obvious, which means more potential newsgroup asking. That doesn't bug me too much though.I'm not especially bothered which syntax is chosen, I just like discussing stuff.Right back at ya.. why not have them both learn to omit 'new'?Simple, intuitive and elegant no matter what your background. Of absense of 'new' means. Both have to learn that D might not stack allocate the RAII class instance. If we use a 'scope' keyword then both sets of programmers have some learning to do. It's not much worse, but this makes it my 2nd choice."Both have to learn that D might not stack allocate the RAII class instance." "If we use a 'scope' keyword then both sets of programmers have some learning to do." If they both have learning to do anyways, why not just have them learn 'scope'?OK I'd like some clarification about the C++ side of things. It seems to me that both syntaxes such as A a = A(); and A a; have been said to cause stack allocation in C++. Is this true? A a; Currently that is the syntax for declaring a variable. It will break any code that relies on 'a' being initialized to null. If that's alright, you could change it to mean RAII/stackalloc in the context of a function, but then you lose consistancy with D's practice of initializing variables to knownly invalid values.I suppose it wouldn't be too bad otherwise, except for one problem: The unfortunate C++ programmer's program worked as expected.Actually, my example was wrong and it doesn't. This poor guy still gets an access violation. Perhaps the new 'auto' syntax should just be: A a; then, my previous example and point would be valid.I say problem and unfortunate, because they may just assume that D behaves like C++ in all of the corner cases, and if I'm correct about the RAII vs stack alloc above, it may not.One of the things Walter tends to do (which bothers some D users) is to emulate C/C++ where appropriate. This makes porting C/C++ to D easier because there aren't corner cases where it does something subtley different. Of course I may be wrong, there may be a corner case, but I believe Walter intentionally tries to reduce these. In our case, I believe the D syntax: auto A a = new A(); and the C++ syntax: A a; behave almost identically. The difference being that D current does not allocate on the stack, but, that may change and if it does they will behave identically.Yeah. I find the current situation wrt searching the D spec pretty clumsy. It would really help to be able to search the spec, and just the spec, and not the forums or anything else at the same time. I think once that is handled, then using keywords searches will narrow things down to a very small number of results that someone could read through. Having to figure out what section something is in is good in some cases, but in others is a real drag IMO :(Then they'll look for the section on variables, or class references, or declaring variables in function, or .. It shouldn't be all that hard to find, assuming half decent documentation.Searching for 'new' is a good idea. What if they don't think of that?For a D newbie reading code, having a keyword is good because it gives them a keyword to search the spec for. Better yet if it is 'scope', because that gives them an idea of where to look. This is also one of those things that is used seldom enough that the succinctness gained from implicit things is only slightly helpful.The C++ programmer will already know what it does. The Java/C++ programmer will search for 'new' (because it's absent). In either case they'll find the docs on RAII at the same time as they find the docs on 'new'.The only reason I would associate the absence of 'new' with allocation is because of the talk from C++ programmers on this newsgroup. Otherwise it's some kind of wacky cool feature of D that they have not read about yet (as it is now!). This is why I prefer 'scope' - it would make scope, unambiguously, THE keyword to search for to find out what's going on.Have you tried searching for an existing D keyword in the docs? First you have to decide which section to go to; is it a declaration, is it a type, is it a property, is it .. Sure it could be made easier with different documentation but that's all this boils down to, ensuring the information is in a logical place, if that's the case it makes no difference whether your searching for a specific keyword or 'RAII' or 'new' or 'class' etc. In an ideal world whatever you search for should find the results you need.That does work. Forces you to put the function outside of the class, but meh, it's just aesthetics/syntax sugar.See above. This is a documentation issue.That's fine as long as you clear up the two things: - What tells a non-C++ coder to look up 'new'? (besides another coder)In a nutshell: assume a programmer of undefined language background, and I believe 'scope' will be much more informative (and therefore intuitive) than a blank space.I've assumed programmers from 2 types of background above, I still think removing 'new' is better than adding 'scope'.- The possible assumption by a C++ coder that RAII syntax means stack allocation. (and subsequent whammy when they hit a pointy corner case) Proving that there are no corner cases in 'stack allocation implies RAII' or me being wrong about that meaning in C++ should clear up that second one.See above. I believe the behaviour is almost identical (and may become identical in the future). I believe Walter intentionally avoids corner cases WRT C++ behavior. That's the best I can do.. if I knew of a corner case I'd let you know ;)OK I think I have not explained my example very well. First I'll simplify my original example and try harder to explain. I've added comments this time. Here it is: import std.stdio; // class used as a function class f { int result; int tempVar1; // this is your non-static variable static int opCall( int x ) { // what do you know, not so 'static' after all! f instance = new f(x); int result = instance.result; // cleanup delete instance; return result; } this( int x ) { // If this were a function with nested functions, // then the main execution would occur here. result = x + internalFunc(); } // this is a non-static function int internalFunc() { return 314; } } void main() { int x = 42; x = f(x); writefln(x); } Now I'll rewrite it into a free function: import std.stdio; int f( int x ) { // Error! internalFunc is not defined. return x + internalFunc(); // oh but here it is... nested functions don't allow this int internalFunc() { return 314; } }Err.. you've re-written your constructor as a free function? not the static opCall. Why? I would have expected this free function: int free_function( int x ) { // what do you know, not so 'static' after all! f instance = new f(x); int result = instance.result; // cleanup delete instance; return result; } void main() { int x = 42; x = free_function(x); writefln(x); }I've gotta go.. so, I'll just post what I've said so far and see what you respond with.. I may reply again to the stuff below.. :) ReganIn a trivial case like this all you have to do is move the nested function internalFunc to the top. In other cases though, where you want to be able to places the functions where they intuitively belong, this becomes annoying. This is that forward referencing issue I was talking about. Also, if 'f' were derived from another class, then the code executed in f's constructor would have access to the super class's members. That's more to do with OOP, but it's all hidden behind a static opCall. I suppose you could use a module function to construct and delete a private class that gets used for it's own scope and inheritance. I worry that I am missing some detail that stopped me from just doing that before. Sean, perhaps you could share some of your uses for static opCall since I'm doing such a bad job at this? Only slightly related - I wonder if D's 'new' even implies heap allocation as it is. That might just be a dmd thing, but I am looking in the spec at Classes -> ctors/dtors, and it doesn't say where they get allocated. Maybe someone who is good at searching the spec can find if it says where classes get allocated? My thought, as xs0 has mentioned as well, is that 'new' could be defined independant of those implementation details. For example, just say that 'new' will allocate a class instance, and that the instance will be cleaned up only after there are no more references to that class. The only exception being explicit deletion. Since RAII gaurantees, AFAIK, that there are no references leaked into code that gets executed after the scope is exited, then stack allocation would work here. I'm finding it hard to imagine code that would require an object to be in the heap's address range or in the stack's address range. xs0 says there are other cases in which a class can be allocated on the stack without breaking the gaurantees of no premature deletion, and I wonder what they are.
Aug 02 2006
True.. however not being a C++ programmer "on a daily basis" I can't say for certain which of the 2 syntaxes I have given as examples of how a C++ programmer would do it, is the more common.Point being it doesn't give you the win-lose, you're still stuck with a lose-lose. If both coders have to learn, then we lose the advantage of chosing this syntax to make it so C++ coders don't have to learn.If they both have learning to do anyways, why not just have them learn 'scope'?Right back at ya.. why not have them both learn to omit 'new'?You still have a point wrt similarity, though I dislike subtly different behaviours as it can lead to bad assumptions.Different behaviour (heap vs stack allocation) is only a problem if it changes the outcome of the program. heap vs stack doesn't change the outcome, but it might affect the speed/efficiency of the program as doing 1,000,000 heap allocations is slower than the same number of stack ones. Adding stack allocation to 'auto' would then be a speed optimisation.Yes, I believe so. To heap allocate you have to use 'new'. My MSDN docs say.. "The new operator is used to allocate objects and arrays of objects. The new operator allocates from a program memory area called the “free store.” In C, the free store is often referred to as the “heap.”"In our case, I believe the D syntax: auto A a = new A(); and the C++ syntax: A a; behave almost identically. The difference being that D current does not allocate on the stack, but, that may change and if it does they will behave identically.OK I'd like some clarification about the C++ side of things. It seems to me that both syntaxes such as A a = A(); and A a; have been said to cause stack allocation in C++. Is this true?A a; Currently that is the syntax for declaring a variable.D initialises 'a' to null.It will break any code that relies on 'a' being initialized to null.No. But it will break any code which assumes it's not null, which is what the poor C++ programmer discovers in his/her first D program.If that's alright, you could change it to mean RAII/stackalloc in the context of a function, but then you lose consistancy with D's practice of initializing variables to knownly invalid values.True. A a; would have to call the class constructor, so it would have a known 'valid' value instead. Likewise:' A a = A(1,2,3); would do the same, only this time you can pass parameters to the class constructor. These two syntaxes are really one and the same.That does work. Forces you to put the function outside of the class, but meh, it's just aesthetics/syntax sugar."function outside of the class" is what I meant by "free function" .. he's free, not trapped in a class ;) So.. I'm still left with little idea when someone would actually use a static opCall and what purpose/problem it solves (beyond being syntactic sugar for free functions or other static methods of a class). If it's just syntactic sugar _and_ we decide we like the omit 'new' syntax (doesn't look promising at this stage, no matter) then I would vote for static opCall to be removed. Regan
Aug 02 2006
Chad J wrote:Regan Heath wrote:Uh, scopes and stack "frames" do not exist only for function frames. They exist for any instruction-block/scope. Such that: void func() { auto Foo fooa = new Foo; { auto Foo foob = new Foo; } // foob gets destroyed here ... } // fooa gets destroyed here So similarly, function inlining creates a scope/instruction-block , so that allocation behavior is preserved. So this code: int a = 2, b = 3; int r = sum(a, b); gets inlined to this: int a = 2, b = 3; int r; { r = a + b; } // De-alloc autos if there were any. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DAdd the new RAII syntax and not only does it not crash, but it behaves just like a C++ program would with A being destroyed at the end of scope.I hear that such syntax, in C++, means that 'A' will be stack allocated, which AFAIK does not imply RAII. One example I can think of that would break RAII is if the function gets inlined, then the stack allocated object may not be deleted until some point outside of the scope's end. It will /probably/ be deleted at the end of the function that the enclosing function was inlined into. I could be wrong about that though.
Jul 29 2006
Bruno Medeiros wrote:Chad J wrote:Ah. Thanks for the info.Regan Heath wrote:Uh, scopes and stack "frames" do not exist only for function frames. They exist for any instruction-block/scope. Such that: void func() { auto Foo fooa = new Foo; { auto Foo foob = new Foo; } // foob gets destroyed here ... } // fooa gets destroyed here So similarly, function inlining creates a scope/instruction-block , so that allocation behavior is preserved. So this code: int a = 2, b = 3; int r = sum(a, b); gets inlined to this: int a = 2, b = 3; int r; { r = a + b; } // De-alloc autos if there were any.Add the new RAII syntax and not only does it not crash, but it behaves just like a C++ program would with A being destroyed at the end of scope.I hear that such syntax, in C++, means that 'A' will be stack allocated, which AFAIK does not imply RAII. One example I can think of that would break RAII is if the function gets inlined, then the stack allocated object may not be deleted until some point outside of the scope's end. It will /probably/ be deleted at the end of the function that the enclosing function was inlined into. I could be wrong about that though.
Aug 02 2006
Regan Heath wrote:On Tue, 25 Jul 2006 23:28:24 -0400, Chad JAre you saying it is intuitive because *it is the same syntax as C++* ?? I hope not, because being the same syntax as C++ not only does not make it intuitive, but it also likely has the inverse effect: making things un-intuitive. -- Bruno Medeiros - MSc. in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DI really don't like the idea of dropping a language feature just for the sake of having a particular syntax that, IMO, is not intuitive.It's the same syntax you see in C++ for a class that has it's destructor called at the end of the scope. That, to me, makes it intuitive. For what reason do you find it un-intuitive?
Jul 29 2006
On Sat, 29 Jul 2006 21:20:22 +0100, Bruno Medeiros <brunodomedeirosATgmail SPAM.com> wrote:Regan Heath wrote:I was in fact wrong about the syntax being the same. That said, syntax and behaviour which is similar to C++ is intuitive (to C++ programmers). That's all I sugested (you need to read my statement in I was attempting to compare the 2 proposals: - absence of 'new' - use of keyword 'scope' or 'local' or <insert favourite keyword> encounter the RAII syntax, as far as I can see they'll either: 1. read some code using it. 2. want to implement RAII and will search the docs. I don't think either method is significantly better or worse in these 2 situations regardless of the programmers background. My mistake was that I thought the "absence of new" syntax was the same as the C++ syntax (for stack allocated, destroy at end of scope classes). This would have made it 'more' intuitive to the general population by virtue of being 'more' intuitive to the C++ programmers. In fact, if the suggested RAII syntax was: class A {} A a; //allocate RAII class then the C++ programmer, who wrote the above for his/her first D program wouldn't get an access violation (as they currently do) and would instead get the expected behaviour. An object (not allocated on the stack.. yet) whose destructor is called at end of scope. So, perhaps the RAII syntax should be this? It benefits C++ programmers a new keyword (as it's essentially the same thing) ReganOn Tue, 25 Jul 2006 23:28:24 -0400, Chad JAre you saying it is intuitive because *it is the same syntax as C++* ?? I hope not, because being the same syntax as C++ not only does not make it intuitive, but it also likely has the inverse effect: making things un-intuitive.I really don't like the idea of dropping a language feature just for the sake of having a particular syntax that, IMO, is not intuitive.It's the same syntax you see in C++ for a class that has it's destructor called at the end of the scope. That, to me, makes it intuitive. For what reason do you find it un-intuitive?
Jul 31 2006
I say lets keep 'auto' for auto type inference (for the reasons you and Don mention)agreed.I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.Why would you want to deal with where the object is allocated? Besides speed, is there any reason at all to allocate on the stack? If you always type the same thing, the compiler is always free to choose the best location. If you restrict "new" to allocating on the heap, you prevent the compiler from optimizing (by allocating on the stack) whenever it determines it's safe to do so (scoped variables are not the only such case). Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;) By the way, I think it would be wise to require references to scope-classes also be tagged with scope, so it'd be harder to miss that not-so-insignificant detail about them..I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful.But there is utility in static opCall in structs; having them there but not in classes doesn't sound to cool/consistent.. xs0
Jul 26 2006
On Wed, 26 Jul 2006 11:58:31 +0200, xs0 <xs0 xs0.com> wrote:My post _must_ have been missleading (more than one person thinks I want stack allocation). I don't want stack allocation. I was simply raising the possibility of stack allocation as a possibly beneficial side-effect of removing 'new' (which implies/required heap allocation, AFAICS)I say lets keep 'auto' for auto type inference (for the reasons you and Don mention)agreed.I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.Why would you want to deal with where the object is allocated?Besides speed, is there any reason at all to allocate on the stack?Speed isn't a good enough reason?If you always type the same thing, the compiler is always free to choose the best location. If you restrict "new" to allocating on the heap, you prevent the compiler from optimizing (by allocating on the stack) whenever it determines it's safe to do so (scoped variables are not the only such case).Is it even possible for 'new' to allocate on the stack? I mean the stack vanishes when the function exits, therefore isn't 'new' restricted to the heap?Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)I disagree, see my recent reply to "Chad J", specifically the scenarios involving the C++ and Java programmers.The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether. ReganI don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful.But there is utility in static opCall in structs; having them there but not in classes doesn't sound to cool/consistent..
Jul 26 2006
I haven't been following this, but static opCall sounds an awful lot like a function call to a function with static variables... I must join the "who would want such a thing"-side. /TThe only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful.But there is utility in static opCall in structs; having them there but not in classes doesn't sound to cool/consistent..
Jul 26 2006
Tommie Gannert wrote:Support for static operator functions can be useful for refactoring code in some cases, or for some odd template uses. I don't use the feature very often, but it's nice to have available. SeanI haven't been following this, but static opCall sounds an awful lot like a function call to a function with static variables... I must join the "who would want such a thing"-side.The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful.But there is utility in static opCall in structs; having them there but not in classes doesn't sound to cool/consistent..
Jul 27 2006
Regan Heath wrote:On Wed, 26 Jul 2006 11:58:31 +0200, xs0 <xs0 xs0.com> wrote:'new' doesn't imply/require that heap allocation actually be done, it just requires the result to behave as if it was (look up "escape analysis")My post _must_ have been missleading (more than one person thinks I want stack allocation). I don't want stack allocation. I was simply raising the possibility of stack allocation as a possibly beneficial side-effect of removing 'new' (which implies/required heap allocation, AFAICS)I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.Why would you want to deal with where the object is allocated?Speed is a good reason to use stack allocation. But that is also a good reason to let the compiler determine where to place an object, not the programmer.Besides speed, is there any reason at all to allocate on the stack?Speed isn't a good enough reason?No. There are many cases where the object is not actually required to be on the heap.If you always type the same thing, the compiler is always free to choose the best location. If you restrict "new" to allocating on the heap, you prevent the compiler from optimizing (by allocating on the stack) whenever it determines it's safe to do so (scoped variables are not the only such case).Is it even possible for 'new' to allocate on the stack? I mean the stack vanishes when the function exits, therefore isn't 'new' restricted to the heap?Well, I'm a Java programmer and if I see A a = A(); I see a function call that returns something of type A. If I see auto a = A(); I definitely see a function call. You'll never convince me that the lack of "new" is a good indication of anything, much less of the fact that it's a scoped variable.Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)I disagree, see my recent reply to "Chad J", specifically the scenarios involving the C++ and Java programmers.The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.Emulating a constructor is not the only utility, it's emulating an arbitrary function. xs0
Jul 27 2006
On Thu, 27 Jul 2006 15:31:24 +0200, xs0 <xs0 xs0.com> wrote:Regan Heath wrote:Ok.On Wed, 26 Jul 2006 11:58:31 +0200, xs0 <xs0 xs0.com> wrote:'new' doesn't imply/require that heap allocation actually be done, it just requires the result to behave as if it was (look up "escape analysis")My post _must_ have been missleading (more than one person thinks I want stack allocation). I don't want stack allocation. I was simply raising the possibility of stack allocation as a possibly beneficial side-effect of removing 'new' (which implies/required heap allocation, AFAICS)I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.Why would you want to deal with where the object is allocated?Exactly. I never suggested otherwise :)Speed is a good reason to use stack allocation. But that is also a good reason to let the compiler determine where to place an object, not the programmer.Besides speed, is there any reason at all to allocate on the stack?Speed isn't a good enough reason?Example?No. There are many cases where the object is not actually required to be on the heap.If you always type the same thing, the compiler is always free to choose the best location. If you restrict "new" to allocating on the heap, you prevent the compiler from optimizing (by allocating on the stack) whenever it determines it's safe to do so (scoped variables are not the only such case).Is it even possible for 'new' to allocate on the stack? I mean the stack vanishes when the function exits, therefore isn't 'new' restricted to the heap?Have you read my other post? Are you telling me you have a "closed mind"? If so, this discussion is pointless.Well, I'm a Java programmer and if I see A a = A(); I see a function call that returns something of type A. If I see auto a = A(); I definitely see a function call. You'll never convince me that the lack of "new" is a good indication of anything, much less of the fact that it's a scoped variable.Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)I disagree, see my recent reply to "Chad J", specifically the scenarios involving the C++ and Java programmers.Yes, but it's a 'static' function. See my other post WRT "information hiding", for that purpose it's actually better to use an actual static function. ReganThe only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.Emulating a constructor is not the only utility, it's emulating an arbitrary function.
Jul 27 2006
Regan Heath wrote:You did - you propose that using "new" forces the allocation on the heap, while not using it leaves the choice to the compiler (however, the variable is then also scoped/raii/auto/banana, so there's not much choice anyway).'new' doesn't imply/require that heap allocation actually be done, it just requires the result to behave as if it was (look up "escape analysis")Ok.Exactly. I never suggested otherwise :)Speed is a good reason to use stack allocation. But that is also a good reason to let the compiler determine where to place an object, not the programmer.Besides speed, is there any reason at all to allocate on the stack?Speed isn't a good enough reason?Did you look up escape analysis like I suggested? Anyway, besides the obvious scoped/raii/auto/banana variables, here's a simple example: void foo(Object a) { writefln("%s", a.toString()); } main() { foo(new Whatever()); } There's no reason why Whatever would have to be on the heap.Example?Is it even possible for 'new' to allocate on the stack? I mean the stack vanishes when the function exits, therefore isn't 'new' restricted to the heap?No. There are many cases where the object is not actually required to be on the heap.Dude, what's wrong with you? Your argument was that Java programmers would see an allocating expression without "new" or any other keyword, and somehow magically determine that there's something to be learned. I responded by saying that they (or me) wouldn't even see it as an allocating expression, and for that I have a closed mind? You know, you're probably right, this discussion is pointless, like so many others you participate in. And I still don't get how you can even think that "" can be a better indication of anything than "scope" (or any other keyword). When you see an empty paper, does a thought "oooh, I need to learn about D's scoped variables" spring to your mind?Have you read my other post? Are you telling me you have a "closed mind"? If so, this discussion is pointless.Well, I'm a Java programmer and if I see A a = A(); I see a function call that returns something of type A. If I see auto a = A(); I definitely see a function call. You'll never convince me that the lack of "new" is a good indication of anything, much less of the fact that it's a scoped variable.Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)I disagree, see my recent reply to "Chad J", specifically the scenarios involving the C++ and Java programmers.Without even reading your other post, I never said it's always better to use static opCall. I'm just saying there are cases where it's cool to have. But, this is basically a separate discussion anyway, so no need to continue with it. xs0Yes, but it's a 'static' function. See my other post WRT "information hiding", for that purpose it's actually better to use an actual static function.The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.Emulating a constructor is not the only utility, it's emulating an arbitrary function.
Jul 28 2006
On Fri, 28 Jul 2006 12:12:49 +0200, xs0 <xs0 xs0.com> wrote:Regan Heath wrote:I'm arguing semantics perhaps but all I did was say that it 'implied' heap allocation 'in my opinion'. My exact words were..You did - you propose that using "new" forces the allocation on the heap, while not using it leaves the choice to the compiler (however, the variable is then also scoped/raii/auto/banana, so there's not much choice anyway).'new' doesn't imply/require that heap allocation actually be done, it just requires the result to behave as if it was (look up "escape analysis")Ok.Exactly. I never suggested otherwise :)Speed is a good reason to use stack allocation. But that is also a good reason to let the compiler determine where to place an object, not the programmer.Besides speed, is there any reason at all to allocate on the stack?Speed isn't a good enough reason?Quoting "Regan Heath"..Until you gave the example below (thanks for that) I did suspect that it was required for 'new' to heap allocate because stack allocation only 'lives' as long as the scope in which it's allocated. So, stack allocation could be done for 'new' in certain cases (like the example below) to optimise, cool. To me 'new' still 'implies' heap allocation. But, now I know that there are some situations where the compiler could stack allocate, situations where the object allocated by 'new' only 'lives' as long as the current scope.'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.Yes. But I still wanted an example from you :)Did you look up escape analysis like I suggested?Example?Is it even possible for 'new' to allocate on the stack? I mean the stack vanishes when the function exits, therefore isn't 'new' restricted to the heap?No. There are many cases where the object is not actually required to be on the heap.Anyway, besides the obvious scoped/raii/auto/banana variables, here's a simple example: void foo(Object a) { writefln("%s", a.toString()); } main() { foo(new Whatever()); } There's no reason why Whatever would have to be on the heap.Nice. So an optimising compiler may choose to allocate 'a' on the stack. It can do that because the object only 'lives' as long as the scope of the function 'foo', correct?Your comment "You'll never convince me.. " caused my response wrt "closed mind". I meant no offence by it.Dude, what's wrong with you? Your argument was that Java programmers would see an allocating expression without "new" or any other keyword, and somehow magically determine that there's something to be learned. I responded by saying that they (or me) wouldn't even see it as an allocating expression, and for that I have a closed mind?Have you read my other post? Are you telling me you have a "closed mind"? If so, this discussion is pointless.Well, I'm a Java programmer and if I see A a = A(); I see a function call that returns something of type A. If I see auto a = A(); I definitely see a function call. You'll never convince me that the lack of "new" is a good indication of anything, much less of the fact that it's a scoped variable.Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)I disagree, see my recent reply to "Chad J", specifically the scenarios involving the C++ and Java programmers.You know, you're probably right, this discussion is pointless, like so many others you participate in.You seem to be atributing me with some sort of malice towards you, that's simply not the case. I avoid posting anything while I'm angry as I tend to regret it. I wasn't even angry or annoyed in this case, just curious. I seem to have angered you, I apologise for that.And I still don't get how you can even think that "" can be a better indication of anything than "scope" (or any other keyword).Then I'm doing a bad job of explaining. I believe you've missunderstood some of what I've tried to say (also my fault for choosing the wrong words to explain it)Actually I think it's important to this discussion. If static opCall is truly useful it makes the 'absence of new' idea rather worse than using a keyword. Among other things I'm trying to determine when/where static opCall is used, and why it's used in favour of another method (or even if one such method exists). I also wanted to know when 'new' could do something other than heap allocate, you've answered that one, thanks. ReganWithout even reading your other post, I never said it's always better to use static opCall. I'm just saying there are cases where it's cool to have. But, this is basically a separate discussion anyway, so no need to continue with it.Yes, but it's a 'static' function. See my other post WRT "information hiding", for that purpose it's actually better to use an actual static function.The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.Emulating a constructor is not the only utility, it's emulating an arbitrary function.
Jul 31 2006
Regan Heath wrote:On Tue, 25 Jul 2006 10:17:13 -0700, kris <foo bar.com> wrote:I don't like the no-allocator-keyword proposal. There are the problems: * the lack of static opCall (which I don't have experience with, so I'll leave the arguing about the usefulness of it to others). * less clear in the code that an allocation (stack or otherwise) is taking place. (somewhat subjective/aesthetical point I guess) But most importantly: * You can't make auto objects out of objects allocated with a function (like a factory method) instead of inline allocation. For example, the following cannot be made with a no-allocator-keyword syntax: auto Foo foo = SomeFactory.newFoo(..); // can't make an auto here auto char[] a = read(filename); // can't make an auto here -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DDon has a good point: changing to "var" would cause conflict with existing variable-names. Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature. I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; } class Foo {} class Bar {} scope class Wumpus {}I say lets keep 'auto' for auto type inference (for the reasons you and Don mention) I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option. - 'scope' at class decl. - no keyword at instatiation. Reasoning: 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes. I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful. Regan
Jul 29 2006
On Sat, 29 Jul 2006 22:17:07 +0100, Bruno Medeiros <brunodomedeirosATgmail SPAM.com> wrote:But most importantly: * You can't make auto objects out of objects allocated with a function (like a factory method) instead of inline allocation. For example, the following cannot be made with a no-allocator-keyword syntax: auto Foo foo = SomeFactory.newFoo(..); // can't make an auto here auto char[] a = read(filename); // can't make an auto hereGood point. That's a big problem. Regan
Jul 31 2006
I vote for banana! or scope.. seems good to reuse it; without parentheses after scope keywo= rd = implying `end of scope destruction`. On Tue, 25 Jul 2006 13:17:13 -0400, kris <foo bar.com> wrote:Don has a good point: changing to "var" would cause conflict with =existing variable-names. Chad et. al. also have a good point about the conflict regarding stati=c =opCall() (via the lack of a "new" keyword). I suspect many people find==the use of "new" to be indicative of allocation, and breaking this =consistency may have a detrimental effect? Further, it was noted that =a =missing "new" can only be used at the instantiation site -- not at the==class decl -- thus, D would be losing an existing feature. I suspect you could count the current number of raii-class uses on a f=ew =hands, whereas the use of "auto" for implied-type is pretty darned =popular -- and rightly so, since it's really very, very useful. Changi=ng =the raii style to use a different keyword, whilst retaining implied-ty=pe ="auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type,==and introduce something *else* for automatic cleanup at end-of-scope =(and also as a class attribute). how about reusing the "scope" keyword=?void main() { auto i =3D 10; auto foo =3D new Foo; auto scope bar =3D new Bar; auto scope wumpus =3D new Wumpus; } class Foo {} class Bar {} scope class Wumpus {}
Jul 25 2006
"Chris Miller" <chris dprogramming.com> wrote in message news:op.tc91g1fjpo9bzi moe...I vote for banana!banana++or scope.. seems good to reuse it; without parentheses after scope keyword implying `end of scope destruction`.I like scope for RAII too. Wonder who originally suggested that *cough*cough* ;)
Jul 27 2006
Jarrett Billingsley wrote:"Chris Miller" <chris dprogramming.com> wrote in message news:op.tc91g1fjpo9bzi moe...No!! I often use banana as an identifier in many of my programs! :P -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DI vote for banana!banana++
Jul 29 2006
vote++; //me likes kris wrote:Don has a good point: changing to "var" would cause conflict with existing variable-names. Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature. I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; } class Foo {} class Bar {} scope class Wumpus {}
Jul 26 2006
On Wed, 26 Jul 2006 02:52:06 -0700, Hasan Aljudy <hasan.aljudy gmail.com> wrote:vote++; //me likesI am sympathetic to the "scope" suggestion also. People have to remember that Walter doesn't like adding any new keywords. Reuse of "scope" may be the best solution here. Are there any drawbacks? Does it fit the intended meaning and purpose appropriately? It seems to. -JJR
Jul 27 2006
John Reimer wrote:On Wed, 26 Jul 2006 02:52:06 -0700, Hasan Aljudy <hasan.aljudy gmail.com> wrote:Given the suggested placement, I assume it would be illegal to reassign a 'scope' reference to another object? ie. class C {} scope C var = new C(); var = new C(); Assuming a reassignment is allowed, I assume the original object would not be destroyed on scope exit? Basically, I'm wondering whether the 'scope' qualifier is attached to the reference or to the referent. Seanvote++; //me likesI am sympathetic to the "scope" suggestion also. People have to remember that Walter doesn't like adding any new keywords. Reuse of "scope" may be the best solution here. Are there any drawbacks? Does it fit the intended meaning and purpose appropriately? It seems to.
Jul 27 2006
Sean Kelly wrote:John Reimer wrote:Maybe we could decide that based on the keyword's placement: class C { int m_i; this(int i) { m_i = i; } int i() { return m_i; } } scope C a = new C(1); // Destroy 'a' at end of scope C b = a; // b is another reference to 1. It will be invalid at the // end of scope, except: a = new C(2); // No, whoops! Destroy 2 at end of scope. // 1 is now referenced by b alone. return b; // Allowed! The reference 'a' will no longer destroy 1. return a; // NOT allowed! a is a scoped reference The alternative: C a = scope new C(1); // Destroy 1 at end of scope. C b = a; // b is another reference to 1, which will be destroyed // at the end of scope. a = new C(2); // A new, plain-old GCed instance. return b; // NOT allowed! 1 is invalid after this scope. return a; // Okay. a is a reference to a regular object. Maybe we could allow both? -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wikiOn Wed, 26 Jul 2006 02:52:06 -0700, Hasan Aljudy <hasan.aljudy gmail.com> wrote:Given the suggested placement, I assume it would be illegal to reassign a 'scope' reference to another object? ie. class C {} scope C var = new C(); var = new C(); Assuming a reassignment is allowed, I assume the original object would not be destroyed on scope exit? Basically, I'm wondering whether the 'scope' qualifier is attached to the reference or to the referent. Seanvote++; //me likesI am sympathetic to the "scope" suggestion also. People have to remember that Walter doesn't like adding any new keywords. Reuse of "scope" may be the best solution here. Are there any drawbacks? Does it fit the intended meaning and purpose appropriately? It seems to.
Jul 27 2006
Kirk McDonald wrote:Maybe we could decide that based on the keyword's placement: class C { int m_i; this(int i) { m_i = i; } int i() { return m_i; } } scope C a = new C(1); // Destroy 'a' at end of scope C b = a; // b is another reference to 1. It will be invalid at the // end of scope, except: a = new C(2); // No, whoops! Destroy 2 at end of scope. // 1 is now referenced by b alone. return b; // Allowed! The reference 'a' will no longer destroy 1. return a; // NOT allowed! a is a scoped reference The alternative: C a = scope new C(1); // Destroy 1 at end of scope. C b = a; // b is another reference to 1, which will be destroyed // at the end of scope. a = new C(2); // A new, plain-old GCed instance. return b; // NOT allowed! 1 is invalid after this scope. return a; // Okay. a is a reference to a regular object. Maybe we could allow both?Sounds reasonable to me, and potentially quite useful (even if often primarily for self-documenting code design, as I suspect in the vast majority of use-cases the effect will be identical). I also think it might very well be reasonable to disallow using 'scope' in tandem with either of 'static' or 'const' as the meaning is... well, questionable. Except perhaps for 'static' in the sole case of recursive functions, in which case I suppose the entity exists until the entire call-stack has unwound. Potentially useful. Allowing 'scope auto' seems harmless, although redundant since 'scope' as a storage class should allow for type-inference via precedance alone. -- Chris Nicholson-Sauls
Jul 28 2006
I think "local" may be a better name. At least I don't think I have ever used a variable with that name. kris wrote:Don has a good point: changing to "var" would cause conflict with existing variable-names. Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature. I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; } class Foo {} class Bar {} scope class Wumpus {}
Jul 27 2006
void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; }Conceptually 'auto' as a scope variable indicator is redundant. In 'ideal D world' struct shall have ctor/dtor and entities required stack allocation shall be declared as structs - not classes. So if you need pure stack allocated object use struct with dtor. And if you need class instance to be managed by stack variable use simple struct based smart pointer: struct local(T) { T ptr; void opAssign(T t) { ptr = t; } ~this() { delete ptr; } } void main() { local!(Bar) bar = new Bar; // opAssign invovation ... do something ... } // implicit dtor invocation happens here -> delete bar.ptr Andrew Fedoniouk. http://terrainformatica.com
Jul 27 2006
kris wrote:Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; }I've argued in the past about being able to elide the 'new' keyword entirely. I like the Python semantics, where 'calling' a class is synonymous with calling a factory function that returns instances of the class. The 'new' keyword is just redundant... until you remember that D has static opCall. So, without imposing an arbitrary restriction of disallowing static opCall for classes (but not for structs!), or saying e.g. that you have to say "new" for any class with static opCall defined for it (which would just be a huge headache)... I think this is the best solution. -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Jul 27 2006
kris wrote:Don has a good point: changing to "var" would cause conflict with existing variable-names. Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature.Agreed. I also don't think 'missing new' proposal is good.I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something else for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; }Looks ok to me, but should be in the reverse order I think: -------------------------------------------------------------- void main() { auto i = 10; auto foo = new Foo; scope auto bar = new Bar; scope auto wumpus = new Wumpus; } -------------------------------------------------------------- and with the current D policy of type inference when 'static' or 'const' is enough for declaration this should be also legal: -------------------------------------------------------------- scope bar = new Bar; -------------------------------------------------------------- -- AKhropov
Jul 27 2006
Andrei Khropov wrote:kris wrote:Someone noted that x = SomeName(); is confusing, since it doesn't convey whether a class is instantiated, or a function is called. That's part of the issue noted above, and it becomes worse when dropping the optional parens x = SomeName; Whereas it is still perfectly meaningful when using new instead: x = new SomeName;Don has a good point: changing to "var" would cause conflict with existing variable-names. Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature.Agreed. I also don't think 'missing new' proposal is good.Yes, thankyou ~ I'd forgotton about that groovy option: void main() { auto i = 10; auto foo = new Foo; scope bar = new Bar; scope wumpus = new Wumpus; } class Foo {} class Bar {} scope class Wumpus {} // can only be used as a scope'd instanceI suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something else for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; }Looks ok to me, but should be in the reverse order I think: -------------------------------------------------------------- void main() { auto i = 10; auto foo = new Foo; scope auto bar = new Bar; scope auto wumpus = new Wumpus; } -------------------------------------------------------------- and with the current D policy of type inference when 'static' or 'const' is enough for declaration this should be also legal: -------------------------------------------------------------- scope bar = new Bar; --------------------------------------------------------------
Jul 28 2006
kris wrote:Someone noted that x = SomeName(); is confusing, since it doesn't convey whether a class is instantiated, or a function is called. That's part of the issue noted above, and it becomes worse when dropping the optional parens x = SomeName; Whereas it is still perfectly meaningful when using new instead: x = new SomeName;Yes, that's an essential flaw in this proposal. Another one was mentioned in http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/40740 : <quote> But how does this proposed syntax handle variable-length arrays? char[] a = read(filename); Is 'a' destroyed at end of scope? </quote> So we'll lose the ability to initialize scope variables by function return value. -- AKhropov
Jul 28 2006
<IMHO> I recently thought about using 'scoped' instead of 'scope'. Yes, it's one extra letter but improved readability (IMHO): ---------------------------------------------------- scope i = 1; // is read like 'i is a scope' ---------------------------------------------------- scoped i = 1; // is read like 'i is scoped' ---------------------------------------------------- and ---------------------------------------------------- scope class Bar{ ... ---------------------------------------------------- scoped class Bar{ ... // is read like 'Bar is a scoped class' ---------------------------------------------------- and current uses of scope are also replaced (also it's consistent with the form 'synchronized') : ---------------------------------------------------- scope(exit) Statement scope(success) Statement scope(failure) Statement ---------------------------------------------------- changed to ---------------------------------------------------- scoped(exit) Statement // is read like 'this statement is scoped at exit' scoped(success) Statement scoped(failure) Statement ---------------------------------------------------- (there's no 'scoped' verb in English AFAIK but it looks very natural and understandable) </IMHO> Does anybody use 'scoped' as identifier? -- AKhropov
Jul 28 2006
kris wrote:Don has a good point: changing to "var" would cause conflict with existing variable-names.[...]I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change? Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword? void main() { auto i = 10; auto foo = new Foo; auto scope bar = new Bar; auto scope wumpus = new Wumpus; } class Foo {} class Bar {} scope class Wumpus {}Up to now, I favored the following keyword proposals: "auto" -> for RAII (autoraii or raiiauto) "var" -> for implicit type deduction. (autotype) The idea that autotype is the most used auto notion, and as such should be the one not to change it's keyword has no support from me. (Although I agree Walter I very resilient towards keyword changes...) When I think the name "auto", I think the most close meaning is that of automatic allocation/decallocation (raiiauto) and not implicit type deduction. And I quite deslike the name "scope" (or even "scoped") for raiiauto, (subjective point) As for autotype, exactly because it is used often I liked the fact that 3.0. But I do agree there is some strangeness to see "var" used as such keyword for type deduction, so I wasn't 100% happy. How about "def" for autotype keyword? It's still one char shorter, and I think the name is pretty nice: def n = 42; def foo = new Foo(); The syntax similarity to dynamic languages is also somewhat... appealing :) -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 29 2006