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.