[erlang-questions] pattern matching with maps in function heads

zxq9 <>
Fri Oct 30 00:26:03 CET 2015

On 2015年10月30日 金曜日 08:09:14 zxq9 wrote:
> On 2015年10月29日 木曜日 17:33:06 Martin Koroudjiev wrote:
> > get_attr(Attr, #{Attr := Val} = Map) ->
> >     Val;
> > get_attr(_Attr, _M) ->
> >     not_found.
> > 
> > but I get compile error: m1.erl:10: variable 'Attr' is unbound


> some_fun(Bar, {notice, Message}) -> send_user(Bar, Message);
> some_fun(Bar, {system, Message}) -> handle_sys(Bar, Message);
> some_fun(Bar, undefined)         -> log_missing(Bar).


> some_fun(Bar, #{Bar := {notice, Message}) -> ...;
> some_fun(Bar, #{Bar := {system, Message}) -> ...;
> some_fun(Bar, _) -> ...
> This just feels too noisy.

I completely forgot to mention the other meaning of "noise" aside from syntax. In the first case some_fun/2 has a slimly constrained typespec, even without knowing much about it:

-spec some_fun(Bar, Message) -> ok
    when Bar     :: term(),
         Message :: {system, term()} | {notice, term()} | undefined.

In the second version, though, nothing can be known about it other than it accepts a map -- and passing entire maps pretty much destroys the utility of dialyzer in many cases.

I know that doesn't matter to a lot of people, but I've found it useful. Early on I might pass a whole map in to lots of functions, but once I've got a good understanding of what a project is really doing internally I like to roll that back and be more deliberate when all I actually want is a single value from the map used within a function -- then dialyzer can sometimes becomes much more useful.


More information about the erlang-questions mailing list