> De: "Brian Goetz" <brian.go...@oracle.com> > À: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Envoyé: Vendredi 12 Mars 2021 20:58:40 > Objet: Looking ahead: pattern assignment
> 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. yes, with remainder please :) NPE if the expression is null, ICCE if the number/type of the bindings are incompatible. > 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.) More questions, About the conversions, you means the conversions with the top-level type of the pattern, or conversions with the sub-patterns too ? For lambda formals, there is a syntax question, do we support a syntax without parenthesis if there are only one argument ? Point(var x, var y) -> ... For methods and lambda formals, does the top-level pattern as to have a binding ? Like in your examples void m(Point(var x, var y) p) { ... } or can we avoid it void m(Point(var x, var y)) { ... } For classical assignment, enhanced for loop, try-with-resources and lambda formals we can have inference, do we have inference with patterns ? - assignment (var x, var y) = aPoint; - enhanced loop for((var x, var y) : aListOfPoints) { ... } - try-with-resources try((var x, var y): aClosablePoint) { ... } - lambdas formals Consumer<Point> consumer = ((var x, var y)) -> ... Also should we support the parenthesized pattern and the AND pattern in those contexts ? - the parenthesized pattern may makes the grammar ambiguous. - do we allow something like Point(var x, _) & Point(_, var y) = aPoint; [...] > 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) Rémi