<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <br>
    <br>
    <div class="moz-cite-prefix">On 9/11/2025 11:55 AM, Brian Goetz
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:ddc28d8b-6487-41b1-9c4d-4b6b02154ff2@oracle.com"><br>
      I explicitly asked you to answer a question on the semantics when
      these conversions were NOT involved before we moved onto these,
      because I think  you are conflating two separate things, and in
      order to get past just repeating "but...lossy!", we have to
      separate them.
      <br>
    </blockquote>
    <br>
    <font size="4" face="monospace">I see Remi has lost interest in this
      discussion, so I will play both parts of the dialogue on his
      behalf now.  <br>
      <br>
      <blockquote type="cite">Let's start with the easy ones:
        <br>
        <br>
            Object p = "foo";           // widen String to Object
        <br>
            Object q = Integer.valueOf(3)  // widen Integer to Object
        <br>
            ...
        <br>
            if (p instanceof String s) { ... }  // yes it is
        <br>
            if (q instanceof String s) { ... }  // no it isn't
        <br>
        <br>
        We can widen String and Integer to Object; we can safely narrow
        p back to String, but we can't do so for q, because it is
        "outside the range" of references to String (which embeds in
        "references to Object".)   Does this make sense so far?  <br>
      </blockquote>
      <br>
      Remi: It has always been this way.  <br>
      <br>
      <blockquote type="cite">OK, now let's do int and long.
        <br>
        <br>
            long small = 3
        <br>
            long big = Long.MAX_VALUE
        <br>
        <br>
            if (small instanceof int a) { ... }    // yes, it is
        <br>
            if (big instanceof int b) { ... }        // no, it isn't
        <br>
        <br>
        What these questions are asking is: can I safely narrow these
        longs to int, just like the above.  In the first case, I can --
        just like with String and Object.  In the second, I can't --
        just like with Integer and Object.  Do we agree these are the
        same?<br>
      </blockquote>
      <br>
      Remi: Yes Socrates, I believe they are.  <br>
      <br>
      <blockquote type="cite">OK, now let's do int and double.
        <br>
        <br>
            double zero = 0;
        <br>
            double pi = 3.14d;
        <br>
        <br>
            if (zero instanceof int i) { ... }
        <br>
            if (pi instanceof int i) { ... }
        <br>
        <br>
        Same thing!  The first exactly encodes a number that is
        representable in int (i.e., could have arisen from widening an
        int to double), the latter does not. <br>
      </blockquote>
      <br>
      Remi: It could be no other way, Socrates.<br>
      <br>
      But we can replace double with float in the previous example, and
      nothing changes:<br>
      <br>
      <blockquote type="cite"><font size="4" face="monospace">    float
          zero = 0; <br>
              float pi = 3.14f; <br>
          <br>
              if (zero instanceof int i) { ... } <br>
              if (pi instanceof int i) { ... } <br>
        </font></blockquote>
      <br>
      Here, we are asking a sound question: does the number encoded in
      this `float` exactly represent an `int`.  For `zero`, the answer
      is "of course"; for `pi`, the answer is "obviously not."<br>
      <br>
      Remi: Yes, Socrates, that is clearly evident.<br>
      <br>
      <br>
      I'm now entering guessing territory here, but I'm pretty sure I
      understand what's making you uncomfortable.  But, despite the
      clickbaity headline and misplaced claims of wrongness, this really
      has nothing to do with pattern matching at all!  It has to do with
      the existing regrettable treatment of some conversions (which we
      well understood are problematic, and are working on), and the fact
      that by its very duality, pattern matching _exposes_ the
      inconsistency that while most "implicit" conversions (more
      precisely, those allowed in method and assignment context) are
      required to be "safe", we allow several lossy conversions in these
      contexts too (int <--> float, long <--> float, long
      <--> double).  (The argument then makes the leap that
      "because this exposes a seeming inconsistency, the new feature
      must be wrong, and should be changed."  But it is neither fair nor
      beneficial to blame the son, who is actually doing it right, for
      the sins of the fathers.)  <br>
      <br>
      In other words, you see these two cases as somehow so different
      that we should roll back several years of progress just to avoid
      acknowledging the inconsistency:<br>
      <br>
          float f = 0;<br>
          if (f instanceof int i) { ... }<br>
      <br>
      and<br>
      <br>
          float g = 200_000_007;  // lossy <br>
          if (g instanceof int i) { ... }<br>
      <br>
      because in the first case, we are merely "recovering" the int-ness
      of something that was an int all along, but in the second case, we
      are _throwing away_ some of the int value and then trying to
      recover it, but without the knowledge that a previous lossy
      operation happened.  <br>
      <br>
      But blaming pattern matching is blaming the messenger.  Your beef
      is with the assignment to g, that we allow a lossy assignment
      without at least an explicit cast.  And this does seem
      "inconsistent"!  We generally go out of our way to avoid lossy
      conversions in assignments and method invocation (by allowing
      widening conversions but not narrowing ones) -- except that the
      conversion int -> float is considered (mystifyingly) a
      "widening conversion."  <br>
      <br>
      Except there's no mystery.  This was a compromise made in 1995
      borne of a desire for Java to not seem "too surprising" to C
      programmers.  So this conversion (and two of its irresponsible
      friends) were characterized as "widenings", when in fact they are
      not.  <br>
      <br>
      If I could go back to 1995 and argue against this, I would.  But I
      can't do that.  What I can do is to acknowledge that this was a
      regrettable misuse of the term widening, and not extrapolate from
      this behavior.  Can we change the language to disallow these
      conversions in assignment and method context?  Unlikely, that
      would break way too much code.  We can, though, clarify the
      terminology in the JLS, and start to issue warnings for these
      lossy implicit conversions, and instead encourage an explicit cast
      to emphasize the "convert to float, dammit" intentions of the
      programmer (which is what we plan to do, we just haven't finalized
      this plan yet.)  But again, this has little to do with the proper
      semantics of pattern matching; it is just that pattern matching is
      the mirror that reveals the bad behavior of existing past mistakes
      more clearly.  It would be stupid to extrapolate this mistake
      forward into pattern matching -- that would make it both more
      confusing and more complicated.  Instead, we admit our past
      mistakes and improve the language as best as we can.  In this
      case, there was a pretty good answer here, despite the legacy
      warts.  <br>
      <br>
      Before I close this thread, I need to reiterate that just because
      there is a seeming inconsistency, this is not necessarily evidence
      that the _most recent move_ is a mistake.  So next time, if you
      see an inconsistency, instead of thumping your shoe on the table
      and crying "mistake! mistake!", you could ask these questions
      instead:<br>
      <br>
       - This seems like an inconsistency, but is it really?<br>
       - If this is an inconsistency, does that mean that one case or
      the other is mistake? <br>
       - If there is a mistake, can it be fixed?  If not, should we
      consider changing course to avoid confusion, or are we better off
      living with a small inconsistency to get a greater benefit?<br>
      <br>
      These are the kinds of questions that language designers grapple
      with every day.  <br>
      <br>
      <br>
    </font>
  </body>
</html>