[pattern-switch] Exhaustiveness

Remi Forax forax at univ-mlv.fr
Tue Sep 1 12:08:33 UTC 2020


----- Mail original -----
> De: "Remi Forax" <forax at univ-mlv.fr>
> À: "Brian Goetz" <brian.goetz at oracle.com>
> Cc: "daniel smith" <daniel.smith at oracle.com>, "Guy Steele" <guy.steele at oracle.com>, "Tagir Valeev" <amaembo at gmail.com>,
> "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Mardi 1 Septembre 2020 03:11:10
> Objet: Re: [pattern-switch] Exhaustiveness

> ----- Mail original -----
>> De: "Brian Goetz" <brian.goetz at oracle.com>
>> À: "daniel smith" <daniel.smith at oracle.com>
>> Cc: "Guy Steele" <guy.steele at oracle.com>, "Remi Forax" <forax at univ-mlv.fr>,
>> "Tagir Valeev" <amaembo at gmail.com>,
>> "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
>> Envoyé: Mardi 1 Septembre 2020 01:30:15
>> Objet: Re: [pattern-switch] Exhaustiveness
> 
>>> I'm still thinking it's worthwhile to change the behavior of enum switches to
>>> throw the same thing as sealed class switches.
>> 
>> I don't necessarily think this is terrible, but see inline.
>> 
>>>
>>> - ICCE is arguably just wrong. It's not an incompatible change to add an enum
>>> constant to an enum declaration.
>> 
>> Kevin made a compelling argument when we did this that ICCE is actually
>> right.  The notion is that ICCE is what users are most likely to
>> associate with "broken classpath"; that the classes on the class path
>> have been inconsistently compiled.  ICCEs go away on recompilation.
>> 
>> This does, of course, hinge on the meaning of incompatible.  Adding an
>> enum constant is not binary-incompatible; all the call sites continue to
>> link.  But "I've never seen this value before", because the value wasn't
>> present at compilation time, is not an unreasonable interpretation.
>> 
>>> - The inconsistency is a risk—somebody thinks they're catching the exception,
>>> then they discover, oops, enum switches throw a different exception type for
>>> historical reasons.
> 
> yes, replacing some enum values by a "case var enumValue ->" is enough to change
> the semantics.

just to be clear here is an example
switch Color { red, green, blue, pink }

switch(color) {
  case "pink" -> System.out.println("contains red");
  case "blue" -> System.out.println("do not contains r");
  case Color c where c != null -> System.out.println("contains r");
}

this switch is optimistically total but if color is null it will not throw a NPE.

> 
>> 
>> Yeah, don't care much about this.  No one catches these anyway.
> 
> Given all mocking libraries that exist, the number of people under the "no one"
> category may be bigger than you estimate.
> 
> Also there is a lot of code that doesn't do an explicit null check on top of a
> public method because the first instruction is a switch, and i'm sure some of
> them are covered by a unit test.
> 
>> 
>>> Of course, behavioral changes are a risk, too, but I think getting it in early,
>>> before there's been much time for adoption of switch expressions and evolution
>>> of enums, minimizes that risk. (We could even make the change in 16 as a spec
>>> bug fix.)
> 
> If we decide to use an UnexpectedFrogException, i will vote for a bug fix.
> 
>> 
>> I don't necessarily disagree, and it would be consistent to throw
>> UnexpectedFrogException for all non-null remainders, but the status quo
>> does not seem wrong to me.
> 
> Rémi

Rémi


More information about the amber-spec-experts mailing list