Elixir Cheatsheet

I’ve been trying to play around with Elixir, I’ve decided to make a little cheatsheet to remember the basics.
Source for documentation: HexaDocs.
Operators
Match Operator
In Elixir there is not concept of “assignment”, the = operator is a match operator, not an assignment operator.
iex(1)> hello = :hello
hello
iex(2)> {status, msg} = {:error, "You've dropped the ball!"}
{:error, "You've dropped the ball!"}
iex(3)> status
:errorEqual Operator
Check if two things are equal ==:
iex(1)> true == :true # See booleans - true is attached to the atom :true
true
iex(2)> 2 + 2 == 4
trueThe Pipe Operator
The pipe operator |> takes the output of a function and uses it as the first argument of the next function.
iex(1)> add_3 = fn a -> a + 3 end
#Function<42.105768164/1 in :erl_eval.expr/6>
iex(2)> iex(4)> [1, 3, 5] |>
...(2)> Enum.sum |>
...(2)> add_3.() # Equivalent to: add_3.(Enum.sum([1, 3, 5]))
12Basic Data Types
For more documentation, see the HexaDocs.
Booleans
Whether something is true or false. Under the hood, booleans are just the atoms :true and :false.
Atoms
Atom are constants. Their name is their value - and they are used similarly to enums in other languages. One of the most common atoms used in elixir is :ok.
Example use of atoms:
tup1 = {:error, "The sky is falling!"} # this is a tuple with an atom and a string in it.
tup2 = {:success, "Everything is under control."}
tup3 = {:something_else, "Davie Crocket"}
defmodule HandleMessage do
def check_message({state, msg}) do # destructure tuple with pattern matching
case state do # case based on the state atom
:error -> "An error occured: '#{msg}' 😭" # if the state is the :error atom -> do this.
:success -> "Hurray! '#{msg}' 🎉" # if the state is the :success atom -> do this.
_ -> "I don't know what to do with this: '#{msg}' 🤷" # otherwise -> do this.
end
end
end
IO.puts(HandleMessage.check_message tup1)
IO.puts(HandleMessage.check_message tup2)
IO.puts(HandleMessage.check_message tup3)An error occured: 'The sky is falling!' 😭
Hurray! 'Everything is under control.' 🎉
I don't know what to do with this: 'Davie Crocket' 🤷Strings
Strings in Elixir are inserted between double quotes and are encoded in UTF-8.
iex(1)> "¿Qué pasa?"
"¿Qué pasa?"Lists
Lists in Elixir are linked lists and are set in square brackets. Many functions for lists are available in the Enum module. Lists can be of different types.
iex(1)> my_nums_list = [1, 2, 3, 4]
[1, 2, 3, 4]
iex(2)> my_random_stuff_list = [1, "Cheese", :billboard, 33.4]
[1, "Cheese", :billboard, 33.4]
iex(3)> Enum.map(my_nums_list, fn x -> IO.puts(x) end)
1
2
3
4
[:ok, :ok, :ok, :ok]
iex(4)> Enum.map(my_random_stuff_list, fn x -> IO.puts(x) end)
1
Cheese
billboard
33.4
[:ok, :ok, :ok, :ok]Tuples
From the hexdocs:
Tuples are intended as fixed-size containers for multiple elements. To manipulate a collection of elements, use a list instead. Enum functions do not work on tuples.
Keyword Lists
Keyword lists are lists of two-element tuples where the first element is an atom. They preserve order and allow duplicate keys — the opposite tradeoff from maps. You’ll see them most often as optional arguments at the end of a function call.
iex(1)> opts = [enabled: true, timeout: 30]
[enabled: true, timeout: 30]
iex(2)> opts == [{:enabled, true}, {:timeout, 30}] # the [key: value] form is just sugar for tuples
true
iex(3)> opts[:timeout]
30Maps
Maps are Elixir’s key-value data structure. Keys can be any type and must be unique — no preserved order, no duplicates.
iex(1)> cheese = %{name: "brie", price: 12.5}
%{name: "brie", price: 12.5}
iex(2)> cheese.name # dot access only works when the key is an atom
"brie"
iex(3)> %{cheese | price: 14.0} # update syntax - only works on keys that already exist
%{name: "brie", price: 14.0}
iex(4)> Map.put(cheese, :in_stock, true) # Map.put/3 can add brand new keys
%{in_stock: true, name: "brie", price: 12.5}Functions
Elixir has named functions, defined with def inside a module, and anonymous functions that get passed around like any other value.
defmodule Greeter do
def hello(name) do
"Hello, #{name}!"
end
end
IO.puts(Greeter.hello("World"))Hello, World!Anonymous functions:
iex(1)> square = fn x -> x * x end
#Function<42.105768164/1 in :erl_eval.expr/6>
iex(2)> square.(4) # anonymous functions are invoked with a dot
16
iex(3)> Enum.map([1, 2, 3], &(&1 * &1)) # the capture operator is shorthand for a one-line fn
[1, 4, 9]Integers
Integers have arbitrary precision — they grow as large as memory allows, no overflow to worry about. Underscores are allowed as a visual separator in large literals.
iex(1)> 1_000_000
1000000
iex(2)> 2 ** 100 # exponentiation
1267650600228229401496703205376
iex(3)> div(7, 2) # integer division
3
iex(4)> rem(7, 2) # remainder
1A quick aside
Enjoying this post?
Come along on WhatsApp or Telegram — new posts, reflections, and the occasional spiral.
Control Flow
This is an example of a case statement:
tup1 = {:error, "The sky is falling!"} # this is a tuple with an atom and a string in it.
tup2 = {:success, "Everything is under control."}
tup3 = {:something_else, "Davie Crocket"}
defmodule HandleMessage do
def check_message({state, msg}) do # destructure tuple with pattern matching
case state do # case based on the state atom
:error -> "An error occured: '#{msg}' 😭" # if the state is the :error atom -> do this.
:success -> "Hurray! '#{msg}' 🎉" # if the state is the :success atom -> do this.
_ -> "I don't know what to do with this: '#{msg}' 🤷" # otherwise -> do this.
end
end
end
IO.puts(HandleMessage.check_message tup1)
IO.puts(HandleMessage.check_message tup2)
IO.puts(HandleMessage.check_message tup3)An error occured: 'The sky is falling!' 😭
Hurray! 'Everything is under control.' 🎉
I don't know what to do with this: 'Davie Crocket' 🤷This can also be accomplished with pattern matching and overloading:
tup1 = {:error, "The sky is falling!"}
tup2 = {:success, "Everything is under control."}
tup3 = {:something_else, "Davie Crocket"}
defmodule HandleMessage2 do
def check_message({:error, msg}) do
"An error occured: '#{msg}' 😭"
end
def check_message({:success, msg}) do
"Hurray! '#{msg}' 🎉"
end
def check_message({_, msg}) do
"I don't know what to do with this: '#{msg}' 🤷"
end
end
IO.puts(HandleMessage2.check_message tup1)
IO.puts(HandleMessage2.check_message tup2)
IO.puts(HandleMessage2.check_message tup3)An error occured: 'The sky is falling!' 😭
Hurray! 'Everything is under control.' 🎉
I don't know what to do with this: 'Davie Crocket' 🤷
