digitalmars.D.bugs - Block Scope Rules
- Derek Parnell (25/25) Mar 30 2005 Either the documentation is wrong or DMD is wrong. The examples below
- Walter (3/22) Apr 03 2005 What do people think? Should this feature be dropped, or implemented?
- Derek Parnell (13/40) Apr 03 2005 I'm in the camp that says that each block has its own scope, and thus a
- Regan Heath (24/63) Apr 03 2005 Having a variable 'hide' (or take precedence over) a previously defined ...
- Derek Parnell (34/95) Apr 03 2005 True. So the questions is on what basis do we "draw the line". Currently
- Regan Heath (73/168) Apr 03 2005 A global variable with a *bad* name and a function declaration with a
- Derek Parnell (74/274) Apr 03 2005 Oh come off it, Regan. Its a f****** example in a post, sheesh! Give me
- Regan Heath (67/103) Apr 03 2005 I've done a bad job of explaining myself. Let me try again:
- Regan Heath (6/115) Apr 03 2005 This is interesting and sort-of on point. :)
- Derek Parnell (7/17) Apr 03 2005 I can live with this. It will mean that occasionally I will be forced to...
- Regan Heath (63/79) Apr 03 2005 I realise some people are going to disagree about what the "right thing"...
- Derek Parnell (12/18) Apr 03 2005 I still want D to be D, rather than an evolved C, so that's not going to
- Thomas Kuehne (15/23) Apr 04 2005 -----BEGIN PGP SIGNED MESSAGE-----
- Regan Heath (13/34) Apr 04 2005 Do you mean?
- Thomas Kuehne (14/38) Apr 04 2005 -----BEGIN PGP SIGNED MESSAGE-----
- Regan Heath (16/49) Apr 04 2005 To me, the above is comparable to:
- Stewart Gordon (11/30) Apr 03 2005 I'm not sure if this should be allowed. Does it really make sense for
- Tom S (4/36) Apr 03 2005 --
Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } } void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code> I need this clarified as I use block-scoped variables heavily and need to know if I have to change my coding style. -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build/ V1.17 released http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage 31/03/2005 9:35:40 AM
Mar 30 2005
"Derek Parnell" <derek psych.ward> wrote in message news:2sue67wyp7ug$.f1delgy6x2ql.dlg 40tude.net...Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } } void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code> I need this clarified as I use block-scoped variables heavily and need to know if I have to change my coding style.What do people think? Should this feature be dropped, or implemented?
Apr 03 2005
On Sun, 3 Apr 2005 11:45:57 -0700, Walter wrote:"Derek Parnell" <derek psych.ward> wrote in message news:2sue67wyp7ug$.f1delgy6x2ql.dlg 40tude.net...I'm in the camp that says that each block has its own scope, and thus a symbol declared in a block is visible to statements in that block and takes precedence over same-named symbols declared in other blocks. Note that not every block is bounded by braces. The 'for' and 'foreach' statements are already implemented thus, as are functions. for (int x = 0; ...) foreach( char c; ...) myFunc(int x) ... -- Derek Parnell Melbourne, Australia 4/04/2005 6:31:30 AMEither the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } } void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code> I need this clarified as I use block-scoped variables heavily and need to know if I have to change my coding style.What do people think? Should this feature be dropped, or implemented?
Apr 03 2005
On Mon, 4 Apr 2005 06:39:31 +1000, Derek Parnell <derek psych.ward> wrote:On Sun, 3 Apr 2005 11:45:57 -0700, Walter wrote:Having a variable 'hide' (or take precedence over) a previously defined variable, be it global or in an enclosing scope, is a source of bugs. Especially if the local variable is renamed but not all instances of it's use are renamed. On the other hand, having to name your variables so that they do not collide may cause you to have to use names which are less than 100% appropriate. Then again, having a global called 'index' is probably less than 100% appropriate, what is it the index of? I think that should be included in it's name i.e. fileIndex, boatIndex, etc. In this case I think I personally would choose safety over convenience as there are workarounds for the convenience issue, but none for the safety issue. It's important to note (I'm sure Derek realises/meant this) that a function "call" is not the same as a new scope. A function "definition" is the same as a new scope. A function call is not expected to have access to variables in the enclosing scope, therefore it cannot 'hide' them. A function definition (typically placed in the global scope) is expected to have access to variables declared in the enclosing scope (global variables). So, as for these 2 examples specifically I believe the first to be illegal and the second to be legal (as Stewart noted). Regan"Derek Parnell" <derek psych.ward> wrote in message news:2sue67wyp7ug$.f1delgy6x2ql.dlg 40tude.net...I'm in the camp that says that each block has its own scope, and thus a symbol declared in a block is visible to statements in that block and takes precedence over same-named symbols declared in other blocks. Note that not every block is bounded by braces. The 'for' and 'foreach' statements are already implemented thus, as are functions. for (int x = 0; ...) foreach( char c; ...) myFunc(int x) ...Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } } void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code> I need this clarified as I use block-scoped variables heavily and need to know if I have to change my coding style.What do people think? Should this feature be dropped, or implemented?
Apr 03 2005
On Mon, 04 Apr 2005 09:18:01 +1200, Regan Heath wrote:On Mon, 4 Apr 2005 06:39:31 +1000, Derek Parnell <derek psych.ward> wrote:True. So the questions is on what basis do we "draw the line". Currently there is no fundamental difference between ... int x; void Foo(){int x; ... } and void Foo(){ int x; { int x; ... } } or even void Foo(){ int x; for(int x = 0; ... } } It could be argued that case-sensitivity is also a source of bugs. But no-one is really wanting that to change (except VB and Progress coders :D ) int index_a; Foo() { int index_A; . . . index_a = 1; // Did I really mean this or index_A? } Maybe we could have an explicit resolution mechanism to disambiguate such name hiding?On Sun, 3 Apr 2005 11:45:57 -0700, Walter wrote:Having a variable 'hide' (or take precedence over) a previously defined variable, be it global or in an enclosing scope, is a source of bugs. Especially if the local variable is renamed but not all instances of it's use are renamed."Derek Parnell" <derek psych.ward> wrote in message news:2sue67wyp7ug$.f1delgy6x2ql.dlg 40tude.net...I'm in the camp that says that each block has its own scope, and thus a symbol declared in a block is visible to statements in that block and takes precedence over same-named symbols declared in other blocks. Note that not every block is bounded by braces. The 'for' and 'foreach' statements are already implemented thus, as are functions. for (int x = 0; ...) foreach( char c; ...) myFunc(int x) ...Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } } void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code> I need this clarified as I use block-scoped variables heavily and need to know if I have to change my coding style.What do people think? Should this feature be dropped, or implemented?On the other hand, having to name your variables so that they do not collide may cause you to have to use names which are less than 100% appropriate. Then again, having a global called 'index' is probably less than 100% appropriate, what is it the index of? I think that should be included in it's name i.e. fileIndex, boatIndex, etc.Hands up all of us who have used 'i' as a variable name? ;-) But meanwhile, in the world of compromise, people don't think ahead enough and we lazily use abbreviated names and meaningless names far too often. But even if we didn't, we could still wish to declare variables physically close to where they are going to be used.In this case I think I personally would choose safety over convenience as there are workarounds for the convenience issue, but none for the safety issue.Yeah, I guess you are right here, but explaining the exceptions to the rule to a new comer could be interesting. Module scope is okay to hide but function scope is a no-no.It's important to note (I'm sure Derek realises/meant this) that a function "call" is not the same as a new scope. A function "definition" is the same as a new scope.(Ahhhh..yep. I did mean function definition.) void myFunc(int x) ... -- Derek Melbourne, Australia 4/04/2005 9:00:32 AM
Apr 03 2005
On Mon, 4 Apr 2005 09:15:45 +1000, Derek Parnell <derek psych.ward> wrote:On Mon, 04 Apr 2005 09:18:01 +1200, Regan Heath wrote:A global variable with a *bad* name and a function declaration with a temporary var called "x".On Mon, 4 Apr 2005 06:39:31 +1000, Derek Parnell <derek psych.ward> wrote:True. So the questions is on what basis do we "draw the line". Currently there is no fundamental difference between ... int x; void Foo(){int x; ... }On Sun, 3 Apr 2005 11:45:57 -0700, Walter wrote:Having a variable 'hide' (or take precedence over) a previously defined variable, be it global or in an enclosing scope, is a source of bugs. Especially if the local variable is renamed but not all instances of it's use are renamed."Derek Parnell" <derek psych.ward> wrote in message news:2sue67wyp7ug$.f1delgy6x2ql.dlg 40tude.net...I'm in the camp that says that each block has its own scope, and thus a symbol declared in a block is visible to statements in that block and takes precedence over same-named symbols declared in other blocks. Note that not every block is bounded by braces. The 'for' and 'foreach' statements are already implemented thus, as are functions. for (int x = 0; ...) foreach( char c; ...) myFunc(int x) ...Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } } void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code> I need this clarified as I use block-scoped variables heavily and need to know if I have to change my coding style.What do people think? Should this feature be dropped, or implemented?and void Foo(){ int x; { int x; ... } }A function with a temporary called "x" and another temporary called "x". Soln: rename one temporary "y" or "i".. So, my first assumption is that a variable like "x" or "i" is a temporary, or rather a variable that is not going to "live" very long. I believe it bad practice to give a long lived variable (a global, or one with a specific purpose) a nondescript or unspecific name. In my mind there is a fundamental difference here. That difference is that in the example with the global, the global "x" was given a *bad* name. The solution being to give it a good name, this is just good programming practice.or even void Foo(){ int x; for(int x = 0; ... } }I see this as the same as the 2nd example above. In this case "x" is a temporary in both cases. Soln: rename one temporary "y" or "i"..It could be argued that case-sensitivity is also a source of bugs. But no-one is really wanting that to change (except VB and Progress coders :D )Some typos will always be bugs. In the example below, it's only a bug if the variables "index_a" and "index_A" both exist at the scope where the typo occurs. I'd argue this to be very unlikely given a few assumptions: - it's bad practice to use a naming sceme that allows both "index_a" and "index_A". - it relies on the global being named badly (unspecific, nondescript name). You can argue given a particular coding style and naming sceme that this is more likely to occur, in answer I'd say that coding style and/or naming sceme is inapproriate for use with D. Sadly we cannot accomodate everyones style and have a language that spots lots of bugs cased by style, it appears to be a tradeoff.int index_a; Foo() { int index_A; . . . index_a = 1; // Did I really mean this or index_A? } Maybe we could have an explicit resolution mechanism to disambiguate such name hiding?This is a joke, right? If not please explain./me puts hand up.On the other hand, having to name your variables so that they do not collide may cause you to have to use names which are less than 100% appropriate. Then again, having a global called 'index' is probably less than 100% appropriate, what is it the index of? I think that should be included in it's name i.e. fileIndex, boatIndex, etc.Hands up all of us who have used 'i' as a variable name? ;-)But meanwhile, in the world of compromise, people don't think ahead enough and we lazily use abbreviated names and meaningless names far too often.Sure, but, I believe good programming style dictates that you only use abbreviated/meaningless names for short-lived temporary variables and more descriptive names for long lived globals, in which case, no collisions should occur between globals and locals. leaving only local to local collision, which can usually be resolved by giving the local another random name i, j, k, l etc.But even if we didn't, we could still wish to declare variables physically close to where they are going to be used.Sure, and that will/should be possible eg. { int x; ... } { int x; ... } no problems here. { int x; ... { int x; <-error, rename to 'y' or 'i' or ... ... } }The rule is if a variable in any scope hides a variable in an outer scope it's an error, plain and simple.In this case I think I personally would choose safety over convenience as there are workarounds for the convenience issue, but none for the safety issue.Yeah, I guess you are right here, but explaining the exceptions to the rule to a new comer could be interesting.Module scope is okay to hide but function scope is a no-no.That's not an exception. Module scope is similar to: { int x; <-module 1 ... } <-module 2 { int x; ... } each module has it's own 'global' scope. Which you access by using the module name. However, D gives us a shortcut, and detects collisions requiring alias to resolve eg. [a.d] int i; [b.d] int i; import a; import b; i = 5; <-error, which one //soln1 a.i = 5; //soln2 alias i a.i; i = 5; Regan
Apr 03 2005
On Mon, 04 Apr 2005 12:11:54 +1200, Regan Heath wrote:On Mon, 4 Apr 2005 09:15:45 +1000, Derek Parnell <derek psych.ward> wrote:Oh come off it, Regan. Its a f****** example in a post, sheesh! Give me some brains. Okay, I'll spell it out 'nicely' then ... uint Line_Counter; . . . uint Foo(char[] File_Path) { uint Line_Counter; ... return Line_Counter; } Line_Counter = Foo("C:\\autoexec.bat");On Mon, 04 Apr 2005 09:18:01 +1200, Regan Heath wrote:A global variable with a *bad* name and a function declaration with a temporary var called "x".On Mon, 4 Apr 2005 06:39:31 +1000, Derek Parnell <derek psych.ward> wrote:True. So the questions is on what basis do we "draw the line". Currently there is no fundamental difference between ... int x; void Foo(){int x; ... }On Sun, 3 Apr 2005 11:45:57 -0700, Walter wrote:Having a variable 'hide' (or take precedence over) a previously defined variable, be it global or in an enclosing scope, is a source of bugs. Especially if the local variable is renamed but not all instances of it's use are renamed."Derek Parnell" <derek psych.ward> wrote in message news:2sue67wyp7ug$.f1delgy6x2ql.dlg 40tude.net...I'm in the camp that says that each block has its own scope, and thus a symbol declared in a block is visible to statements in that block and takes precedence over same-named symbols declared in other blocks. Note that not every block is bounded by braces. The 'for' and 'foreach' statements are already implemented thus, as are functions. for (int x = 0; ...) foreach( char c; ...) myFunc(int x) ...Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } } void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code> I need this clarified as I use block-scoped variables heavily and need to know if I have to change my coding style.What do people think? Should this feature be dropped, or implemented?void Foo(){ uint Line_Counter; { uint Line_Counter; ... } }and void Foo(){ int x; { int x; ... } }A function with a temporary called "x" and another temporary called "x". Soln: rename one temporary "y" or "i".. So, my first assumption is that a variable like "x" or "i" is a temporary, or rather a variable that is not going to "live" very long. I believe it bad practice to give a long lived variable (a global, or one with a specific purpose) a nondescript or unspecific name.Of course it is, but it happens all the time. How are you going to stop that!In my mind there is a fundamental difference here. That difference is that in the example with the global, the global "x" was given a *bad* name. The solution being to give it a good name, this is just good programming practice.Sure, but we a talking about syntax and semantics here, and not what, in some people's option, is good programming practice.ITS AN EXAMPLE! I couldn't be bother writing an example with a decent variable name because I figured people reading this could see beyond the specific and generalize it instead.or even void Foo(){ int x; for(int x = 0; ... } }I see this as the same as the 2nd example above. In this case "x" is a temporary in both cases. Soln: rename one temporary "y" or "i"..Regan, you are just not getting it are you? These are just examples, dashed off in the heat of writing a news-group post! Seriously, would my point be any worse if I'd come up with names more pleasing to you? Try generalizing by examples, instead of nit picking. What if I had've used "Text_Offset" and "Text_offset", etc, etc, etc, etc ...It could be argued that case-sensitivity is also a source of bugs. But no-one is really wanting that to change (except VB and Progress coders :D )Some typos will always be bugs. In the example below, it's only a bug if the variables "index_a" and "index_A" both exist at the scope where the typo occurs. I'd argue this to be very unlikely given a few assumptions: - it's bad practice to use a naming sceme that allows both "index_a" and "index_A". - it relies on the global being named badly (unspecific, nondescript name).You can argue given a particular coding style and naming sceme that this is more likely to occur, in answer I'd say that coding style and/or naming sceme is inapproriate for use with D. Sadly we cannot accomodate everyones style and have a language that spots lots of bugs cased by style, it appears to be a tradeoff.No, it was not a joke. Ok, try not to get hung up with the specific characters I just coincidently happen to use in this reply; try generalizing it instead. But what if, the character ' ' when prefixing a symbol name, was an instruction for the compile to use the inner most scope to resolve an otherwise ambiguous symbol name. For example ... void Foo() { int Pretend_That_This_Is_A_Decent_Variable_Name; { double Pretend_That_This_Is_A_Decent_Variable_Name; . . . // Explicitly refer to the innermost scope. Pretend_That_This_Is_A_Decent_Variable_Name += 1.2; } } See, no joke involved.int index_a; Foo() { int index_A; . . . index_a = 1; // Did I really mean this or index_A? } Maybe we could have an explicit resolution mechanism to disambiguate such name hiding?This is a joke, right? If not please explain.Smack! ;-)/me puts hand up.On the other hand, having to name your variables so that they do not collide may cause you to have to use names which are less than 100% appropriate. Then again, having a global called 'index' is probably less than 100% appropriate, what is it the index of? I think that should be included in it's name i.e. fileIndex, boatIndex, etc.Hands up all of us who have used 'i' as a variable name? ;-)And I'm sure everybody always does that religiously.But meanwhile, in the world of compromise, people don't think ahead enough and we lazily use abbreviated names and meaningless names far too often.Sure, but, I believe good programming style dictates that you only use abbreviated/meaningless names for short-lived temporary variables and more descriptive names for long lived globals, in which case, no collisions should occur between globals and locals. leaving only local to local collision, which can usually be resolved by giving the local another random name i, j, k, l etc.Yep, I'm sure this would be the most common workaround.But even if we didn't, we could still wish to declare variables physically close to where they are going to be used.Sure, and that will/should be possible eg. { int x; ... } { int x; ... } no problems here. { int x; ... { int x; <-error, rename to 'y' or 'i' or ... ... } }Except for module scoped symbols ;-) A variable declared inside a function hides a same-named variable declared outside the function inside the same module. Example ... uint Line_Counter; import std.stdio; uint foo() { uint Line_Counter; Line_Counter = 2; return Line_Counter; } And thus we have an exception to the rule "if a variable in any scope hides a variable in an outer scope it's an error".The rule is if a variable in any scope hides a variable in an outer scope it's an error, plain and simple.In this case I think I personally would choose safety over convenience as there are workarounds for the convenience issue, but none for the safety issue.Yeah, I guess you are right here, but explaining the exceptions to the rule to a new comer could be interesting.I wasn't talking about same-named symbols declared in different modules. And note, we have a mechanism to disambiguate that situation, so thus I (unjokingly) suggested that a similar mechanism might be useful within a single module. -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build/ v.1.19 released 04/Apr/2005 http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage 4/04/2005 10:55:12 AMModule scope is okay to hide but function scope is a no-no.That's not an exception. Module scope is similar to: { int x; <-module 1 ... } <-module 2 { int x; ... } each module has it's own 'global' scope. Which you access by using the module name. However, D gives us a shortcut, and detects collisions requiring alias to resolve eg. [a.d] int i; [b.d] int i; import a; import b; i = 5; <-error, which one //soln1 a.i = 5; //soln2 alias i a.i; i = 5;
Apr 03 2005
I've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none. What I was trying to do below was give solutions to the obvious problems this rule will create, reasons for those solutions in terms of good programming practice and the reasons why I see it as good programming practice. In short, all of these would be errors: int a; void foo(int a) {} int a void foo() { int a; } int a; void foo() { if(true) { int a; } } void foo() { int a; if(true) { int a; } } int a; for(int a;;){} int a; for(;;){ int a; } ..etc.. you get the idea. To solve the above you have to rename one of the variables. I don't see that as a bad thing, in fact I believe it could force better programming practice. For example: int index; void foo() { int index; } here, perhaps the global should be renamed (or even moved). Why is it global? What is "index" an index of? Possble solutions: class File { int index; } void foo() { int index; } int fileIndex; void foo() { int index; } or perhaps the temporary should be renamed: int index; void foo() { int i; } I appologise for missunderstanding your next comment...I thought you were referring to the typo above not the original topic when you said "Maybe we could have an explicit resolution mechanism to disambiguate ... ". I thought you might be jokingly suggesting that to resolve the problem with the typo was to type the correct character. :) Using a symbol to refer to the inner/current scope isn't a bad idea. It's like the "." used for outermost?/module?/file? scope. If however my rule was implemented you wouldn't get as far as to actually use it, as:No, it was not a joke. Ok, try not to get hung up with the specific characters I just coincidently happen to use in this reply; try generalizing it instead. But what if, the character ' ' when prefixing a symbol name, was an instruction for the compile to use the inner most scope to resolve an otherwise ambiguous symbol name. For example ... void Foo() { int Pretend_That_This_Is_A_Decent_Variable_Name; { double Pretend_That_This_Is_A_Decent_Variable_Name; . . . // Explicitly refer to the innermost scope. Pretend_That_This_Is_A_Decent_Variable_Name += 1.2; } } See, no joke involved.int index_a; Foo() { int index_A; . . . index_a = 1; // Did I really mean this or index_A? } Maybe we could have an explicit resolution mechanism to disambiguate such name hiding?This is a joke, right? If not please explain.void Foo() { int Pretend_That_This_Is_A_Decent_Variable_Name; { double Pretend_That_This_Is_A_Decent_Variable_Name;would error here. The rest of the post I have snipped as it appears to me to revolve around our missunderstanding. Regan
Apr 03 2005
This is interesting and sort-of on point. :) http://www.cse.unsw.edu.au/~cs3141/ip.asf http://www.codegeneration.net/tiki-read_article.php?articleId=61 http://www.edge.org/digerati/simonyi/simonyi_p1.html Regan On Mon, 04 Apr 2005 15:11:14 +1200, Regan Heath <regan netwin.co.nz> wrote:I've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none. What I was trying to do below was give solutions to the obvious problems this rule will create, reasons for those solutions in terms of good programming practice and the reasons why I see it as good programming practice. In short, all of these would be errors: int a; void foo(int a) {} int a void foo() { int a; } int a; void foo() { if(true) { int a; } } void foo() { int a; if(true) { int a; } } int a; for(int a;;){} int a; for(;;){ int a; } ..etc.. you get the idea. To solve the above you have to rename one of the variables. I don't see that as a bad thing, in fact I believe it could force better programming practice. For example: int index; void foo() { int index; } here, perhaps the global should be renamed (or even moved). Why is it global? What is "index" an index of? Possble solutions: class File { int index; } void foo() { int index; } int fileIndex; void foo() { int index; } or perhaps the temporary should be renamed: int index; void foo() { int i; } I appologise for missunderstanding your next comment...I thought you were referring to the typo above not the original topic when you said "Maybe we could have an explicit resolution mechanism to disambiguate ... ". I thought you might be jokingly suggesting that to resolve the problem with the typo was to type the correct character. :) Using a symbol to refer to the inner/current scope isn't a bad idea. It's like the "." used for outermost?/module?/file? scope. If however my rule was implemented you wouldn't get as far as to actually use it, as:No, it was not a joke. Ok, try not to get hung up with the specific characters I just coincidently happen to use in this reply; try generalizing it instead. But what if, the character ' ' when prefixing a symbol name, was an instruction for the compile to use the inner most scope to resolve an otherwise ambiguous symbol name. For example ... void Foo() { int Pretend_That_This_Is_A_Decent_Variable_Name; { double Pretend_That_This_Is_A_Decent_Variable_Name; . . . // Explicitly refer to the innermost scope. Pretend_That_This_Is_A_Decent_Variable_Name += 1.2; } } See, no joke involved.int index_a; Foo() { int index_A; . . . index_a = 1; // Did I really mean this or index_A? } Maybe we could have an explicit resolution mechanism to disambiguate such name hiding?This is a joke, right? If not please explain.void Foo() { int Pretend_That_This_Is_A_Decent_Variable_Name; { double Pretend_That_This_Is_A_Decent_Variable_Name;would error here. The rest of the post I have snipped as it appears to me to revolve around our missunderstanding. Regan
Apr 03 2005
On Mon, 04 Apr 2005 16:33:21 +1200, Regan Heath wrote:On Mon, 04 Apr 2005 15:11:14 +1200, Regan Heath <regan netwin.co.nz> wrote:I can live with this. It will mean that occasionally I will be forced to do the 'right thing' but, hey, why not try something new ;-) -- Derek Melbourne, Australia 4/04/2005 3:36:36 PMI've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none. What I was trying to do below was give solutions to the obvious problems this rule will create, reasons for those solutions in terms of good programming practice and the reasons why I see it as good programming practice.
Apr 03 2005
On Mon, 4 Apr 2005 15:38:31 +1000, Derek Parnell <derek psych.ward> wrote:On Mon, 04 Apr 2005 16:33:21 +1200, Regan Heath wrote:I realise some people are going to disagree about what the "right thing" to do is. Of course this *is* a divergance from C/C++ where this is "legal" code (at least according to MSVC). --[hide.c]-- int the_var = 0; void foo(int the_var) { the_var = 2; } void bar() { int the_var; the_var = 3; } int main() { int the_var = 1; foo(the_var); bar(); //for(int the_var = 4;;) { break; } for(;;) { int the_var = 5; break; } { int the_var = 6; the_var = 7; { int the_var = 8; the_var = 9; } } return 0; } NOTE: The commented line above, C does not allow this for construction. --[hide.cpp]-- int the_var = 0; void foo(int the_var) { the_var = 2; } void bar() { int the_var; the_var = 3; } int main() { //int the_var = 1; foo(the_var); bar(); for(int the_var = 4;;) { break; } for(;;) { int the_var = 5; break; } { int the_var = 6; the_var = 7; { int the_var = 8; the_var = 9; } } return 0; } NOTE: The commented line above, if added to the code causes an error on the first for loop. But notice the global did not cause the same error. Regan p.s. Did you read/watch the link on IP. IIRC it's basically using a database to detatch the identity of a variable from it's name, allowing you to call variables by the most appropriate name in each situation/location. Sort of like D's alias (but not quite) and sort of like what happens when you pass things to a function i.e. void foo(int index) {} int i; //temporary var used to calculate something i = //calculate something foo(i); So 'i' a temporary becomes "index" when passed to foo. The name has changed but the variable is the same.On Mon, 04 Apr 2005 15:11:14 +1200, Regan Heath <regan netwin.co.nz> wrote:I can live with this. It will mean that occasionally I will be forced to do the 'right thing' but, hey, why not try something new ;-)I've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none. What I was trying to do below was give solutions to the obvious problems this rule will create, reasons for those solutions in terms of good programming practice and the reasons why I see it as good programming practice.
Apr 03 2005
On Mon, 04 Apr 2005 18:00:35 +1200, Regan Heath wrote: [snip]I realise some people are going to disagree about what the "right thing" to do is. Of course this *is* a divergance from C/C++ where this is "legal" code (at least according to MSVC).I still want D to be D, rather than an evolved C, so that's not going to worry me.p.s. Did you read/watch the link on IP.Yes. Very thought provoking. -- Derek Parnell Melbourne, Australia http://www.dsource.org/projects/build/ v1.19 released 04/Apr/2005 http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage 4/04/2005 4:18:46 PM
Apr 03 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Derek Parnell schrieb am Mon, 4 Apr 2005 15:38:31 +1000:On Mon, 04 Apr 2005 16:33:21 +1200, Regan Heath wrote:<snip>On Mon, 04 Apr 2005 15:11:14 +1200, Regan Heath <regan netwin.co.nz> wrote:I've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none.I can live with this. It will mean that occasionally I will be forced to do the 'right thing' but, hey, why not try something new ;-)That's sensible - with one restriction: modules are the higest scope level, trying to enforce this for package/subpackage scopes would be troublesome. Please activate that rule for the -w mode first, so that there is enough time to fix existing code. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCUOkC3w+/yD4P9tIRAuYQAJ9z3z3tL3UrQmQkiptJ1rP+32ZQkQCbBFNQ ggz8iZBUVeArGH1qNFnrQFw= =EL8s -----END PGP SIGNATURE-----
Apr 04 2005
On Mon, 4 Apr 2005 09:13:06 +0200, Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Derek Parnell schrieb am Mon, 4 Apr 2005 15:38:31 +1000:Do you mean? --[pack\mod1.d]-- int i; --[pack\mod2.d]-- int i; --[foo.d]-- import pack.mod1; import pack.mod2; i = 5; <- error, which one.On Mon, 04 Apr 2005 16:33:21 +1200, Regan Heath wrote:<snip>On Mon, 04 Apr 2005 15:11:14 +1200, Regan Heath <regan netwin.co.nz> wrote:I've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none.I can live with this. It will mean that occasionally I will be forced to do the 'right thing' but, hey, why not try something new ;-)That's sensible - with one restriction: modules are the higest scope level, trying to enforce this for package/subpackage scopes would be troublesome.Please activate that rule for the -w mode first, so that there is enough time to fix existing code.Good idea. Walter what do you think? Regan
Apr 04 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Regan Heath schrieb am Tue, 05 Apr 2005 09:45:23 +1200:On Mon, 4 Apr 2005 09:13:06 +0200, Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> wrote:<snip> - --[pack\mod1.d]-- int i; - --[pack\mod2.d]-- int i; <- error, second i in package scope "pack" Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCUbwr3w+/yD4P9tIRApMYAKC1GLbWe6wkis53ZbZsr2VAFyvAawCgjpQo GSGXEvV+dbOoi+XTz9PlQWw= =yIcs -----END PGP SIGNATURE-----Derek Parnell schrieb am Mon, 4 Apr 2005 15:38:31 +1000:Do you mean?On Mon, 04 Apr 2005 16:33:21 +1200, Regan Heath wrote:<snip>On Mon, 04 Apr 2005 15:11:14 +1200, Regan Heath <regan netwin.co.nz> wrote:I've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none.I can live with this. It will mean that occasionally I will be forced to do the 'right thing' but, hey, why not try something new ;-)That's sensible - with one restriction: modules are the higest scope level, trying to enforce this for package/subpackage scopes would be troublesome.
Apr 04 2005
On Tue, 5 Apr 2005 00:14:04 +0200, Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> wrote:-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Regan Heath schrieb am Tue, 05 Apr 2005 09:45:23 +1200:To me, the above is comparable to: void pack() { { //mod1 int i; } { //mod2 int i; } } as in mod1 and mod2 are beside each other, one is not inside the other. However, if it were possible for "int i" to exist in "pack" itself, then the one in "mod1" or "mod2" would be in hiding a variable in an outer scope "pack". ReganOn Mon, 4 Apr 2005 09:13:06 +0200, Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> wrote:<snip> - --[pack\mod1.d]-- int i; - --[pack\mod2.d]-- int i; <- error, second i in package scope "pack"Derek Parnell schrieb am Mon, 4 Apr 2005 15:38:31 +1000:Do you mean?On Mon, 04 Apr 2005 16:33:21 +1200, Regan Heath wrote:<snip>On Mon, 04 Apr 2005 15:11:14 +1200, Regan Heath <regan netwin.co.nz> wrote:I've done a bad job of explaining myself. Let me try again: I believe the rule should be "If a variable in a scope hides a variable in an outer scope it is an error" - no exceptions, none.I can live with this. It will mean that occasionally I will be forced to do the 'right thing' but, hey, why not try something new ;-)That's sensible - with one restriction: modules are the higest scope level, trying to enforce this for package/subpackage scopes would be troublesome.
Apr 04 2005
Derek Parnell wrote:Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } }I'm not sure if this should be allowed. Does it really make sense for local variables to eclipse each other?void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code><snip> This ought to be legal, considering that they have disjoint scopes, and so the first x would be out of the current symbol table by the time the second one comes along. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on on the 'group where everyone may benefit.
Apr 03 2005
++Stewart.opinion.votes; Stewart Gordon wrote:Derek Parnell wrote:-- Tomasz Stachowiak /+ a.k.a. h3r3tic +/Either the documentation is wrong or DMD is wrong. The examples below compile and run successfully, but according to the docs they should fail. <code> void func2() { int x; {int x;// illegal, x is multiply defined in function scope } }I'm not sure if this should be allowed. Does it really make sense for local variables to eclipse each other?void func3() { {int x; } {int x;// illegal, x is multiply defined in function scope } } </code><snip> This ought to be legal, considering that they have disjoint scopes, and so the first x would be out of the current symbol table by the time the second one comes along.
Apr 03 2005