2009-07-24 25 views
12

En Erlang ¿hay alguna manera de referenciar la función que se está ejecutando actualmente?Erlang: ¿cómo puedo hacer referencia a una función anónima desde dentro del cuerpo?

que serían útiles para desovar un bucle infinito:

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

En JavaScript arguments.callee hace justamente eso, ver la especificación de MDC.

Edita para responder un 'por qué harías eso': mayormente curiosidad; también es útil para definir un temporizador cuando prorotyping:

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

¿Por qué necesitarías eso? – zakovyrya

+1

Esto también se ha respondido en esta pregunta: 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, que se fusionó en Erlang a finales de 2012. –

Respuesta

24

En Erlang/OTP 17.0-RC1, se puede utilizar un divertido designado por ella:

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 

En versiones anteriores, hay no hay forma de hacer exactamente eso. Se podía pasar a la propia función como argumento:

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

Si usted se siente como torcer un poco las cosas:

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

Enjuagar el par de mensajes de veces para ver el resultado:

flush(). 

Por supuesto, Y es más útil si lo coloca en algún tipo de biblioteca. También usted puede encontrar este artículo en Y Combinator: http://bc.tech.coop/blog/070611.html bastante interesante

3

El lenguaje Erlang no expone ninguna manera por funciones anónimas que se refieren a ellos mismo, pero hay un rumor de que Core Erlang (una representación intermedia, pero oficial en las fases del compilador) tiene esa característica.

No sé por qué lo estoy reenviando, pero ya sabes, si estás generando Core Erlang en una DSL o similar, es algo que está a tu alcance.

Cuestiones relacionadas