Expression switch - an alternate proposal

Stephen Colebourne scolebourne at joda.org
Sun Apr 8 23:58:03 UTC 2018


What follows is a set of changes to the current expression switch
proposal that I believe result in a better outcome.

The goal is to tackle four specific things (in order):
1) The context as to whether it is a statement or expression switch
(and thus what is or is not allowed) is too remote/subtle
2) Mixing arrows and colons is confusing to read
3) Blocks that do not have a separate scope
4) Fall through by default
while still keeping the design as a unified switch language feature.

To tackle #1 and #2, all cases in an expression switch must start with
arrow -> (and all in statement switch must start with colon :)
To tackle #3, all blocks in an expression switch must have braces
To tackle #4, disallow fall through in expression switch (or add a
fallthrough keyword)

Here is the impact on some code:

Current:

 var action = switch (light) {
   case RED:
     log("Red found");
     break "Stop";
   case YELLOW:
   case GREEN -> "Go go go";
   default:
     log("WTF: " + light);
     throw new WtfException("Unexpected color: " + light);
 }

Alternate proposal:

 var action = switch (light) {
   case RED -> {
     log("Red found");
     break "Stop";
   }
   case YELLOW, GREEN -> "Go go go";
   default: -> {
     log("WTF: " + light);
     throw new WtfException("Unexpected color: " + light);
   }
 }

How is this still a unified switch? By observing that switch can be
broken down into two distinct phases:
- matching
- action
What makes it unified is that the matching phase is shared. Where
statement and expression switch differ is in the action phase.

The unified matching phase includes:
- target expression to switch on
- case null
- constant case clauses
- pattern matching case clauses
- default clause

The action phase of a statement switch is:
- followed by a colon
- have non-scoped blocks
- fall through by default
- can use return/continue/break

The action phase of an expression switch is:
- followed by an arrow
- have an expression or a block (aka block-expression)
- cannot fall through
- cannot use return/continue/break

By having a unified matching phase and a separate (but consistent)
action phase in each form, I believe that the overall language feature
would be much simpler to learn. And importantly, it achieves the goal
of not deprecating or threatening the existence of the classic
statement switch.

All the key differences are in the action phase, which is clearly
identified by arrow or colon (no remote context). Developers will come
to associate the rule differences between the two forms with the arrow
or colon, while the pattern matching knowledge is shared.

Of course, the matching phase is not completely unified - expression
switches must be exhaustive, and they may have auto default case
clauses. (Perhaps the unified matching phase mental model suggests
that auto default would be better written explicitly, eg. "default
throw;", which could then apply to both statement and expression. Not
sure.)

I hope this alternate proposal is clear. To me, the split between a
unified matching phase and a consistent but different action phase
clearly identified in syntax results in much better readability,
learning and understandability.

Stephen
PS. I think there are alternate block expression syntaxes, including
ones that avoid "break expression", but I've chosen to avoid that
bikeshed and use the closest one to the current proposal for the
purpose of this mail


More information about the amber-dev mailing list