Expression switch feedback
Stephen Colebourne
scolebourne at joda.org
Sat Apr 7 23:35:49 UTC 2018
Some feedback on expression switches (from having to write a
presentation about Project Amber features).
The model being used for expression switches is that they are just
switches with a few enhancements. I'm uncomfortable with this for a
number of reasons.
1) Personally I find the following to be deep flaws in statement switch:
- fall through by default - a source of bugs and confusion
- case clauses that act like blocks but without their own scope, such
that variable declarations clash with other cases (hit me again today)
I fully understand the reluctance to create a second switch-like
language feature. But it seems to me that these two problems can be
designed out without expression switch being completely different.
(The only use case for fall through I ever see presented is low level
network code, which is very much an edge case. Is there some use case
in pattern matching for fall through that I am unaware of?)
2) Normally when adding a new feature the desire is to add the feature
in a way that will makes sense viewed 10 years hence. However the
current explanation for expression switch is couched in terms of 'its
just the same old statement switch with a few new extras'. This gives
the appearance of being a design for existing developers migrating,
rather than a strong design for the longer term.
3) Expression switch is unlike any other kind of element in the
language, and this is causing rough edges. It is not especially like a
"normal" expression, nor like a "normal" statement or method.
While expressions in Java can be large, they are generally relatively
small. The largest expressions (and I think the only ones with curly
braces) are inner classes and block lambdas, both of which define
method-like constructs with very clear method-like scoping and
semantics. With the current proposal, we have curly braces inside
expressions where they are not methods, and those braces have impacts
on use of the return keyword for example. It will also be tricky to
explain in 10 years time why if..else has ternary as its expression
counterpart, but switch is both statement and expression.
4) The context as to whether it is an expression or statement has the
potential to be too remote and impact reading/writing code. The
problem is most apparent with return. The current proposal is to
disallow return within expression lambdas (a reasonable choice,
although I'm not 100% convinced of it). The problem is that switch
statements tend to be large, and the is no reason why expression
switches would not also be large (since blocks are allowed).
Specifically, it is not uncommon for a switch statement to be longer
than the vertical editor space, and thus you may be reading code in
the middle of a switch without context of whether it is a statement or
an expression switch.
// lots of code
case FOO:
if (bar == null) {
return "str"; // is this allowed or not?
}
// lots more code
This is only allowed in a statement switch, yet because switches can
be large, the context as to whether it is a statement or expression
switch cannot be seen, ie. the context that determines code validity
is too remote.
Some other more positive thoughts:
1) The addition of "case null" seems simple to understand and explain
2) The addition of comma separated cases also seems simple to
understand and explain
3) The use of "break expression" seems generally to be fine, I'm not
too concerned about the interaction with "break label".
However, I would ask for consideration to allow "break :label" and
"continue :label" (a colon before the label) to be valid syntax, so
that over time developers could transition to a clearer way to express
labelled breaks distinct from expression breaks.
4) The automatic default clause for enums seems good and desirable,
but it will be odd not having it in statement switches.
Finally, as far as I can tell, the following is legal in the current
proposal. Is this true?:
var action = switch (trafficLight) {
case RED: System.out.println("Found red"); // fallthru
case YELLOW -> "Stop";
case GREEN:
System.out.println("Found green");
break "Green";
}
(I find this mixture of expression and statement styles complex and ugly)
Rather than complicate this mail, I'll follow up separately with my
thoughts on what I'd change in the current proposal.
Stephen
More information about the amber-dev
mailing list