2012-06-26 26 views
18

Tôi đang bối rối về cách defun công trình vĩ mô, vìtại sao defun không giống như (setq <name><lambda>)?

(defun x() "hello") 

sẽ tạo ra chức năng x, nhưng biểu tượng x vẫn sẽ được cởi ra.

Nếu tôi sẽ ràng buộc một số lambda để x thì x sẽ có giá trị, nhưng nó sẽ không được xử lý bằng thông dịch viên là chức năng theo hình thức như thế này:

(x) 

tôi nghĩ rằng nó có liên quan đến thực tế là defun nên định nghĩa hàm trong môi trường toàn cầu, nhưng tôi không chắc nó có ý nghĩa gì. Tại sao tôi không thể che giấu nó trong môi trường hiện tại?

Có cách nào để buộc trình thông dịch coi biểu tượng là hàm nếu một số lambda bị ràng buộc với nó không? Ví dụ:

(setq y (lambda() "I want to be a named function")) 
(y) 

P .: Tôi đang sử dụng SBCL.

Trả lời

20

Common Lisp có không gian tên khác nhau cho các chức năng và giá trị.

Bạn xác định các hàm trong không gian tên hàm bằng DEFUN, FLET, LABELS và một số loại khác.

Nếu bạn muốn nhận đối tượng hàm làm giá trị, bạn sử dụng FUNCTION.

(defun foo (x) (1+ x)) 

(function foo) -> #<the function foo> 

hoặc ngắn hơn:

#'foo -> #<the function foo> 

Nếu bạn muốn gọi một chức năng, sau đó bạn viết (foo 100).

Nếu bạn muốn gọi hàm như một giá trị thì bạn cần phải sử dụng FUNCALL hay APPLY:

(funcall #'foo 1) 

Bạn có thể vượt qua chức năng xung quanh và gọi họ là:

(defun bar (f arg) 
    (funcall f arg arg)) 

(bar #'+ 2) -> 4 

Trong trường hợp DEFUN:

Nó không phải là (setf (symbol-value 'FOO) (lambda ...)).

Nó giống như (setf (symbol-function 'foo) (lambda ...)).

Lưu ý rằng hai không gian tên cho phép bạn viết:

(defun foo (list) 
    (list list)) 

(foo '(1 2 3)) -> ((1 2 3)) 

Không có mâu thuẫn giữa các built-in chức năng LIST và biến LIST. Vì chúng ta có hai không gian tên khác nhau nên chúng ta có thể sử dụng cùng tên cho hai mục đích khác nhau.

Cũng lưu ý rằng trong trường hợp các hàm cục bộ, không có biểu tượng . Các không gian tên không nhất thiết gắn liền với các ký hiệu. Do đó đối với các biến cục bộ, việc tra cứu hàm thông qua tên biểu tượng là không thể.

5

Lisp thường có nhiều vị trí cho mỗi biểu tượng, bao gồm một khe giá trị và một khe chức năng. Khi bạn sử dụng cú pháp (x), giao diện lisp chung cho chức năng-khe-ràng buộc của x. Nếu bạn muốn gọi giá trị ràng buộc, hãy sử dụng funcall hoặc apply.

Xem http://cl-cookbook.sourceforge.net/functions.html

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