Elixir Cheatsheet
Functions and Modules
Use this Elixir reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Module Shape
defmodule Greeter do @moduledoc "Greeting helpers." def hello(name) do "Hello, #{name}" end defp normalize(name), do: String.trim(name) end Greeter.hello("Ada")
defmodule defines a module. def defines a public function, defp a private one. Nest namespaces with dots: defmodule MyApp.Accounts.User.
alias, import, require, use
defmodule MyApp.Billing do alias MyApp.Accounts.User # now just User alias MyApp.Accounts.{User, Team} # multi-alias alias MyApp.Repo, as: DB # rename import Ecto.Query, only: [from: 2] # call from/2 without the module prefix import String, except: [length: 1] require Logger # needed before using a module's MACROS Logger.info("compiled") use GenServer # runs GenServer.__using__/1: injects code end
Rule of thumb: alias for shorter names (default choice), import sparingly and with :only, require for macros (Logger, Integer.is_even/1), use when a library tells you to (it injects callbacks, imports, and behaviour wiring).
Module Attributes
defmodule Circle do @moduledoc "Circle math." # module docs (heredoc for long text) @pi 3.14159 # compile-time constant @timeout :timer.seconds(5) # evaluated at compile time @doc "Area from a radius." @spec area(number()) :: float() def area(r), do: @pi * r * r end
@doc/@moduledoc feed h Circle.area in IEx and hexdocs. @spec documents types for Dialyzer: @spec fetch(String.t()) :: {:ok, map()} | {:error, atom()}. Define custom types with @type user_id :: pos_integer(). Attributes are inlined at compile time — they are constants, not mutable state.
Arity
Functions are identified by module, name, and arity:
String.length("abc") # String.length/1 Enum.map([1, 2], fn x -> x * 2 end) # Enum.map/2
same/1 and same/2 are different functions and can coexist.
One-line Functions
def double(x), do: x * 2 def zero?(0), do: true def zero?(_), do: false
Use block form when the body needs several expressions.
Multiple Clauses and Guards
defmodule MathList do def sum([]), do: 0 def sum([head | tail]), do: head + sum(tail) def describe(n) when is_integer(n) and n > 0, do: :positive def describe(0), do: :zero def describe(_), do: :other end
The first matching clause runs. Clauses of the same function must be adjacent.
Anonymous Functions
double = fn x -> x * 2 end double.(10) # called with a dot: fun.(args) add = fn a, b -> a + b end handle = fn {:ok, value} -> value # anonymous functions can have clauses {:error, _} -> nil end
Capture Shorthand
Enum.map([1, 2, 3], &(&1 * 2)) Enum.reduce([1, 2, 3], 0, &+/2) Enum.map(["a ", " b"], &String.trim/1) # &Mod.fun/arity captures a named function parse = &Integer.parse/1
&1, &2, … refer to arguments. Prefer a full fn when the body is more than one small expression.
Default Arguments
def greet(name, prefix \\ "Hello") do "#{prefix}, #{name}" end
When combining defaults with multiple clauses, declare a bodiless function head first:
def greet(name, prefix \\ "Hello") def greet(name, prefix), do: "#{prefix}, #{name}"
Keyword Options
def search(query, opts \\ []) do limit = Keyword.get(opts, :limit, 10) sort = Keyword.get(opts, :sort, :asc) {query, limit, sort} end search("elixir", limit: 5) # trailing keyword list needs no brackets
An options keyword list as the last argument is the standard Elixir API shape (Enum.sort/2, String.split/3, GenServer options all use it).