Reputation: 6571
I'm new to Elixir. I have this code:
defmodule DefaultParams do
def func(p1, p2 \\ 2, p3 \\ 3, p4) do
IO.inspect [p1, p2, p3, p4]
end
end
With this code, I do:
DefaultParams.func("a", "b") #=> ("a", 2, 3, "b")
I understand why it works that way: because of pattern matching. Elixir tries to match the supplied parameters to the ones defined in the function definition.
However, I don't understand this:
DefaultParams.func("a", "b", "c") #=> ("a", "b", 3, "c")
Why is the output not ("a", 2, "b", "c")
? That also fits the pattern defined in the parameters. I looked for an in-depth explanation in the docs but couldn't find anything.
After thinking about it for a while, I developed the suspicion that it works like this:
Can someone confirm/explain?
edit: fixed typos
Upvotes: 5
Views: 2361
Reputation: 4152
To use your example:
def func(p1, p2 \\ 2, p3 \\ 3, p4) do
IO.inspect [p1, p2, p3, p4]
end
If you compile your code and type h DefaultParams.func
with tab
, it will show you
iex> h DefaultParams.func
func/2 func/3 func/4
It actually created 3 functions for you.
def func(p1, p4), do: func(p1, 2, 3, p4)
def func(p1, p2, p4), do: func(p1, p2, 3, p4)
def func(p1, p2, p3, p4) do
IO.inspect [p1, p2, p3, p4]
end
iex> func(:a, :b) # calling func/2, which is actually func(p1, 2, 3, p4)
[:a, 2, 3, :b]
iex> func(:a, :b, :c) # calling func/3, which is actually func(p1, p2, 3, p4)
[:a, :b, 3, :c]
iex> func(:a, :b, :c, :d) # calling func/4
[:a, :b, :c, :d]
Upvotes: 11
Reputation: 44298
Can't find a good reference for it, but my understanding is it attempts to match left to right. so a and b get matched, p3 doesn't match to c because p4 has no value, so next option is p4 with c
Upvotes: 2