Next up for patterns: type patterns in switch

Remi Forax forax at univ-mlv.fr
Thu Jul 23 21:53:12 UTC 2020



On July 23, 2020 6:52:50 PM UTC, Brian Goetz <brian.goetz at oracle.com> wrote:
>
>
>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?

Yes, we agree.

>
>> 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:
>
>or
>
>     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.

I am worry about the whole complexity.

What about guard clauses with an order
switch(a) {
 case Object & a instanceof A -> 
 case Object & a instanceof B ->
}
Can the two cases be swapped ?

And the size of the JLS section that will explain how to compute the exhaustiveness. 

By example
switch(p) {
 case P & v >= 0 ->
 case P & v < 0 ->
}
Can be ok or not depending if v is an int or  a double.

or
switch(opt) {
  case Optional & opt.isPresent() ->
  case Optional & opt.isEmpty() ->
}

You will have to draw a line somewhere and because Java uses a lot of abstraction in libraries collection, optional, etc you may have to go pretty far.

>
>> 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.

var x and default are not on the same plane. So it's not really a third thing.
We are introducing something special for the bottom, null, but not for the top ?

Remi

--
On mobile


More information about the amber-spec-experts mailing list