Thread overview
do ... while visibility rules
Oct 25, 2004
h3r3tic
Oct 25, 2004
Ivan Senji
Oct 25, 2004
h3r3tic
Oct 26, 2004
JSRS
Oct 26, 2004
Ivan Senji
Oct 26, 2004
Derek Parnell
October 25, 2004
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 ?
October 25, 2004
"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 ?




October 25, 2004
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
October 26, 2004
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


October 26, 2004
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
October 26, 2004
"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

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