I wrote a simple program in Erlang. Its task is to compute the value of given polynomial 2*x^2 + 3*x + 5. Both 2*x^2 and 3*x are computed parallely, and at the very end these both parts are added together, 5 is added and finally we get the result. There is one function computing 2*x^2, the second one computing 3*x and the last one which calculates the final result. Here is the code:
-module(count2).
-compile([export_all]).
%-export([f_main/0]).
%computes the value of the polynomial 2*x^2 + 3*x + 5
f_result() ->
{Arg1, Res_1} = receive
{f1, X1, Temp1} -> {X1, Temp1}
end,
Res_2 = receive
{f2, _, Temp2} -> Temp2
end,
Res = Res_1 + Res_2 + 5, %adds 5 to the result of 2*X^2+3*X
io:format("f(~p) = ~p~n",[Arg1, Res]),
f_result().
%when the line 14 was io:format("f(~p) = ~p~p,[X1, Res], the compilation error occured:
%variable 'X1' unsafe in 'receive'
f_2(PidWyn) -> %computes 2*X^2
receive
{f2, X} ->
Res = 2*math:pow(X,2),
PidWyn ! {f2, X, Res},
f_2(PidWyn);
{finish} ->
io:format("f_2 : finish~n")
end.
f_1(PidWyn) -> %computes 3*X
receive
{f1, X} ->
Res = 3*X,
PidWyn ! {f1, X, Res},
f_1(PidWyn);
{finish} ->
io:format("f_1 : finish~n")
end.
f_main() ->
PidW = spawn(?MODULE, f_result, []), %the process ID of the function that computes and displays the final result
Pid1 = spawn(?MODULE, f_1, [PidW]),
Pid2 = spawn(?MODULE, f_2, [PidW]),
L = [1,2,3,4,5],
[Pid1 ! {f1, X} || X <- L], %sends a series of messages to the function f_1
[Pid2 ! {f2, X} || X <- L], %sends a series of messages to the function f_2
Pid2 ! {finish},
Pid1 ! {finish},
PidW ! {finish}, %sends the message to the function f_result to make it stop
io:format("f_main : finish~n").
As you can see, the f_result function has two receive statements one by one. The first one receives the tuple from f_1 function, and the second one receives the tuple from f_2 function. After that the function displays the results and calls itself to make a loop.
I would like to make f_result function receive {finish} tuple what would tell it to stop working (similar solution is visible in f_1 and f_2 function), but I can't place required receive properly. I tried to put
{Arg1, Res_1} = receive
{f1, X1, Temp1} -> {X1, Temp1};
{finish} -> io:format("f_result : finish~n"),
exit(0)
end,
but it makes the following output:
f_main : finish
f_result : finish
f_1 : finish
f_2 : finish
ok
I will be grateful if you can give me some advice.