Modules & Named Functions
Clauses are tried top to bottom; first match wins.
8.1 Defining modules
defmodule Math do
def sum(a, b), do: a + b # public, keyword syntax
def square(x) do # public, block syntax
x * x
end
defp secret(x), do: x * 42 # private (only callable inside Math)
end
Math.sum(1, 2)
Math.square 4 # parentheses optional, but recommended8.2 Multiple clauses & pattern matching
Clauses are tried top to bottom; first match wins.
defmodule Greeter do
def hello(%{name: name}), do: "Hello, #{name}"
def hello(name) when is_binary(name), do: "Hello, #{name}"
def hello(_), do: "Hello, stranger"
end8.3 Guards
Allowed in guards: comparison, boolean, arithmetic, in, type checks, abs, div, rem, length, map_size, tuple_size, elem, hd, tl, byte_size, is_map_key, binary_part, bitwise functions, and custom guards built with defguard.
Errors inside guards make the guard fail silently (no exception).
defmodule Number do
def classify(n) when is_integer(n) and n < 0, do: :negative
def classify(0), do: :zero
def classify(n) when is_integer(n), do: :positive
def classify(n) when is_float(n), do: :float
enddefmodule Guards do
defguard is_even(n) when is_integer(n) and rem(n, 2) == 0
end
import Guards
def f(n) when is_even(n), do: :even8.4 Default arguments
With multiple clauses, declare defaults in a function head:
defmodule Hi do
def greet(name, greeting \\ "Hello"), do: "#{greeting}, #{name}"
end
Hi.greet("Ann") # "Hello, Ann"
Hi.greet("Ann", "Hey") # "Hey, Ann"def join(a, b \\ nil, sep \\ " ")
def join(a, nil, _sep), do: a
def join(a, b, sep), do: a <> sep <> b8.5 Naming conventions
Modules: CamelCase (MyApp.UserController).
Functions & variables: snake_case.
Predicate functions end in ? (empty?), guard-safe predicates start with is_.
Functions that raise end in ! (File.read!/1).
Unused variables start with _.
8.6 Nested modules
Module nesting is just naming: Shop.Cart is the atom :"Elixir.Shop.Cart".
defmodule Shop do
defmodule Cart do
def new, do: []
end
end
Shop.Cart.new()8.7 Function references & apply
apply(Math, :sum, [1, 2])
fun = &Math.sum/2
fun.(1, 2)
Kernel.function_exported?(Math, :sum, 2)