Implementing an if Statement

Learn the implementation of the 'if' statement in Elixir.

We'll cover the following

Introduction

Have you ever felt frustrated that a language didn’t have just the right feature for some code you were writing? Or have you found yourself repeating chunks of code that weren’t amenable to factoring into functions? Have you just wished you could program closer to your problem domain?

If so, then you’ll love this chapter.

But before we get into the details, here’s a warning: macros can easily make our code harder to understand because we’re essentially rewriting parts of the language. For that reason, we never use a macro when we could use a function. Let’s repeat that:

Warning: Never use a macro when we could use a function.

In fact, we probably won’t write a macro in regular application code. But if we’re writing a library and want to use some of the metaprogramming techniques, we’ll need to know how macros work.

The if statement

Let’s imagine that Elixir didn’t have an if statement and that all it had is case. Although we’re prepared to abandon the while loop, not having an if statement is just too much to bear. So, we set about implementing one.

We’ll want to call it using something like this:

myif «condition» do 
  «evaluate if true»
else
  «evaluate if false»
end

We know that blocks in Elixir are converted into keyword parameters, so this is equivalent to the following:

myif «condition»,
  do: «evaluate if true», 
  else: «evaluate if false»

Here’s a sample call:

My.myif 1==2, do: (IO.puts "1 == 2"), else: (IO.puts "1 != 2")

Let’s try to implement myif as a function:

defmodule My do
  def myif(condition, clauses) do
    do_clause = Keyword.get(clauses, :do, nil) 
    else_clause = Keyword.get(clauses, :else, nil)
    case condition do
      val when val in [false, nil]
            -> else_clause
      _otherwise
            -> else_clause
    end 
  end
end

We can try executing it with the following commands:

iex> c "My.exs"
[My]
iex> My.myif 1==2, do: (IO.puts "1 == 2"), else: (IO.puts "1 != 2") 
1 == 2
1 != 2
:ok

Run commands shown in the snippets above in the given terminal:

Get hands-on with 1200+ tech skills courses.