If and Cond statements
The last language features being discussed for managing Code Flow are the if and cond statements. The reason the if is introduced at this late stage is to emphasize how less important it is in Elixir. The if statement works like you might expect from other languages. However, an if statement does not support pattern matching. By now you’ve seen that pattern matching is everywhere in Elixir! This similarity to other languages is a weakness for the if statement.
Contents
if statements
There are valid uses for if conditions like needing to test a single value. Typically, if you find yourself reaching for an if by default, realize there is probably a better way to write the code. In general, consider the writing of an if statement as a possible anti-pattern. With that said, let’s look at the syntax and talk about how it works.
if condition do
# executed when condition is truthy
else
# executed when condition is falsy
end
A falsy value is nil or false and a truthy value is everything else.
If you want to test that a value is false, you would write it as if value == false do... A better way is to use pattern matching.
Variables and leaking
By now you’ve seen that variables bound inside a clause don’t leak out. This is also true for the if. It is a common pattern in other languages to assign variables inside an if statement. Beneficially, the compiler recognizes this common mistake and points you in the right direction.
# This doesn't work!
do_thing = false
if some_condition do
do_thing = true
end
#=> warning: variable "do_thing" is unused
#=>
#=> Note variables defined inside case, cond, fn, if and similar do not leak. If you want to conditionally override an existing variable "do_thing", you will have to explicitly return the variable. For example:
#=>
#=> if some_condition? do
#=> atom = :one
#=> else
#=> atom = :two
#=> end
#=>
#=> should be written as
#=>
#=> atom =
#=> if some_condition? do
#=> :one
#=> else
#=> :two
#=> end
That’s a pretty helpful error message! This shows that the if statement returns a value and that’s how you get conditional values out of it.
Note that you aren’t able to bind multiple results like this. That is an extra signal that an if isn’t the preferred way to manage Code Flow.
Ternary statements
In languages like Javascript, there is a ternary operator. This doesn’t exist in Elixir. However, the if statement supports being expressed as a Keyword list putting it inline. Note that it doesn’t use the end.
result = if true, do: "true", else: "false"
result
#=> "true"
Nested if statements
When you see a nested if statement, that is definitely a code smell and an anti-pattern in Elixir. This is an opportunity to refactor into one or more of the following alternative structures:
- multiple function clauses with pattern matching
- a
casestatement - possibly a
condstatement (up next)
unless statement
If usage of an if clause is a code smell of a possible anti-pattern then usage of the unless statement is even more so.
unless condition do
# executed when condition is falsy
end
The unless clause exists, but is negative logic. This is harder to reason about and is best avoided.
No “else if” conditions
Note that the if statement does not have an elsif or built-in else if style clause. If you need that, then the cond statement is a better fit.
cond statements
The cond statement is well suited for replacing the if ... else if clauses you find in many other languages. However, because Elixir provides many more powerful features for controlling Code Flow, cond is used much less frequently.
It evaluates a series of conditions and stops at the first truthy one.
value = 123
cond do
value > 200 ->
"Greater than 200"
value > 100 ->
"Greater than 100"
value > 50 ->
"Greater than 100"
end
#=> "Greater than 100"
If nothing matches, it raises an exception.
value = 123
cond do
value in 1..10 ->
"Between 1 an 10"
value > 200 ->
"Greater than 200"
value < 100 ->
"Less than 100"
end
#=> ** (CondClauseError) no cond clause evaluated to a truthy value
To ensure something matches like the last else clause of an if ... else if statement, use true as your condition.
value = 123
cond do
value in 1..10 ->
"Between 1 an 10"
value > 200 ->
"Greater than 200"
value < 100 ->
"Less than 100"
true ->
"It was something else..."
end
#=> "It was something else..."
The final true provides a “default” or grand else clause to ensure you have a match.
Recap
- “falsy” is when a condition is
nilorfalse - “truthy” is anything not falsy
ifstatements do not support pattern matching- Nested
ifstatements are an anti-pattern - You can do simple inline statements:
if 1 == 1, do: "One!", else: "...uh..." - Don’t use
unlessstatements. They are negativeifstatements. condhandles theif ... else ifstatements you may be familiar withcondstatements can end withtrueto ensure a match
1 Comments
Comments are closed on this static version of the site.

Comments are closed
This is a static version of the site. Comments are not available.