Подтвердить что ты не робот

Эрланг: как я могу ссылаться на анонимную функцию внутри тела?

В Erlang есть ссылка на текущую исполняемую функцию)?

Было бы полезно создать бесконечный цикл:

spawn(fun() -> do_something, this_fun() end)

В JavaScript arguments.callee делает именно это, см. спецификацию MDC.

Отредактируйте ответ: "зачем вы это делаете": в основном любопытство; также полезно определить таймер при проритизации:

Self = self(),
spawn(fun() -> Self ! wake_up, receive after 1000 -> nil end, this_fun() end),
%% ...
4b9b3361

Ответ 1

В Erlang/OTP 17.0-rc1 вы можете использовать именованное fun для этого:

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

В более ранних версиях нет никакого способа сделать именно это. Вы можете передать функцию как аргумент:

Self = self(),
Fun = fun(ThisFun) ->
          Self ! wake_up,
          receive after 1000 -> nil end,
          ThisFun(ThisFun)
      end
spawn(fun() -> Fun(Fun) end),
%% ...

Ответ 2

Если вы немного закручиваете вещи:

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().

Конечно, Y более полезен, если вы поместите его в какую-то библиотеку. Также вы можете найти этот пост на Y Combinators: http://bc.tech.coop/blog/070611.html довольно интересно

Ответ 3

Язык Erlang не предоставляет возможности анонимным функциям ссылаться на них самостоятельно, но есть слухи, что Core Erlang (промежуточное, но официальное представление на фазах компилятора) имеет такую ​​функцию.

Я не знаю, почему я перенаправляю это, но вы знаете, что если вы создаете Core Erlang в DSL или аналогично, это то, что находится в пределах досягаемости.