With variables:
iex(2)> x = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(3)> %{a: 1, b: 2} = y
** (CompileError) iex:3: undefined function y/0
With function parameter variables:
defmodule A do
def go1(z = %{a: a}) do
IO.inspect z
IO.puts a
end
def go2(%{a: a} = z) do
IO.inspect z
IO.puts a
end
end
In iex:
iex(4)> c "a.ex"
warning: redefining module A (current version defined in memory)
a.ex:1
[A]
iex(5)> map = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(6)> A.go1(map)
%{a: 1, b: 2}
1
:ok
iex(7)> A.go2(map)
%{a: 1, b: 2}
1
:ok
Function args are pattern matched to the function parameter variables. And, in elixir function parameters can be constants, e.g. 1 or an atom, maps, tuples, etc--not just a variable, like x, y, or z. Here is how go1()
works:
A.go1(%{a: 1 b: 2})
|-----+----|
|
| %{a: a} = %{a: 1 b: 2}
V
def go1(z = %{a: a}) do
The "parameter variable" is %{a: a}
, and it gets matched to the function argument %{a: 1 b: 2}
, which binds a
to 1
. Then, you might think that you get the pattern match: z = %{a: 1}
, however, the pattern match %{a: a} = %{a: 1 b: 2}
actually returns the right hand side:
iex(10)> %{a: a} = %{a: 1, b: 2}
%{a: 1, b: 2}
Therefore, you get the pattern match: z = %{a: 1, b: 2}
. Here is another demonstration of that:
iex(13)> z = %{a: a} = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(14)> a
1
iex(15)> z
%{a: 1, b: 2}
Here is how go2()
works:
A.go1(%{a: 1 b: 2})
|-----+----|
|
| z = %{a: 1, b: 2}
V
def go2(%{a: a} = z)
z
is the parameter variable and it gets matched to the function argument %{a: 1 b: 2}
. The match z = %{a: 1 b: 2}
returns the right hand side:
iex(10)> z = %{a: 1, b: 2}
%{a: 1, b: 2}
So, next you get the pattern match: %{a: a} = %{a: 1, b: 2}
, which binds a
to 1
.
Therefore, all is consistent: with every pattern match, the pattern containing the variables is on the left of =
, and the values are on the right side. If you are looking for a rule it's: in the parameter list for a function definition, the thing on the right of an =
sign is the "parameter variable". The thing on the left is a pattern that will get matched after the "parameter variable" is matched to the function argument (or as you would say in other languages: "after the function argument is assigned to the parameter variable").