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

Reply via email to