Letting the nulls flow (Was: Exhaustiveness)
Brian Goetz
brian.goetz at oracle.com
Sun Aug 23 20:31:09 UTC 2020
> 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.
More information about the amber-spec-experts
mailing list