----- Mail original -----
> De: "Brian Goetz" <[email protected]>
> À: "Stephen Colebourne" <[email protected]>, "amber-dev"
> <[email protected]>
> Envoyé: Lundi 11 Décembre 2017 20:59:27
> Objet: Re: New JEP: Switch Expressions for the Java Language
> On 12/11/2017 7:04 AM, Stephen Colebourne wrote:
>> At first, my reaction was "great!", but after doing some analysis I'm
>> left feeling this isn't going to work well as proposed...
>>
>> To summarise the proposal, expression switches get:
>> - comma separated OR values
>> - case null
>> - no fall through
>> - enforced default
>> - auto default clause for enums
>>
>> And statement switches get none of these (AFAICT).
>
> Incorrect on the first two items. JEP says:
>
> repeated labels: "A case clause *in a switch statement or expression
> *can provide a comma-separated list of alternatives, such as:"
>
> null: "In *a switch expression **or statement *whose whose argument is a
> reference type (boxed primitives, strings, and enums), a case clause can
> can specify null:"
>
> On the other three, these are driven by either intrinsic properties of
> expression-ness, or compatibility:
> - no fall through -- well, fall through doesn't make sense (in its
> unvarnished form) in expression switch.
> - enforced default -- expressions must be total; conditional
> statements can be unbalanced (like if with no else)
> - auto default clause for enums -- can't do that to statement switch,
> it would change the semantics of existing code.
[...]
to summarize,
we enhance le old switch by adding comma separated list of case values and by
adding null as a possible pattern, and a warning if there is no default or the
default is not at the ends,
then we add an expression switch which extends the old switch as a poly
expression with no fall through (make no sense), no weird scoping rules, the
compiler emits an error if the switch is not exhaustive (need a default at the
end apart for enums).
what i'm currently doing with switch is using statement switch + return as a
poor's man expression switch i.e
instead of
Color color;
switch(name) {
case "red":
color = Color.RED;
break;
case "blue":
color = Color.BLUE;
break;
default:
throw new AssertionError("invalid " + name);
}
...
I tend to refactor by introducing a method
Color color = getColorFromName(name);
...
private static Color getColorFromName(String name) {
switch(name) {
case "red":
return Color.RED;
case "blue":
return Color.BLUE;
default:
throw new AssertionError("invalid " + name);
}
}
which provides most of the guarantee that provide the expression switch, you
ends the case with a return, so no fallthrough,
using return make it a poly-expression (BTW, why do we need to specify the name
of the enum class in a poly-expression ?),
no weird scoping rule, the compiles forces you to write a 'default', otherwise
it doesn't compile.
So when we have started this discussion, i've seen the expression switch as a
way to simplify this pattern, by avoiding to write the switch in a private
method
Color color = switch(name) {
case "red" -> Color.RED;
case "blue" -> Color.BLUE;
default:
throw new AssertionError("invalid " + name);
};
But if we support expression block in the expression switch, the two forms are
very close syntactically,
by example, can you find the difference between
return switch(name) {
case "red" -> {
return Color.RED;
};
case "blue" -> {
return Color.BLUE;
};
default -> {
throw new AssertionError("invalid " + name);
};
};
and
switch(name) {
case "red": {
return Color.RED;
};
case "blue": {
return Color.BLUE;
};
default: {
throw new AssertionError("invalid " + name);
};
};
this is far from obvious, and as a dev you have to because the semantics are
differents.
I wonder if we should either make the syntactic difference more clear, Stephen
proposes switch ... when but what if there is no case at all, IMO the syntax
should not even starts with switch, or we can ban expression block inside an
expression switch.
regards,
Rémi