13

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),
%% ...
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matteo Caprari
  • 2,869
  • 4
  • 27
  • 35

3 Answers3

28

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),
%% ...
legoscia
  • 39,593
  • 22
  • 116
  • 167
7

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

zakovyrya
  • 9,579
  • 6
  • 39
  • 28
3

The Erlang language does not expose any way for anonymous functions to refer to them self, but there is a rumour that Core Erlang (an intermediate but official representation in the compiler phases) does have such a feature.

I don't know why I am forwarding this, but you know, if you happen to be generating Core Erlang in a DSL or similar it is something that is within reach.

Christian
  • 9,417
  • 1
  • 39
  • 48