JEP325: Switch expressions spec

Kevin Bourrillion kevinb at
Fri Apr 20 17:37:13 UTC 2018

On Wed, Apr 18, 2018 at 11:16 AM, Kevin Bourrillion <kevinb at>

If one of the patterns is a constant expression or enum constant that is
>> equal to the value of the selector expression, then we say that the pattern
>> *matches*.
> I think "equal" is ambiguous for strings (and will be for doubles when
> they happen).

Whoops: I belatedly noticed that we *are* expanding to all primitive types
already. Okay. So, unless I missed it somewhere, I think we need to specify
that all comparisons are made *as if by equals()* on the (boxed) type (or
whatever better way to word it). We might even want to call out the
specific consequences that case NaN: works as expected, and that 0.0 and
-0.0 are fully distinct despite being ==.

But here is the real wrench I want to throw in the works... (and I
apologize, as always, if I am unknowingly rehashing old decisions that were
already finalized):

The most compelling reason to support float and double switches is the fact
that pattern matching will automatically cover them via boxing anyway. If
it were not for that, I believe it is a feature with too much risk to be
useful. case 0.1: simply does not mean what* any* developer would wish it
to mean. At Google we spend real effort trying to get our developers to
depend *less* on exact floating-point equality, not more.

So, all I'm asking is: can we make this particular change atomically with
patterns itself, not before? I believe that the change has negative value
until then because it is too easy to use it to write bugs. (If this means
that long and boolean also wait until then, I don't think anyone would
really mind. If necessary I can look up how common simulated-switch-on-long
happens in our codebase, but we all know it won't be much.)


Separately but similarly, the merits of case null: have also been justified
almost entirely in the context of patterns. Without patterns, I believe the
benefits are far too slight. We studied six digits' worth of switch
statements in the Google codebase, using a *liberal* interpretation of
whether they are simulating a null case, and came up with ... 2.4%.  (You
will find that suspicious as hell, since it's the exact same percentage I
cited for fall-through yesterday, but I swear it's a coincidence!)

Worse than the benefit being small is the fact that compatibility is
forcing us to make a concession in its behavior that I am sure we would
*never* make for a freshly designed feature. What we will be saying is: "
default means default... except when it doesn't." It also will force us to
support the construct default, case null: in the language, which we would
never need for any other reason. (Occasionally people *do* list default
together with other case labels, but they never *need* to.)

Another problem, which is *much* smaller, is the "moral hazard" of possibly
moving the needle back toward null-friendly programming - more than just
permitting null, but actually ascribing particular *meaning* to null, which
is well understood to be a code smell. Eh, I almost didn't mention this,
but thought it should at least be considered.

So, separately but similarly, I also ask: can we please delay this change
until such time as it is (tragically) forced by patterns?

More information about the amber-spec-observers mailing list