It would have to be something like

    try (Deconstructor(var x, var y) d = e) { }

and then `d` would be the resource.  It might be that this comes up so rarely that we don't bother.

On 3/12/2021 4:58 PM, Alan Malloy wrote:
try-with-resources is a little more subtle than the other contexts. Suppose that I write:

try (Foo(Bar x)) {
  ...
}

What should be closed in the finally? The variable x that we bound to, or the Foo that contained it? Both answers seem a little weird to me. Might it be better not to allow patterns in this context?

On Fri, Mar 12, 2021 at 12:41 PM Brian Goetz <brian.go...@oracle.com <mailto:brian.go...@oracle.com>> wrote:

    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.

    Just as we were successfully able to unify pattern variables with
    locals*, I would like to be able to unify pattern assignment with
    assignment.

    A pattern assignment takes the form:

        P = e

    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.

    Pattern assignment should work in all of the following contexts:

     - Assignment statements: P = e
     - foreach-loops: for (P : e) { ... }
     - (optional) try-with-resources: try (P = e) { ... }
     - (optional) method formals: void m(Point(var x, var y) p) { ... }
     - (optional) lambda formals: (Point(var x, var y) p) -> { ... }

    (And I'm sure I forgot some.)

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

    Early in the game, we explored supporting partial patterns in
    pattern assignment, such as:

        let P = e
        else { ... }

    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:

     - (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;
     - (pragmatic) It just doesn't add very much value; if the else
    throws, it is no less verbose than an if-else.

    The remaining case where this construct helps is when we want to
    assign default values:

        let Point(var x, var y) = aPoint
        else { x = y = 0; }
        // can use x, y here either way

    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.

    I suspect the right time to formalize pattern assignment is when
    we formalize deconstructor declarations (probably next round).  In
    the meantime, we should:

     - gather a complete list of contexts where pattern assignment
    makes sense;
     - nail down semantics of primitive type patterns (see earlier mail);
     - think about how to align the conversion rules in JLS 5 to align
    with existing usage.




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


Reply via email to