Skip to content
Erlang

Stateful Server via Tail Recursion

Hold mutable state in a process by threading it through recursive calls.

#state#tail-recursion#server

Code

erlang
-module(kvstore).
-export([start/0, put/2, get/1, dump/0]).
-export([loop/1]).

%% API: clients send tagged requests with a reference for replies.
start() -> spawn(fun() -> loop(#{}) end).

put(K, V) -> cast({put, K, V}).
get(K)    -> call({get, K}).
dump()    -> call(dump).

cast(Msg) -> ?MODULE ! Msg, ok.   % Note: ?MODULE used as a registered name
                                    % in this demo — register it in real code.
call(Msg) ->
    Ref = make_ref(),
    ?MODULE ! {call, Ref, self(), Msg},
    receive {Ref, Reply} -> Reply end.

%% Server loop: state is the function argument, threaded through tail calls.
loop(State) ->
    receive
        {put, K, V} ->
            loop(maps:put(K, V, State));
        {call, Ref, From, {get, K}} ->
            From ! {Ref, maps:get(K, State, undefined)},
            loop(State);
        {call, Ref, From, dump} ->
            From ! {Ref, State},
            loop(State)
    end.