[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