A basic mutable state in an Erlang process

I have been feeling a bit dense and struggling with a problem of how to change the state of a running process in Erlang. The problem was that Erlang is a Functional language that only allows single assignment. The solution to holding state in Functional languages is (apparently, to keep the state in function parameters. Thanks to the folk on the Erlang Questions lists, sorry it took so long.

Well, what follows is the outcome of a rusty developer trying to get the hang of state in a functional, Actor based language. It is probably not very “erlangy” but I hope it helps others get out of the mess I was in.
If you are interested the key point for me was to realise that the receive loop happens inside the function (loop()). This means that the loop parameter is already bound and is accessible, but cannot be reassigned. Each set of code can use X but X can only be changed by calling loop() with a new value.

I hope the following makes sense (It does work).
-module(basic).
-export([start/0, rpc/2]).

start() ->

spawn(fun() -> loop(1) end).

rpc(Pid, Msg) ->

Pid ! {self(),Msg},
receive

{Pid, Response} -> Response

after 50 ->

io:format(”no response~n”)

end.

loop(X) ->

receive

{From, cancel} ->

io:format(”~p is exiting~n”, [From]),
From ! {self(), X};

{From, {get_x}} ->

io:format(”X is currently: ~p~n”, [X]),
From ! {self(), X},
loop(X);

{From, {set_x, Dx}} ->

io:format(”Changing X from: ~p to: ~p ~n”, [X, Dx]),
From ! {self(), Dx},
loop(Dx);

DoNotUnderstand ->

io:format(”~p does not understand: ~p ~n”, [self(), DoNotUnderstand]),
loop(X)

after 10000 ->

io:format(”Nothing has happened, X is:~p~n”,[X]),
loop(X)

end.

3 Responses to “A basic mutable state in an Erlang process”

  1. Patrick Logan Says:

    Nicely explained.

    And if you call…

    basic:loop(X) % Fully qualified module:function name

    …then the system will check for a new version of the basic module to load before calling loop. So you can upgrade the loop function while running if desired.

    One way to do that is have another message pattern looking for the atom ‘upgrade’ or some such. The message could include a magic token to indicate the sender is capable of sending the ‘upgrade’ message.

  2. Tom Says:

    Thank you Patrick. Dynamic upgrade is something I am looking forward to investigating (but I still have a huge amount to grok first).

  3. Michael Campbell Says:

    There’s a section in Joe’s book about code replacement, just before the introducing gen_server part. It was one of the (many) “ah-hah!” sections for me.