4

これらのフォームがこのように動作するのはなぜですか?

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ユーザー>

ループ マクロ バージョンはどうなっていますか?

4

2 に答える 2

4

この名前numは、LOOP の評価中に同じバインディングを表します。多分あなたは書きたい:

(mapcar 'constantly (list 1 2 3 4))

あなたが意味したことを得るために。

于 2013-03-30T10:12:11.143 に答える