Ege Ersoz
Ege Ersoz

Reputation: 6571

Pattern matching and default parameters

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:

  1. "a" is matched to p1
  2. "b" is matched to p2
  3. "c" is not matched to p3 because then there would be a mismatch. So it is skipped, and p3 gets the default value, which is 3
  4. "c" is matched to p4

Can someone confirm/explain?

edit: fixed typos

Upvotes: 5

Views: 2361

Answers (2)

sbs
sbs

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

Keith Nicholas
Keith Nicholas

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

Related Questions