language icon indicating copy to clipboard operation
language copied to clipboard

Use block-scoped variables in `while`

Open alexeyinkin opened this issue 6 months ago • 1 comments

Currently this does not work:

void main() {  
  do {
    int n = 1;
  } while (n > 1); // Error: Undefined name 'n'.
}

This is because the scope of n ends with }

However, this does not mirror the way that for works. for creates a scope that end with } despite that the variable is defined outside of {}:

void main() {
  for (int n in [1]) {}
  n = 2; // Error: Setter not found: 'n'.
}

If this suggestion is implemented, conditional loops can be made easier.

alexeyinkin avatar Jan 08 '24 03:01 alexeyinkin

There is one issue with making variables created inside do loops visible in the condition:

int x = 0;
do {
  if ((++x).isEven) continue;
  var mod3 = x % x;
} while ((x.isEven ? mod3 = -1 : mod3) != 0);

Here there is a conditional continue before the variable declaration, which means it's possible to reach the while expression without initializing the variable.

It's not an insurmountable issue, that variable could just not be definitely assigned in the condition, so it would be invalid to read it (but not write it, as the example shows), but it's still different from other variables, which we don't allow you to refer to at all if execution hasn't passed the declaration.

It's consistent with the Dart specification of variables, which is that they are all introduced at the beginning of the block, and you just can't refer to them until after the declartion. Here, the condition is after the declaration. It's just that everywhere else, it's not possible to jump past a variable declaration without also nesting that declaration inside another block, which would have ended its scope a the jump target. By extending the scope past the block, in a construct that contains a way to jump to the end of the block, we introducve this new complication.

lrhn avatar Jan 08 '24 08:01 lrhn