Lisp thường được giả định.
Tại sao cần phải có báo giá sắc nét hoặc thậm chí có thể?
Nếu bạn muốn tính toán một đối tượng chức năng từ một tên hàm (đặc biệt nếu bạn muốn đề cập đến một từ vựng ràng buộc) hoặc một biểu thức lambda, bạn cần các nhà điều hành đặc biệt FUNCTION
, hoặc ngắn hơn #'
.
biểu thức lambda trở lại đối tượng chức năng,
Họ không. Biểu thức Lambda thậm chí không thể được đánh giá.
Trong Lisp thông thường có vẻ như (lambda() nil)
có thể được đánh giá. Nhưng nó không thể.
Thỉnh thoảng sau khi CLtL1 một macro LAMBDA
đã được thêm vào để mở rộng nó thành biểu thức (FUNCTION ...)
. Macro này tiết kiệm một số đánh máy và chúng ta hãy mã trông giống như Scheme. Hãy kiểm tra LAMBDA
macro này:
CL-USER 17 > (macroexpand-1 '(lambda()())) ; not a lambda expression
(FUNCTION
(LAMBDA NIL NIL) ; <- this is a lambda expression
)
T
Điều này có nghĩa rằng những điều sau đây sẽ xảy ra nếu bạn đánh giá (lambda()())
:
LAMBDA
là một macro. Do đó, biểu mẫu được mở rộng thành (function (lambda()()))
.
(function (lambda()()))
->FUNCTION
là một toán tử đặc biệt. Nó trả về một đối tượng hàm
- ->
Nếu bạn viết: #'(lambda()())
hoặc (function (lambda()()))
, sau đó bạn sẽ bỏ qua việc mở rộng vĩ mô.
rồi, bây giờ cho một cái gì đó kỳ lạ:
CL-USER 18 > (lambda()()) ; <- this is not a lambda expression.
; it's a macro form, see above
#<anonymous interpreted function 40600009FC>
Bởi vì ở trên là một hình thức vĩ mô, nó sẽ được mở rộng đầu tiên và sau đó nó có thể được đánh giá.
CL-USER 19 > (function ; <- this is a special form
(lambda()()) ; <- this is a lambda expression
)
#<anonymous interpreted function 4060000C0C>
Đây thực sự là biểu thức lambda. Bên trong toán tử đặc biệt FUNCTION
biểu mẫu sẽ không được macro mở rộng hoặc tương tự.
CL-USER 20 > ( ; <- this is a function call
(lambda()()) ; <- this is a lambda expression
)
Trên một lần nữa, hiển thị biểu thức lambda. Trường hợp ((function (lambda()())))
không hợp lệ Common Lisp. Ở vị trí chức năng của một cuộc gọi hàm, Common Lisp dự kiến hoặc là một tên hàm hoặc một biểu thức lambda, nhưng không phải là một cái gì đó cần được đánh giá.
và trả về trích dẫn sắc nét đối tượng chức năng từ tên.
FUNCTION
, mà #'
là một ký hiệu ngắn, trả về đối tượng chức năng từ tên hàm hay biểu thức lambda.
Xem tài liệu: FUNCTION.
Tôi cũng đã nghe thông tin trái ngược nhau về việc liệu các biểu thức lambda là những cái tên - đặc biệt On Lisp mâu thuẫn với tiêu chuẩn, nhưng mã của ông dường như làm việc mà còn mâu thuẫn với tiêu chuẩn.
Nếu bạn muốn nghe từ cuối cùng, hãy đọc tiêu chuẩn ANSI CL. Hoặc sử dụng Common Lisp Hyperspec, có thể đọc được trên web và được lấy từ tiêu chuẩn.
On Lisp chắc chắn là hữu ích để đọc, nhưng nó có thể không làm theo những chỉ dẫn hoặc ngữ nghĩa của ANSI CL đầy đủ chi tiết. Trên Lisp đã được xuất bản sau CLtL2, nhưng trước khi ANSI CL.
có nghĩa là gì thực tế khi viết mã?
Nếu bạn cũ, như tôi, và CLtL1 là điều cuối cùng bạn đọc của Common Lisp sau đó viết mã như:
(mapcar #'(lambda (x) (* x x)) '(1 2 3))
Nếu bạn thậm chí còn lớn hơn và lớn lên với Đề án, hoặc là trẻ và đã đọc Common Lisp Hyperspec, sau đó bạn có thể muốn viết:
(mapcar (lambda (x) (* x x)) '(1 2 3))
Nhưng đối với tất cả, khi nói đến hoạt động tên, đây là mặc định để viết:
(mapcar #'sin '(1 2 3))
Xem thêm [sách hướng dẫn tham khảo Elisp] (https://www.gnu.org/software/emacs/manual/html_node/elisp/Anonymous-Functions.html#Anonymous-Functions) ngụ ý rằng 'hàm' trích dẫn sẽ giúp trình biên dịch byte xác định các đoạn mã cần được biên dịch. Nhưng tôi đồng ý rằng điều này có lẽ nên được giải thích chi tiết hơn bởi ai đó với cái nhìn sâu sắc thích hợp. – tripleee