Cond for control flow in Elixir

Published October 14, 2018 by Toran Billups

In part 20 of my Elixir journey I wanted to give a quick example of how the `cond` macro differs from `case` for control flow.

Cond

The first time I looked at `case` and `cond` side by side I couldn't see why you might use one vs the other. Today I was trying to do a quick comparision for learning sake and wrote this program that would print if a number was even AND greater than 10, even AND less than 10 or odd.

    defmodule MyProgram do
      def even(n), do: rem(n, 2) == 0
      def gt(n, max), do: n > max
      def calc([]), do: []
      def calc([head | tail]) do
        IO.puts "calculation for #{head}"
        case even(head) do
          true ->
            case gt(head, 10) do
              true ->
                IO.puts "even and > 10"
              false ->
                IO.puts "even and < 10"
            end
          false ->
            IO.puts "odd number"
        end
        calc(tail)
      end
    end
  
    MyProgram.calc([2, 16, 3])
  

The part I disliked about this example specifically was the nested `case`. I decided to rewrite the above function using `cond` to see how it might look by comparison.

    defmodule MyProgram do
    def even(n), do: rem(n, 2) == 0
    def odd(n), do: rem(n, 2) == 1
    def gt(n, max), do: n > max
    def lt(n, max), do: n <= max
    def calc([]), do: []
    def calc([head | tail]) do
      IO.puts "calculation for #{head}"
      cond do
        even(head) and gt(head, 10) ->
          IO.puts "even and > 10"
        even(head) and lt(head, 10) ->
          IO.puts "even and < 10"
        odd(head) ->
          IO.puts "odd number"
      end
      calc(tail)
    end
    end
  

I found that when the control flow you need centers around a set of conditions that are driven from code you should reach for `cond` instead of `case`. I was able to visibily see the difference in that one had nesting and the other did not but that could also be my inexperience with `case` more generally.


Buy Me a Coffee

Twitter / Github / Email