Next up for patterns: type patterns in switch

Brian Goetz brian.goetz at oracle.com
Wed Aug 12 16:57:19 UTC 2020


> But now I realize that this model is not quite what we had discussed before: I think I need to change one of the rules above (**) to three rules:
>
> 	`default T p` is equivalent to `T p = o; if (true)`
> 	`default var p` is equivalent to `var p = o; if (true)`
> 	`default P(Q)` is equivalent to `if (DEFAULT_EXPAND(o, P(Q)))`
>
> That is, at “top level”, the situations `default T p` and `default var p` are not conditional, but are required to succeed, and you get a static error for the first one if o is not assignable to T.  This may be ugly, but at least it reveals explicitly that we are treating the outermost situation in a `default` label a bit differently from nested situations.

This is the key thing -- the important part is pattern composition (the 
non-nested cases are the mostly uninteresting ones, except for how they 
compose with containing patterns.)  The essence of this approach is that 
`default` modifies not only the pattern, but how patterns compose with 
each other.

And we have been here before, on the road to the current proposed 
semantics!  In an earlier iteration, we first tried to roll 
null-handling into the definition of nesting rather than the definition 
of matching (because we were leaning on the wrong primitive, 
instanceof).  This gave us more flexibility, but we had to give up this 
simple rule for composition:

     x matches P(Q) == x matches P(alpha) && alpha matches Q

to adjust for the observation that total patterns seemed very desirable 
at nested levels even if it was not obvious whether they are as useful 
at the top level.  The cost of this version was that the rules for 
nesting were less compositional, and again, this inhibits what 
refactorings can be done.  Essentially, it meant that top-level patterns 
and nested patterns were different, as a way of rescuing the null 
behavior of switch.

(One conclusion I've come to from the many attempts we've made to find 
the perfect story here is that it is far far easier to start with 
totality and define composition simply and then filter, than to start 
with a non-total set of base cases or sharp-edged compositional rules 
and then try to bake totality back in.)

This direction strikes me as a whack-a-mole exercise for several reasons:

  - It is mucking with composition.  This rarely ends well, and you 
rarely end up with only one knob (or, if one is enough, you still have 
two sets of composition semantics.)
  - There is no fine grained-control; either you muck with the 
composition all the way down, or you don't.
  - (big one) It is using switch syntax to affect pattern semantics. 
What happens for the same patterns in instanceof or catch or 
assignment?  Do we have to invent a different way to say "modify this 
pattern this way" in all these contexts?

(aside, of course, from the baseline "I think this is fixing a problem 
that doesn't really exist" suspicion.)


Here's an observation that the Remi+Stephen crowd are missing: the shape 
of pattern switches will likely be dramatically different from the shape 
of existing switches, and we're trying to apply the wrong intuitions.

The current switches are very, very simple: N-way comparison to 
constants, plus maybe a catch-all, in domains where null almost never 
shows up (and when it does, is almost always an error.)   They are 
"symmetric" in this way.

In pattern switches, though, I'd expect the common (nontrivial) case to 
be much more like:

     case Box(SomethingSpecial x): ...
     case Box(EverythingElse):

     case Bag(SomethingElseSpecial x):
     case Bag(EverythingElse):

     case EverythingElse:

If you think about the partial ordering on patterns given by 
dominance/value set inclusion, you see multiple disjoint chains of 
strictly ordered cases, where each chain locally terminates in a 
catch-all for that chain (or a sub-chain), leaning on the dictionary 
order imposed by composition, with the whole thing often terminating in 
a global catch-all.  That's a very different "shape" that our switches 
today, and I think we're trying to impose intuition from the old shape 
on the new.




More information about the amber-spec-experts mailing list