In the code below a closure is created, then later called. At call time, the closed-over variables point to the wrong values. - - - (in-package :cl-user) (defclass lexer (standard-generic-function) () (:metaclass pcl:funcallable-standard-class)) (defun make-lexer (closed-over-var) (let ((lexer (make-instance 'lexer))) (format t "outside 1:~% closed-over-var = ~S~% lexer = ~S~%" closed-over-var lexer) (flet ((inner () (format t "closure:~% closed-over-var = ~S~% lexer = ~S~%" closed-over-var lexer))) (pcl:set-funcallable-instance-function lexer #'inner) (format t "outside 2:~% closed-over-var = ~S~% inner = ~S~% lexer = ~S~%" closed-over-var #'inner lexer) lexer))) (let ((lexer (make-lexer :foo))) (funcall lexer)) - - - CMU Common Lisp 20b-pre2 (20B Unicode), running on framboos With core: /home/willem/lisp/cmucl-20b-pre2/lib/cmucl/lib/lisp-sse2.core Dumped on: Mon, 2010-09-06 19:12:52+02:00 on lorien2 See <http://www.cons.org/cmucl/> for support information. Loaded subsystems: Unicode 1.8 with Unicode version 5.1.0 Python 1.1, target Intel x86/sse2 CLOS based on Gerd's PCL 2010-03-19 15:19:03 * (progn (compile-file "/tmp/foo.lisp") (load "/tmp/foo")) ; Python version 1.1, VM version Intel x86/sse2 on 2010-09-24 23:03:15. ; Compiling: /tmp/foo.lisp 2010-09-24 23:03:06 ; Compiling Load Time Value of (PCL::ENSURE-CTOR '(PCL::CTOR LEXER) 'LEXER ...): ; Converted MAKE-LEXER. ; Compiling DEFUN MAKE-LEXER: ; Byte Compiling Top-Level Form: ; /tmp/foo.sse2f written. ; Compilation finished in 0:00:00. ; Loading #P"/tmp/foo.sse2f". Warning: Changing meta-class of LEXER from KERNEL::STANDARD-CLASS to KERNEL:RANDOM-PCL-CLASS. outside 1: closed-over-var = :FOO lexer = #<LEXER NIL (0) {584ABBE9}> outside 2: closed-over-var = :FOO inner = #<Closure Over Function (FLET INNER MAKE-LEXER) {584ADAA9}> lexer = #<LEXER NIL (0) {584ABBE9}> closure: closed-over-var = #<Wrapper #<FUNCALLABLE-STANDARD-CLASS LEXER {582BFBDD}> {582CC1FD}> <-- !!! lexer = #<Closure Over Function (FLET INNER MAKE-LEXER) {584ADA99}> <-- !!! T - - - However, when the Lisp file is loaded without compiling, things go fine: * (load "/tmp/foo.lisp") ; Loading #P"/tmp/foo.lisp". outside 1: closed-over-var = :FOO lexer = #<LEXER NIL (0) {5867E8B9}> outside 2: closed-over-var = :FOO inner = #<Interpreted Function (FLET INNER) {5867F7B9}> lexer = #<LEXER NIL (0) {5867E8B9}> closure: closed-over-var = :FOO lexer = #<LEXER NIL (0) {5867E8B9}> T - Willem