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.