Skip to content
BIFs and the lists Module
step 1/7

Reading — step 1 of 7

Learn

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

BIFs (Built-In Functions) are functions implemented in C inside the BEAM, exposed in Erlang. Combined with the standard library modules (lists, maps, string, io, etc.), they cover most everyday tasks.

Common BIFs (in erlang module, no module prefix needed)

length([1, 2, 3])              %% 3
hd([1, 2, 3])                  %% 1 — head
tl([1, 2, 3])                  %% [2, 3] — tail
element(2, {a, b, c})          %% b — 1-indexed!
setelement(2, {a, b, c}, x)    %% {a, x, c}
tuple_size({a, b, c})          %% 3
is_atom(foo)                   %% true
is_list([1, 2])                %% true
is_integer(42)                 %% true
self()                          %% your PID
spawn(Fun)                     %% start a process

All callable without erlang: prefix because they're auto-imported.

Conversion BIFs

integer_to_list(42)            %% "42"
list_to_integer("42")          %% 42
atom_to_list(hello)            %% "hello"
list_to_atom("hello")          %% hello (CAREFUL — atoms aren't GC'd)
binary_to_list(<<"hello">>)    %% "hello"
list_to_binary("hello")         %% <<"hello">>
float_to_list(3.14)            %% "3.14000000000000012434e+00"
float_to_list(3.14, [{decimals, 2}])  %% "3.14"

Erlang's string handling has quirks — strings are lists of integers. Modern Erlang prefers binaries (<<"...">>) for text.

The lists module — your daily companion

lists:append([[1,2], [3,4]])         %% [1,2,3,4]
lists:concat(["a", "b", "c"])         %% "abc"
lists:reverse([1,2,3])                %% [3,2,1]
lists:sort([3,1,2])                   %% [1,2,3]
lists:sort(fun(A,B) -> A > B end, [1,2,3])  %% custom sort
lists:member(2, [1,2,3])              %% true
lists:nth(2, [a,b,c])                 %% b — 1-indexed
lists:zip([1,2,3], [a,b,c])           %% [{1,a},{2,b},{3,c}]
lists:unzip([{1,a},{2,b}])            %% {[1,2],[a,b]}
lists:flatten([[1],[2,[3]]])          %% [1,2,3]
lists:max([3,1,2])                    %% 3
lists:min([3,1,2])                    %% 1
lists:sum([1,2,3])                    %% 6
lists:any(fun(X) -> X > 2 end, [1,2,3])  %% true
lists:all(fun(X) -> X > 0 end, [1,2,3])  %% true

Learn these — they replace 90% of hand-written list code.

The string module

string:trim(" hello ")               %% "hello"
string:tokens("a,b,c", ",")          %% ["a","b","c"]
string:join(["a","b","c"], "-")       %% "a-b-c"
string:to_upper("hello")              %% "HELLO"
string:to_lower("HELLO")              %% "hello"
string:length("hello")                %% 5
string:replace("hello world", " ", "_")  %% ["hello_world"]

Note: Erlang strings are LISTS OF INTEGERS. For real text processing, prefer the unicode module or binary strings (<<"...">>).

Common mistakes

  • 1-indexed access — element/2, lists:nth/2 are 1-indexed (not 0-indexed). Common bug source.
  • String confusion — "hello" is [104, 101, 108, 108, 111] (a list of code points). Different from <<"hello">> (binary). Pick one and stick to it.
  • list_to_atom on user input — atoms aren't garbage-collected. Untrusted input can DoS the VM by exhausting the atom table.
  • Forgetting BIFs vs library functions — BIFs are auto-imported; library functions need module prefix. lists:sum is library; length is BIF.
  • Mixing strings and binaries — converts often confuse newcomers. Decide on representation early.

Discussion

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

Sign in to post a comment or reply.

Loading…