🐧
Practical Elixir
  • ðŸĨWelcome!
  • 🐷Prerequisites
  • ðŸļWhy functional programming?
  • ðŸĶ‹History of Elixir
  • 🐙Elixir fundamentals
    • 🐝Types
      • 🐒Basic types
      • ðŸŠąList and tuples
      • ðŸĶ‰Keyword lists and maps
    • ðŸĶ€Pattern matching
    • ðŸŪModules
    • ðŸĶŽFunctions
    • ðŸĶ­Conditionals
    • ðŸģRecursion
    • 🐖Enumerables
    • ðŸĶMix
  • ðŸĶ…Web development with Elixir
    • ðŸĶDirectory structure
    • ðŸĶĪFirst steps
    • ðŸĶ‡Phoenix basics
    • ðŸĢViewing to-do list
    • 🐔Adding dynamic behavior
    • ðŸĶ†Data persistence
  • 🐍Resources
Powered by GitBook
On this page
  • case
  • if
  • cond
  • unless
  • Returning conditionals
Edit on GitHub
  1. Elixir fundamentals

Conditionals

PreviousFunctionsNextRecursion

Last updated 1 year ago

When writing functions you may notice that the function behaviors may differ based on the state of the arguments. While and in the function declaration may help to alleviate some of these problems, some derived variables (i.e. variables that are composed of the arguments) cannot be handled through these mechanisms and as such, will require explicit control through conditions.

case

case is used to compare a given value against many patterns until a matching one is found. This is most similar to switch statements in other languages:

case {1, 2, 3} do
    {1, 2, 5} -> "This will not return"
    {4, 5, 6} -> "Neither will this"
    {1, x, 3} -> "This will work with any #{x}"
    _ -> "This is used as the 'default' case"
end

If a pattern contains a reference to a variable outside of the case, you need to use the pin operator ^ which "locks" in the variable at the time of use, preventing it from being re-assigned (like in the above example with x):

x = 5
case {1, 2, 3} do
    {1, 2 ^x} -> "This will also try matching {1, 2, 5} and fail"
    _ -> "This will be the result"
end

You can also use with cases, specifying restrictions on each clause:

case {1, 2, 3} do
    {1, 2, 5} -> "This will not return"
    {4, 5, 6} -> "Neither will this"
    {1, x, 3} when x < 3 -> "This will work with any #{x} < 3"
    _ -> "This is used as the 'default' case"
end

If none of the clauses match the given value, then an error is raised.

if

if is relatively straightforward and is pretty much the same as the other languages:

x = 5
if x > 3 do
    "Greater"
else
    "Lesser"
end

There is no explicit elif so if you have multiple if statements, you will have to nest them as such:

if x > 3 do
    "Greater"
else
    if x < 0 do
        "Negative"
    else
        "Lesser"
    end
end

Like functions, you can also write the if statements as one-liners:

if x > 3, do: "Greater", else: "Lesser"

cond

Notice that when using if, the lack of an explicit elif causes your code to adopt an arrowhead style. This is can make your code look messy. This is where cond comes in. cond is the same as flattening the nested if statements:

cond do
    x > 3 -> "Greater"
    x < 0 -> "Negative"
    true -> "Lesser"
end

The final true clause is used as the "default" case. This is because each clause in cond is supposed to evaluate to a boolean.

unless

A final conditional we are introducing is the unless conditional which works as the opposite of if. The statement given to unless must be false for the body to run.

unless true do
    "This will not return"
end

Returning conditionals

Everything in Elixir is an expression. This means that even the conditionals are just expressions. This allows the conditionals to be assigned to variables or returned from functions:

x = if y > 3, do: "Greater", else: "Lesser"

def foo do
    if true do
        "This is returned"
    else
        "This isn't"
    end
end
🐙
ðŸĶ­
Pattern matching
Guard clauses
Guard clauses