12

I've made this elixir module that should print each number, "counting" up to the number you give it.

defmodule Count do
  def to(n) do
    m = 1
    _to(n, m)
  end
  defp _to(n, m) when (m <= n) do
    IO.puts "#{m}"
    x = m + 1
    _to(n, x)
  end
end

...but when I run it, it performs exactly as expected except that it throws this error at the end. What is happening here?

iex(1)> Count.to 5  
1
2
3
4
5
** (FunctionClauseError) no function clause matching in Count._to/2
count.exs:6: Count._to(5, 6)
iex(1)>

Thank you for any help.

3 Answers 3

13

Elixir doesn't silently ignore a function call if none of the clauses match -- you get a FunctionClauseError. In this case, when m > n, no function clause in _to matches, so Elixir throws that error. You need to add another version of _to which accepts any m and n (or you could add a when m > n there, if you want) and does nothing.

defp _to(n, m) when (m <= n) do
  IO.puts "#{m}"
  x = m + 1
  _to(n, x)
end
defp _to(n, m) do
end
Sign up to request clarification or add additional context in comments.

Comments

4

You did not handle the case when m > n, but you are still calling it. You either dont call it, or have a function definition that handles this case.

  defp _to(n, m) when (m <= n) do
    IO.puts "#{m}"
    x = m + 1
    _to(n, x)
  end

  defp _to(n, m), do: IO.puts "Completed Counting" end

Comments

1

This shortens it up after looking at the answers given here. The explanation for the answer was a great one, thank you guys.

defmodule Count do
  def to(n, m \\ 1)
  def to(n, m) when n == m, do: IO.puts "#{n}"
  def to(n, m) do
    IO.puts "#{m}"
    to(n, m + 1)
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.