re: Understanding Recursion with Elixir VIEW POST

TOP OF THREAD FULL DISCUSSION
re: Not sure I understand. Are you saying that all versions of the function have to have the same arity, so it needs a default value in order to have a...

No, no, clauses with different arities are fine. Multiple clauses of the same arity with defaults are not. If it leads to ambiguity, Elixir compiler raises.

iex|1  defmodule M do                      
...|1    def foo(_arg1 \\ nil, arg2), do: arg2
...|1    def foo(arg1, _arg2 \\ nil), do: arg1
...|1  end

** (CompileError) iex:1: def foo/2 defines defaults multiple times. Elixir allows defaults to be declared once per definition. Instead of:

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

one should write:

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

When Elixir is able to handle multiple clauses without ambiguity, it issues a warning.

iex|2  defmodule M do                       
...|2    def foo(arg1, _arg2 \\ nil), do: arg1
...|2    def foo(arg1, arg2), do: arg1 <> arg2
...|2  end

warning: def foo/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

But still, the head clause should be used to avoid possible human mistakes and make the intent clear.

code of conduct - report abuse