(CondClauseError) no cond clause evaluated to a truthy value Error

Hello, everyone, I’m new to Elixir I’m reading a book entitled Phoenix in Action I’m on its second chapter where the author introduces to Elixir but I’m facing this error when I run it into the Elixir shell. This is here:

iex(5)> Fizzbuzz.go(1, 100)
** (CondClauseError) no cond clause evaluated to a truthy value
    (fizzbuzz 0.1.0) lib/fizzbuzz.ex:11: Fizzbuzz.show_results/1
    (elixir 1.10.1) lib/enum.ex:789: anonymous fn/3 in Enum.each/2
    (elixir 1.10.1) lib/enum.ex:3371: Enum.reduce_range_inc/4
    (elixir 1.10.1) lib/enum.ex:2116: Enum.each/2

And the code is here:

defmodule Fizzbuzz do
  def go(minNumber, maxNumber) do
    Enum.each(minNumber..maxNumber, fn number -> show_results(number) end)
  end

  def show_results(number) do
    # IO.puts(number)
    cond do
      rem(number, 3) == 0 && rem(number, 5) == 0 -> IO.puts("FizzBuzz")
      rem(number, 3) == 0 -> IO.puts("Fizz")
      rem(number, 5) == 0 -> IO.puts("buzz")
    end
  end
end

But in the show_results function when I just add IO.puts(number) only I can see them in the console. I need your help, please.

2 Likes

The message is telling you that there are no conditions within the cond expression that evaluate to truthy. What should a cond do if no conditions are met? it raises an exception :slight_smile:

The usual approach is to add a final condition that is guaranteed to evaluate to a truthy value. Often true. So:

     cond do
      rem(number, 3) == 0 && rem(number, 5) == 0 -> IO.puts("FizzBuzz")
      rem(number, 3) == 0 -> IO.puts("Fizz")
      rem(number, 5) == 0 -> IO.puts("buzz")
      true -> IO.puts("Nothing to see here")
    end
3 Likes

Thank you @kip for your response.

The thing that I’m not understanding is why there’s no truthy evaluated as I can see I have numbers from 1 to 100

Aah!! I actually got it so it means if it encounters nothing evaluated it will just stop the program and raise the exception ? Thank you again @kip

1 Like

exactly. Also just be careful, the catch-all for cond is true, and the catch-all for case is _ (or any variable), It’s easy to get confused if you refactor one to the other.

2 Likes

I had this same question. The first run of cond had no truthy values so gave an error. Adding a default end condition using the true -> "do stuff" solved it.