Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Module 2: Booleans, if, string and case

elixir-intro/module2.livemd

Module 2: Booleans, if, string and case

Preparation

Boolean Expressions

We can work with truth values (aka boolean values):

true
false

A comparison (that is ==, >=. <=, >, < and !=) creates a truth value:

page_count = 108
long_book = page_count > 100

There are special operators that we can use to do calculations on truth values:

reached_top = true
first = false
winner = reached_top and first
best = true
winner = first or best
looser = not winner

These expressions can be combined:

looser = not (first or best)

The if-else and if constructions

Lets take a look at a property of a circle:

r = -3

The radius variable can be negative, zero or positive. Often, we have a need to handle such possibilities in different ways. This can be done using the if construct:

{:success, area} =
  if r<0 do
    {:error, :negative_radius}
  else
    {:success, :math.pi * r*r}
  end

Notes:

  • Names starting with a colon are of a special type called atoms. Their role is to be equal to them selves and nothing else. One could have used a unique integer instead, but as humans we are capable of interpreting the name of the atom to improve readability. Also, this means that we won’t have to keep track of which integers have been used.
  • In this code we use pattern matching to – in the case of a success – bind the variable area to the result of the calculation. If the match fails then we will get a MatchError. So far, this is not a problem for us. Elixir has mechanisms to deal with problems such as this.

There is another variant of the if construct. It is missing the else part. This variant only does something if the condition (the truth value) evaluates to true. This is often used to print something to the screen:

if area > 180 do
  IO.puts("That's a big circle!")
end

Text Strings

A text string (or just string) is essentially a sequence of characters. We will often print it out using IO.puts. That looks like this:

IO.puts("Hello, World")

Strings can be concatenated using the <> operator:

"Hello"<>", World"

But we can also compose them using exising names and expressions:

"A circle with radius #{r} has the area #{:math.pi * r*r}!"

Some times you want a string that spans multiple lines. That is best done like this:

s =
  """
  A circle with radius #{r} has ...
  - An area of #{:math.pi * r*r}, and
  - A circumference of #{2 * :math.pi * r}
  """
IO.puts(s)

The case construction

An if construction has at most two outcomes, and the choice between these is expressed as an expression that evaluates to a boolean value. That can be quite limiting.

The most commonly used alternative is to use the case construction. Here, one value is compared with a number of patterns. The first pattern that matches dictates the outcome:

result = {:error, :paper_jam}

case result do
  {:error, :paper_jam} -> {:result, "printer is jamming"}
  {:error, {:code, 12}} -> {:result, "house on fire"}
  {:error, {:reason, reason}} -> {:result, "error due to reason '#{reason}'"}
  {:success, value} -> {:result, "succeeded with value #{value}"}
  _ -> {:result, "This matches anything"}
end

Exercise

Try to scroll up to the cell where the variable r is defined. Adjust the value to $-3$ and evaluate the next cell. What happens?

We are at a birthday party with a number of participants:

participant_count = 13

The host has made a layered cake. Slicing a cake is easy if the number of slices is even, and complicated if it is odd. Based on the variable participant_count, assign the variable easy a truth value representing whether the job of slicing is easy.

Note: The function rem returns the remainder of an integer division. rem(value, 2) will thus evaluate to $1$ if value is odd.

easy = rem(participant_count, 2)

Use an if construction to either print out “It is easy” or “It is hard” based on the value of the variable easy:

easy = rem(participant_count, 2) < 1

Do the same with a case construction:

case easy do
  true -> IO.puts("It is easy")
  false -> IO.puts("It is hard")
end

Next step …

When you are done, you can continue with the next exercise here.