On Mar 23, 2018, at 11:45 AM, Brian Goetz <brian.go...@oracle.com> wrote: > > 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.)
It surprises me that break-e is so much more restricted than return, since I would expect we would aim at a design where an switch-e could be refactored incrementally to a method and vice versa (in cases where the e-switch had no side effects on locals). The symptom of this design choice is the large number of X entries in the break-e column, where there are few X entries in the return column. I suppose you are aiming in this direction to reduce occasional ambiguities between break-e and break-l. But such ambiguities can be controlled in other ways while getting more free passage of break-e to its enclosing switch, through intervening control flow. The break-e column assigns L to switch-e (obviously the root requirement) and X to everything else except block. I would expect the break-e column would assign P to everything except lambda and method, in symmetry with the return column, which assigns P to everything except switch-e (and naturally L to lambda and method). Specifically, this should not be ruled out, IMO: int x = switch (e) ( case 0: for (int y : someInts) { if (y < x) break (y); } return 0; default: return e; }; We have already discussed ways to deal with the ambiguity that could (rarely!!) arise if a name like "y" above also looks like a statement label. Reporting the ambiguity as an error is an easy thing to do, or quietly accepting the label in preference to the expression is also easy. Under either rule, users can use parens (as above) to make clear which kind of break statement they mean. Am I missing some other consideration? — John