First class environments: Difference between revisions

Added Erlang
(Added Erlang)
Line 291:
Counts:
0 1 7 2 5 8 16 3 19 6 14 9</pre>
 
=={{header|Erlang}}==
The Erlang modifiable environment, aka process dictionary, has the following warning in the documentation:
<pre>
Note that using the Process Dictionary:
Destroys referencial transparency
Makes debugging difficult
Survives Catch/Throw
</pre>
There is a lot of code below to manage the tabular printout. Otherwise the task is simple.
<lang Erlang>
-module( first_class_environments ).
 
-export( [task/0] ).
 
task() ->
Print_pid = erlang:spawn( fun() -> print_loop() end ),
Environments = lists:seq( 1, 12 ),
Print_pid ! "Environment: Sequence",
Pids = [erlang:spawn(fun() -> hailstone_in_environment(Print_pid, X) end) || X <- Environments],
Counts = counts( Pids ),
Print_pid ! "{Environment, Step count}",
Print_pid ! lists:flatten( io_lib:format("~p", [Counts]) ),
ok.
 
 
 
counts( Pids ) ->
My_pid = erlang:self(),
[X ! {count, My_pid} || X <- Pids],
counts( Pids, [] ).
counts( [], Acc ) -> Acc;
counts( Pids, Acc ) ->
receive
{count, N, Count, Pid} -> counts( lists:delete(Pid, Pids), [{N, Count} | Acc] )
end.
 
hailstone_in_environment( Print_pid, N ) ->
erlang:put( hailstone_value, N ),
erlang:put( count, 0 ),
hailstone_loop( hailstone_loop_done(N), Print_pid, N, [N] ).
 
hailstone_loop( stop, Print_pid, N, Acc ) ->
Environment = lists:flatten( io_lib:format("~11B:", [N]) ),
Sequence = lists:flatten( [io_lib:format("~4B", [X]) || X <- lists:reverse(Acc)] ),
Print_pid ! Environment ++ Sequence,
Count= erlang:get( count ),
receive
{count, Pid} -> Pid ! {count, N, Count, erlang:self()}
end;
hailstone_loop( keep_going, Print_pid, N, Acc ) ->
Next = hailstone_next( erlang:get(hailstone_value) ),
erlang:put( hailstone_value, Next ),
Count = erlang:get( count ),
erlang:put( count, Count + 1 ),
hailstone_loop( hailstone_loop_done(Next), Print_pid, N, [Next | Acc] ).
 
hailstone_loop_done( 1 ) -> stop;
hailstone_loop_done( _N ) -> keep_going.
 
hailstone_next( 1 ) -> 1;
hailstone_next( Even ) when (Even rem 2) =:= 0 -> Even div 2;
hailstone_next( Odd ) -> (3 * Odd) + 1.
 
print_loop() ->
receive
String -> io:fwrite("~s~n", [String] )
end,
print_loop().
</lang>
{{out}}
<pre>
13> first_class_environments:task().
Environment: Sequence
1: 1
2: 2 1
3: 3 10 5 16 8 4 2 1
4: 4 2 1
5: 5 16 8 4 2 1
6: 6 3 10 5 16 8 4 2 1
7: 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
8: 8 4 2 1
9: 9 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
10: 10 5 16 8 4 2 1
11: 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
12: 12 6 3 10 5 16 8 4 2 1
{Environment, Step count}
[{12,9}, {11,14}, {10,6}, {9,19}, {8,3}, {7,16}, {6,8}, {5,5}, {4,2}, {3,7}, {2,1}, {1,0}]
</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
Anonymous user