[enhanced-switches] My experience of converting old switches to new ones

Brian Goetz brian.goetz at oracle.com
Sun Sep 18 13:21:56 UTC 2022


Thanks for the extensive feedback!


> 3. It's also sad that signaling about impossible cases is quite long.
> `default -> assert false;` is not accepted for obvious reasons.

Java lacks suitable abstraction over effects, so we cannot use our 
regular abstraction tools for simplifying a throw -- you have to do it 
all inline, unfortunately.

We have talked about various sugary things here, such as:

     default -> unreachable;
or
     default -> throw;

but could never get all that excited about it; its not that powerful, 
and invariably someone will want to customize the exception.  You could 
have a simple library method:

     AssertionError unreachable() {
         return new AssertionError("got lost in the weeds");
     }

     default -> throw unreachable();

which seems better than a language feature, though you end up with some 
"junk" frames on the stack trace.  If that point is really unreachable, 
that won't matter.

But as you say, really you'll want to provide some context about the 
data that brought you to this point.  Which suggests you want something 
that is part of switch, so it can at least reproduce the selector.  I 
kind of like your idea about a case that says "impossible", as it is 
tied to the switch and can carry the selector value, so it can give you 
a better error.  (Ideally, something that the existing synthetic 
defaults could be shorthand for.)

> > We need total switch statements.

Is this different from the "default impossible" above?

> 5. At first, I thought that switch expressions are best for return
> values, assignment rvalues and variable declaration initializers, but
> in other contexts they are too verbose and may make things more
> complex than necessary. However, I started liking using them as the
> last argument of the call.

Not unlike lambdas.  A sensible style has emerged in many libraries that 
encourage a single lambda argument at the end, for this same reason.

> 7. I really miss `case null`. I saw many switches these days, during
> my conversion quest. And it happens quite often in our codebase that
> the null case is handled separately before the switch (often the same
> as 'default', but sometimes not). In the IntelliJ codebase, we really
> use nulls extensively, even though some people may think that it's a
> bad idea. It's good that we will have `case null` in future.

Hopefully near future!

> 9. Some old switches are actually shorted than new ones, and I'm not
> sure about conversion.

There's nothing wrong with old switches when you need complex control 
flow.  Even if we made all switches exhaustive, a `default: break` would 
suffice here.  I think there's no need to use the new thing here; you 
want some weird control flow, old switches are good for that.

> Usually, it's like this:
>
> if (condition) {
>    switch(value) {
>    case 1: return "a";
>    case 2: return "b";
>    case 3: return "c";
>    // no default case, execution continues
>    }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20220918/3feeba12/attachment.htm>


More information about the amber-spec-observers mailing list