01 — pattern-matching functions
Each clause is one case; the mailbox receive is the heart of every process.
loop() ->
receive
{ping, From} -> From ! pong, loop();
stop -> ok
end.§ 02 — Eras · 1986
nine nines, designed into the grammar
Left: era context, features, and the 101 hello. Right: 3 core concepts, 3 deeper 201 lessons, the factorial specimen, and where Erlang lives today — each column scrolls on its own.
Telephone switches must never go down. Erlang made concurrency, distribution and fault-tolerance primitives of the language.
Numerically slow, syntactically alien, and a hiring pool the size of its home town — brilliant for the nine-nines niche.
Session one is the smallest program that still counts as speaking Erlang: what every tutorial prints first, in the dialect that mattered when the language arrived (1986).
io:format("Hello, world~n").101First contact — hello world and 3 ideas that define how Erlang reads. 201 — 3 lessons on mechanisms you meet after the factorial specimen: the sharp edges practitioners actually use.
3 fragments, each naming a habit of mind in Erlang. Read the note, then the code — together they are the 101 in one sitting.
01 — pattern-matching functions
Each clause is one case; the mailbox receive is the heart of every process.
loop() ->
receive
{ping, From} -> From ! pong, loop();
stop -> ok
end.02 — processes & messages
Millions of tiny processes, no shared memory, messages only — failure is isolation.
Pid = spawn(fun loop/0),
Pid ! {ping, self()},
receive pong -> ok end.03 — let it crash
Don’t code defensively: crash, and let the supervisor restart a clean copy.
supervisor(one_for_one,
[{ship, {ship, start_link, []},
permanent, 5000, worker, [ship]}]).The 201 assumes you have read the 101 and the specimen. Each lesson is one mechanism — what it is for, how it looks in code, and the trap or payoff that makes Erlang distinctive at scale.
A behaviour is a callback contract; gen_server, gen_event and supervisors build on it, so the shape of a process is a convention everyone can read.
-callback init(Args :: term()) -> {ok, State :: term()}
| {error, Reason :: term()}.ETS tables hold state outside the process heap: fast, shared, and the reason hot code reload works without losing data.
ets:new(crew, [named_table, set, {read_concurrency, true}]),
ets:insert(crew, {perch, 24}).Specs describe types for the dialyzer, which proves properties across a whole system — the closest Erlang comes to static checking.
-spec tons(ship()) -> non_neg_integer().
tons(#ship{tons = T}) -> T.The mailbox: every process owns one, messages are the only shared thing, crashes are isolated and supervised — nine nines, designed into the grammar.
loop() ->
receive
{ping, From} -> From ! pong, loop();
stop -> ok
end.installbrew install erlang
runescript fact.erl
WhatsApp ran hundreds of millions of users per Erlang node; Discord and RabbitMQ still do.