> From: "Brian Goetz" <brian.go...@oracle.com> > To: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Sent: Monday, February 28, 2022 7:08:07 PM > Subject: Re: [External] : Re: Primitive type patterns
>>> So *of course* there's an obvious definition of how `int x` matches against >>> Integer, and its not a question of whether we "define" it that way, its a >>> question of whether we expose the obvious meaning, or suppress it. I think >>> the >>> arguments in favor of suppression are pretty weak. >> The strong argument is that instanceof/switch case is about subtyping >> relationship while assignment is about assignment conversions, trying to blur >> the lines between the two has already been tried in the past and it results >> in >> pain (see below). > This is pretty much assuming your conclusion, and then stating it as > justification :) > I get it; you would prefer that pattern matching be *only* about subtyping. I > understand why you prefer that. But I think this is mostly a "retreat to the > comfort zone" thing. >> What about ? >> Object o =... >> if (o instanceof byte) { ... } >> Does it means that o can be a Long ? > This is a good question. (But I know it's also a trap.) We first have to ask > about (static) applicability: is the pattern `byte b` applicable to Object? If > not, we'll get a compilation error. > My earlier message said: > - A primitive type pattern `P p` should be applicable to a reference target T > if > T unboxes to P, or T unboxes to a primitive type that can be widened to P [ or > if T unboxes to a primitive type that can be narrowed to P. ] > Does Object unbox to byte? No. > Does Object unbox to a primitive type that can be widened to byte? No. > [brackets] Does Object unbox to a primitive type than can be narrowed to byte? > No. > How does this square with assignments? I cannot assign > byte b = anObject > | incompatible types: java.lang.Object cannot be converted to byte > If I try this with casting: > Object o = 0L > byte b = (byte) o > I get a CCE, because the cast will only convert from Byte. > Now, what if instead of Object, we start with Long? > Long l = 0L > if (l instanceof byte b) { ... } > First, applicability: does Long unbox to a primitive type that can be narrowed > to byte? Yes! Long unboxes to long, and long can be narrowed to byte. > Then: matching: if the RHS is not null, we unbox, and do a range check. (The > rules in my previous mail probably didn't get this case perfectly right), but > 0L will match, and 0xffff will not -- as we would expect. This is totally alien to me, when you have x instanceof Foo (note: this is not the pattern version) with X the type of x, then if x is declared with a super type of X it works the exact same way, i.e i don't have to care to much about the type on what i'm doing an instanceof / switching over it. The rule you propose breaks that, i've to take a very close look to the type of 'x'. As i said earlier, it's too smart for me. I see no problem to have such semantics specified by a pattern method, but i don't think we should make the type pattern too clever. Rémi