<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">I'm going to try and address
        these points *for the benefit of everyone else*.  (Note to Remi
        only: this is not an invitation to continue the back and forth,
        as doing so would likely be unconstructive unless you have
        something either (a) radically new that no one has thought of
        yet and/or (b) something that is so obviously right and
        compelling that I will immediately weep with embarrassment for
        how wrong I was.  That's the bar at this point.  I get that you
        hate this feature.  You've made that manifestly clear.  But
        unless you have some significantly new light to shed on it, it
        is unconstructive to just keep banging this drum, and you are
        creating an environment where others feel less comfortable
        sharing their thoughts, which is unacceptable.)  <br>
      </font></font><br>
    <blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">1)
      having a primitive pattern doing a range check is useless because
      this is rare that you want to do a range check + cast in real
      life,
      <br>
         How many people have written a code like this
      <br>
      <br>
          int i = ...
      <br>
          if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE)
      {
      <br>
            byte b = (byte) i;
      <br>
            ...
      <br>
          }
      <br>
      <br>
         It's useful when you write a bytecode generator without using
      an existing library, ok, but how many write a bytecode generator ?
      <br>
         It should not be the default behavior for the primitive type
      pattern.
      <br>
    </blockquote>
    <br>
    This argument stems from a misunderstanding of what we are trying to
    accomplish here.  Yes, it is correct that `case byte b` is not
    something everyone will use (I have written this many times, though
    I admit this is probably unusual.)  But that's not the point of this
    exercise; the point of the exercise is uniformity, in part because
    the lack of uniformity is complexity, and in part we want to offer
    new semantic symmetries that programmers can count on.  You are
    trying to tinker at the margins, asking if each conversion carries
    its weight; that's a recipe for creating new, ad-hoc complexity
    surface.  Sometimes that's the right move, and sometimes it is
    unavoidable, but there is such an obviously correct interpretation
    of primitive instanceof here -- "would a cast to this type be safe"
    -- that it would be an unforced error to opt for the ad-hoc
    complexity just because you can't imagine using it that often.  <br>
    <br>
    If I have a record:<br>
    <br>
        record R(int x) { }<br>
    <br>
    I can construct it with <br>
    <br>
        new R(aShort)<br>
    <br>
    but under the strict semantics of primitive type patterns,  I cannot
    deconstruct it with<br>
    <br>
        case R(short s) { }<br>
    <br>
    which would ask: "could this record have come from a constructor
    invocation `new R(s)`".   And this is gratuitously different than
    the correspond case with reference widening:<br>
    <br>
        record S(Object o) { }<br>
    <br>
        S s = new S("foo");<br>
        if (s instanceof S(String ss)) { ... }<br>
    <br>
    Further, I take objection to your continued characterization of this
    as a "range check", as this is a mischaracterization as well as
    minimizing what is going on.  Casting subsumes boxing and unboxing
    as well as widening and narrowing, so a more correct
    characterization would be "could I cast this without loss or error
    to a short".  Which applies not only to wider and narrower types,
    but to types like Short and Object.  Just like `instanceof` for
    reference types, which asks whether the type could be cast to
    another type.  And without creating a new context for what is
    allowable.  <br>
    <br>
    Not only is the term "useless" unconstructive, but it is not even
    the right measure.  The bar here is not "would people use it a
    lot."  We're making the language simpler by making it more uniform. 
    To say "let's gratuitously knock some of the boxes out of the cast
    matrix because I can't imagine using them" only makes the language
    more complicated.  <br>
    <br>
    <blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">
      2) It's also useless because there is no need to have it as a
      pattern, when you can use a cast in the following expression
      <br>
          Person person = ...
      <br>
          switch(person) {
      <br>
            // instead of
      <br>
            // case Person(double age) -> foo(age);
      <br>
            // one can write
      <br>
            case Person(int age) -> foo(age);  // widening cast
      <br>
          }
      <br>
    </blockquote>
    <br>
    Same argument (also you got your example backwards).  I get that you
    think its fine to have to do this, but it is yet another gratuitous
    asymmetry between aggregation and destructuring that confuses people
    about how destructuring works.  Why can you pass an int or a double
    to `new Person`, but could only take an `double` out?  Whereas with
    Object/String, you could take either out?  <br>
    <br>
    Again, this is gratuitous complexity, which I think is rooted in
    your unwillingness to let go of "instanceof means subtype."  Sorry,
    it doesn't any more (but it means something that generalizes it.)  <br>
    <br>
    <blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">
      3) when you read a conditional primitive patterns, you have no
      idea what is the underlying operation until you go to the
      declaration (unlike the code just above).
      <br>
    </blockquote>
    <br>
    This is the same complaint you had in the past about partial and
    total nested patterns.  As I've said, I understand why you find it
    uncomfortable ("action at a distance"), but we evaluated the pros
    and cons extensively already, and we made our decision.  There's no
    reason to reopen it here, nor are the considerations any different
    in this case.  <br>
    <br>
    <blockquote type="cite" cite="mid:27437ad6-7a87-580f-a593-9866f1ee8af5@oracle.com">
      4) if we change the type pattern to be not just about subtyping,
      we should revisit the JLS to avoid to have too many different
      semantics.
      <br>
    </blockquote>
    <br>
    This is FUD, implying that we are going to have to reexamine
    everything.  I don't buy it.  Many of the things that lean on
    subtyping today are just ... subtyping.  And the things that have
    conversions involving primitives already lean on conversions and
    contexts.  <br>
    <br>
    By way of concrete example, you raised the question about covariant
    overrides.  Which was a good example, and which I appreciate, but I
    wish you would have raised it differently.  <br>
    <br>
    A constructive way to raise this would be: "Do we also want to
    reexamine covariant overrides to use castability (or some other
    criteria) rather than subtyping?"  <br>
    <br>
    An unconstructive way to raise this would be: "This feature is bad,
    look at the problems you are creating for covariant overrides,
    everything will have to be reexamined."  <br>
    <br>
    <br>
  </body>
</html>