Next up for patterns: type patterns in switch

John Rose john.r.rose at oracle.com
Fri Jul 24 01:17:14 UTC 2020


On Jul 23, 2020, at 3:48 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
>> P.S. Well, not exactly.  You didn’t expect *no* comment from me? :-)
> 
> There's always one ....
> 
>> It is slightly premature to completely outlaw `x instanceof 42`,
>> because of nulls:  You can replace that with `x == 42` only if `x`
>> is `int`.  With strings, identity is also a problem; `x instanceof "foo"`
>> does not replace with an `==` expression.  In the end, if we outlaw
>> `x instanceof 42` the workaround might be `Objects.equals(x,42)`
>> but that incurs boxing overhead if `x` happens to be a primitive.
>> So, I think the fate of `EXPR instanceof CON_PAT` is up for grabs.
>> That said, I’m fine with leaving it out for starters; it can be added
>> after further thought—or not.
> 
> Truth be told, I am hoping we can avoid doing constant patterns entirely.  The obvious denotation (a literal) leads to at least the appearance of ambiguity -- when a user looks at `foo(0)`, they can't immediately tell whether the 0 is a parameter or a nested pattern (and worse when patterns have parameters.)
> 
> In instanceof, we can avoid them entirely by unrolling into
> 
>     if (x instanceof Foo(var y) && y == 0) { ... }
> 
> which is more flexible anyway because we can have not only equality constraints, but comparison constraints, etc.  If we have guards, we can do the same with cases:
> 
>     case Foo(var y) where y == 0
> 
> So it's not clear whether we need constant patterns _at all_, except as far as it looks like existing switches are full of constant patterns.  But maybe that's really just a funny form of case label….

Sure, but that wasn’t my point.  You can’t really say “y == 0” uniformly,
so it’s a trap to appeal to that nice looking workaround.  You probably have
to say “Objects.equal(y, 0)” to get the equivalent to what we are considering
with constant patterns.

Here’s the example I was trying to evoke:

Integer x = flipcoin() ? null : 42;
if (x == 42)  ; // throws NPE 50% of the time
case (x) {  // never throws
case null: ;
case 42: break;
}
if (x instanceof 42) ; // never throws



More information about the amber-spec-experts mailing list