> De: "Brian Goetz" <[email protected]>
> À: "amber-spec-experts" <[email protected]>
> 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