Treatment of nested 'break'

Dan Smith daniel.smith at
Wed May 9 18:14:06 UTC 2018

> On May 8, 2018, at 7:16 PM, Brian Goetz <brian.goetz at> wrote:
>> I am concerned about the treatment of 'break' statements in switch expressions. The following seems like something that would be very natural to do:
>> boolean x = switch (expr()) {
>>   case FOO -> {
>>       for (String s : strings) {
>>           if (s.isEmpty()) break false;
>>       }
>>       break true;
>>   }
>>   case BAR -> true;
>>   default -> false;
>> };
> This should be valid.  If you recall the table I posted regarding abrupt completion, the for-loop should be transparent to “break val”, in the same way it is transparent to “return” or “throw” or that block expressions are transparent to all abruptly completing statements.  The constraint on “case Foo -> { … }” is that the block must complete abruptly via break-value.  

Definitely prohibited in the current spec. But... this table?

> More formally; we can construct a table whose rows are the control constructs and whose columns are the nonlocal branches, and whose entries are "handlers" for a nonlocal branch.  Each block has a parent (the immediately enclosing block.)
>             break-e   break   break-l   continue   return
> switch-e      L         X       X         X          X
> switch-s      X         L       P         L          P
> for           X         L       P         L          P
> while         X         L       P         L          P
> block         P         P       P         P          P
> labeled       X         X L*        X          P
> lambda        X         X       X         X L
> method        X         X X         X          L
> The handlers mean:
> X -- not allowed
> P -- let the parent handle it
> L -- handle it and complete normally
> L* -- handle it and complete normally if the labels match, otherwise P

I'm worried about those X's in the first column.

A simplified model which the spec suggests: there are certain constructs that introduce control flow barriers: method, constructor, initializer, lambda body, switch expression body. It's an error if a break/continue/return reaches one of those and cannot be handled. Nested within one of those, all constructs may choose to handle a break/continue/return, or (by default) propagate it outward.

A method/constructor/initializer/lambda body/switch expression body cannot choose to propagate a break/continue/return outward (i.e., "P" is not valid), and other constructs cannot choose to prohibit a break/continue/return (i.e., "X" is not valid).

More information about the amber-spec-experts mailing list