Subscribe for only $15 to access all of our content

#33: Elixir Control Flow

Elixir 1.5.3


In this episode we’ll take a look at control flow in Elixir.

Specifically we’ll look at three different control structures: if/else, case statements, and conditionals.

Let’s get started.

Here we have a module Greeter with a single function greet that returns the string "Hello".

Now let’s update our function to only return "Hello" if the language is English.

First we’ll add the parameter lang to our function.

And then let’s add an if statement. So that if our lang variable is the abbreviation for English - "en" - "Hello" is returned.

greeter.exs

defmodule Greeter do
  def greet(lang) do
    if lang == "en" do
      "Hello"  
    end
  end
end

Let’s try it out.

We’ll go to the console and run iex with our file greeter.exs. And if we run Greeter.greet("en") - it returns "Hello".

Now let’s try it again only this time we’ll run it with another language like French.

And nil is returned.

> Greeter.greet("en")
"Hello"
> Greeter.greet("fr")
nil

Let’s go back to our module and add an else statement to print "Bonjour" if the language isn’t English. (Skip to last part of recording - I went back and re-did a better take - I think - at the end.)

Now while this will work as-is. We can shorten it and collapse it to one line.

greeter.exs

defmodule Greeter do
  def greet(lang) do
    if lang == "en", do: "Hello", else: "Bonjour"
  end
end

Then let’s go back and reload our module.

And if we use "en" it still returns "Hello"

Then if we use "fr" it now returns "Bonjour".

While this is great, what happens if we try another language.

Let’s try it with the abbreviation for Spanish.

And "Bonjour" is returned, which is not what we wanted.

> r(Greeter)
{:reloaded, Greeter, [Greeter]}
> Greeter.greet("en")
"Hello"
> Greeter.greet("fr")
"Bonjour"
> Greeter.greet("es")
"Bonjour"

In order to add more branches of logic, let’s reach for another control flow structure - the case statement.

The case statement let’s us match against many different values for our variable lang.

We’ll define our case statement with the variable we want to match against.

And let’s match against English, Frech, and Spanish.

greeter.exs

defmodule Greeter do
  def greet(lang) do
    case lang do
      "eng" -> "Hello"
      "fr" -> "Bonjour"
      "es" -> "Hola"
    end
  end
end

Then back in our iex session we’ll reload the module.

And let’s try it out.

English returns “Hello”.

And Spanish returns “Hola”.

Then if we try a language that we haven’t defined, we get an error: no case clause matching.

Let’s go back to our module.

And let’s add an underscore to catch all other cases.

greeter.exs

defmodule Greeter do
  def greet(lang) do
    case lang do
      "eng" -> "Hello"
      "fr" -> "Bonjour"
      "es" -> "Hola"
      _ -> "We don't have a greeting for that."
    end
  end
end

In iex we’ll reload our module.

And let’s try it again with a language we didn’t define a clause for.

And great, our catch-all message was triggered.

Now case statements are great for matching on the value of our variable, but what if we need to match against expressions that return true?

For that we can use another control flow structure: cond (condition).

Let’s go back to our module. And we’ll define our conditions for when English is true, French, and Spanish.

Now if we want to define a final expression to catch any other conditions we’ll just use true and then add a message.

greeter.exs

defmodule Greeter do
  def greet(lang) do
    cond do
      lang == "en" ->
        "Hello"
      lang == "fr" ->
        "Bonjour"
      lang == "es" ->
        "Hola"
      true ->
        "We don't have a greeting for that."
    end
end

Then we’ll go back it iex on last time and reload our module.

And if we try our function with different languages, we still get the correct greetings.

More Episodes

#81: Building Structs from External Data

Here we’ll see how structs can be used to format data. We’ll start with an introduction to structs and then explore different ways to map external data to a struct, including using the ExConstructor package.

Watch episode
Alchemist's Edition

#80: Proactive Caching

In this episode we’ll use proactive caching with Cachex. Proactive caching can help ensure there is never a cache miss since data is loaded when the application starts.

Watch episode
Alchemist's Edition

#79: Caching with Cachex

Here we look at how to use Cachex to create a cache in an Elixir application. We’ll start by seeing how to interact with Cachex and then we’ll implement a simple cache in our application.

Watch episode