Destructuring / Patterns in for-each
Brian Goetz
brian.goetz at oracle.com
Wed Jan 20 00:16:38 UTC 2021
Yes, absolutely this is on the radar. There is a whole constellation of
related features to use total patterns in various places. The use in
for-loops is a generalization of the pattern-bind statement; right now,
you can declare locals as
Foo f = expr
If you squint, you can see this as an unconditional pattern bind; the
LHS is a pattern (`Foo f` is a type pattern) that declares a binding
variable `f`, the RHS can be a match target, and the pattern is total on
the static type of the target, so no conditional wrapping (instanceof,
switch, try, etc) is needed. If so, we can generalize this to
deconstruction patterns:
Point(var x, var y) = aPoint
Readers might find this weird at first, so we've considered other
syntaxes (e.g., a `let` statement), but I prefer this version for the
very reason you have cited -- that it can be lifted directly into things
like foreach loops, try-with-resources blocks, method declarations, and
any other places where "locals" are declared.
Your Map.Entry inquiry illustrates one of the reasons why we want
patterns to be full-fledged class members; if we can put a
deconstruction pattern on an interface like `Map.Entry` (and there's no
reason we can't), we can iterate a map with:
for (Map.Entry(var key, var value) : map.entrySet())
System.out.printf("%s: %s%n", key, value);
This isn't quite as concise as Python's
for x, y in dict.items():
...
but it's close.
So: yes, yes, and bonus yes.
On 1/19/2021 7:06 PM, August Nagro wrote:
> Hello,
>
> I wouldn't be surprised if this has been thought of / discussed before, but
> I would love to some day use destructuring in for-each loops, kind of like
> the for-of loop in JavaScript.
>
> For example, instead of
>
> record Point(double x, double y) {};
>
> double greatestMagnitude = 0.0;
> Point[] points = ...
>
> for (Point p : points) {
> greatestMagnitude =
> max(greatestMagnitude, sqrt(pow(p.x(), 2) + pow(p.y(), 2)))
> }
>
> We could have:
>
> for (Point(var x, var y) : points) {
> greatestMagnitude =
> max(greatestMagnitude, sqrt(pow(x, 2) + pow(y, 2)))
> }
>
> Not a huge improvement in this example, but there's a lot of code like
> this. It would be a nice bonus if Map.Entry could be destructured, but I
> don't see how that would be possible since it's an interface.
>
> Regards,
>
> August
More information about the amber-dev
mailing list