Closed-over variables get wrong values
Willem Broekema
metawilm at gmail.com
Fri Sep 24 23:10:25 CEST 2010
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
More information about the cmucl-imp
mailing list