Reading — step 1 of 5
Learn
~1 min readProcess Patterns
Stateful Erlang processes use tail-recursive loops. The function calls itself with new state at the end of each iteration.
-module(main).
-export([main/1]).
start() ->
spawn(fun() -> loop(0) end).
loop(N) ->
receive
increment -> loop(N + 1);
{get, From} ->
From ! {value, N},
loop(N);
stop -> ok
end.
main(_) ->
Pid = start(),
Pid ! increment,
Pid ! increment,
Pid ! increment,
Pid ! {get, self()},
receive
{value, V} -> io:format("~w~n", [V])
end.
Key points:
- The
loop/1function is tail-recursive — Erlang optimizes this to constant stack space. - Each branch of
receiveeither callsloopagain (with potentially new state) or returns (terminating the process). From ! Msgsends a message.self()is the current process's PID.- The receiver pattern-matches on a unique tag (
{value, N}) to know what message to receive.
Synchronous request/reply:
The "send a message including self(), then receive a reply" pattern is so common that it has a name: a synchronous call. Real Erlang code uses gen_server:call to wrap it.
Selective receive — receive only matches messages whose patterns match. Other messages stay in the mailbox:
receive
{priority_task, T} -> handle_priority(T)
after 0 ->
%% skip if no priority message right now
ok
end
The after Timeout clause runs if no message arrives within Timeout ms. after 0 is non-blocking.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…