Real (Không Fake) đóng cửa trong Emacs 24.
Mặc dù Emacs 24 có tát từ vựng khi biến từ vựng-binding có giá trị t, các defun đặc biệt hình thức không hoạt động đúng trong bối cảnh ràng buộc từ vựng (ít nhất là không phải trong Emacs 24.2.1.) Điều này làm cho nó khó khăn, nhưng không không thể, để xác định thực (không giả) đóng cửa.Ví dụ:
(let ((counter 0))
(defun counting()
(setq counter (1+ counter))))
sẽ không hoạt động như mong đợi vì các biểu tượng truy cập trong defun sẽ bị ràng buộc vào biến toàn cầu của tên đó, nếu có một, và không phải là biến từ vựng xác định trong để. Khi hàm đếm được gọi, nếu biến toàn cục không tồn tại thì sẽ rõ ràng là không thành công. Hoever nếu có một biến toàn cầu như vậy nó được cập nhật, mà có lẽ không phải là những gì đã được dự định và có thể là một khó khăn để theo dõi lỗi kể từ khi chức năng có vẻ như đang hoạt động đúng.
biên dịch
Byte không đưa ra một cảnh báo nếu bạn sử dụng defun theo cách này và có lẽ vấn đề này sẽ được giải quyết trong một số phiên bản tương lai của Emacs, nhưng cho đến khi đó macro sau có thể được sử dụng:
(defmacro defun** (name args &rest body)
"Define NAME as a function in a lexically bound context.
Like normal `defun', except that it works correctly in lexically
bound contexts.
\(fn NAME ARGLIST [DOCSTRING] BODY...)"
(let ((bound-as-var (boundp `,name)))
(when (fboundp `,name)
(message "Redefining function/macro: %s" `,name))
(append
`(progn
(defvar ,name nil)
(fset (quote ,name) (lambda (,@args) ,@body)))
(if bound-as-var
'nil
`((makunbound `,name))))))
Nếu bạn xác định đếm như sau:
(let ((counter 0))
(defun** counting()
(setq counter (1+ counter))))
nó sẽ làm việc như mong đợi và cập nhật các lexically ràng buộc biến đếm mỗi khi được gọi, trong khi trả về giá trị mới.
caveat: vĩ mô sẽ không hoạt động đúng nếu bạn cố gắng defun ** một hàm có cùng tên là một trong những biến lexically ràng buộc. I.e nếu bạn làm điều gì đó như:
(let ((dont-do-this 10))
(defun** dont-do-this()
.........
.........))
Tôi không thể tưởng tượng bất kỳ ai thực sự làm điều đó nhưng nó đáng được đề cập đến.
Lưu ý: Tôi đã đặt tên cho vĩ mô defun **để nó không xung đột với các vĩ mô defun * trong cl gói, tuy nhiên nó không phụ thuộc vào bất kỳ cách nào vào đó gói.
Theo như tôi đã nghe, JavaScript thực sự khá chức năng. – Svante
Nó phụ thuộc vào quan điểm của một người. Đối với tôi, nếu hầu hết các mã trong ngôn ngữ là bắt buộc thì nó bắt buộc. Đó là trường hợp ở đây. – vava
Kể từ phiên bản 24, Emacs hiện có phạm vi từ vựng. –