Destructuring / Patterns in for-each
August Nagro
augustnagro at gmail.com
Wed Jan 20 00:36:00 UTC 2021
Awesome, that's exciting!
I definitely see how such class-member patterns could benefit serialization
libraries too.
On Tue, Jan 19, 2021, 4:16 PM Brian Goetz <brian.goetz at oracle.com> wrote:
> 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