Date: Wed, 18 Dec 2024 22:57:18 -0800
> If you take this logic to the extreme, you should not be allowed to
write:
> > if (...) {
> > break;
> > }
You can't
On Wed, Dec 18, 2024 at 9:34 PM Jan Schultke <janschultke_at_[hidden]>
wrote:
> > IMHO, this violates the idea of scope encapsulation. The inner
> loop/scope should not know or care what the outer loop/scope is doing nor
> why. And vise-versa. Just because you can does not mean you should.
>
> If you take this logic to the extreme, you should not be allowed to write:
> > if (...) {
> > break;
> > }
>
> The scope inside of the if statement should not care about the
> surrounding loop, so break should be ill-formed here, right?
> Obviously, this is a cartoonish take, but what about:
>
> > switch (c) {
> > case ' ': break outer;
> > default: count++;
> > }
>
> If breaking a loop from inside an if statement is totally fine and
> doesn't violate this strict notion of "scope containment", then why
> would it not be okay to break a loop from inside a switch? Switches
> and if statements do very similar things.
>
> Another thing to consider is that many loops (and this is a common use
> case for break/continue outer) is that many loops are "closely tied".
> For example:
> > outer: for (int y = 0; y < height; ++y)
> > for (int x = 0; x < width; ++x)
>
> While this is technically two loops, it's really just a way of
> iterating over say, all pixels in a buffer, and so an action such as
> "break" or "continue" can be applied to both loops, reasonably. I
> don't see anything wrong with this; these two loops are spiritually
> one loop over all positions anyway.
>
> Furthermore, if "break outer" is wrong, then what do you think about
> "return" inside a loop? Return can also escape arbitrarily many loops
> at the same time. Is that a wrong thing to do?
>
> > 'Break' breaks out of the scope and goes to after the _end_ of this
> scope.
> > 'Continue' stays in the loop, continuing with for the next iteration of
> the scope, from the the _top_ of this scope.
>
> The proposal doesn't change that; that's still exactly how it works.
> The only difference is that the "continue" and "break" don't have to
> apply to the innermost surrounding scope, but you can e.g. target the
> for loop enclosing the switch where you break. Philosophically, we are
> still targeting "this scope", we're just free to make "this scope" a
> bit broader.
>
> Fwiw, you're not the first person to allege that "break label" will
> lead to spaghetti. However, I don't see any empirical evidence to back
> this up, and I have never seen a style guide for a language with this
> feature that would disallow breaks with labels. Also, I encourage you
> to come up with a way to rewrite the motivating example in the draft
> without use of "continue process_files". Or do you think the
> motivating example is actually fine, and the use of "continue
> process_files" does NOT lead to spaghetti?
>
write:
> > if (...) {
> > break;
> > }
You can't
On Wed, Dec 18, 2024 at 9:34 PM Jan Schultke <janschultke_at_[hidden]>
wrote:
> > IMHO, this violates the idea of scope encapsulation. The inner
> loop/scope should not know or care what the outer loop/scope is doing nor
> why. And vise-versa. Just because you can does not mean you should.
>
> If you take this logic to the extreme, you should not be allowed to write:
> > if (...) {
> > break;
> > }
>
> The scope inside of the if statement should not care about the
> surrounding loop, so break should be ill-formed here, right?
> Obviously, this is a cartoonish take, but what about:
>
> > switch (c) {
> > case ' ': break outer;
> > default: count++;
> > }
>
> If breaking a loop from inside an if statement is totally fine and
> doesn't violate this strict notion of "scope containment", then why
> would it not be okay to break a loop from inside a switch? Switches
> and if statements do very similar things.
>
> Another thing to consider is that many loops (and this is a common use
> case for break/continue outer) is that many loops are "closely tied".
> For example:
> > outer: for (int y = 0; y < height; ++y)
> > for (int x = 0; x < width; ++x)
>
> While this is technically two loops, it's really just a way of
> iterating over say, all pixels in a buffer, and so an action such as
> "break" or "continue" can be applied to both loops, reasonably. I
> don't see anything wrong with this; these two loops are spiritually
> one loop over all positions anyway.
>
> Furthermore, if "break outer" is wrong, then what do you think about
> "return" inside a loop? Return can also escape arbitrarily many loops
> at the same time. Is that a wrong thing to do?
>
> > 'Break' breaks out of the scope and goes to after the _end_ of this
> scope.
> > 'Continue' stays in the loop, continuing with for the next iteration of
> the scope, from the the _top_ of this scope.
>
> The proposal doesn't change that; that's still exactly how it works.
> The only difference is that the "continue" and "break" don't have to
> apply to the innermost surrounding scope, but you can e.g. target the
> for loop enclosing the switch where you break. Philosophically, we are
> still targeting "this scope", we're just free to make "this scope" a
> bit broader.
>
> Fwiw, you're not the first person to allege that "break label" will
> lead to spaghetti. However, I don't see any empirical evidence to back
> this up, and I have never seen a style guide for a language with this
> feature that would disallow breaks with labels. Also, I encourage you
> to come up with a way to rewrite the motivating example in the draft
> without use of "continue process_files". Or do you think the
> motivating example is actually fine, and the use of "continue
> process_files" does NOT lead to spaghetti?
>
Received on 2024-12-19 06:57:31