Anonymous Functions
Functions as values in Elixir -- the fn syntax, the capture shorthand, and closures over surrounding variables.
3 min read
Alongside named functions defined in modules, Elixir has anonymous functions — functions that exist as values, which you can assign to variables, pass around, and call directly.
The fn syntax
add = fn a, b -> a + b end
add.(2, 3)
# => 5Two things stand out compared to named functions: the body goes between fn and end with -> separating parameters from the body, and calling it requires a dot before the parentheses (add.(2, 3), not add(2, 3)). That dot is how Elixir tells apart a call to a variable holding a function from a call to a named function.
The capture shorthand: &
For short function bodies, the & capture operator is a more compact alternative, using &1, &2, etc. as positional placeholders for arguments:
add = &(&1 + &2)
add.(2, 3)
# => 5
square = &(&1 * &1)
square.(4)
# => 16& can also capture an existing named function directly, which is extremely common when passing functions to Enum functions:
names = ["ada", "grace", "margaret"]
Enum.map(names, &String.capitalize/1)
# => ["Ada", "Grace", "Margaret"]&String.capitalize/1 here means "the function String.capitalize with arity 1, as a value" — no need to wrap it in fn x -> String.capitalize(x) end when the capture syntax does the same thing more concisely.
Passing functions as arguments
Anonymous functions are what make higher-order functions like Enum.map/2, Enum.filter/2, and Enum.reduce/3 so central to everyday Elixir code:
numbers = [1, 2, 3, 4, 5, 6]
evens = Enum.filter(numbers, fn n -> rem(n, 2) == 0 end)
# => [2, 4, 6]
doubled = Enum.map(numbers, &(&1 * 2))
# => [2, 4, 6, 8, 10, 12]
total = Enum.reduce(numbers, 0, fn n, acc -> n + acc end)
# => 21Instead of writing a manual loop, you describe the transformation and hand it to the function that knows how to walk the collection — this is functional programming's central habit, and it's worth getting comfortable with early since it appears constantly in idiomatic Elixir.
Closures
An anonymous function closes over variables from the scope where it was defined, capturing their value at creation time:
multiplier = 3
triple = fn n -> n * multiplier end
triple.(5)
# => 15
multiplier = 10
triple.(5)
# => 15 -- still uses the multiplier value from when triple was createdBecause Elixir data is immutable, this behaves predictably: triple captured the value 3, not a live reference to multiplier, so reassigning multiplier afterward has no effect on functions already created.
Multi-clause anonymous functions
Like named functions, an anonymous function can have multiple clauses matched by pattern:
classify = fn
0 -> "zero"
n when n > 0 -> "positive"
_n -> "negative"
end
classify.(5)
# => "positive"
classify.(-3)
# => "negative"(The when guard here gets its own full treatment in the next lesson.) Anonymous functions and named module functions cover different needs — anonymous ones for quick, local, often one-off transformations passed to another function; named ones for anything reused or worth naming on its own.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.