Immutability and Memory

Get introduced to the pipe operator and immutability in Elixir.

The pipe operator

The pipe operator |> is one of the first constructs Elixir developers learn because it embodies transformation and the decoupling between data and behavior. When we pipe between functions, the pipe operator receives all data it needs as input and returns all relevant information as output. There’s never hidden or mutated data. Each pipe is a standalone transformation with an explicit contract.

When writing our business logic, we may use Ecto changesets to handle datacasting and validation:

Press + to interact
def changeset(user, params \\ %{}) do
user
|> cast(params, [:name, :email, :age])
|> validate_required([:name, :email])
|> validate_format(:email, ~r/@/)
|> validate_inclusion(:age, 18..120)
|> unique_constraint(:email)
end

How immutability works in Elixir

Each function along the way transforms the changeset. What about the cost of immutability? Many developers assume that each time we change a map or a struct, Elixir creates a whole new one in memory. That’s not true.

Elixir represents a map with multiple ...