Search code examples
erlang

Erlang: how can I reference an anonymous function from within the body?


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),
%% ...

Solution

  • In Erlang/OTP 17.0 and later, 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),
    %% ...