Why do these forms behave this way?
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
I would have expected the first funcall to return 1, and the second to return 2, etc. This behavior is consistent with both Clozure Common Lisp and Steel-Bank Common Lisp implementations.
If I rework the loop macro to a version using dolist, what I'd expect is what's returned:
(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>
What's going on with the loop macro version?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…