process - erlang processes communication (code error) -
i new erlang. in code try give each of 2 processes list of numbers. process oid should send numbers in list process eid, should send odd numbers in process oid. when process finishes filtering own list starts reading messages received other process, adds them output list, , prints list.
when run code these errors:
=error report==== 28-apr-2015::23:01:25 ===
error in process <0.296.0> exit value: {if_clause,[{test,odd,2,[{file,"test.erl"},{line,25}]}]}=error report==== 28-apr-2015::23:01:25 ===
error in process <0.297.0> exit value: {if_clause,[{test,even,2,[{file,"test.erl"},{line,49}]}]}
here's code:
-module(test). -export([start/0]). -export([odd/2]). -export([even/2]). start() -> register(oid, spawn(test, odd, [[1,2,3,4,5],[]])), register(eid, spawn(test, even, [[6,7,8,9],[]])). %--------------------------------------------- odd(c,o) -> receive done -> lists:foreach( fun(x) -> io:fwrite("~p\n", x) end, io:fwrite("~p\n", oid) ); num -> o++[num], odd(c,o) end; odd([],o) -> eid ! done, odd(c,o); odd([a|rest],o) -> if rem 2 =:= 0 -> eid ! a; rem 2 =/= 0 -> o++[a], odd([rest],o) end. %-------------------------------------------- even(c,e)-> receive done -> lists:foreach( fun(x) -> io:fwrite("~p\n", x) end, io:fwrite("~p\n", eid) ); num -> e++[num], even(c,e) end; even([],e) -> oid ! done, even(c,e); even([a|rest],e) -> if rem 2 =/= 0 -> oid ! a; rem 2 =:= 0 -> e++[a], even([rest],e) end. %--------------------------------------------- pri([h|t]) -> io:format("~p~n", [h]), pri(t); pri([]) -> true.
there number of problems code. did compile it?
first, easy problem: io:fwrite/2 calls need have arguments printed passed in list, not individual terms, this:
io:fwrite("~p\n", oid) is wrong. should be:
io:fwrite("~p\n", [oid]) but there's little point in printing constant oid anyway. should rid of code:
lists:foreach( fun(x) -> io:fwrite("~p\n", x) end, io:fwrite("~p\n", oid) ); (which broken , won't compile anyway) , use pri/1 function instead (or pri/2, shown later).
next, you're attempting add elements lists if lists mutable. variables in erlang immutable. instead of this:
o++[a], odd([rest],o) you need:
odd(c,o++[num]) to create new list pass next iteration, or better yet:
odd(c,[num|o]) which more efficient appending because adds new head list. note though builds list backwards, we'll need reverse later. fortunately, reversing list inexpensive.
next, if statement error messages caused way pass rest recursively. when have construct [a|rest], rest variable is list. there's no need pass [rest]; should passed rest. let's a 1 , rest list [2,3,4,5]; when pass next recursive call [rest], [a|rest] in new call equivalent [[2,3,4,5] | []] , error occurs because [2,3,4,5] rem 2 meaningless operation.
another problem odd/2 , even/2 functions use if @ all, since can use function clauses instead. if not used in idiomatic erlang code. still problem functions clauses send messages don't make recursive calls handle elements remaining in rest. instead of this:
odd([a|rest],o) -> if rem 2 =:= 0 -> eid ! a; rem 2 =/= 0 -> o++[a], odd([rest],o) end. you instead write this:
odd([a|rest],o) when rem 2 =:= 0 -> eid ! a, odd(rest,o); odd([a|rest],o) -> odd(rest,[a|o]). note avoids need 2 rem tests, since number not detected guard in first clause being automatically odd , handled second clause. note instead of o++[a] we're using prepending form [a|o] construct new list.
one more problem artificial way of handling end of list passing atom c odd/2 , even/2. better approach make odd/1 , even/1 , leave c out altogether:
odd(o) -> receive done -> l = lists:sort(lists:reverse(o)), pri(oid,l); num -> odd([num|o]) end. this approach uses pri/2 printing, , list passed reversed here undo effects of building via prepending, , sorted put in order. pri/2 function looks this:
pri(id, [h|t]) -> io:format("~p: ~p~n", [id, h]), pri(id,t); pri(_, []) -> true. if run whole thing, this:
2> test:start(). eid: 2 oid: 1 eid: 4 oid: 3 true oid: 5 eid: 6 oid: 7 eid: 8 oid: 9 where true in middle result of test:start() call, , order of printing 2 processes indeterminate since they're concurrent.
Comments
Post a Comment