In Erlang is there a way reference the currently executing function)?
That would be useful to spawn an infinite loop:
spawn(fun() -> do_something, this_fun() end)
In JavaScript arguments.callee
does just that, see the specification on MDC.
Edit to answer a 'why would you do that': mostly curiosity; it is also useful to define a timer when prorotyping:
Self = self(),
spawn(fun() -> Self ! wake_up, receive after 1000 -> nil end, this_fun() end),
%% ...
Anonymous Function is a function that does not have any name associated with it. Normally we use the function keyword before the function name to define a function in JavaScript, however, in anonymous functions in JavaScript, we use only the function keyword without the function name.
Advertisements. Funs are used to define anonymous functions in Erlang.
These functions are called anonymous because they are not declared in the standard manner by using the def keyword. You can use the lambda keyword to create small anonymous functions. Lambda forms can take any number of arguments but return just one value in the form of an expression.
Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function.
In Erlang/OTP 17.0-rc1, you can use a named fun for that:
1> Self = self(),
1> Fun = fun ThisFun() ->
Self ! wake_up,
receive after 1000 -> nil end,
ThisFun()
end.
#Fun<erl_eval.44.71889879>
2> spawn(Fun).
<0.35.0>
3> flush().
Shell got wake_up
Shell got wake_up
Shell got wake_up
ok
In earlier versions, there is no way to do exactly that. You could pass the function itself as an argument:
Self = self(),
Fun = fun(ThisFun) ->
Self ! wake_up,
receive after 1000 -> nil end,
ThisFun(ThisFun)
end
spawn(fun() -> Fun(Fun) end),
%% ...
If you feel like twisting things a little bit:
Y = fun(M,B) -> G = fun(F) -> M(fun() -> (F(F))() end, B) end, G(G) end.
spawn(Y(fun(F, ParentPid) -> fun() -> ParentPid ! wake_up, receive after 1000 -> ok end, F() end end, self())).
Flush the messages couple times to see the result:
flush().
Of course, Y is more useful if you put it in some sort of library. Also you can find this post on Y Combinators: http://bc.tech.coop/blog/070611.html quite interesting
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