Call for bikeshed -- break replacement in expression switch

Alex Buckley alex.buckley at oracle.com
Thu May 16 19:36:38 UTC 2019


On 5/16/2019 8:24 AM, Brian Goetz wrote:
> We’ve probably pretty much explored the options at this point;  time to
> converge around one of the choices...

I am very happy with `yield` as the new construct for concluding the 
evaluation of a switch expression and leaving a value on the stack for 
consumption within the method.

I think a statement form for the new construct is ideal. The purpose of 
the new construct is to complete abruptly in an attempt to transfer 
control back to the switch expression, which then completes normally 
with a value. Abrupt completion and an attempt to transfer control are 
the hallmarks of `break`, `continue`, and `return`; having `yield` as 
the junior member of that club is quite natural. Putting the junior and 
senior members side by side shows both similarity and difference:

-----
A `yield` statement attempts to transfer control to the innermost 
enclosing switch expression; this expression ... then immediately 
completes normally and the value of the _Expression_ becomes the value 
of the switch expression.

A `return` statement attempts to transfer control to the invoker of the 
innermost enclosing constructor, method, or lambda expression ... In the 
case of a return statement with value _Expression_, the value of the 
_Expression_ becomes the value of the invocation.
-----

Note that the aspect of _attempting_ to transfer control applies to 
`yield` just as much as to `break`, `continue`, and `return`. Below, the 
`finally` block "intercepts" the transfer of control started by `yield`. 
The `finally` block then completes normally, so the transfer of control 
proceeds and the switch expression completes normally, leaving 5 or 6 on 
the stack.

```
int result = switch (x) {
     case 0 -> {
         try {
             ...
             if (...) yield 5;
             ...
             yield 6;
          }
          finally {
              cleanUp();
          }
     }

     default -> 42;
};
```

Abrupt completion and transfer of control are not the hallmarks of 
operators. The purpose of an operator is to indicate the kind of 
expression to be evaluated (numeric addition, method invocation, etc), 
so an operator-like syntax such as `^` would suggest the imminent 
evaluation of a NEW expression. However, we are ALREADY in the process 
of evaluating a switch expression; in fact we would like to finish it up 
by transferring control from the {...} block (which has been happily 
executing statements sequentially) to the switch expression itself (so 
it can complete normally). So, I think an operator-like syntax is 
inappropriate.

Alex


More information about the amber-spec-observers mailing list