[erlang-questions] How to do counters?
Michael Truog
mjtruog@REDACTED
Tue Jun 30 06:27:43 CEST 2009
Richard O'Keefe wrote:
>
> On Jun 30, 2009, at 11:56 AM, Witold Baryluk wrote:
>> You can also use parametrized modules:
>
> You _can_, but why use an experimental and moderately
> heavyweight feature when the *fundamental* mechanisms
> of the language are perfectly adequate?
>
I am not trying to justify the usage of parametrized modules, but they
are a bit new to me, so I find their usage interesting. I have an
example that attempts to be object-oriented with a tuple list of functions:
-module(counter).
-export([new/0]).
new() ->
class:new([
{increment, fun(State) -> State + 1 end},
{decrement, fun(State) -> State - 1 end},
{reset, fun(_) -> 0 end},
{read, fun(State) -> State end}
], 0).
-module(class, [Class]).
-export([new/2, call/1]).
new(Functions, State) when is_list(Functions) ->
class_impl:new(Functions, State).
call(Method) when is_atom(Method) ->
ipc(Class, {call, Method}).
ipc({class, Pid}, Msg) when is_pid(Pid) ->
Pid ! {Msg, self()},
receive {Pid, Result} -> Result end.
-module(class_impl).
-export([new/2]).
new(Functions, State) when is_list(Functions) ->
class:instance({class, spawn(fun() -> loop(Functions, State) end)}).
loop(Functions, State) when is_list(Functions) ->
receive {{call, Method}, Sender} ->
case lists:keyfind(Method, 1, Functions) of
false ->
Sender ! {self(), badfun};
{Method, F} ->
NewState = F(State),
Sender ! {self(), NewState},
loop(Functions, NewState)
end
end.
Erlang R13B01 (erts-5.7.2) [source] [64-bit] [smp:4:4] [rq:4]
[async-threads:0] [kernel-poll:false]
Eshell V5.7.2 (abort with ^G)
1> c(class_impl).
{ok,class_impl}
2> C = counter:new().
{class,{class,<0.40.0>}}
3> C:call(read).
0
4> C:call(increment).
1
5> C:call(increment).
2
6> C:call(increment).
3
7> C:call(increment).
4
8> C:call(decrement).
3
9> C:call(decrement).
2
10> C:call(decrement).
1
11> C:call(decrement).
0
12> C:call(decrement).
-1
13> C:call(reset).
0
More information about the erlang-questions
mailing list