Function has multiple clauses and also declares default values.

Viewed 1159

Here is my module:

defmodule Test do
  def try(10 = num, other_num \\ 10) do
    num + other_num
  end
  def try(_num, _other_num) do
    raise "This is incorrect"
  end
end

When I run iex I get this warning:

warning: def try/2 has multiple clauses and also declares default values. In such cases, the default values should be defined in a header. Instead of:

    def foo(:first_clause, b \\ :default) do ... end
    def foo(:second_clause, b) do ... end

one should write:

    def foo(a, b \\ :default)
    def foo(:first_clause, b) do ... end
    def foo(:second_clause, b) do ... end

I honestly have no idea what this is trying to tell me to do. Can anyone break this down for me, what is the compiler want me to do here? Thank you!

1 Answers

The compiler wants you to write a function head (i.e. a function without a body) where you specify the default value.

def try(num, other_num \\ 10)
def try(10 = num, other_num) do
  num + other_num
end
def try(_num, _other_num) do
  raise "This is incorrect"
end

The reason for this is requirement is so that the user is unable to specify different default values for the same function, which would be ambiguous because functions with default values are compiled to multiple functions by the Elixir compiler.

def a(b, c \\ 10), do: b + c

is compiled to:

def a(b), do: a(b, 10)
def a(b, c), do: b + c

There is no straightforward translation when a function specifies different default values:

def a(b, c \\ 10), do: b
def a(b, c \\ 20), do: c
Related