> De: "Alan Malloy" <amal...@google.com> > À: "Brian Goetz" <brian.go...@oracle.com> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Envoyé: Vendredi 12 Mars 2021 22:58:44 > Objet: Re: Looking ahead: pattern assignment
> 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? The instance of Foo, not the instance of Bar. > Both answers seem a little weird to me. Might it be better not to allow > patterns > in this context ? 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 try (HttpRequest.parse(var header, var content) = getAHttpRequestFrom(...)) { ... } regards, Rémi > On Fri, Mar 12, 2021 at 12:41 PM Brian Goetz < [ > mailto:brian.go...@oracle.com | > 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)