Note that if we keep "default", it has to accept null because fundamentally, "default" is 
like "else".

I agree on default, and I also agree on the comparison to `else`. Which underscores the importance of totality here; a switch:

    case Frog f:
    case Tadpole t:
    default / case var x / case _ / case Object o / ... any of these, they're all total

is really equivalent to the if-else chain:

    if (x instanceof Frog f)  { ... }
    else if (x instanceof Tadpole t) { ... }
    else { ... }

... *precisely because* the patterns in the last line are total.  In other words, a total pattern in a switch is like the `else` of an `if` (and like with `if`, nothing can come after an unqualified `else` clause, because it would be dead.)  I believe this is the analogy you are looking for in the comments above about refactoring between switch and if chains; if the pattern is a "no op", when refactoring to/from an if-else chain, the "no op" pattern maps to the else clause.

(Note that we already see this nod to totality elsewhere in the language, too; we distinguish between static casts, unchecked casts, and dynamic casts, based on ... wait for it ... totality.  If the "test" in question is total, that affects the semantics of the "test", such as what exceptions it may throw.)

For a destructuring pattern on Foo, if there is no "case Foo(null)", "case Foo(var x)" 
(or case var x at the top-level/or default), i don't see why this pattern has to accept "null" when 
destructutring because the switch will not know what to do with that null. Raising a NPE the earliest seems 
the right semantics for me.

I am not sure exactly what you are saying here.

    case Foo(var x)

alwyas matches Foo(null), but it only matches `null` itself when `Foo(var x)` is total on the target type (IOW, when the pattern test is a no-op.)


I tried the usual jedi mind trick to convince you that a statement switch 
doesn't have to behave like a legacy switch but my force power doesn't seem to 
work through internet.

It was a good try, you made me think for a few minutes.
In that case, i suppose we can choose among the solutions proposed by Guy to get a 
statement switch which has no implicit "default".

Let's be careful to separate the "optimistically total" feature (in the presence of sealing) from the base switch semantics.  I think the base switch semantics are quite simple now -- we carve out legacy behavior for three kinds of types (enums, strings, and boxes), and then switches are 100% null-friendly after that.

Scaling optimistic totality to sealed classes wrapped in deconstruction patterns looks like it is going to require more work, but I think that's a separate problem.


Reply via email to