2009-07-24 6 views
12

Dans Erlang existe-t-il un moyen de référence à la fonction en cours d'exécution)?Erlang: comment puis-je faire référence à une fonction anonyme dans le corps?

Ce serait utile pour frayer une boucle infinie:

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

En JavaScript arguments.callee exactement ce que fait, voir la spécification sur MDC.

Modifier pour répondre à la question «pourquoi voudriez-vous faire cela»: surtout curiosité; il est également utile de définir une minuterie lorsque prorotyping:

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

Pourquoi auriez-vous besoin de ça? – zakovyrya

+1

Il a également été répondu à cette question: http://stackoverflow.com/questions/867418/how-do-you-write-a-fun-thats-recursive-in-erlang/867525#867525 –

+0

"Funs with Names ": http://www.erlang.org/eeps/eep-0037.html, qui a été fusionné à Erlang fin 2012. –

Répondre

24

vous pouvez utiliser un amusement nommé pour que dans Erlang/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 

Dans les versions précédentes, il est pas moyen de faire exactement cela. Vous pouvez passer la fonction elle-même comme un argument:

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

Si vous sentez que les choses tordant un peu:

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 fois le couple de messages pour voir le résultat:

flush(). 

Bien sûr, Y est plus utile si vous le mettez dans une sorte de bibliothèque. vous pouvez également trouver ce post sur Y Combinator: http://bc.tech.coop/blog/070611.html très intéressant

3

Le langage Erlang ne pas exposer aucune façon pour les fonctions anonymes de se référer à eux-même, mais il y a une rumeur que Core Erlang (une représentation intermédiaire, mais officiel les phases du compilateur) a une telle caractéristique. Je ne sais pas pourquoi je transmets ceci, mais vous savez, si vous générez Core Erlang dans un DSL ou similaire, c'est quelque chose qui est à portée de main.

Questions connexes