Looking ahead: pattern assignment

Alan Malloy amalloy at google.com
Fri Mar 12 21:58:44 UTC 2021


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.goetz at 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)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210312/d93edfc5/attachment-0001.htm>


More information about the amber-spec-experts mailing list