これらのフォームがこのように動作するのはなぜですか?
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 番目の funcall は 2 を返すなどと予想していました。この動作は、Clozure Common Lisp と Steel-Bank 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ユーザー>
ループ マクロ バージョンはどうなっていますか?