2009-07-24 63 views
12

Erlang有沒有方法引用當前正在執行的函數)?Erlang:我如何從身體內引用一個匿名函數?

這將是產卵一個無限循環有用:

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

在JavaScript arguments.callee做到了這一點,看到MDC規範。

編輯回答'爲什麼你會那樣做':主要是好奇心;它也是有用的定義定時器prorotyping時:

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

爲什麼你需要那個? – zakovyrya 2009-07-24 19:29:27

回答

24

在二郎山/ OTP 17.0 RC1,您可以使用一個名爲有趣:

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

如果你覺得像扭曲的東西一點點:

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上組合算符這個帖子:http://bc.tech.coop/blog/070611.html挺有意思

3

用Erlang語言不公開任何方式對匿名函數引用它們自身,但有傳言說核心二郎(中間,但官方表示在編譯器階段)確實有這樣的功能。

我不知道我爲什麼要轉發此內容,但是您知道,如果您恰巧在DSL或類似設備中生成Core Erlang,那麼這是可以實現的。

相關問題