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.

Reply via email to