As an example of the bug, The Common Lisp Zip Library
project (http://common-lisp.net/project/zip/ ) contains
the following in zip.lisp:
(defmacro define-record (constructor (&key (length
(gensym))) &rest fields)
`(progn
(defconstant ,length
,(loop
for (nil type) in fields
sum (ecase type (:int 4) (:short 2))))
(defun ,constructor (&optional s)
; BAD: ,length expands to #Gxxxx, instead of the
actual value.
; The CLISP 2.35 compiler doesn't complain, but the
loader chokes on the
; uninterned symbol.
(let ((bytes (make-byte-array ,length)))
(when s
(read-sequence bytes s))
bytes))
,@(loop
for (name type) in fields
for offset = 0 then (+ offset length)
for length = (ecase type (:int 4) (:short 2))
for reader = (ecase type (:int 'get-int) (:short
'get-short))
unless (eq name :dummy)
append `((defun ,name (r)
(,reader r ,offset))
(defun (setf ,name) (newval r)
(setf (,reader r ,offset)
newval))))))
...
(define-record make-directory-entry ()
(cd/signature :int)
(cd/version-made-by :short)
(cd/version-needed-to-extract :short)
(cd/flags :short)
(cd/method :short)
(cd/time :short)
(cd/date :short)
(cd/crc :int)
(cd/compressed-size :int)
(cd/size :int)
(cd/name-length :short)
(cd/extra-length :short)
(cd/comment-length :short)
(cd/disc-number :short)
(cd/internal-attributes :short)
(cd/external-attributes :int)
(cd/offset :int))
[7]> (pprint (macroexpand '(define-record
make-directory-entry () (end/signature :int)
(end/this-disc :short) (end/central-directory-disc
:short) ...)))
expands to the following:
(PROGN (DEFCONSTANT #:G9428 46)
(DEFUN MAKE-DIRECTORY-ENTRY (&OPTIONAL S)
(LET ((BYTES (MAKE-BYTE-ARRAY #:G9428))) (WHEN S
(READ-SEQUENCE BYTES S))
BYTES))
(DEFUN END/SIGNATURE (R) (GET-INT R 0))
(DEFUN (SETF END/SIGNATURE) (NEWVAL R) (SETF (GET-INT
R 0) NEWVAL))
(DEFUN END/THIS-DISC (R) (GET-SHORT R 4)) ...)
Whereas Clisp 2.35 compiles the file, it fails on
loading, giving the following:
...
;; Loading file /home/stranger/oss/lisp/zip/zip.fas ...
*** - EVAL: variable #:G9428 has no value
The following restarts are available:
USE-VALUE :R1 You may input a value to be
used instead of #:G9428.
STORE-VALUE :R2 You may input a new value for
#:G9428.
RETRY :R3
Retry performing #<ASDF:LOAD-OP NIL #x20446756> on
#<ZIP-SYSTEM::SILENT-SOURCE-FILE
"zip" #x20448276>.
ACCEPT :R4
Continue, treating #<ASDF:LOAD-OP NIL #x20446756> on
#<ZIP-SYSTEM::SILENT-SOURCE-FILE
"zip" #x20448276> as having been successful.
ABORT :R5 ABORT
As defined in CLHS, Common Lisp treats forms in a
toplevel PROGN as toplevel forms, and the progn creates
a lexical environment for those forms. I haven't yet
found anything in the standard that defines either
behavior as implementation dependent.
SBCL 0.9.5 loads the aforementioned compiled file
without complaint, and I believe others had success
with the zip library on other implementations. This
would lead me to believe that the macro is valid Lisp code.
Let me know if I have missed something.
Logged In: YES
user_id=5735
this is a duplicate of bug [ 836838 ]:
uninterned symbols not shared between forms in FAS file
https://sourceforge.net/tracker/index.php?func=detail&aid=836838&group_id=1355&atid=101355
This artifact has been marked as a duplicate of artifact 836838 with reason:
same issue