New candidate JEP: 361: Switch Expressions (Standard)

Thomas Zimmermann zimmermann.tho at gmail.com
Mon Oct 28 12:23:33 UTC 2019


Hello dear OpenJDK developers!

I have some feedback regarding switch expressions, more precisely the 
new non-exhaustive arrow-switch statements.
The original code was in Kotlin, but I recreated the structure in Java 
and the problem remains the same.

Context:
An Android app showing the current location on a map. The UI is 
listening to a stream of update events that cover
all corner cases of the dynamic environment that is Android:

enum LocationUpdate {
     SUCCESS, // new location, yay
     UNKNOWN, // no location fix for whatever reason
     PERMISSION_DENIED // user revoked permission while we were 
listening to GPS :(
}

(`LocationUpdate` should really be a sealed type, but let's stay with 
one preview feature for now)

The UI will react to each update as follows:

void onLocationUpdate(LocationUpdate update) {
     switch (update) {
         case SUCCESS -> updateLocationMarker();
         case UNKNOWN -> removeLocationMarker();
         // woops, forgot to handle permission denied case
     }
     doSomethingElse();
}

I hope you can see my problem: I expected the compiler to help me even 
when the switch does not produce a value.
The most obvious work around is pretty terrible (useless variable, 
yielding arbitrary values):

void onLocationUpdate(LocationUpdate update) {
     var ignored = switch (update) {
         case SUCCESS-> {
             updateLocationMarker();
             yield true;
         }
         case UNKNOWN-> {
             removeLocationMarker();
             yield true;
         }
         // compiler error, good
     };
     doSomethingElse();
}

Probably shortsighted proposal:
Make arrow-switch statements exhaustive (for sealed types and enums at 
least).
Getting back the non-exhaustiveness if desired seems simple in this case:

switch (update) {
     case SUCCESS -> updateLocationMarker();
     case UNKNOWN -> removeLocationMarker();
     // don't care about the other cases
     default -> {}
}

... whereas getting exhaustiveness from the non-exhaustive switch is 
hard (see work around above).


JEP 361 [0] only says "Obviously |switch|statements are not required to 
be exhaustive".
Was this discussed previously? I feel like I am missing something.

As a sidenote, Kotlin is also missing this feature [1], maybe Java can 
learn from this (IMO) mistake?

[0] https://openjdk.java.net/jeps/361
[1] https://youtrack.jetbrains.com/issue/KT-12380

Best regards,
Thomas Zimmermann

P.S.: I'm very excited about the new upcoming features, stellar work 
everyone!


More information about the amber-spec-observers mailing list