Bitwise
Bitwise

Reputation: 8461

Function has multiple clauses and also declares default values

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 have no idea what this is trying to tell me to do. What does the compiler want me to do here?

Upvotes: 5

Views: 1868

Answers (1)

Dogbert
Dogbert

Reputation: 222118

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

Upvotes: 19

Related Questions