Variables must not be named with a single letter.
Single-letter names carry no meaning, so every reader has to reconstruct what the value is from the surrounding code. Name the value after what it holds.
# BAD — the letters say nothing about the values
def double(x), do: x * 2
Enum.map(users, fn u -> u.name end)
# GOOD — the names say what each value is
def double(number), do: number * 2
Enum.map(users, fn user -> user.name end)Only binding sites are reported — function heads, fn clauses, case/receive
and rescue clauses, = matches, and for/with generators. A later use of an
already-flagged variable is not reported again, and neither is a pin (^x), since
the pinned variable was reported where it was bound.
cond clause heads and the after head of a receive are expressions rather
than patterns, so they are not searched for bindings — using an already-bound
variable there is not reported again, while a binding made inside a head, as in
(result = f()) > 1 -> result, is still caught through its =.
Type signatures (@spec, @type, @typep, @opaque, @callback, and
@macrocallback) are ignored entirely — a and b in
@spec transform(t, (a -> b)) :: [b] are type variables, not variables.
The wildcard _ and underscore-prefixed names such as _x mark intentionally
unused values and are always allowed.
Names that must stay single-letter (for example in mathematical code) can be
exempted through the :allowed_names param.