Basics
This check is disabled by default.
Learn how to enable it via .credo.exs.
This check has a base priority of normal and works with any version of Elixir.
Explanation
Encourages the capture syntax & for anonymous functions that just
pass their arguments through to another function or apply a simple
operator to them.
When an fn forwards its arguments (in the same order) to a function
call, or applies a single operator to a single argument, the capture
form says the same thing with less ceremony and keeps the surrounding
pipeline easy to scan.
Bad
Enum.map(list, fn x -> String.upcase(x) end)
Enum.map(list, fn x -> x * 2 end)
Enum.map(list, fn x -> Map.get(x, :key) end)Good
Enum.map(list, &String.upcase/1)
Enum.map(list, &(&1 * 2))
Enum.map(list, &Map.get(&1, :key))The check flags three bands:
- Pass-through —
fn x -> foo(x) end→&foo/1, including multi-arg calls in the same order and remote calls. - Simple expressions —
fn x -> x * 2 end→&(&1 * 2)for operator bodies. - Partial application —
fn x -> Map.get(x, :key) end→&Map.get(&1, :key)where only some arguments are captured.
The check is intentionally conservative — the following are not flagged:
- Anonymous functions with multiple clauses.
- Pattern-matched arguments (
fn {a, b} -> ... end). - Guards (
fn x when x > 0 -> ... end). - Arguments used zero or more than once in the body.
- Multi-arg fns where the arguments appear in a different order
than declared (
fn x, y -> f(y, x) end). - Multi-statement bodies, or
case/cond/if/with/trybodies. - Pipe-chain bodies (
fn x -> x |> a() |> b() end). - Bodies containing a nested
fnor&capture. - Bodies containing
assert/refute(and relatives) — ExUnit assertion macros can't be captured. - Zero-arity anonymous functions and the identity
fn x -> x end.
Check-Specific Parameters
There are no specific parameters for this check.
General Parameters
Like with all checks, general params can be applied.
Parameters can be configured via the .credo.exs config file.