On Jul 23, 2020, at 3:48 PM, Brian Goetz <brian.go...@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