Switch expressions -- some revisions

Remi Forax forax at univ-mlv.fr
Thu Dec 14 22:59:53 UTC 2017


> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Jeudi 14 Décembre 2017 22:22:48
> Objet: Switch expressions -- some revisions

> After reviewing the feedback on the proposal for switch expressions, and a bit
> of going back to the drawing board, I have some proposed changes to the plan
> outlined in the JEP.

> 1. Throw expressions. While throw expressions are a reasonable feature, many
> expressed concern that if permitted too broadly (such as in method invocation
> context), they would encourage "tricky" code for little incremental
> expressiveness. The real need here is for arms of expression switches to be
> able to throw when an unexpected state is encountered; secondarily it may be
> useful allow a value-bearing lambda to unconditionally throw as well. But
> extending this to &&, ||, assignment, and method invocation context seems like
> asking for trouble. So we'll narrow the treatment here, allowing throw on the
> RHS of a switch expression ARM, and possibly also the RHS of a lambda. (This
> doesn't close any doors on making `throw` an expression later, if desired.)

> 2. Local return from switch. In the proposal, we borrowed the convention from
> lambda to use "return" for nonlocal return, mostly on the theory of "follow the
> arrow". But this is pretty uncomfortable, made worse by several factors: a)
> despite the syntactic similarity, we don't follow exactly the same rules for
> case arms of expression switches as for lambdas (such as treatment of captured
> vars), and b) when refactoring from statement switch to expression switch or
> vice versa, there's a danger that an existing "return" could silently swap
> between nonlocal and local return semantics.

> So we dusted off an old idea, which we'd previously explored but which had some
> challenges, which is to use "break" with an operand instead of "return" to
> indicate local return in switch expressions. So:

> int y = switch(abs(x)) {
> case 1 -> 1;
> case 2 -> 2;
> case 3 -> 3;
> default -> {
> println("bigger than 3");
> break x;
> }
> };

> The challenge is ambiguity; this could be interpreted as a nonlocal break out of
> an enclosing loop whose label is `x`. But then we realized that if `x` is both
> a variable and a label, we can just reject this, and tell the user to rename
> one or the other; since alpha-renaming the label is always source- and
> binary-compatible, the user has at least one (if not two) reasonable choices to
> get out of this problem.

> The benefit here is that now "break" means basically the same thing in an
> expression switch as it does in a statement switch; it terminates evaluation of
> the switch, providing a value if one is needed. Having addressed the ambiguity
> problem, I think this is a slam-dunk, as it aligns expression switch and
> statement switch quite a bit (same capture rules, same control flow
> statements.) We can also, if we like, support "break" for local return in
> lambdas (we should have done this in 8), to align the two.

I'm Ok with break value, having 'return' with two different meaning is dangerous, 
but i still think we should no have the same keyword for the switch and the expression switch (so we will not name i the expression switch), whatever keyword is fine for me but not switch, it's not the same semantics. 

In a language that as no statement or allow the value of a block to be the value of the last expression, it makes sense to have the same construct for statement and expression, 
but Java makes a difference between expression and statement, its' a legacy from the C. 

I've proposed a more lightweight syntax for switch expression because it's what the C or Java do, you have a lightweight syntax if it's an expression and a more heavyweight syntax if it's a statement. 
Now, again, we can keep the 'case', introduce ->, use break with a value for the expression switch but i strongly feel we should not use the same keyword, i.e. for people of the future, Java will have two ways to specify the matching one using switch which is a statement and one using 'put your own keyword here' which is an expression. 

Rémi 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20171214/90c0e98b/attachment.html>


More information about the amber-spec-experts mailing list