Erlang:如何从函数体中引用匿名函数?

c2e8gylq  于 2023-11-15  发布在  Erlang
关注(0)|答案(3)|浏览(260)

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

wvt8vs2t

wvt8vs2t1#

在Erlang/OTP 17.0及更高版本中,您可以使用命名的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),
%% ...

ogq8wdun

ogq8wdun2#

如果你想稍微扭曲一下:

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放在某种库中,它会更有用。

axr492tv

axr492tv3#

Erlang语言没有公开匿名函数引用自身的任何方式,但有传言说Core Erlang(编译器阶段的中间但官方表示)确实有这样的功能。
我不知道我为什么要转发这个,但是你知道,如果你碰巧在DSL或类似的东西中生成Core Erlang,它是触手可及的。

相关问题