www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - break while; break for; break foreach

reply Steven Schveighoffer <schveiguy gmail.com> writes:
I've had a few occasions where I have to label a loop that contains a 
switch statement (or vice versa), and then write `break label;` in order 
to break out of the outer construct.

Wouldn't it be nice to just have this implicit, and allow `break 
keyword;` where keyword is one of `for`, `while`, `foreach` and even 
`switch`?

The labeling thing has drawbacks as well -- you can only have one label 
of a given name in a function, making it hard when you have compile-time 
loops that generate the same code with the same label (I've had to deal 
with this by enclosing each branch in it's own immediately-called lambda).

Does this make sense as a language feature? I believe it doesn't break 
(no pun intended) any code since you currently can't have a keyword in 
that position.

Could also allow `continue keyword` though that can be dicey, since 
continue doesn't work for `switch`, and you would have to have 2 
different loops to make it reasonable. But for consistency, you could 
have it.

-Steve
May 13
next sibling parent reply sighoya <sighoya gmail.com> writes:
On Thursday, 13 May 2021 at 16:55:18 UTC, Steven Schveighoffer 
wrote:
 Wouldn't it be nice to just have this implicit, and allow 
 `break keyword;` where keyword is one of `for`, `while`, 
 `foreach` and even `switch`?
I think yes. What about lexical non-local returns?
 Does this make sense as a language feature? I believe it 
 doesn't break (no pun intended) any code since you currently 
 can't have a keyword in that position.
The problem is if you have nested ifs, whiles or fors, wouldn't it be better then to annotate them and likewise the break/continue/return keyword? Kotlin does it similar: https://blog.mindorks.com/learn-kotlin-returns-jumps-labels
May 13
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/13/21 1:34 PM, sighoya wrote:
 On Thursday, 13 May 2021 at 16:55:18 UTC, Steven Schveighoffer wrote:
 Wouldn't it be nice to just have this implicit, and allow `break 
 keyword;` where keyword is one of `for`, `while`, `foreach` and even 
 `switch`?
I think yes. What about lexical non-local returns?
D doesn't have that I think. It would be a much bigger change.
 
 Does this make sense as a language feature? I believe it doesn't break 
 (no pun intended) any code since you currently can't have a keyword in 
 that position.
The problem is if you have nested ifs, whiles or fors, wouldn't it be better then to annotate them and likewise the break/continue/return keyword?
D already does this, you can break using a label. The problem I've had with it is that a label cannot be repeated within a function, so it's hard to write generic code which requires this feature. It may be that we have to require labeling when there is an ambiguity.
 Kotlin does it similar: 
 https://blog.mindorks.com/learn-kotlin-returns-jumps-labels
This is almost exactly how D handles it today (except the return-to-label feature) -Steve
May 13
next sibling parent reply sighoya <sighoya gmail.com> writes:
On Thursday, 13 May 2021 at 19:36:28 UTC, Steven Schveighoffer 
wrote:
 The problem I've had with it is that a label cannot be repeated 
 within a function, so it's hard to write generic code which 
 requires this feature.
Can't this be relaxed in some way?
May 13
next sibling parent reply tsbockman <thomas.bockman gmail.com> writes:
On Thursday, 13 May 2021 at 20:14:45 UTC, sighoya wrote:
 On Thursday, 13 May 2021 at 19:36:28 UTC, Steven Schveighoffer 
 wrote:
 The problem I've had with it is that a label cannot be 
 repeated within a function, so it's hard to write generic code 
 which requires this feature.
Can't this be relaxed in some way?
Yeah, why not just apply the same scoping rules to labels as apply to variables? This would be a non-breaking change. (Undoing the change later would not be, though.)
May 13
parent tsbockman <thomas.bockman gmail.com> writes:
On Friday, 14 May 2021 at 00:58:45 UTC, tsbockman wrote:
 On Thursday, 13 May 2021 at 20:14:45 UTC, sighoya wrote:
 On Thursday, 13 May 2021 at 19:36:28 UTC, Steven Schveighoffer 
 wrote:
 The problem I've had with it is that a label cannot be 
 repeated within a function, so it's hard to write generic 
 code which requires this feature.
Can't this be relaxed in some way?
Yeah, why not just apply the same scoping rules to labels as apply to variables? This would be a non-breaking change. (Undoing the change later would not be, though.)
Well, not the same rules, I guess - since it's currently possible to `goto` from one scope to another. But, there could be a rule that says that a label "bubbles up" to the most outer scope inside the current function where it won't conflict with anything else.
May 13
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/13/21 4:14 PM, sighoya wrote:
 On Thursday, 13 May 2021 at 19:36:28 UTC, Steven Schveighoffer wrote:
 The problem I've had with it is that a label cannot be repeated within 
 a function, so it's hard to write generic code which requires this 
 feature.
Can't this be relaxed in some way?
I'm not sure how. If you were not able to jump into scopes, then it might make sense to allow multiple labels of the same name. Besides, this doesn't fix the issues that you brought up. If you have multiple labels, named the same thing, how do you decide which one to go to? -Steve
May 14
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/14/21 10:17 AM, Steven Schveighoffer wrote:
 On 5/13/21 4:14 PM, sighoya wrote:
 On Thursday, 13 May 2021 at 19:36:28 UTC, Steven Schveighoffer wrote:
 The problem I've had with it is that a label cannot be repeated 
 within a function, so it's hard to write generic code which requires 
 this feature.
Can't this be relaxed in some way?
I'm not sure how. If you were not able to jump into scopes, then it might make sense to allow multiple labels of the same name. Besides, this doesn't fix the issues that you brought up. If you have multiple labels, named the same thing, how do you decide which one to go to?
Hm... possibly another solution, is to attribute the label as "scope only", that is, it's only valid within the scope it's declared in. This is kind of similar to how case labels work. Like: ```d static foreach(...) { { // note extra scope needed scope loop: foreach(...) { switch(...) { break loop; } } }} // goto loop; // would be an error ``` This actually might be more powerful than just breaking out of a given loop, because it would enable other label statements like `goto`, and also allows dealing with nested loops. -Steve
May 14
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 13 May 2021 at 19:36:28 UTC, Steven Schveighoffer 
wrote:
 D already does this, you can break using a label. The problem 
 I've had with it is that a label cannot be repeated within a 
 function, so it's hard to write generic code which requires 
 this feature.
Reusing keywords for different things is not a good idea as it makes code harder to skim through (harder to read fast). If this is only for generic programming, how about a way to break N scopes out and make that N a compiletime expression? So break(1) would jump 1 scope out, break(2) would jump 2 scopes out etc. Maybe overkill.
May 13
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
It's an interesting idea.

One of the downsides is when refactoring code, the "break while" may suddenly 
apply to an unintended while. With "break label" that isn't going to happen.
May 13
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/13/21 3:16 PM, Walter Bright wrote:
 It's an interesting idea.
 
 One of the downsides is when refactoring code, the "break while" may 
 suddenly apply to an unintended while. With "break label" that isn't 
 going to happen.
True. But this also happens with a non-labeled break statement. But we may not want to duplicate that pain with a new feature. Possibly, we could require labels if the target is ambiguous (i.e. `break while` in a `while` nested in a `while`). For sure, the most common use case I think is a switch inside a loop or a loop inside a switch, which should be pretty unambiguous. -Steve
May 13
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/13/21 12:55 PM, Steven Schveighoffer wrote:
 I've had a few occasions where I have to label a loop that contains a 
 switch statement (or vice versa), and then write `break label;` in order 
 to break out of the outer construct.
 
 Wouldn't it be nice to just have this implicit, and allow `break 
 keyword;` where keyword is one of `for`, `while`, `foreach` and even 
 `switch`?
 
 The labeling thing has drawbacks as well -- you can only have one label 
 of a given name in a function, making it hard when you have compile-time 
 loops that generate the same code with the same label (I've had to deal 
 with this by enclosing each branch in it's own immediately-called lambda).
 
 Does this make sense as a language feature? I believe it doesn't break 
 (no pun intended) any code since you currently can't have a keyword in 
 that position.
 
 Could also allow `continue keyword` though that can be dicey, since 
 continue doesn't work for `switch`, and you would have to have 2 
 different loops to make it reasonable. But for consistency, you could 
 have it.
 
 -Steve
break static foreach would be really really nice
May 13
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/13/21 10:59 PM, Andrei Alexandrescu wrote:

 
 break static foreach would be really really nice
Different problem -- this would add a feature that currently doesn't exist. I think there are good reasons why you can't break on a static foreach (a static break might be reasonable though). -Steve
May 14