Next up for patterns: type patterns in switch

Brian Goetz brian.goetz at oracle.com
Wed Aug 12 14:29:50 UTC 2020


>
>
>     So, who is bothered by the fact that case #3 gets Box(null), and
>     case #6 gets Bag(null)?  Anyone? (And, if not, but you are
>     bothered by the lack of totality on the true catch-alls, why not?)
>
>
> I'm bothered if the pattern are not declared as total

That's too bad, because there was a proposal that might work (`default` 
enables type checking for totality on switches) and now you want to 
escalate it to something that "totally" does not work (`default` makes 
_patterns_ total.)

> and i believe Stephen Colebourne on amber-dev is proposing exactly the 
> same rules.
>

You should read my long explanation to Stephen over there.  TL;DR: this 
is not engaging with half of what pattern matching is really for, and so 
is coming to the wrong answer.  Totality needs to be a property of the 
pattern, not the context -- otherwise, the same pattern in switch 
doesn't mean the same pattern in instanceof, and each construct needs 
its own totality hacks.  This is just another bad variant; worse, in 
fact, that the "any x" proposal.

Having total patterns is very important; if I have:

     record Bag<T>(T t) implements Container<T> { }
     record DoubleBox<T>(InnerBox<T> x) implements Container<T> { }
     record InnerBox<T>(T x) { }

and I do

     switch (container) {
         case DoubleBox(InnerBox(var x)): ...
     }

the outer pattern is not total on Containers (doesn't match Bag), but 
the inner pattern is once we match DoubleBox.  I want to match all 
DoubleBoxes, and destructure their contents.  If I try to wedge totality 
into patterns through switch case modifiers, then (a) the totality is 
all or nothing, at all levels, and (b) what do I do when I want to 
refactor that switch into a chain of instanceof operations?  Then 
there's no way to express the pattern I want! Totality must be a 
property of the pattern, and then we can define (orthogonally, please) 
how the patterns interact with the enclosing construct.


I think the mistake that is dragging you down the wrong road is the 
assumption that pattern matching is always about conditionality. But 
destructuring is just as important as conditionality.  Sometimes a 
pattern is total (on a given type), and sometimes its not, but in all 
cases it describes the same destructuring.   What was wrong with the 
"just use case var x" proposal is that it said "you can't use 
destructuring when you're total, because a null might sneak along for 
the ride", which was just mean.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200812/55a9f51a/attachment.htm>


More information about the amber-spec-experts mailing list