Erlang basics: what the language is and where it is used
What Erlang is
Erlang is a functional programming language
built for systems that must not stop. Ericsson designed it in the 1980s
for telephone switches, where a failed call must not take the exchange
down, and that requirement still shapes the language.
Programs run on the BEAM virtual machine. A BEAM node holds millions of
lightweight processes that share nothing and talk by messages, and a
supervisor restarts the processes that crash. The standard library and
the OTP framework turn those two ideas into the pattern behind every
Erlang backend you meet in production.
Install Erlang and check the version
Every installation is the same runtime, one Erlang/OTP release. Install
it from the package manager of your system: APT on
Ubuntu, EPEL with DNF on
Linux distributions that follow
RHEL, Homebrew on macOS, pkg on
FreeBSD, Chocolatey or Winget on
Windows 11. The install pages carry the exact
commands for each system.
Docker needs no install at all: the
Erlang in Docker page runs
the official image.
The version check is the same everywhere. Ask the shell for its version:
erl -version
Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version 15.2.7.14
The emulator version follows the OTP release. Ask for the release number itself:
erl -noshell -eval 'io:format("~s~n", [erlang:system_info(otp_release)]), halt().'
27
Both answers were measured on Erlang/OTP 27 on Alpine Linux 3.24 (x86_64). A newer OTP release prints its own numbers.
The first module
Every Erlang program is a module: one .erl file whose header names the module and whose export list names the functions that other modules may call. Save this as hello.erl.
-module(hello).
-export([main/0]).
main() ->
io:format("Hello, Erlang!~n").
Compile it with erlc, which writes hello.beam, the bytecode the runtime loads. Then call the function and stop the node:
erlc hello.erl
erl -noshell -eval 'hello:main(), halt().'
Hello, Erlang!
The header is not ceremony. The name after -module must equal the file name without .erl, so erlc rejects a hello.erl that declares another module, and the arity in the export list is the argument count: main/0 is main with no arguments.
The shell
The erl program is also an interactive shell. Start it with no arguments, type an expression, and end the line with a period.
erl
1> 2 + 3.
5
2> hello.
hello
3> [1, 2, 3] ++ [4].
[1,2,3,4]
The shell prints the value of every expression. Arithmetic returns a
number, an atom prints as itself, and a list prints as its elements
inside brackets. None of the three needs a module or a compile step,
which makes the shell the fastest way to test an idea.
Type q(). to leave the shell. Lesson 3 covers the helpers: b() lists
the current bindings, h() the history, and v(N) recalls an earlier
result.
Three examples
Three short programs show what the language is built around: recursion instead of loops, pattern matching instead of casts, and guards instead of nested conditions.
Recursion over a list
Erlang has no loop statement. A list is a head and a tail, and a recursive function walks it until the tail is empty. Save this as total.erl.
-module(total).
-export([sum/1]).
sum([]) ->
0;
sum([Head | Tail]) ->
Head + sum(Tail).
Compile the module and add the numbers of a list:
erlc total.erl
erl -noshell -eval 'io:format("~p~n", [total:sum([1, 2, 3, 4])]), halt().'
10
Pattern matching
The = sign is not an assignment: it matches the right side against the pattern on the left. A pattern with an unbound variable binds it, and a pattern that does not fit fails at once. In the shell:
erl
1> {ok, Value} = {ok, 42}.
{ok,42}
2> Value.
42
3> [Head | Tail] = [1, 2, 3].
[1,2,3]
4> Head.
1
5> Tail.
[2,3]
The tuple and the list split into their parts in one step, with no index and no cast. The same mechanism picks the arguments of a function, which is how most Erlang code is written.
Guards
A guard is the test after the when keyword. When several clauses of a function match, the guards decide which one runs. Save this as classify.erl.
-module(classify).
-export([number/1]).
number(N) when N > 0 ->
positive;
number(0) ->
zero;
number(_) ->
negative.
Compile it and classify three numbers:
erlc classify.erl
erl -noshell -eval 'io:format("~p ~p ~p~n", [classify:number(7), classify:number(0), classify:number(-3)]), halt().'
positive zero negative
The course
The
Erlang course
goes on for fifty lessons: types, recursion, pattern matching, EUnit,
GenServer, supervisors, distributed nodes, and two capstone projects.
Start with lesson 1,
What is Erlang and where it runs,
and follow the chain of previous and next links at the bottom of every
page.
The code on this page was run with Erlang/OTP 27 on Alpine Linux 3.24 (x86_64).
Article author: Arthur Isaev