爲什麼這些表單行爲如此?循環宏和閉包的意外行爲
CL-USER>
(setf *closures*
(loop for num in (list 1 2 3 4)
collect (lambda()
num)))
(
#<COMPILED-LEXICAL-CLOSURE #x302004932E1F>
#<COMPILED-LEXICAL-CLOSURE #x302004932DCF>
#<COMPILED-LEXICAL-CLOSURE #x302004932D7F>
#<COMPILED-LEXICAL-CLOSURE #x302004932D2F>)
CL-USER>
(funcall (first *closures*))
4
CL-USER>
(funcall (second *closures*))
4
我本來期望第一funcall返回1,第二個返回2,等等。這種行爲是與兩個Clozure的Common Lisp和鋼銀行Common Lisp的實現方式是一致的。
如果我使用dolist返工循環宏的一個版本,我會想到的是所返回的內容:
(setf *closures*
(let ((out))
(dolist (item (list 1 2 3 4) (reverse out))
(push (lambda() item) out))))
(
#<COMPILED-LEXICAL-CLOSURE #x302004A12C4F>
#<COMPILED-LEXICAL-CLOSURE #x302004A12BFF>
#<COMPILED-LEXICAL-CLOSURE #x302004A12BAF>
#<COMPILED-LEXICAL-CLOSURE #x302004A12B5F>)
CL-USER>
(funcall (first *closures*))
1
CL-USER>
(funcall (second *closures*))
2
CL-USER>
這是怎麼回事用循環宏版本?
順便說一句,你可以命名'num1'爲'num';) (讓((NUM NUM))...) – monoid
我以前用過這樣的:'(defmacro重新綁定(增值經銷商和身體的身體)\' (讓((mapcar#'list vars vars),@ body))' – lmj
非常好的宏:) – monoid