[patterns] Destructuring without matching?
Tagir Valeev
amaembo at gmail.com
Fri Jul 7 15:21:28 UTC 2017
Hello!
Sometimes it's reasonable to deconstruct the object of known type. A
classical example is Map.Entry. E.g. currently I can write:
// Map<String, Integer> wordCounts
wordCounts.entrySet().stream()
.filter(e -> e.getValue() > 10)
.map(e -> e.getKey()+": "+e.getValue())
.forEach(System.out::println);
It's desired to refer by concrete name to key and value like this:
wordCounts.entrySet().stream()
.filter((_, count) -> count > 10)
.map((word, count) -> word+": "+count)
.forEach(System.out::println);
Of course such syntax is not possible. Reading pattern matching proposal I
thought whether it could solve this somehow. I see these alternatives:
wordCounts.entrySet().stream()
.filter(e -> e matches Entry(_, count) && count > 10)
.map(e -> e matches Entry(word, count) ? word+": "+count : null)
.forEach(System.out::println);
Or
wordCounts.entrySet().stream()
.filter(e -> exprswitch(e) {case Entry(_, count) -> count > 10; default
-> false;})
.map(e -> exprswitch(e) {case Entry(word, count) -> word+": "+count;
default -> null;})
.forEach(System.out::println);
In the latter case default branch is redundant as we know that e is always
an Entry. Probably compiler could figure out this as well and do not
require default branch? In this case exprswitch will have only one branch
and looks too verbose.
The matches operator case is shorter, but also has redundant : null. It
would be nice to develop a separate simpler syntax for deconstruction
without matching. Probably lambda/method parameter could be deconstructed
at declaration point like
wordCounts.entrySet().stream()
.filter(Entry(_, count) -> count > 10)
.map(Entry(word, count) -> word+": "+count)
.forEach(System.out::println);
What do you think?
With best regards,
Tagir Valeev.
More information about the amber-dev
mailing list