Erlang gives quite some emphasis on readability.
Pattern matching,list comprehensions are good tools to minimize your code without actually ruining the readability. However,oftentimes anonymous functions are passed in as function parameter in erlang.
for me it is annoying to read that.Is there any particular reason why this is done?
for exmple in general:
hhfuns:fold(fun(A,B) -> A + B end, 0, lists:seq(1,6)).
You can handle this any way you like. The syntax can be annoying at first, but you will likely get used to it. In any case, you are trying to pass a value to a function, the same way you do any other parameter. If you keep this in mind you will realize you have three ways to do this.
Consider the following example module:
-module(funplay).
-export([external/1, internal/1, inline/1]).
apply_foo(Foo, Thingy) -> Foo(Thingy).
add_one(N) -> N + 1.
external(X) ->
apply_foo(fun add_one/1, X).
internal(X) ->
AddOne = fun(N) -> N + 1 end,
apply_foo(AddOne, X).
inline(X) ->
apply_foo(fun(N) -> N + 1 end, X).
I can't think of any better way to explain it than with the code above.
I prefer the external way if I know I'll be using the same thing a bunch of places (in which case, I really need to define the procedure, not re-write it anonymously everywhere). I prefer the internal way whenever I need to pass a non-trivial or multi-line condition to a function (just easier for me to read, and I hate indentation in arguments) or if I will need it more than once within the same function, and I prefer the inline way for trivial checks in something like a filter or fold.
Choosing the syntax is a matter of taste, or company coding rules, but what is interesting is the power of this feature. here is an example where I send the function in a message to an another node, which forward in turn to a list of process which finally execute it (note that I chose anonymous function, doing this I am sure that the receiving node will be able to execute the function):
start 2 nodes:
erl -sname node1
erl -sname node2
on node1, in the shell (needs R17 to work with this syntax):
Loop = fun Loop(X) -> receive
{forward, Mess} -> lists:foreach(fun(Pid) -> Pid ! Mess end, X), Loop(X);
stop -> ok
end
end.
Proc = fun Proc(X) -> receive
{do,Fun} -> Y = Fun(X), Proc(Y);
stop -> ok
end
end.
L = [spawn(fun() -> Proc(0) end) || _ <- lists:seq(1,10)].
register(server,spawn(fun() -> Loop(L) end)).
on node2:
(node2@XXX)1>net_adm:ping(node1@XXX).
pong
(node2@XXX)2> {server,node1@XXX} ! {forward,{do,fun(X) ->Self = self(), io:format("~p state is ~p~n",[Self,X]),X end}}.
{forward,{do,#Fun<erl_eval.6.90072148>}}
(node2@XXX)3> {server,node1@XXX} ! {forward,{do,fun(X) -> X + 1 end}}.
{forward,{do,#Fun<erl_eval.6.90072148>}}
(node2@XXX)4> {server,node1@XXX} ! {forward,{do,fun(X) ->Self = self(), io:format("~p state is ~p~n",[Self,X]),X end}}.
{forward,{do,#Fun<erl_eval.6.90072148>}}
(node2@XXX)4>
the result on node1:
<0.42.0> state is 0
<0.43.0> state is 0
<0.44.0> state is 0
<0.45.0> state is 0
<0.46.0> state is 0
<0.47.0> state is 0
<0.48.0> state is 0
<0.49.0> state is 0
<0.50.0> state is 0
<0.51.0> state is 0
<0.43.0> state is 1
<0.42.0> state is 1
<0.44.0> state is 1
<0.45.0> state is 1
<0.46.0> state is 1
<0.47.0> state is 1
<0.48.0> state is 1
<0.49.0> state is 1
<0.50.0> state is 1
<0.51.0> state is 1
(node1@XXX)5>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With