www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - do ... while visibility rules

reply h3r3tic <foo bar.baz> writes:
It has always seemed counter-intuitive to me that in the <while> block 
of the <do...while> loop inner names can't be accessed...
simplest example: bubble sort

do {
     bool changes = false;

     // iterate thru all elements
     // if swapping anything, set changes = true
} while (changes)

^ This will cause an error complaining about undefined identifier 
'changes'. Yet it's more intuitive to code that way...


bool changes;
do {
     changes = false;

     //...
} while (changes)

^ This will work fine


It seems a little bit C-ish to explicitly define a variable just two 
lines above its initialization. Maybe this could be changed yet ? Or am 
I missing something ?
Oct 25 2004
next sibling parent reply "Ivan Senji" <ivan.senji public.srce.hr> writes:
"h3r3tic" <foo bar.baz> wrote in message
news:clicl1$1ibv$1 digitaldaemon.com...
 It has always seemed counter-intuitive to me that in the <while> block
 of the <do...while> loop inner names can't be accessed...
 simplest example: bubble sort

 do {
      bool changes = false;

      // iterate thru all elements
      // if swapping anything, set changes = true
 } while (changes)

 ^ This will cause an error complaining about undefined identifier
 'changes'. Yet it's more intuitive to code that way...

The problem is that the scope of 'changes' ends with }. And it would be impossible to change it and invent some other reasonable rules. If changes was part of the upper scope than this wouldn't be possible: do { bool changes = false; //something }while(changes) do { bool changes = false; //ERROR allready defined in first do-while //something else }while(!changes)
 bool changes;
 do {
      changes = false;

      //...
 } while (changes)

 ^ This will work fine

And it is the best solution becuase after do-while we still have the state of changes variable.
 It seems a little bit C-ish to explicitly define a variable just two
 lines above its initialization.

It is this way in your tiny code example but very often variables that need to be checked in the condition are assigned to in the middle or near the end of large do-while's, so it is just two lines only in the simplest examples, and isn't generally a problem.
 Maybe this could be changed yet ?

It wouldn't be D anymore, because scoping rules are very well defined now and i don't see how it could be changed.
 Or am
 I missing something ?

Oct 25 2004
parent reply h3r3tic <foo bar.baz> writes:
Ivan Senji wrote:
 The problem is that the scope of 'changes' ends with }. And it would be
 impossible
 to change it and invent some other reasonable rules. If changes was part of
 the
 upper scope than this wouldn't be possible:

 (...)

But I don't mean the 'changes' var to be a part of the outer scope, What I mean is the inner scope should be extended to the while() part. do { // foo } while (...) ^ scope might end with while(...) and not with } It's just like the for loop, you have for (int i; ...) { // i visible here } // i gone here And though 'i' is not defined inside {}, it's invisible after } This would follow the same reasoning do { int i; // ... } while(i) // i gone here /me gone here
Oct 25 2004
next sibling parent "JSRS" <jsrs moselle.com> writes:
I absolutely agree with h3r3tic here.  One of the consistent design goals of 
D is to not have to do stupid things "just because".

In the example, we should not be thinking of the code inside of the braces 
as the relevant part of the do-while loop; instead, we should be thinking of 
everything from "do" to the expression trailing "while" as the relevant 
part.  I fear we are all too quick to think like a compiler here, instead of 
like people!  Make the compiler do the work as much as possible.

As for changing the scoping rules midstream, D is still beta--how many times 
did scoping rules change in C++ before it got finalized?  :-)

Steve

"h3r3tic" <foo bar.baz> wrote in message 
news:clj1ho$2am4$1 digitaldaemon.com...
 Ivan Senji wrote:
 The problem is that the scope of 'changes' ends with }. And it would be
 impossible
 to change it and invent some other reasonable rules. If changes was part 
 of
 the
 upper scope than this wouldn't be possible:

 (...)

But I don't mean the 'changes' var to be a part of the outer scope, What I mean is the inner scope should be extended to the while() part. do { // foo } while (...) ^ scope might end with while(...) and not with } It's just like the for loop, you have for (int i; ...) { // i visible here } // i gone here And though 'i' is not defined inside {}, it's invisible after } This would follow the same reasoning do { int i; // ... } while(i) // i gone here /me gone here

Oct 25 2004
prev sibling parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
"h3r3tic" <foo bar.baz> wrote in message
news:clj1ho$2am4$1 digitaldaemon.com...
 Ivan Senji wrote:
 The problem is that the scope of 'changes' ends with }. And it would be
 impossible
 to change it and invent some other reasonable rules. If changes was part


 the
 upper scope than this wouldn't be possible:

 (...)

But I don't mean the 'changes' var to be a part of the outer scope, What I mean is the inner scope should be extended to the while() part. do { // foo } while (...) ^ scope might end with while(...) and not with } It's just like the for loop, you have for (int i; ...) { // i visible here } // i gone here

Now that you say this it is starting to make sense, and i am beginning to like your idea. :)
 And though 'i' is not defined inside {}, it's invisible after }
 This would follow the same reasoning

 do {
      int i;
      // ...
 } while(i)
 // i gone here




 /me gone here

Oct 25 2004
prev sibling parent Derek Parnell <derek psych.ward> writes:
On Mon, 25 Oct 2004 10:14:17 +0200, h3r3tic wrote:

 It has always seemed counter-intuitive to me that in the <while> block 
 of the <do...while> loop inner names can't be accessed...
 simplest example: bubble sort
 
 do {
      bool changes = false;
 
      // iterate thru all elements
      // if swapping anything, set changes = true
 } while (changes)
 
 ^ This will cause an error complaining about undefined identifier 
 'changes'. Yet it's more intuitive to code that way...
 
 bool changes;
 do {
      changes = false;
 
      //...
 } while (changes)
 
 ^ This will work fine
 
 It seems a little bit C-ish to explicitly define a variable just two 
 lines above its initialization. Maybe this could be changed yet ? Or am 
 I missing something ?

Seems like a logical change to make to the scoping rules of the language. The 'while' is a part of the 'do' statement even though it appears after the final brace. The workaround is to create a block around the 'do-while', something like ... { bool changes; do { changes = false; //... } while (changes) } -- Derek Melbourne, Australia 26/10/2004 12:53:50 PM
Oct 25 2004