Next up for patterns: type patterns in switch

Brian Goetz brian.goetz at
Thu Jul 23 18:52:50 UTC 2020

On 7/23/2020 2:38 PM, Remi Forax wrote:
> Don't do deconstruction now ! We are not ready :)

Now I'm confused.  Didn't I say exactly that in the first paragraph?

> On guards, they do not work well with exhaustiveness. Still not sure 
> they are useful.

It works fine, it's just more work for the user to get right.

We induce a domination ordering on patterns.  If `T <: U`, then `T t` < 
`U u` (`T t` is less specific than `U u`.)  Similarly, for all guard 
conditions g, `P & g` < `P`.  What this says is that if you want 
exhaustiveness, you need an unguarded pattern somewhere, either:

     case A:
     case B & g:
     case B:              // catches B & !g
     case C:


     case A:
     case B & g:
     case C:
     case Object:    // catches B & !g

I understand your diffidence about guards, but I'm not sure we can do 
nothing.  The main reason that some sort of guards feel like a forced 
move (could be an imperative guard, like `continue`, but I don't think 
anyone would be happy with that) is that the fall-off-the-cliff behavior 
is so bad.  If you have a 26-arm switch, and you want the equivalent of 
the second of the above cases -- B-but-not-g gets shunted into the 
bottom clause -- you may very well have to refactor away from switch, or 
at least mangle your switch badly, which would be pretty bad.

> On nullity, I prefer the total pattern to be explicit instead of 
> implicit (given we have var, the type on the expression taken by the 
> switch can be fuzzy for someone doing a quick look to the code), case 
> any x, case _ x or whatever the syntax is, is more readable IMO.

It is unfortunate that `var x` is more fuzzy about types, but less fuzzy 
about totality (`var x` is always total.)  It is also unfortunate that 
`default` can't be our "any" clause.   Not sure that introducing a third 
thing is helpful, though.

More information about the amber-spec-experts mailing list