Friday, April 20, 2018

Enhancing Java switch Statement with Introduction of switch Expression

In late December of last year, I posted "Switch Expressions Coming to Java?" Since then, there has been significant discussion, expressed differences of opinion, and now a coalescence of general agreement regarding the future of switch expressions in Java. I have tried to capture some of the major developments related to switch expressions as comments on my December blog post. However, I felt like this week's Brian Goetz message title "[switch] Further unification on switch" on the amber-spec-observers mailing list warranted a new blog post on Java switch expressions.

Goetz opens his message with a reminder that the end game is not Java switch expressions. Instead, Goetz points out that "switch expressions are supposed to just be an uncontroversial waypoint on the way to the real goal, which is a more expressive and flexible switch construct that works in a wider variety of situations, including supporting patterns, being less hostile to null, use as either an expression or a statement, etc."

Goetz also points out that "switch does come with a lot of baggage" and he points out that "this baggage has produced the predictable distractions in the discussion." Goetz states that "the worst possible outcome ... would be to invent a new construct that is similar to, but not quite the same as switch ... without being a 100% replacement for today's quirky switch." Given that concern, the original proposed switch expression syntax is being discarded because it was leading the discussion toward this "worst possible outcome."

The new switch unification proposal (dubbed "Unification Attempt #2" [UA2]) proposes that "that _all_ switches can support either old-style (colon) or new-style (arrow) case labels -- but must stick to one kind of case label in a given switch." This means that a given switch's case labels all must use either the "colon" syntax we're used to today with switch statements or used the new proposed "arrow" syntax, but cannot use both within the same switch.

There are reasons a developer might choose one form over the other ("colon" versus "arrow"). Goetz highlights some advantages of the "arrow" syntax associated with switch's current proposal: "in the all-arrow form, all of the things people hate about switch -- the need to say break, the risk of fallthrough, and the questionable scoping -- all go away."

Goetz, in text, presents how the "structural properties" of the various "switch forms" drive "control flow and scoping rules." This is shown in the following table.

("Nonlocal control flow _out_ of a switch [continue to an enclosing loop, break with label, return]")
(Totality: return a value)
(Enables Fall-through)
switch we know and "love", but enhanced break returns a value like return
(Prevents Fall-through)
"Syntactic shorthand" for Statement/Colon (above) plus
  • "obviates the annoyance of 'break'"
  • "implicitly prevents fallthrough of all forms"
  • "avoids the confusion of current switch scoping"
Arrow (->) points to returned value

Goetz summarizes what the above table shows with the statement "the colon form gives you the old control flow and the arrow form gives you the new. And either can be used as a statement, or an expression. And no one will be confused by mixing." He also specifically describes the structure in the lower left corner of the table above (switch statement with "arrow" syntax): "Switch statements now come in a simpler (arrow) flavor, where there is no fallthrough, no weird scoping, and no need to say break most of the time. Many switches can be rewritten this way, and this form can even be taught first."

Goetz concludes his post with this promising summary:

The result is one switch construct, with modern and legacy flavors, which supports either expressions or statements. You can immediately look at the middle of a switch and tell (by arrow vs colon) whether it has the legacy control flow or not.

The overall response so far to the proposed "Unification Attempt #2" so far has been overwhelming positive, but not without the expected lingering concerns. Gavin Bierman summarizes this proposal by saying "it's really all about enhancement as opposed to a new construct" and states, "Writing revised spec as we speak - be ready!"

1 comment:

@DustinMarx said...

There continues to be detailed discussions on the OpenJDK mailing lists regarding switch expressions with some of the recent discussions starting with these messages: "Continue in switch", "Treatment of nested 'break'", "JEP325: Switch expressions spec", and "Exhaustiveness in switch".