Erlang/OTP 20 [erts-9.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10]
[hipe] [kernel-poll:false] [dtrace]
Elixir 1.6.1 (compiled with OTP 20)
A pattern match assertion with a literal value passes, but the same assertion fails if a pinned variable with the exact same value is executed.
Equal behaviour for literal values and pinned variables in pattern matching.
This repro project contains a single test file that reproduces this behaviour, alongside some comments and test output in README.
This is expected behaviour. Matching against a pinned variable is effectively an equality check between two values. Matching against a pattern is more complex. Especially in case of maps that is important since map patterns match on subsets of keys, while equality checks verify exact contents.
In other words:
map = %{foo: 1, bar: 2}
%{foo: 1} = map # passes - we check subset of keys
value = %{foo: 1}
^value = map # fails - we check for equality between value and map
Ok, thanks for the clarification. I trust careful thought has gone into this decision. I'd still be interested if there was a backstory to this.
There's no backstory other than the fact that variables hold values not patterns.
Similar how you can't do:
pattern = [_, _]
^pattern = [1, 2]
you can't do what you're trying with a map - you assign a value to a variable, not a pattern. There's no reason for maps to behave different than everything else.
If there's a distinction between the two that makes sense. Maybe they are different things in the parser grammar as well? On reflection, this makes sense. The different nature is also underlined by the fact that one needs the pin operator to place a variable in a pattern, I just realise.
Interestingly, I can use a module attribute to store a pattern (or make my example pass), but I guess that is because these are more similar to macros / textual substitution?
Interestingly, I can use a module attribute to store a pattern (or make my example pass), but I guess that is because these are more similar to macros / textual substitution?
Precisely, they exist at compile-time and are 'injected' into the reference site.
Most helpful comment
This is expected behaviour. Matching against a pinned variable is effectively an equality check between two values. Matching against a pattern is more complex. Especially in case of maps that is important since map patterns match on subsets of keys, while equality checks verify exact contents.
In other words: