Closed-over variables get wrong values

Willem Broekema <[email protected]>
Newsgroups gmane.lisp.cmucl.devel
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.