Now we're just going in circles, we already discussed this one.  It creates at least as much trouble as it solves.

One problem is that while this seems like an obvious syntactic trick when the patterns are as simple as they are today, what happens when you get to deconstruction patterns?

Another is that you're kind of pretending this is a special case of an OR pattern, in which case you'd write it:

    case Number n | null n: ...

but now we need binding merging (which we simplified away, to everyone's pleasure.)  If you want to do this as a type pattern, you could interpret it as

    case (Number | Null) n: ...

where `Null t` is a special type pattern that only matches null; this is consistent with the treatment of | in catch, which is also like a pattern.  But this all seems pretty ad-hoc, and doesn't really help where we need it most, which is nesting:

     Box<String> bs;
     switch (bs) {
         case Box(var x): ...
// or
         case Box(String s): ...
     }

If this doesn't match Box(null), this will be a much bigger source of mistakes than this current concern.  It is pretty clear that both of the above want to match "all boxes", and people will routinely forget to say "| null" (or, be annoyed they do have to) in these cases.

If we already had a `T?` type, there'd be a natural denotation of both nullable and non-nullable type patterns, and this would be less annoying, but we don't.

So there's a reason we didn't pick this one the first time around.


(Stepping back, I would remind you that we are in the classic trap of, after having considered the problem in entirety, trying to fix the things we don't like locally, without re-doing the global analysis, just becomes someone noticed one of the things we don't like for the first time?)


On 7/27/2020 5:05 PM, Remi Forax wrote:

Instead of having an idiom, we can use a restricted Java-ish syntax.
For me it's a lot like when you want a serializable lambda and you end up with an ad hoc java-ish syntax (Foo & Serializable) s -> ...

So i propose Number | null,
  switch (o.get1().get2()) {
    case Integer i -> ...
    case Number | null n -> …
  }

it's a restricted syntax too, it's either "type | null" and it's obviously explicit, it also makes the rule that say if a switch accept null or not more obvious because it's decouple from the notion of a total coverage, if a case accept null then the switch accept null.

Reply via email to