Erlang Thursday – lists:map/2

Today’s Erlang Thursday features lists:map/2.

lists:map/2 takes two arguments, a “mapping” function which takes a single argument, and a list of Erlang terms. The result is a new list of items that is the result of mapping the function applied to each value in the original list.

lists:map(fun(X) -> X + 1 end, [1, 2, 3, 4]).
% [2,3,4,5]
lists:map(fun(X) -> X * X end, [1, 2, 3, 4]).
% [1,4,9,16]

Because strings in Erlang are just lists of integers, you can map against strings as well.

lists:map(fun(X) -> X - 1 end, "IBM").
% "HAL"

On Functions in Erlang

If you look at the first example above, you see that the first argument we are passing is fun(X) -> X + 1 end. This is Erlang’s syntax for an anonymous function. An anonymous function takes the form:

fun(Args1) OptionalGuardClause1 ->
        Expression1, Expression2;
   (Args2) OptionalGuardClause2 ->
        Expression3, Expression4;
   (Args3) OptionalGuardClause3 ->
        Expression5, Expression6;
end

Because we have the power of normal functions, except for being able to recursively call an anonymous function before version 17.0, we can use anonymous functions with multiple clauses when passing to map.

lists:map(fun(X) when is_atom(X) -> atom; (X) -> nil end, [1, x, {x}, [], 'B']).
[nil,atom,nil,nil,atom]

Passing Existing Named Functions to lists:map/1

While in some cases an inline anonymous function may work, many times we would want to have a named function for clarity. We can pass named functions to map by using the qualified name of the function – module:function_name/arity – prefaced with fun. The examples below use math:log10/1 and erlang:is_atom/1 to demonstrate.

lists:map(fun math:log10/1, [1, 10, 100, 1000, 10000]).
[0.0,1.0,2.0,3.0,4.0]
lists:map(fun erlang:is_atom/1, [1, x, {x}, [], 'B']).
[false,true,false,false,true]

–Proctor