Knocking off two more vestiges of legacy switch

Brian Goetz brian.goetz at oracle.com
Mon Sep 12 22:57:40 UTC 2022


>
> It shows that the semantics you propose for the primitive type pattern 
> is not the right one.
>
> Currently, a code like this does not compile
>   byte b = ...
>   switch(b) {
>     case 200 -> ....
>   }

Thanks, that's a good catch -- we currently do more type checking than a 
strict interpretation of this story for constant patterns provides.  But 
this can be addressed by additional compile-time type checking for 
constant patterns.

But this would be a critique of _constant patterns_, not of primitive 
type patterns (and easily addressed.)

>
> because 200 is not a short which is great because otherwise at runtime 
> it will never be reached.

I think you mean "not a byte"?

>
> But if we apply the rules above + your definition of the primitive 
> pattern, the code above will happily compile because it is equivalent to
>
>   byte b = ...
>   switch(b) {
>     case short s when s == 200 -> ....
>   }

I think you mean "case int s when s == 200"?

>
> Moreover, i think R(true) and R(false) should be exhaustive, it's not 
> a big deal because you can rewrite it R(true) and R (or R(_)) but i 
> think that R(true) and R(false) is more readable.

Agree, that's in the plan.  Booleans are like enums, so true/false 
covers boolean, and therefore R(true) and R(false) covers R(boolean).

>
> I agree, it's quite sad that we have to support float and double but 
> as you said composition is more important.

It would have been unfortunate if we had to add these as special cases 
for switch.  But with primitive type patterns plus "constants are 
patterns" then this falls out trivially without additional 
specification; all we have to do is _remove_ the existing restriction.

>
>
>     **Bonus round: the last (?) vestige.**  Currently, we allow
>     statement switches on legacy switch types (integers, their boxes,
>     strings, and enums) with all constant labels to be partial, and
>     require all other switches to be total.  Patching this hole is
>     harder, since there is lots of legacy code today that depends on
>     this partiality.  There are a few things we can do to pave the way
>     forward here:
>
>      - Allow `default -> ;` in addition to `default -> { }`, since
>     people seem to have a hard time discovering the latter. 
>
>
> we should also fix that for lambdas, the fact that the lambda syntax 
> and the case arrow syntax are not aligned currently ; `() -> throw 
> ...`is not legal while `case ... -> throw ...` is, is something that 
> trouble a lot of my student (i also introduce the switch syntax before 
> the lambda, so the lambda seems less powerful ??).

Good thought.

>       - Issue a warning when a legacy switch construct is not
>     exhaustive.  This can start as a lint warning, move up to a
>     regular warning over time, then a mandatory (unsuppressable)
>     warning. Maybe in a decade it can become an error, but we can
>     start paving the way sooner.
>
>
> I agree with a switch warning if all the IDEs stop fixing the warning 
> by adding a `default` when the type switched upon is sealed.

Right, I think over some time, IDEs will fix all the occurrences and 
then it is less disruptive to tighten.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20220912/800a6e40/attachment-0001.htm>


More information about the amber-spec-observers mailing list