Modules and Functions
Elixir modules, named functions, anonymous functions, defaults, and guards
Modules
Modules group named functions. By convention, module names are CamelCase.
defmodule Math do
def add(a, b), do: a + b
def subtract(a, b), do: a - b
end
Math.add(1, 2) # => 3Nested modules
defmodule MyApp.User do
defstruct name: nil, email: nil
end
# Equivalent to:
defmodule MyApp.User do ... endNamed functions
defmodule Greeter do
# Single-line (do: syntax)
def hello(name), do: "Hello, #{name}"
# Multi-line (do/end block)
def greet(name) do
message = "Hi #{name}!"
IO.puts(message)
message
end
# Private function (only callable within the module)
defp format(name), do: String.capitalize(name)
endDefault arguments
defmodule Http do
def get(url, opts \\ []) do
# opts defaults to []
end
# With defaults, you need a function head for multiple clauses
def connect(host \\ "localhost", port \\ 4000)
def connect(host, port) when is_binary(host) do
# ...
end
endGuards
Guards extend pattern matching with additional checks:
defmodule Calculator do
def divide(_, 0), do: {:error, "division by zero"}
def divide(a, b) when is_number(a) and is_number(b), do: {:ok, a / b}
def max(a, b) when a >= b, do: a
def max(_, b), do: b
endAllowed guard expressions
Only a subset of expressions are allowed in guards:
- Comparison:
==,!=,===,!==,>,<,<=,>= - Boolean:
and,or,not - Type checks:
is_atom/1,is_binary/1,is_bitstring/1,is_boolean/1,is_float/1,is_function/1,is_function/2,is_integer/1,is_list/1,is_map/1,is_number/1,is_pid/1,is_port/1,is_reference/1,is_tuple/1 - Arithmetic:
+,-,*,/,rem,abs,div - Other:
elem/2,hd/1,tl/1,length/1,map_size/1,bit_size/1,byte_size/1,node/1,self/0,in/2
Anonymous functions
# Basic
square = fn x -> x * x end
square.(4) # => 16
# Shorthand (& capture syntax)
add = &(&1 + &2)
add.(1, 2) # => 3
# Capturing a named function
upcase = &String.upcase/1
upcase.("hello") # => "HELLO"
# Closures (captures variables from outer scope)
defmodule Counter do
def make do
count = 0
{fn -> count end, fn -> count = count + 1 end}
end
endModule attributes
defmodule Config do
@default_port 4000
@app_name "MyApp"
# Accumulating attribute (appends to a list)
Module.register_attribute(__MODULE__, :plugins, accumulate: true)
@plugins :auth
@plugins :logging
def port, do: @default_port
def name, do: @app_name
endCommon attributes: @moduledoc, @doc, @spec, @since, @deprecated.