matching on maps

Fred Hebert mononcqc@REDACTED
Wed May 13 15:55:36 CEST 2020

On 05/13, Andreas Schultz wrote:
>In the OTP-23 blog entry, there is an example of a illegal map match:
>  illegal_example(Key, #{Key := Value}) -> Value.
>Can someone explain why the compiler couldn't automatically rewrite that to:
>   legal_example(Key, Map) when is_map_key(Key, Map) -> maps:get(Key, Map).
>Such a rewrite should be possible whenever there are further restrictions
>(matches or guards) on the content of Value, right?

I don't think it would be impossible, but it just makes you hit another
barrier rather rapidly:

     tricky(Key, Val, #{Key := Val}) -> numberwang;
     tricky(Key, Val, #{Key := Value}) when Val > Value -> boom;
     tricky(Key, _,   #{Key := Val}) when is_number(Val) -> keep_trying;

Those can all feel like natural extensions that wouldn't work if the thing you
do is just matching the key through the guards. Anything that wants to do work
with the value can cause problems.

There's also ambiguous definitions of what it means for the `Key' variable to
be bound:

     weird(#{K := _}, #{K := _}) when K == 5 -> ???

Clearly this one represents a big search that doesn't make sense and won't
work the way you could match heads of a list. However `K` is bound in a guard.
Should the compiler be smart enough to handle it and propagate to the match
clause? What if there are more guard options?

Some cases would however be easier to deal with I guess, like:

     weird(Opt=concise, #{Opt := Val}) -> Val

It sounds like `Opt` is clearly bound and shouldn't be confusing!

In all cases I'm guessing here that it's been simpler to simply not allow the
patterns rather than add partial support for a small subset of the potential
matches that could exist.


More information about the erlang-questions mailing list