[patterns] Destructuring without matching?

Brian Goetz brian.goetz at oracle.com
Fri Jul 7 15:34:51 UTC 2017



On 7/7/2017 11:21 AM, Tagir Valeev wrote:
> 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.

Not so fast!  We know that its static type is Entry, but it might be 
null.  In which case it would be foolish to try to let it match 
Entry(var w, var c) -- because once we cast to Entry, we'll NPE 
immediately when we try to extract the word/count components.  (See the 
recent writeup on patterns and nullity on amber-spec-experts.) Without 
nullity information in the type system, that pesky default branch is 
actually needed.




More information about the amber-dev mailing list