ppl
ppl copied to clipboard
[LAST ERLANG CLASS] Easier brancy?
What if we simply impose an order in the reception of the messages from the subtrees? They'll just stack in the mailbox, no deadlock should arise:
brancy(L, R, Fun) ->
receive
{ask, P} ->
% they ask their sons for the values
L ! {ask, self()},
R ! {ask, self()},
% at this point you expect an answer...
receive
{L, V1} -> Op1 = V1
end,
receive
{R, V2} -> Op2 = V2
end,
% now you evaluate your function for the father
P ! {self(), Fun(Op1, Op2)}
end.
This sounds easier to me...
I thought the same while re-doing the exercise on my own. The only thing I didn't like was having a hanging receive on a branch while the other one may have already finished. The solution I came up with is a little more verbose, but exploiting pattern matching it becomes easier to read and reason about, while keeping the branchy interface the same.
waitBranches(Left, Right, nil, nil) ->
receive
{Left, V} -> waitBranches(Left, Right, V, nil);
{Right, V} -> waitBranches(Left, Right, nil, V)
end;
waitBranches(Left, Right, LVal, RVal) ->
receive
{Left, V} -> {V, RVal};
{Right, V} -> {LVal, V}
end.
branchy(F, Left, Right) ->
receive
{ask, P} ->
Left ! {ask, self()},
Right ! {ask, self()},
{LVal, RVal} = waitBranches(Left, Right, nil, nil),
P ! {self(), F(LVal, RVal)}
end.
Edit: Changed code according to https://github.com/riccardotommasini/ppl/issues/10#issuecomment-356995756
I like it a lot more, can I include this code in the repository?
@leonardoarcari you need to swap :) (if I'm getting that right...)
waitBranches(Left, Right, LVal, RVal) ->
receive
{Left, V} -> {V, RVal};
{Right, V} -> {LVal, V} <-------
end.
As for me, no problem with using my code :)
@DavideSampietro Sure thing! Thanks!