[External] : Re: Primitive type patterns

Brian Goetz brian.goetz at oracle.com
Mon Feb 28 18:53:07 UTC 2022


>     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.

Yes, I understand your discomfort.  And I will admit, I don't love this 
particular corner-of-a-corner either.  (But let's be clear: it is a 
corner.  If you're seeking to throw out the whole scheme on the basis 
that corners exist, you'll find the judge to be unsympathetic.)

So why have I proposed it this way?  Because, unfortunately, of this 
existing line in JLS 5.2 (which I never liked):

 > an unboxing conversion followed by a widening primitive conversion

This is what lets you say:

     long l = anInteger

And, I never liked this rule, but we're stuck with it.  The inverse, 
from which we would derive this rule, is that

     anInteger instanceof long l

should be applicable, and in fact always match when the LHS is 
non-null.  I would prefer to not allow this assignment conversion, and 
similarly not allow both unboxing and widening in one go in pattern 
matching, but I didn't get to write JLS 5.2.

What's new here is going in the *other* direction:

     anInteger instanceof short s

and I think what is making you uncomfortable is that you are processing 
two generalizations at once, and it's pushing your "OMG different! 
scary!" buttons:

  - that we're defining primitive type patterns in a way such that we 
can derive the existing assignment conversions;
  - that primitive type patterns can have dynamic checks that primitive 
assignments cannot, so we're including the value-range check.

Each individually is not quite as scary, but I can understand why the 
two together would seem scary.  (And, as I mentioned, I don't like the 
unbox-and-widen conversions either, but I didn't invent those.)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20220228/38a97636/attachment-0001.htm>


More information about the amber-spec-experts mailing list