Skip to content
Higher-Order Functions and Funs
step 1/7

Reading — step 1 of 7

Learn

~2 min readHigher-Order Functions, BIFs, and IO

In Erlang, functions are values. Anonymous functions (called funs) and the lists module's higher-order operations replace what other languages do with loops. Programming Erlang treats this as foundational.

Defining a fun

Double = fun(N) -> N * 2 end.
Double(5).                       %% 10

Add = fun(A, B) -> A + B end.
Add(3, 4).                       %% 7

Funs capture variables from the enclosing scope (closures):

fact_maker() ->
    Pi = 3.14159,
    fun(R) -> Pi * R * R end.

Area = fact_maker(),
Area(5).                         %% 78.539...

The inner fun captured Pi from fact_maker's scope.

Function references

fun Module:Function/Arity references a named function as a value:

F = fun lists:reverse/1.
F([1, 2, 3]).                    %% [3, 2, 1]

Upper = fun string:to_upper/1.
Upper("hello").                  %% "HELLO"

Within the same module, you can omit the module name:

F = fun double/1.

lists:map, lists:filter, lists:foldl

The canonical higher-order functions:

lists:map(fun(N) -> N * 2 end, [1, 2, 3]).
%% [2, 4, 6]

lists:filter(fun(N) -> N > 2 end, [1, 2, 3, 4, 5]).
%% [3, 4, 5]

lists:foldl(fun(N, Acc) -> N + Acc end, 0, [1, 2, 3, 4, 5]).
%% 15

foldl takes the fold function as (Element, Accumulator) -> NewAcc, an initial accumulator, and a list. Reduces the list to a single value.

List comprehensions — sugar over higher-order functions

List comprehensions are syntactic sugar for map+filter:

[X * 2 || X <- [1, 2, 3, 4, 5]].
%% [2, 4, 6, 8, 10]

[X * X || X <- [1, 2, 3, 4, 5], X rem 2 =:= 0].
%% [4, 16] — squares of evens

[{X, Y} || X <- [1, 2, 3], Y <- [a, b]].
%% [{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}] — Cartesian product

Syntax: [Expression || Generator, Filter, ...]. Multiple generators give Cartesian products; filters thin the result.

Composing higher-order functions

Nums = [1, 2, 3, 4, 5].
Result = lists:sum(
    lists:map(
        fun(N) -> N * N end,
        lists:filter(fun(N) -> N rem 2 =:= 1 end, Nums))).
%% sum of squares of odds = 1 + 9 + 25 = 35

Verbose. Comprehension equivalent:

lists:sum([X * X || X <- Nums, X rem 2 =:= 1]).

Common mistakes

  • Forgetting end on funsfun(X) -> X * 2 (missing end) is a syntax error.
  • Using = to assign in a fun — Erlang has no assignment. = is pattern match. Bind once.
  • Capturing too much in closures — large captured contexts can cause memory retention. Pass only what's needed.
  • fun Module:F/Arity vs fun F/Arity — the first works across modules; the second is module-local.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…