Continue in switch
Brian Goetz
brian.goetz at oracle.com
Tue May 8 19:31:37 UTC 2018
This is not an urgent issue for the expression switch work, but I'd like
to get some ideas about how we will want to handle guards in pattern
switch, as we may want to lay some groundwork in the form of warnings now.
Initially we considered explicit guards:
case Foo(var x, var y)
where x <= y: ...
(Note that there is a connection between nested patterns and guards; a
nested pattern P(Q) is equivalent to P(x) with a guard of x matches Q.)
While this is semantically attractive (the guard condition is
declarative), I worry that it is not likely to be very satisfying in
practice. In toy examples, it looks great, but as examples expand to a
more realistic scale, the pattern, guard, and imperative consequence can
easily mush together. For example:
case Point(var x, var y)
where x > 0 && y > 0 && x < y -> x + y;
You can try reformatting:
case Point(var x, var y)
where x > 0 && y > 0 && x < y
-> x + y;
but its not that much better. So, I'm pretty down on this approach
right now, and I think several others are as well.
An alternative is to provide an imperative means to refine the switch
selection. The obvious choice is to give "continue" semantics within a
switch:
case Foo(var x, var y):
if (x > y)
continue; // keep processing at next case
foo(x, y);
break;
Continuing in a switch means "keep testing the target against case
labels, starting with the next case label." This is only a short hop
from the current notion of continue in for/while loops.
Of course, compatibility raises its ugly head. You could have a switch
today with continue-in-switch-in-for:
for (...) {
switch (x) {
case 0: continue; // valid today, means continue the loop
}
}
This code works today, which means a continue in a switch in a loop
would be ambiguous, and would require a label.
As a means of mitigation, we could also allow the syntax "continue
switch" or "continue while" to mean "continue from the innermost
switch/while". This is arguably more readable, and reduces the number
of cases where a label would be required.
If we're going to go the "continue" route, we might want to consider
warning now in cases where there would be an ambiguity, suggesting that
the user use a labeled continue, to move codebases in the right direction.
If continue is the right notion, our choice is essentially between:
- drive towards continue in switch working like it does in everything
else, and deal with ambiguities (switch in loop) as they come up;
- drive towards something that looks sufficiently different from
"naked" continue (continue with label, "continue switch") in switches,
and accept there will be a permanent seam (in switch you do it this way,
in loops, this other way.)
More information about the amber-spec-experts
mailing list