[erlang-questions] Illegal map key in pattern

Valentin Micic v@REDACTED
Mon Aug 5 12:28:48 CEST 2019


> On 05 Aug 2019, at 11:03, Per Hedeland <per@REDACTED> wrote:
> 
> On 2019-08-05 09:29, Raimo Niskanen wrote:
>> On Sat, Aug 03, 2019 at 06:14:15PM +0200, Valentin Micic wrote:
>>> Hi,
>>> 
>>> I am a bit nonplussed with the behaviour of map module&consider the following map:
>>> 
>>> 
>>> f(MAP), MAP = #{ {12,1} => "some value", {12,2} => "some other value"}.
>>> 
>>> 
>>> Then, the following works:
>>> 
>>> 
>>> f(V), case MAP of #{ {1,12} := V} -> V end.
>>>                             "some value"
>>> 
>>> 
>>> 
>>> Then, surely, a snippet below should also work... except that it doesnt:
>>> 
>>> 
>>>  f(DCID), f(SORD), DCID = 12, SORD=1.
>>> 
>>> f(V), case MAP of #{ {DCID, SORD} := V} -> V end.
>>> 
>>> * 1: illegal map key in pattern
>> The syntax of your examples makes no sense to me, so I take a shot in the
>> dark on your gripe.
> 
> It's just "shell syntax", try it:-) - the f/1 is the shell's "forget"
> function, to ensure that the variable is unbound.
> 
>>     fun (K, V, Map) ->
>> 	case Map of
>> 	    #{ K := V} -> V
>> 	end
>>     end.
>>     fun (K, V, Map) ->
>> 	case Map of
>> 	    #{ {K} := V} -> V
>> 	end
>>     end.
>>     fun (K, V, Map) ->
>> 	K_1 = {K},
>> 	case Map of
>> 	    #{ K_1 := V} -> V
>> 	end
>>     end.
>> Try those in the shell and you will find out that the first produces a
>> fun(), the second barfs with "illegal map key in pattern", and the third
>> produces a fun().
>> From:
>>     http://erlang.org/doc/reference_manual/expressions.html#map-expressions
>> section "Maps in Patterns"
>>     Matching of key-value associations from maps is done as follows:
>>     #{ K := V } = M
>>     Here M is any map. The key K must be an expression with bound
>>     variables or literals. V can be any pattern with either bound
>>     or unbound variables.
>> So, the key must be a literal or a bound variable.
> 
> Hm, that's not what the documentation that you quote says - surely, if
> K is a bound variable, {K} is "an expression with bound variables", as
> is {DCID, SORD} in Valentin's case. And of course there's no way the
> variableS can be plural if not combined into an expression somehow...
> 
>> It's a known limitation.
> 
> So it seems the documentation is wrong, and should drop the
> "expression" and plurals: "The key K must be a bound variable or a
> literal." (as you said).
> 
> —Per

Thank you Per for articulating my issue in a way I wasn’t able to do. :-)

Indeed, documentation seems a bit misleading. When they are referencing a plural (bound variables), they are probably referring to a multitude of “single” variables used as keys to a multitude of maps. 

But, documentation aside — that could be corrected; do you think that this kind of implementation is in line with a principle of least astonishment?

V/

> 
>> / Raimo
>>> 
>>> 
>>> 
>>> To make things worse, when I just replace an explicit term, such as {DCID, SORD}, with something like this:
>>> 
>>> 
>>> f(GRP_KEY), GRP_KEY={DCID, SORD}.
>>> 
>>> f(V), case MAP of #{ GRP_KEY := V} -> V end.
>>> 
>>> "some value

>>> 
>>> 
>>> 
>>> Then the whole thing works again.
>>> 
>>> I would argue that all cases should just work.
>>> How come they dont?
>>> 
>>> 
>>> Kind regards
>>> 
>>> V/
>>> 
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list