2009-07-24 13 views
12

In Erlang esiste un modo per fare riferimento alla funzione attualmente in esecuzione)?Erlang: come posso fare riferimento a una funzione anonima dall'interno del corpo?

che sarebbe utile a generare un ciclo infinito:

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

In JavaScript arguments.callee fa proprio questo, si veda la specifica sulla MDC.

Modifica per rispondere a "perché lo faresti?": Per lo più curiosità; è anche utile per definire un timer quando prorotyping:

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

Perché ne hai bisogno? – zakovyrya

+1

Anche questa domanda ha risposto: 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, che è stato fuso in Erlang alla fine del 2012. –

risposta

24

in Erlang/OTP 17,0-rc1, è possibile utilizzare un divertente chiamato per questo:

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 

Nelle versioni precedenti, non ci non c'è modo di fare esattamente questo. Si potrebbe passare la funzione stessa come un argomento:

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

Se ti senti come torcendo le cose un po ':

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

Lavare il paio di messaggi di volte per vedere il risultato:

flush(). 

Ovviamente, Y è più utile se lo inserisci in una sorta di libreria. Inoltre è possibile trovare questo post su Y Combinator: http://bc.tech.coop/blog/070611.html abbastanza interessante

3

Il linguaggio Erlang non espone alcun modo per le funzioni anonime per riferirsi a loro stessi, ma c'è una voce che Core Erlang (una rappresentazione intermedia, ma ufficiale le fasi del compilatore) ha questa caratteristica.

Non so perché lo sto inoltrando, ma sai, se ti capita di generare Core Erlang in un DSL o qualcosa di simile è a portata di mano.

Problemi correlati