www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - Do Loop with Variable

reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
I have the feeling this isn’t gonna fly, but I’ll say it anyways 
because maybe someone finds a solution.
```d
do (int x = 0)
{ }
while (++x < 10);
```
which would be equivalent to
```d
{
     int x = 0;
     do
     { }
     while (++x < 10);
}
```

Obviously, we can’t just parse `do` plus the opening parenthesis 
because things like `do (x + y).ufcs while (…)` certainly exist. 
But it can be parsed:

After `do` plus opening parenthesis, scan for the closing 
parenthesis. From there, if an opening brace follows, scan for 
the closing brace. If the closing brace is followed by `while`, 
it’s the new construct.

The new construct must use braces, otherwise ambiguity lurks.
Jul 08
next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```
 [snip]
What is your motivation for this? Making sure `x` doesn't stay around or making sure it doesn't conflict with `x` elsewhere in the program?
Jul 08
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Tuesday, 8 July 2025 at 17:24:11 UTC, jmh530 wrote:
 On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```
 [snip]
What is your motivation for this? Making sure `x` doesn't stay around or making sure it doesn't conflict with `x` elsewhere in the program?
Exactly that. I really would like to have this also in C. I would even go as far as having a special scope rule only applying to `do {} while()`. Where the scope extends to closing parenthesis of the `while`. ```c do { int a = 0; ... } while(a++ < 10); ``` I know that something like that would never fly.
Jul 09
parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Wednesday, 9 July 2025 at 17:13:27 UTC, Patrick Schluter wrote:
 On Tuesday, 8 July 2025 at 17:24:11 UTC, jmh530 wrote:
 On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```
 [snip]
What is your motivation for this? Making sure `x` doesn't stay around or making sure it doesn't conflict with `x` elsewhere in the program?
Exactly that. I really would like to have this also in C. I would even go as far as having a special scope rule only applying to `do {} while()`. Where the scope extends to closing parenthesis of the `while`. ```c do { int a = 0; ... } while(a++ < 10); ``` I know that something like that would never fly.
In C, yeah, it’s not gonna be added. But D? It could be added. D doesn’t allow local variable shadowing, which means that `a` in `while (a++ < 10)` can’t be another local variable (because that would shadow the one defined in the loop body). It could theoretically be a member or global variable, though, but I doubt anyone would intentionally write such code (likely it’s a bug). Essentially, it would mean that ``` do Statement while (Condition); ``` would be equivalent to: ```d { start: Statement if (Condition) goto start; } ``` instead of: ```d { start: { Statement } if (Condition) goto start; } ``` It wouldn’t be the only `{}` that don’t introduce scope. `static if`/`version`/`debug` don’t introduce scope and the first `for` doesn’t introduce scope either: ```d for ({int i; double d = 10;} i < 10; ++i, d /= 2) { } ```
Jul 17
prev sibling next sibling parent reply Dukc <ajieskola gmail.com> writes:
On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```
I would probably prefer if symbols declared inside the do statement would be accessible in the condition. Would be a breaking change though, requiring a warning from the compiler if a symbol declared both inside and outside the do block would be used in `while` and probably doing it over an edition switch.
Jul 17
parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Thursday, 17 July 2025 at 13:43:33 UTC, Dukc wrote:
 On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```
I would probably prefer if symbols declared inside the do statement would be accessible in the condition. Would be a breaking change though, requiring a warning from the compiler if a symbol declared both inside and outside the do block would be used in `while` and probably doing it over an edition switch.
Realistically, if you reference a symbol that’s defined within the loop in the condition that coincidentally resolves because it’s *also* defined in the outer scope, that should be an error. You can always refer to such a symbol in an unambiguous way. Here’s what I mean: ```d struct S { int x; void f() { do { int x; …; } while (x > 0); // likely a bug } } ``` The `x` in `x > 0` refers to `this.x`, not the local variable defined in the loop. My sense is: No-one actually writes such code intentionally. If it really makes sense to name a `do`-loop-body variable the same as an outer-scope variable used in its condition, it’s not too much to ask to make this clear: Use `this.x` or `.x` (global) or whatever. (I filed this as an issue.)
Jul 28
prev sibling parent reply Atila Neves <atila.neves gmail.com> writes:
On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```

 Obviously, we can’t just parse `do` plus the opening 
 parenthesis because things like `do (x + y).ufcs while (…)` 
 certainly exist. But it can be parsed:

 After `do` plus opening parenthesis, scan for the closing 
 parenthesis. From there, if an opening brace follows, scan for 
 the closing brace. If the closing brace is followed by `while`, 
 it’s the new construct.

 The new construct must use braces, otherwise ambiguity lurks.
I think this is of limited utility and there's a workaround.
Jul 31
parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Thursday, 31 July 2025 at 08:38:18 UTC, Atila Neves wrote:
 On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```

 Obviously, we can’t just parse `do` plus the opening 
 parenthesis because things like `do (x + y).ufcs while (…)` 
 certainly exist. But it can be parsed:

 After `do` plus opening parenthesis, scan for the closing 
 parenthesis. From there, if an opening brace follows, scan for 
 the closing brace. If the closing brace is followed by 
 `while`, it’s the new construct.

 The new construct must use braces, otherwise ambiguity lurks.
I think this is of limited utility and there's a workaround.
What’s your opinion on the issue that eponymous symbols can be referenced, leading to bugs? See [this thread entry](https://forum.dlang.org/post/izeyfioitzzcmkjemcii forum.dlang.org). D often bans things that have well-defined semantics in similar languages, but are confusing and easily lead to bugs, especially if being more explicit simply avoids the confusion. Examples include: - Plain assignment expressions cannot be used as conditions. - Combining `=> {}` isn’t allowed. - Bitwise and comparison operators require parentheses. - Shadowing a local variable isn’t allowed. It’d be very much in the same spirit as the last bullet point, just in reverse.
Aug 01
parent Atila Neves <atila.neves gmail.com> writes:
On Friday, 1 August 2025 at 16:19:41 UTC, Quirin Schroll wrote:
 On Thursday, 31 July 2025 at 08:38:18 UTC, Atila Neves wrote:
 On Tuesday, 8 July 2025 at 16:40:24 UTC, Quirin Schroll wrote:
 I have the feeling this isn’t gonna fly, but I’ll say it 
 anyways because maybe someone finds a solution.
 ```d
 do (int x = 0)
 { }
 while (++x < 10);
 ```
 which would be equivalent to
 ```d
 {
     int x = 0;
     do
     { }
     while (++x < 10);
 }
 ```

 Obviously, we can’t just parse `do` plus the opening 
 parenthesis because things like `do (x + y).ufcs while (…)` 
 certainly exist. But it can be parsed:

 After `do` plus opening parenthesis, scan for the closing 
 parenthesis. From there, if an opening brace follows, scan 
 for the closing brace. If the closing brace is followed by 
 `while`, it’s the new construct.

 The new construct must use braces, otherwise ambiguity lurks.
I think this is of limited utility and there's a workaround.
What’s your opinion on the issue that eponymous symbols can be referenced, leading to bugs? See [this thread entry](https://forum.dlang.org/post/izeyfioitzzcmkjemcii forum.dlang.org).
I'd say I've never encountered such a bug, and therefore am biased to think that writing it would be unlikely. I've often said that programmers seem to want features that would prevent them from writing the bugs they usually encounter, this might be an example. I realise that this might happen a lot more often than I think; but at this point in time am unconvinced that it warrants the change.
Sep 03