<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><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>"Alan Malloy" <amalloy@google.com><br><b>À: </b>"Brian Goetz" <brian.goetz@oracle.com><br><b>Cc: </b>"amber-spec-experts" <amber-spec-experts@openjdk.java.net><br><b>Envoyé: </b>Vendredi 12 Mars 2021 22:58:44<br><b>Objet: </b>Re: Looking ahead: pattern assignment<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;"><div dir="ltr">try-with-resources is a little more subtle than the other contexts. Suppose that I write:<br><div><font face="monospace">try (Foo(Bar x) = ...) {</font></div><div><font face="monospace">  ...</font></div><div><font face="monospace">}</font></div><br><div>What should be closed in the finally? The variable x that we bound to, or the Foo that contained it? </div></div></blockquote><div><br></div><div>The instance of Foo, not the instance of Bar.</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;"><div dir="ltr"><div>Both answers seem a little weird to me. Might it be better not to allow patterns in this context ?</div></div></blockquote><div><br></div><div>It can be handy if we have a pattern method that decomposes the Closeable, by example we have a pattern method HttpRequest.parse() that returns the header and the content of the HTTP request<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>  try (HttpRequest.parse(var header, var content) = getAHttpRequestFrom(...)) {<br data-mce-bogus="1"></div><div>    ...<br data-mce-bogus="1"></div><div>  }<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>regards,<br data-mce-bogus="1"></div><div>Rémi<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><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 12, 2021 at 12:41 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

  
  <div>
    <font size="+1"><font face="monospace">While this is not on the
        immediate horizon, I think we are ready to put the pieces
        together for pattern assignment.  I think we now understand the
        form this has to take, and the constraints around it.  <br><br>
        Just as we were successfully able to unify pattern variables
        with locals*, I would like to be able to unify pattern
        assignment with assignment.  <br><br>
        A pattern assignment takes the form:<br><br>
            P = e<br><br>
        where P is a pattern with at least one binding variable that is
        total (perhaps with remainder) on the type of e.  (If P has some
        remainder on the type of e, then the assignment will throw NPE
        or ICCE.)  All bindings in P are in scope and DA for the
        remainder of the block in which P appears, just as with local
        variable declaration.<br><br>
        Pattern assignment should work in all of the following contexts:<br><br>
         - Assignment statements: P = e<br>
         - foreach-loops: for (P : e) { ... }<br>
         - (optional) try-with-resources: try (P = e) { ... }<br>
         - (optional) method formals: void m(Point(var x, var y) p) {
        ... }<br>
         - (optional) lambda formals: (Point(var x, var y) p) -> {
        ... }<br><br>
        (And I'm sure I forgot some.)  <br><br>
        Minimally, we have to align the semantics of local variable
        declaration with assignment with that of pattern matching; `T t
        = e` should have the same semantics whether we view it as a
        local declaration plus assignment, or a pattern match.  This
        means that we have to, minimally, align the assignment-context
        conversions in JLS 5.  (If we wish to support patterns in
        method/lambda formals, we also have to align the
        method-invocation context conversions.)<br><br>
        Early in the game, we explored supporting partial patterns in
        pattern assignment, such as:<br><br>
            let P = e<br>
            else { ... }<br><br>
        where the `else` clause must either complete abruptly, or assign
        to all bindings declared in `P`.  (It wasn't until we unified
        pattern variables with locals that there was an obvious way to
        specify the latter.)  While this construct is sound, it is in
        tension with other uses of pattern assignment:<br><br>
         - (syntactic) Its pretty hard to imagine an `else` clause
        without introducing the assignment with some sort of keyword,
        such as `let`, but this limits its usefulness in other contexts
        such as method parameter declarations;<br>
         - (pragmatic) It just doesn't add very much value; if the else
        throws, it is no less verbose than an if-else.<br><br>
        The remaining case where this construct helps is when we want to
        assign default values:<br><br>
            let Point(var x, var y) = aPoint<br>
            else { x = y = 0; }<br>
            // can use x, y here either way<br><br>
        But, I think we can get there another way, by letting patterns
        bind to existing variables somehow (we want something like this
        for the analogue of super-delegation and similar in pattern
        declarations anyway.)  I won't paint that bikeshed here, except
        to suggest that the let-else construct seems to be a losing
        price-performance proposition.<br><br>
        I suspect the right time to formalize pattern assignment is when
        we formalize deconstructor declarations (probably next round). 
        In the meantime, we should:<br><br>
         - gather a complete list of contexts where pattern assignment
        makes sense;<br>
         - nail down semantics of primitive type patterns (see earlier
        mail);<br>
         - think about how to align the conversion rules in JLS 5 to
        align with existing usage.<br><br><br><br></font></font><br>
    <font size="+1"><font face="monospace"><font size="+1"><font face="monospace">*the only remaining difference between
            pattern variables and locals is that pattern variables have
            a more interestingly-shaped scope (and perhaps in the
            future, pattern variables may have multiple declaration
            points in the presence of OR patterns / merging via ORing of
            boolean expressions)</font></font></font></font>
  </div>

</blockquote></div><br></blockquote></div></div></body></html>