JEP proposed to target JDK 12: 325: Switch Expressions (Preview)

Brian Goetz brian.goetz at oracle.com
Tue Aug 28 00:02:55 UTC 2018


>
> The few objections raised here are not new, having already been raised
> and answered over on the amber-dev and amber-spec-experts lists.  I’ve
> therefore targeted this JEP to JDK 12.
>

As Mark says, the issues raised on this thread were already considered 
and discussed at some length during the design of the feature.  But, for 
the convenience of readers here, I will summarize for the record some of 
the reasons why these suggestions were not incorporated into the final 
design of the feature when they came around the first time.

Stephen raised several specific objections, which I'll summarize as:

  - You're increasing complexity by adding three features, one of which 
is silly, and which gives us more fallthrough rather than less, which is 
surely a move in the wrong direction!
  - I don't love the syntax.
  - You should have created a new syntactic form (hereafter, "snitch", 
for "new switch") and left classic switch for dead, rather than piling 
more complexity on existing switch, because existing switch is 
hopelessly tied to the dumb idea of fallthrough.  Die, fallthrough, die.

Ben expressed general agreement, and specifically for the "you should 
have killed switch and made something new" position.  While I understand 
where these opinions come from, and we did consider these issues 
seriously, we concluded that abstracting the existing switch construct 
as we did was a better long-term path.

Ben also raised the excellent point that language design is a balance 
between the interests of experienced developers and of newcomers -- a 
concern we struggle with in every single feature, and which also played 
into our decision here.


The first sentiment, which I've seen expressed in a few places, relies 
on a somewhat tortured notion of "feature".  We have not added three 
features (enhanced statement switch, classic expression switch, enhanced 
expression switch), as much as added _two_ features, defined at a very 
different level:

  - The ability for switch to be an expression or a statement
  - The choice of classic case labels or enhanced case labels, where the 
latter are single consequent, fallthrough-free, and free of the 
confusing scoping of the classic switch block (essentially, fixing most 
of the things people complain about with respect to switch.)

  These features work orthogonally, so that you can mix and match them 
freely, and I don't think anyone could reasonably object that either is 
frivolous or undesirable.  So while they do give rise to four 
combinations, these combinations are not features in themselves.  
Defining the improvements to switch as orthogonal choices makes the 
design and implementation _simpler_, not more complex, as we can then 
reason about the semantics of a particular combination based on the 
semantics of simpler orthogonal primitives.

The fact that some combinations of these features are more desirable 
than others is not evidence that a mistake was made.  This is often the 
natural consequence of providing simple primitives that can be combined 
orthogonally; some of the combinations are always going to be more 
sensible than others, and that's fine.  So while "classic expression 
switch" may seem silly, and will almost certainly be rarely used in 
practice, that doesn't mean that we should distort the language design 
to prevent it.  In fact, doing so would increase, not decrease, the 
complexity, as it introduces arbitrary constraints and special cases.  
(As a possibly tortured analogy, while we might almost never write a 
combination of public setter and private getter, that's no reason to try 
and outlaw that combination.)

As to syntax preferences ... because syntax is so deeply subjective, 
there is never going to be a syntax that satisfies everyone.  And, 
people being what they are, they tend to only complain about the things 
they disagree with, and are quiet about the things they agree with.  So 
any syntax decision (whatever it is) is going to be met with some degree 
of "I don't like it" or "I would have preferred X" -- but again, that 
isn't necessarily actionable or dispositive.  The syntax choice we made 
here is consistent with how similar things are done in similar languages 
-- and we think it will, perhaps after a few days of initial 
brain-retraining, be well-understood and accepted by Java developers.

The final concern is a combination of pragmatism and language evolution 
philosophy -- whether it is better to abandon an existing feature and 
create a replacement, or to try and rehabilitate or generalize an 
existing feature.  While we asked ourselves many times whether switch 
could indeed be rehabilitated (not just in the context of this smaller 
feature, but in the context of the bigger feature arc of pattern 
matching), we found that, at each turn, it was more practical to 
rehabilitate it than one might have initially thought.  And we felt it 
better to build on the existing feature that is well understood and well 
documented, than to create a wholly new one, just because the old one 
was imperfect.

Ben expressed concerns along the lines of "think of the students" with 
respect to the proliferation of switch forms, but the reality with a 
separate "snitch" form would most likely be worse.  Students would not 
be fully absolved of the need to learn "old switch", not only because 
they will encounter code that uses it, but because snitch would almost 
certainly be tilted towards the "happy cases", which, while common, are 
not universal.  And by un-anchoring snitch from switch, the differences 
would likely be more arbitrary.  So new students would encounter a 
language with two suspiciously similar constructs, but subtly different 
in harder-to-understand ways, and wonder why there are two ways to do 
it.  The burning hulk of "old switch" would lie forever on the roadside, 
but unable to be ever hauled away.  Its nice to think that we can invent 
the ideal "snitch" construct, and just leave "switch" in the past, but 
that's a fantasy.

Now, if switch were truly broken, it might be different.  But for all 
the distaste of fallthrough-by-default, the existing switch construct is 
_not_ fundamentally broken; it's not just what we'd design now if we had 
a clean sheet of paper.  (BTW, fallthrough itself is not a problem, and 
sometimes is essential; the real mistake was fallthrough _by default_.)  
Therefore, while we did consider whether it would be necessary to retire 
"switch" to pasture, we found no evidence that this was actually 
necessary -- and found that it was possible to enhance switch to support 
all the desired behaviors, rather than to abandon it, however tempting 
the latter course might initially seem.  Enhancing switch builds on the 
existing understanding of Java developers; abandoning it for snitch 
invalidates that understanding.

At a meta level, this inclination -- "just abandon switch and build 
something better" -- illustrates a common temptation that is best 
avoided: over-rotating towards the desire to "fix" the mistakes of the 
past because they offend us, and because the current opportunity seems 
"the last chance" to right a wrong that's been bugging us for years.  
These are natural motivations, but they are frequently siren-songs that 
lure us away from the path that calmer reason might otherwise have 
chosen.  Yes, it would have been better if switch were designed 
differently 20 years ago, but that was billions of programmer-hours and 
lines of code ago, and the calculus is very different with such a large 
existing base of code and user understanding.  So, while I understand 
why it feels like an "opportunity missed", the cost of "seizing" this 
opportunity was too great, and the benefit too small.  Its natural to 
regret that we can't fix the mistakes of the past, but in this case, it 
would have been the wrong choice.

The preview mechanism will allow us to gather feedback on the feature 
from actual use, rather than theorizing from no examples, and 
potentially adjust the specification before final release if warranted.  
So if any _new_ issues up come as a result of actual experience, we are 
happy to hear about them.




More information about the jdk-dev mailing list