“Evaluates to” is the gotcha here, the arguments of a function are always a “match context” which has special properties - this:
def some_fun(whole_arg = %{single_value: v}) do
and this:
def some_fun(%{single_value: v} = whole_arg) do
both result in the same function that matches a map with a single_value key and binds whole_arg and v.
This is not the same = that you get when writing those statements alone:
# requires `v` to be defined beforehand, binds a new map `whole_arg`
# always succeeds
whole_arg = %{single_value: v}
# vs
# requires `whole_arg` to be defined beforehand as a map, binds `v`
# fails with MatchError if `whole_arg` does not have a :single_value key
%{single_value: v} = whole_arg
I suspect this is why it’s a common convention to write pattern-matches on structs on the left-hand side:
def may_attend_after_party(%Attendee{} = attendee) do
as it’s clearly distinguishable from the “evaluation” =.






















