[erlang-questions] Apparently strange dict behaviour
Darryn
djreid@REDACTED
Tue Aug 9 08:58:38 CEST 2011
Kind Sirs/Madams,
I'm new to erlang, but have extensive prior experience with Haskell. I thought
I'd play with a small version of a parallel map/fold operation, but have run
into an annoying problem. The test example is just a parallel estimation by
sampling of Pi.
pmap(Input, MapFn) ->
process_flag(trap_exit, true),
spawn_workers(self(), MapFn, Input),
M = length(Input),
collect(M, dict:new()).
spawn_workers(Pid, Fn, Pairs) ->
lists:foreach(fun({K1, V1}) ->
spawn_link(fun() -> worker(Pid, Fn, {K1, V1}) end) end, Pairs).
worker(Pid, Fn, {K1, V1}) ->
Pid ! Fn(K1, V1).
collect(0, Dict) -> Dict;
collect(N, Dict) ->
receive
{Key2, Val2} ->
DictD = dict:append(Key2, Val2, Dict),
%% <- problem: inserted Val2 integer apparently turns into a string?!!
io:format("Collected result:{~p,~p}~n", [Key2, Val2]),
io:format(" ->is_integer?~p~n", [is_integer(Val2)]),
io:format(" ->~p~n", [dict:to_list(DictD)]),
collect(N, DictD);
{'EXIT', Who, Why} ->
io:format("Worker ~p terminated with ~p~n",[Who, Why]),
collect(N-1, Dict)
end.
samples(Index, N) ->
random:seed(erlang:now()),
{Index, do_samples(0, N, 0)}.
doit() ->
Results = pmap([{1,100}, {2,100}, {3, 100}], fun samples/2),
dict:to_list(Results).
The problem seems to lie in the collect function, where the collected Val2
integer (the io:format confirms it is an integer) suddenly becomes a string
upon insertion into the dictionary. Here is example output to illustrate.
20> c(pisim).
{ok,pisim}
21> pisim:doit().
Collected result:{1,88}
->is_integer?true
->[{1,"X"}]
Worker <0.114.0> terminated with normal
Collected result:{1,87}
->is_integer?true
->[{1,"XW"}]
Worker <0.116.0> terminated with normal
Collected result:{2,76}
->is_integer?true
->[{2,"L"},{1,"XW"}]
Worker <0.115.0> terminated with normal
[{2,"L"},{1,"XW"}]
22> c(pisim).
{ok,pisim}
23> pisim:doit().
Worker <0.118.0> terminated with normal
Collected result:{1,78}
->is_integer?true
->[{1,"N"}]
Worker <0.123.0> terminated with normal
Collected result:{2,83}
->is_integer?true
->[{2,"S"},{1,"N"}]
Worker <0.124.0> terminated with normal
[{2,"S"},{1,"N"}]
I don't understand how the Val2 integer suddenly turns into a string upon
being inserted into the dictionary; when I manually cut and paste the relevant
bits of code into the shell I get dictionary values with integers as I intend.
I wonder if anyone more experienced can see what I've done wrong? Thanks so
much for any help!
Darryn.
More information about the erlang-questions
mailing list