[erlang-questions] How to do counters?
Alpar Juttner
ajuttner.list@REDACTED
Fri Jun 26 08:02:45 CEST 2009
On Thu, 2009-06-25 at 21:45 -0400, Jarrod Roberson wrote:
> On Thu, Jun 25, 2009 at 7:10 PM, Vance Shipley <vances@REDACTED> wrote:
>
> > On Thu, Jun 25, 2009 at 06:29:26PM -0400, Jarrod Roberson wrote:
> > } what do you mean by "internal state" I don't understand how a process
> > would
> > } store any mutable state
> >
> > http://erlang.org/doc/man/gen_server.html#Module:handle_call-3
> >
> > The last argument in gen_server/gen_fsm callback functions
> > is State. It's "mutable" by the fact that the return value
> > includes NewState.
> >
> > In functional programming everything a function needs to know
> > is passed in as arguments. Tail recursion keeps the balls in
> > the air.
> >
> > loop(State) ->
> > ...
> > loop(NewState).
> >
> >
> > --
> > -Vance
> >
>
> I still don't see how this is supposed to work.
> If I do tail recursion, how do I return anything, if the loop(NewState)
> needs to be the last thing I do?
>
> If I have functions inc() dec() and current() which should return the
> current value of the counter, how do all these functions share state?
You have a single registered process which runs the loop().
The function inc() and dec() send messages to this process. These
messages instruct loop() to increase/decreace its counter state. The
function current() sends a query message and also its own pid in order
that loop() will be able to send the current value back.
Look at the code below. First, start it with counter:start(), then
counter:inc(), counter:dec() and counter:current() will do what you
want.
Regards,
Alpar
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% counter.erl
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(counter).
-export([inc/0,dec/0,current/0,start/0,loop/1]).
inc() ->
global_counter ! inc_counter,
ok.
dec() ->
global_counter ! dec_counter,
ok.
current() ->
global_counter ! {get_counter, self()},
receive
{ counter_value, Cnt } ->
Cnt
end.
start() ->
register(global_counter,spawn(counter,loop,[0])),
ok.
loop(Counter) ->
receive
inc_counter ->
NewCounter = Counter+1;
dec_counter ->
NewCounter = Counter-1;
{get_counter, Pid} ->
Pid ! { counter_value, Counter },
NewCounter = Counter
end,
loop(NewCounter).
More information about the erlang-questions
mailing list