<html><body><div id="zimbraEditorContainer" style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000" class="35"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>De: </b>"Brian Goetz" <brian.goetz@oracle.com><br><b>À: </b>"Remi Forax" <forax@univ-mlv.fr><br><b>Cc: </b>"Guy Steele" <guy.steele@oracle.com>, "Alan Malloy" <amalloy@google.com>, "amber-spec-experts" <amber-spec-experts@openjdk.java.net><br><b>Envoyé: </b>Mardi 8 Septembre 2020 00:52:11<br><b>Objet: </b>Re: Is case var(var x, var y) a valid syntax ?<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br>
    <blockquote cite="mid:1162477749.995924.1599515765693.JavaMail.zimbra@u-pem.fr">
      <div style="font-family: arial, helvetica, sans-serif; font-size:
        12pt; color: #000000">
        <div>
          <div><br>
          </div>
          <div>The deconstruction pattern is a special case of type
            pattern</div>
        </div>
      </div>
    </blockquote>
    <br>
    No, it isn't.  I think you want it to be, but it isn't.  <br>
    <br>
    <blockquote cite="mid:1162477749.995924.1599515765693.JavaMail.zimbra@u-pem.fr">
      <div style="font-family: arial, helvetica, sans-serif; font-size:
        12pt; color: #000000">
        <div>
          <div>, both starts by doing a typecheck (an instanceof), what
            is different is how they bind variables after the typecheck.<br>
          </div>
          <div>So having the type inference on the type used by the
            typecheck working for the type pattern but not for the
            destruction pattern strike me as weird.<br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    I think you may just not understand the model here.  <br>
    <br>
    In generality, a pattern:<br>
    <br>
     - Is either total or partial.  Deconstruction patterns are total;
    other patterns we'll be able to express later, such as
    `Optional.of(var x)`, are partial.<br>
     - Has a target type.  In order for the pattern to match, the
    dynamic type of the target must be cast-convertible to this target
    type.<br>
     - Has a set of output bindings.  </blockquote><div><br></div><div>Let's focus on the total pattern first, as you said a deconstruction pattern is total, it's an instanceof + a destructuring phase + a binding phase,</div><div>while a type pattern is just an instanceof + a binding phase, that why a deconstruction pattern is a subset of a <br data-mce-bogus="1"></div><div>A declared pattern (the partial one) is an instanceof + destructurring + a where clause + a binding phase so it's not a subset of a deconstruction pattern but it's a subset of the type pattern too.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
    <br>
    So, if the user says:<br>
    <br>
        case Foo(int x):<br>
    <br>
    This means:<br>
     - (static) perform overload selection on the deconstructors of Foo,
    and look for one that is compatible with the binding list `(int
    x)`.  Compile error if there isn't one (or are too many.)<br>
     - (dynamic) test the target to see if it is cast-convertible to
    Foo.  If it is, because the pattern is total (no additional match
    conditions), the deconstruction pattern is going to match.  Invoke
    the deconstructor to get the bindings.</blockquote><div><br></div><div>yes,<br data-mce-bogus="1"></div><div>it's the same semantics of a type pattern followed by a call to the deconstructor + a binding of the variables,<br data-mce-bogus="1"></div><div>i believe that the problem is that you see the deconstructor as an inverse of the constructor, which is a kind of right but not fully right.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br>
    <br>
    <blockquote cite="mid:1162477749.995924.1599515765693.JavaMail.zimbra@u-pem.fr">
      <div style="font-family: arial, helvetica, sans-serif; font-size:
        12pt; color: #000000">
        <div>
          <div>At the same time, i understand why people can find the
            syntax awkward. I just want to be sure that it's not awkward
            just because it's a new syntax.</div>
        </div>
      </div>
    </blockquote>
    <br>
    It's not the syntax, it's the concept. <br>
    <br>
    <blockquote cite="mid:1162477749.995924.1599515765693.JavaMail.zimbra@u-pem.fr">
      <div style="font-family: arial, helvetica, sans-serif; font-size:
        12pt; color: #000000">
        <div>
          <div>By example, with this switch, that has two cases that are
            semantically identical<br>
          </div>
          <div>  switch(point) {</div>
          <div>    case Point p where p.x() == 0 -> ...<br>
          </div>
          <div>    case Point(var x, var _) where x == 0 -> ...<br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    No, they are not semantically identical, except maybe for a record
    (because records are so constrained.)  The first is invoking a
    method p.x(); the second is invoking a deconstructor, which has a
    binding called x.  If the two happen to be talking about the same x,
    then it will come out the same, but you have no reason to assume
    that just based on the spelling of `x`.  They could be describing
    entirely different things.  The language has no business guessing
    the semantics of a method based on its name.  </blockquote><div><br></div><div>given your example here, it doesn't work for a record too,<br data-mce-bogus="1"></div><div>if someone add an override method x() that return the value of y, it doesn't work.<br></div><div>The same is true with a deconstructor, if you return for the deconstructor (int x, int y) the value of y and 0, you have exacly the same kind of issue.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>So there are semantically equivalent iff the accessor and the deconstructor are not correctly written.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br>
    <br>
    In order to make them work out, you need a system of "properties" to
    guarantee that when a deconstructor binds a `x`, and an accessor
    method returns an `x`, they are guaranteed to be the same `x`.  I
    don't blame you for wanting such a system, but you don't get to
    sneak it in the back door....</blockquote><div><br></div><div>you don't need properties, because for a record, you have the components which is very like properties and for the other classes, you have a mechanism to transform an instance to a record, what you call a deconstructor, so by transitivity you have a way to unbundle an instance to a set of components.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><br>
    <br>
    <blockquote cite="mid:1162477749.995924.1599515765693.JavaMail.zimbra@u-pem.fr">
      <div style="font-family: arial, helvetica, sans-serif; font-size:
        12pt; color: #000000">
        <div>How the deconstructors are
          represented in the surface language, how they are called or
          how the data values flow to the bindings are another stories
          for another time.<br>
        </div>
      </div>
    </blockquote>
    <br>
    No, this is not a syntax problem; it is a conceptual problem.  You
    are asserting that deconstructors means something different than
    they do.  </blockquote><div><br></div><div>No, what i've proposed is _at runtime_ to have a different way to bind the components to the local variable to have a better backward compatibility, from the language POV, you still have a deconstructor that you call<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>You have proposed to use a synthetic record as return value of a deconstructor, i don't like it because it means that each time you re-compile your code you may have an issue and that if you use a name generated from the set of all record component types, it doesn't work if you add a new component. I think that we can come with a better way to reference the deconstructor in the bytecode in a way that support adding a new component to a deconstructor.</div><div><br data-mce-bogus="1"></div><div>I may be wrong, but anyway, it has nothing to do with if a type pattern is a subtype of a deconstructor pattern or not.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Rémi<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div></div></div></body></html>