Recursion question in Elixir

Hi guys,
one question about recursion.

why this is not causing an error? cause if i write two or more function with the same name should cause an error right?

defmodule Recursion do

def countdown(0), do: IO.puts "ended the recursion."

def countdown(n) when n == 2 do
 IO.puts n
 countdown(n - 1)
end

def countdown(n) when is_integer n do
 IO.puts n
 countdown(n - 1)
end

end

Recursion.countdown(5)

thanks

read this
https://quickleft.com/blog/pattern-matching-elixir/

2 Likes

Every function head makes a different pattern in your case

2 Likes

They are not ‘two functions with the same name’, they are two different clauses of the same function. The compiler takes your code and creates a single function equivalent to something like:

def countdown(n) when is_integer(n) do
  cond do
    n == 0 -> IO.puts "ended the recursion."
    n == 2 -> 
      IO.puts n
      countdown(n - 1)
    true ->
      IO.puts n
      countdown(n - 1)
  end
end
4 Likes

Thank you tyro again,

so basically because of the different when call, elixir know that i’m defining clauses.
Cause i knew were clauses, but i was asking myself if that when caused the difference.

thank you.

1 Like

And thanks guys for the support.

1 Like

Ok i think i understood, was my confusion, arriving from an OOP approach.

So basically, when i have multiple named functions with the same name but different arguments i’m defining clauses, like i do in anonymous functions with multiple bodies.

Now is clear.

So i can’t define two clauses with the same name and same number of arguments. Make sense.

thanks.

1 Like

More precisely: the same number of arguments (or “arity”) is fine, as long as they each match parameters uniquely. In your original example all three countdown functions take 1 argument, but two match on (different) literal values and one only checks the data type of the parameter.

This would also work when added to your Recursion module:

def countdown(n) when is_string(n) do
0
end

as would:

def countdown(n) do
0
end

That last one would match whenever the parameter was not 0, 2 or an integer.

1 Like