Archive for August, 2007

A basic mutable state in an Erlang process

Monday, August 20th, 2007

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.