2009-07-24 24 views
12

Trong Erlang có cách nào tham chiếu đến chức năng hiện đang thực hiện) không?Erlang: làm thế nào tôi có thể tham chiếu một hàm ẩn danh từ bên trong cơ thể?

Đó sẽ là hữu ích để đẻ trứng một vòng lặp vô hạn:

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

Trong JavaScript arguments.callee không chỉ đó, xem đặc điểm kỹ thuật trên MDC.

Chỉnh sửa để trả lời 'tại sao bạn sẽ làm điều đó': phần lớn là tò mò; nó cũng rất hữu ích để xác định một bộ đếm thời gian khi prorotyping:

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

Tại sao bạn cần điều đó? – zakovyrya

+1

Điều này cũng đã được trả lời trong câu hỏi này: 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, được sáp nhập vào Erlang vào cuối năm 2012. –

Trả lời

24

Trong Erlang/OTP 17,0-rc1, bạn có thể sử dụng một cách vui vẻ đặt tên cho rằng:

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 

Trong các phiên bản trước đó, có không có cách nào để làm chính xác điều đó. Bạn có thể vượt qua các chức năng chính nó như là một cuộc tranh cãi:

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

Nếu bạn cảm thấy như xoắn thứ một chút:

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 các thông điệp vài lần để xem kết quả:

flush(). 

Tất nhiên, Y là hữu ích hơn nếu bạn đặt nó trong một số loại thư viện. Ngoài ra, bạn có thể tìm thấy bài đăng này trên Y Combinators: http://bc.tech.coop/blog/070611.html khá thú vị

3

Ngôn ngữ Erlang không phơi bày bất kỳ cách nào cho các chức năng ẩn danh để tự giới thiệu, nhưng có tin đồn rằng Core Erlang (trung gian nhưng đại diện chính thức) các giai đoạn của trình biên dịch) có một tính năng như vậy.

Tôi không biết tại sao tôi chuyển tiếp điều này, nhưng bạn biết đấy, nếu bạn tình cờ tạo ra Erlang lõi trong DSL hoặc tương tự, đó là điều gì đó trong tầm tay.

Các vấn đề liên quan