0.6.8.10:
authorWilliam Harold Newman <william.newman@airmail.net>
Tue, 7 Nov 2000 17:50:11 +0000 (17:50 +0000)
committerWilliam Harold Newman <william.newman@airmail.net>
Tue, 7 Nov 2000 17:50:11 +0000 (17:50 +0000)
tested for bug 21, didn't find it, removed it from BUGS.
added SANE-PACKAGE to handle non-PACKAGE values of *PACKAGE*
deleted some unused and redundant stuff from PCL

23 files changed:
BUGS
NEWS
package-data-list.lisp-expr
src/assembly/assemfile.lisp
src/code/array.lisp
src/code/debug.lisp
src/code/defbangmacro.lisp
src/code/defbangstruct.lisp
src/code/defstruct.lisp
src/code/fop.lisp
src/code/primordial-extensions.lisp
src/code/print.lisp
src/code/reader.lisp
src/code/symbol.lisp
src/code/target-load.lisp
src/code/target-package.lisp
src/compiler/debug-dump.lisp
src/compiler/main.lisp
src/pcl/boot.lisp
src/pcl/cache.lisp
src/pcl/macros.lisp
tests/compiler-1.impure.lisp
version.lisp-expr

diff --git a/BUGS b/BUGS
index 1208231..30de7f1 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -253,15 +253,6 @@ becomes FASL:
   DTC's recommended workaround from the mailing list 3 Mar 2000:
        (setf (pcl::find-class 'ccc1) (pcl::find-class 'ccc))
 
-21:
-  There's probably a bug in the compiler handling of special variables
-  in closures, inherited from the CMU CL code, as reported on the
-  CMU CL mailing list. There's a patch for this on the CMU CL
-  mailing list too:
-    Message-ID: <38C8E188.A1E38B5E@jeack.com.au>
-    Date: Fri, 10 Mar 2000 22:50:32 +1100
-    From: "Douglas T. Crosher" <dtc@jeack.com.au>
-
 22:
   The ANSI spec, in section "22.3.5.2 Tilde Less-Than-Sign: Logical Block",
   says that an error is signalled if ~W, ~_, ~<...~:>, ~I, or ~:T is used
diff --git a/NEWS b/NEWS
index 6515f4e..741ced8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -548,8 +548,7 @@ changes in sbcl-0.6.9 relative to sbcl-0.6.8:
   ** The TOP debugger command is also gone, since it's redundant with the
      FRAME 0 command, and since it interfered with abbreviations for the
      TOPLEVEL restart.
-* DEFCONSTANT has been made more ANSI-compatible (completely ANSI-compatible,
-  as far as I know):
+* fixed bugs in DEFCONSTANT ANSI-compatibility:
   ** DEFCONSTANT now tests reassignments using EQL, not EQUAL, in order to 
      warn about behavior which is undefined under the ANSI spec. Note: This
      is specified by ANSI, but it's not very popular with programmers.
@@ -560,14 +559,15 @@ changes in sbcl-0.6.9 relative to sbcl-0.6.8:
      pre-ANSI IR1 translation magic, so it does the ANSI-specified thing
      when it's used as a non-toplevel form. (This is required in order
      to implement the DEFCONSTANT-EQX macro.)
-?? fixed bug: (DEFCONSTANT X 1) (DEFVAR X) (SETF X 2) no longer "works".
-?? fixed bug 21, a compiler bug re. special variables in closures. One
-  consequence of this is that ILISP should work better, because idioms like
-  (LET ((*PACKAGE* ..)) (DO-SOMETHING)) no longer have screwy side-effects.
+  ** (DEFCONSTANT X 1) (DEFVAR X) (SETF X 2) no longer "works".
+  ** Unfortunately, non-toplevel DEFCONSTANT forms can still do some
+     funny things, due to bugs in the implementation of EVAL-WHEN
+     (bug #IR1-3). This probably won't be fixed until 0.7.x. (Fortunately,
+     non-toplevel DEFCONSTANTs are uncommon.)
 * The core file version number and fasl file version number have been 
   incremented, because the old noncompliant DEFCONSTANT behavior involved
   calling functions which no longer exist.
-
-?? signal handling reliability
-?? fixed some bugs mentioned in the man page:
-  ?? DEFUN-vs.-DECLAIM
+* removed bug 21 from BUGS, since Martin Atzmueller points out that 
+  it doesn't seem to affect SBCL after all
+* The system now recovers better from non-PACKAGE values of the *PACKAGE*
+  variable.
index dc4c6bf..ed136ee 100644 (file)
@@ -676,6 +676,7 @@ retained, possibly temporariliy, because it might be used internally."
              ;; useful but non-standard user-level functions..
              "ASSQ" "DELQ" "MEMQ"
             "%FIND-PACKAGE-OR-LOSE" "FIND-UNDELETED-PACKAGE-OR-LOSE"
+             "SANE-PACKAGE"
 
             ;; ..and macros
              "COLLECT"
index 6578aa2..a4e9faf 100644 (file)
@@ -48,7 +48,8 @@
        (let ((*features* (cons :sb-assembling *features*)))
          (init-assembler)
          (load (merge-pathnames name (make-pathname :type "lisp")))
-         (fasl-dump-cold-load-form `(in-package ,(package-name *package*))
+         (fasl-dump-cold-load-form `(in-package ,(package-name
+                                                  (sane-package)))
                                    *lap-output-file*)
          (sb!assem:append-segment *code-segment* *elsewhere*)
          (setf *elsewhere* nil)
index 4f03dfc..3e94740 100644 (file)
 
 (defun array-has-fill-pointer-p (array)
   #!+sb-doc
-  "Returns T if the given Array has a fill pointer, or Nil otherwise."
+  "Return T if the given ARRAY has a fill pointer, or NIL otherwise."
   (declare (array array))
   (and (array-header-p array) (%array-fill-pointer-p array)))
 
 (defun fill-pointer (vector)
   #!+sb-doc
-  "Returns the Fill-Pointer of the given Vector."
+  "Return the FILL-POINTER of the given VECTOR."
   (declare (vector vector))
   (if (and (array-header-p vector) (%array-fill-pointer-p vector))
       (%array-fill-pointer vector)
   (declare (vector vector) (fixnum new))
   (if (and (array-header-p vector) (%array-fill-pointer-p vector))
       (if (> new (%array-available-elements vector))
-       (error "New fill pointer, ~S, is larger than the length of the vector."
-              new)
+       (error
+        "The new fill pointer, ~S, is larger than the length of the vector."
+        new)
        (setf (%array-fill-pointer vector) new))
       (error 'simple-type-error
             :datum vector
 
 (defun vector-push (new-el array)
   #!+sb-doc
-  "Attempts to set the element of Array designated by the fill pointer
-   to New-El and increment fill pointer by one. If the fill pointer is
-   too large, Nil is returned, otherwise the index of the pushed element is
+  "Attempt to set the element of ARRAY designated by its fill pointer
+   to NEW-EL, and increment the fill pointer by one. If the fill pointer is
+   too large, NIL is returned, otherwise the index of the pushed element is
    returned."
   (declare (vector array))
   (let ((fill-pointer (fill-pointer array)))
index 0a6cb5c..80ae5ca 100644 (file)
@@ -595,7 +595,19 @@ Function and macro commands:
       (let ((*debugger-hook* nil))
        (funcall hook condition hook))))
   (sb!unix:unix-sigsetmask 0)
-  (let ((original-package *package*)) ; protected from WITH-STANDARD-IO-SYNTAX
+
+  ;; Elsewhere in the system, we use the SANE-PACKAGE function for
+  ;; this, but here causing an exception just as we're trying to handle
+  ;; an exception would be confusing, so instead we use a special hack.
+  (unless (and (packagep *package*)
+              (package-name *package*))
+    (setf *package* (find-package :cl-user))
+    (format *error-output*
+           "The value of ~S was not an undeleted PACKAGE. It has been
+reset to ~S."
+           '*package* *package*))
+  (let (;; Save *PACKAGE* to protect it from WITH-STANDARD-IO-SYNTAX.
+       (original-package *package*))
     (with-standard-io-syntax
      (let* ((*debug-condition* condition)
            (*debug-restarts* (compute-restarts condition))
index 7e7dba3..c243552 100644 (file)
@@ -23,7 +23,7 @@
   ;; of the system running to finish processing it
   (defstruct delayed-def!macro
     (args (required-argument) :type cons)
-    (package *package* :type package))
+    (package (sane-package) :type package))
   ;; a list of DELAYED-DEF!MACROs stored until we get DEF!MACRO working fully
   ;; so that we can apply it to them. After DEF!MACRO is made to work, this
   ;; list is processed, and then should no longer be used; it's made unbound in
index 55cff76..e4d8a2e 100644 (file)
@@ -98,7 +98,7 @@
   ;; enough of the system running to finish processing it
   (defstruct delayed-def!struct
     (args (required-argument) :type cons)
-    (package *package* :type package))
+    (package (sane-package) :type package))
   ;; a list of DELAYED-DEF!STRUCTs stored until we get DEF!STRUCT
   ;; working fully so that we can apply it to them then. After
   ;; DEF!STRUCT is made to work fully, this list is processed, then
index 2f86b39..221cdd6 100644 (file)
   (intern (string (dsd-%name dsd))
          (if (dsd-accessor dsd)
              (symbol-package (dsd-accessor dsd))
-             *package*)))
+             (sane-package))))
 \f
 ;;;; typed (non-class) structures
 
index c5791ed..b47aa4e 100644 (file)
                                                 ,n-size
                                                 ,n-package)))))))))
 
-  ;; Note: CMU CL had FOP-SYMBOL-SAVE and FOP-SMALL-SYMBOL-SAVE, but since they
-  ;; made the behavior of the fasloader depend on the *PACKAGE* variable, not
-  ;; only were they a pain to support (because they required various hacks to
-  ;; handle *PACKAGE*-manipulation forms) they were basically broken by design,
-  ;; because ANSI gives the user so much flexibility in manipulating *PACKAGE*
-  ;; at load-time that no reasonable hacks could possibly make things work
-  ;; right. The ones used in CMU CL certainly didn't, as shown by e.g.
+  ;; Note: CMU CL had FOP-SYMBOL-SAVE and FOP-SMALL-SYMBOL-SAVE, but
+  ;; since they made the behavior of the fasloader depend on the
+  ;; *PACKAGE* variable, not only were they a pain to support (because
+  ;; they required various hacks to handle *PACKAGE*-manipulation
+  ;; forms) they were basically broken by design, because ANSI gives
+  ;; the user so much flexibility in manipulating *PACKAGE* at
+  ;; load-time that no reasonable hacks could possibly make things
+  ;; work right. The ones used in CMU CL certainly didn't, as shown by
+  ;; e.g.
   ;;   (IN-PACKAGE :CL-USER)
   ;;     (DEFVAR CL::*FOO* 'FOO-VALUE)
   ;;     (EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE)
index 63bb972..9facae7 100644 (file)
@@ -11,7 +11,6 @@
 ;;;; files for more information.
 
 (in-package "SB!INT")
-
 \f
 ;;;; DO-related stuff which needs to be visible on the cross-compilation host
 
   (let ((*package* *keyword-package*))
     (apply #'symbolicate things)))
 
+;;; Access *PACKAGE* in a way which lets us recover if someone has
+;;; done something silly like (SETF *PACKAGE* :CL-USER). (Such an
+;;; assignment is undefined behavior, so it's sort of reasonable for it
+;;; to cause the system to go totally insane afterwards, but it's
+;;; a fairly easy mistake to make, so let's try to recover gracefully
+;;; instead.)
+(defun sane-package ()
+  (let ((maybe-package *package*))
+    (cond ((and (packagep maybe-package)
+               ;; For good measure, we also catch the problem of
+               ;; *PACKAGE* being bound to a deleted package.
+               ;; Technically, this is not undefined behavior in itself,
+               ;; but it will immediately lead to undefined to behavior,
+               ;; since almost any operation on a deleted package is
+               ;; undefined.
+               (package-name maybe-package))
+          maybe-package)
+         (t
+          ;; We're in the undefined behavior zone. First, munge the
+          ;; system back into a defined state.
+          (let ((really-package (find-package :cl-user)))
+            (setf *package* really-package)
+            ;; Then complain.
+            (error 'simple-type-error
+                   :datum maybe-package
+                   :expected-type 'package
+                   :format-control
+                   "~S can't be a ~S:~%  ~S has been reset to ~S"
+                   :format-arguments (list '*package* (type-of maybe-package)
+                                           '*package* really-package)))))))
+
 ;;; Give names to elements of a numeric sequence.
 (defmacro defenum ((&key (prefix "") (suffix "") (start 0) (step 1))
                   &rest identifiers)
index 1f61fcc..7b4d3fe 100644 (file)
          (write-char #\: stream))
         ;; Otherwise, if the symbol's home package is the current
         ;; one, then a prefix is never necessary.
-        ((eq package *package*))
+        ((eq package (sane-package)))
         ;; Uninterned symbols print with a leading #:.
         ((null package)
          (when (or *print-gensym* *print-readably*)
            (write-string "#:" stream)))
         (t
-         (multiple-value-bind (symbol accessible) (find-symbol name *package*)
+         (multiple-value-bind (symbol accessible)
+             (find-symbol name (sane-package))
            ;; If we can find the symbol by looking it up, it need not
            ;; be qualified. This can happen if the symbol has been
            ;; inherited from a package other than its home package.
 
 (defun output-integer (integer stream)
   ;; FIXME: This UNLESS form should be pulled out into something like
-  ;; GET-REASONABLE-PRINT-BASE, along the lines of GET-REASONABLE-PACKAGE
-  ;; for the *PACKAGE* variable.
+  ;; (SANE-PRINT-BASE), along the lines of (SANE-PACKAGE) for the
+  ;; *PACKAGE* variable.
   (unless (and (fixnump *print-base*)
               (< 1 *print-base* 37))
     (let ((obase *print-base*))
index f37d54f..d4abe78 100644 (file)
       (casify-read-buffer escapes)
       (let ((found (if package-designator
                       (find-package package-designator)
-                      *package*)))
+                      (sane-package))))
        (unless found
          (error 'reader-package-error :stream stream
                 :format-arguments (list package-designator)
index 5bf53d8..2ba6558 100644 (file)
 (defvar *gentemp-counter* 0)
 (declaim (type unsigned-byte *gentemp-counter*))
 
-(defun gentemp (&optional (prefix "T") (package *package*))
+(defun gentemp (&optional (prefix "T") (package (sane-package)))
   #!+sb-doc
-  "Creates a new symbol interned in package Package with the given Prefix."
+  "Creates a new symbol interned in package PACKAGE with the given PREFIX."
   (declare (type string prefix))
   (loop
     (let ((*print-base* 10)
index f015581..c928da9 100644 (file)
 
   (let ((sb!c::*default-cookie* sb!c::*default-cookie*)
        (sb!c::*default-interface-cookie* sb!c::*default-interface-cookie*)
-       (*package* *package*)
+       (*package* (sane-package))
        (*readtable* *readtable*)
        (*load-depth* (1+ *load-depth*))
        ;; The old CMU CL LOAD function used an IF-DOES-NOT-EXIST argument of
index baa3ef8..ebac39b 100644 (file)
   (defun package-external-symbol-count (package)
     (stuff (package-external-symbols package))))
 \f
-(defvar *package* () ; actually initialized in cold load
+(defvar *package* (error "*PACKAGE* should be initialized in cold load!") 
   #!+sb-doc "the current package")
 ;;; FIXME: should be declared of type PACKAGE, with no NIL init form,
 ;;; after I get around to cleaning up DOCUMENTATION
-;;;
-;;; FIXME: Setting *PACKAGE* to a non-PACKAGE value (even a plausible
-;;; one, like :CL-USER) makes the system fairly unusable, without
-;;; generating useful diagnostics. Is it possible to handle this
-;;; situation more gracefully by replacing references to *PACKAGE*
-;;; with references to (DEFAULT-PACKAGE) and implementing
-;;; DEFAULT-PACKAGE so that it checks for the PACKAGEness of *PACKAGE*
-;;; and helps the user to fix any problem (perhaps going through
-;;; CERROR)?
-;;;   Error: An attempt was made to use the *PACKAGE* variable when it was
-;;;      bound to the illegal (non-PACKAGE) value ~S. This is
-;;;      forbidden by the ANSI specification and could have made
-;;;      the system very confused. The *PACKAGE* variable has been
-;;;      temporarily reset to #<PACKAGE "COMMON-LISP-USER">. How
-;;;      would you like to proceed?
-;;;        NAMED Set *PACKAGE* to ~S (which is the package which is
-;;;              named by the old illegal ~S value of *PACKAGE*, and
-;;;              is thus very likely the intended value) and continue
-;;;              without signalling an error.
-;;;        ERROR Leave *PACKAGE* set to #<PACKAGE "COMMON-LISP-USER">
-;;;              and signal PACKAGE-ERROR to the code which tried to
-;;;              use the old illegal value of *PACKAGE*.
-;;;        CONTINUE Leave *PACKAGE* set to #<PACKAGE "COMMON-LISP-USER">
-;;;              and continue without signalling an error.
 
 ;;; a map from package names to packages
 (defvar *package-names*)
             *package-names*)
     res))
 \f
-(defun intern (name &optional (package *package*))
+(defun intern (name &optional (package (sane-package)))
   #!+sb-doc
   "Returns a symbol having the specified name, creating it if necessary."
   ;; We just simple-stringify the name and call INTERN*, where the real
             (length name)
             (find-undeleted-package-or-lose package))))
 
-(defun find-symbol (name &optional (package *package*))
+(defun find-symbol (name &optional (package (sane-package)))
   #!+sb-doc
   "Returns the symbol named String in Package. If such a symbol is found
   then the second value is :internal, :external or :inherited to indicate
 \f
 ;;; If we are uninterning a shadowing symbol, then a name conflict can
 ;;; result, otherwise just nuke the symbol.
-(defun unintern (symbol &optional (package *package*))
+(defun unintern (symbol &optional (package (sane-package)))
   #!+sb-doc
   "Makes Symbol no longer present in Package. If Symbol was present
   then T is returned, otherwise NIL. If Package is Symbol's home
                    (unintern symbol q)
                    (return t))))))))))
 \f
-(defun export (symbols &optional (package *package*))
+(defun export (symbols &optional (package (sane-package)))
   #!+sb-doc
   "Exports Symbols from Package, checking that no name conflicts result."
   (let ((package (find-undeleted-package-or-lose package))
     t))
 \f
 ;;; Check that all symbols are accessible, then move from external to internal.
-(defun unexport (symbols &optional (package *package*))
+(defun unexport (symbols &optional (package (sane-package)))
   #!+sb-doc
   "Makes Symbols no longer exported from Package."
   (let ((package (find-undeleted-package-or-lose package))
 \f
 ;;; Check for name conflict caused by the import and let the user
 ;;; shadowing-import if there is.
-(defun import (symbols &optional (package *package*))
+(defun import (symbols &optional (package (sane-package)))
   #!+sb-doc
   "Make Symbols accessible as internal symbols in Package. If a symbol
   is already accessible then it has no effect. If a name conflict
 \f
 ;;; If a conflicting symbol is present, unintern it, otherwise just
 ;;; stick the symbol in.
-(defun shadowing-import (symbols &optional (package *package*))
+(defun shadowing-import (symbols &optional (package (sane-package)))
   #!+sb-doc
   "Import Symbols into package, disregarding any name conflict. If
   a symbol of the same name is present, then it is uninterned.
        (pushnew sym (package-%shadowing-symbols package)))))
   t)
 
-(defun shadow (symbols &optional (package *package*))
+(defun shadow (symbols &optional (package (sane-package)))
   #!+sb-doc
   "Make an internal symbol in Package with the same name as each of the
   specified symbols, adding the new symbols to the Package-Shadowing-Symbols.
   t)
 \f
 ;;; Do stuff to use a package, with all kinds of fun name-conflict checking.
-(defun use-package (packages-to-use &optional (package *package*))
+(defun use-package (packages-to-use &optional (package (sane-package)))
   #!+sb-doc
   "Add all the Packages-To-Use to the use list for Package so that
   the external symbols of the used packages are accessible as internal
        (push package (package-%used-by-list pkg)))))
   t)
 
-(defun unuse-package (packages-to-unuse &optional (package *package*))
+(defun unuse-package (packages-to-unuse &optional (package (sane-package)))
   #!+sb-doc
   "Remove Packages-To-Unuse from the use list for Package."
   (let ((package (find-undeleted-package-or-lose package)))
index e36ec9b..0fce8dd 100644 (file)
                 minimal-debug-function-name-component)
                ((not pkg)
                 minimal-debug-function-name-uninterned)
-               ((eq pkg *package*)
+               ((eq pkg (sane-package))
                 minimal-debug-function-name-symbol)
                (t
                 minimal-debug-function-name-packaged))))
index 442b43a..4717b0f 100644 (file)
         #+nil (*compiler-style-warning-count* 0)
         #+nil (*compiler-note-count* 0)
         (*block-compile* *block-compile-argument*)
-        (*package* *package*)
-        (*initial-package* *package*)
+        (*package* (sane-package))
+        (*initial-package* (sane-package))
         (*initial-cookie* *default-cookie*)
         (*initial-interface-cookie* *default-interface-cookie*)
         (*default-cookie* (copy-cookie *initial-cookie*))
index 6c096a9..cb710f2 100644 (file)
@@ -1007,14 +1007,14 @@ bootstrapping.
                                                      ,(cadr var)))))))
                   (rest `((,var ,args-tail)))
                   (key (cond ((not (consp var))
-                              `((,var (get-key-arg ,(make-keyword var)
+                              `((,var (get-key-arg ,(sb-int:keywordicate var)
                                                    ,args-tail))))
                              ((null (cddr var))
                               (multiple-value-bind (keyword variable)
                                   (if (consp (car var))
                                       (values (caar var)
                                               (cadar var))
-                                      (values (make-keyword (car var))
+                                      (values (sb-int:keywordicate (car var))
                                               (car var)))
                                  ;; MNA: non-self-eval-keyword patch
                                 `((,key (get-key-arg1 ',keyword ,args-tail))
@@ -1026,7 +1026,7 @@ bootstrapping.
                                   (if (consp (car var))
                                       (values (caar var)
                                               (cadar var))
-                                      (values (make-keyword (car var))
+                                      (values (sb-int:keywordicate (car var))
                                               (car var)))
                                  ;; MNA: non-self-eval-keyword patch
                                 `((,key (get-key-arg1 ',keyword ,args-tail))
@@ -1313,14 +1313,13 @@ bootstrapping.
          (or mf (method-function-from-fast-function mff)))))))
 \f
 (defun analyze-lambda-list (lambda-list)
-  ;;(declare (values nrequired noptional keysp restp allow-other-keys-p
-  ;;            keywords keyword-parameters))
-  (flet ((parse-keyword-argument (arg)
+  (flet (;; FIXME: Is this redundant with SB-C::MAKE-KEYWORD-FOR-ARG?
+        (parse-keyword-argument (arg)
           (if (listp arg)
               (if (listp (car arg))
                   (caar arg)
-                  (make-keyword (car arg)))
-              (make-keyword arg))))
+                  (sb-int:keywordicate (car arg)))
+              (sb-int:keywordicate arg))))
     (let ((nrequired 0)
          (noptional 0)
          (keysp nil)
@@ -1354,7 +1353,7 @@ bootstrapping.
 (defun keyword-spec-name (x)
   (let ((key (if (atom x) x (car x))))
     (if (atom key)
-       (intern (symbol-name key) *keyword-package*)
+       (intern (symbol-name key) sb-int:*keyword-package*)
        (car key))))
 
 (defun ftype-declaration-from-lambda-list (lambda-list name)
index 4bc0854..d40141f 100644 (file)
 ;;; be resolved by renaming SB-INT:ITERATE to SB-INT:NAMED-LET, or
 ;;; with more gruntwork by punting the SB-ITERATE package and
 ;;; replacing calls to SB-ITERATE:ITERATE with calls to CL:LOOP.
+;;; So perhaps:
+;;;   * Do some sort of automated check for overlap of symbols to make
+;;;     sure there wouldn't be any other clashes.
+;;;   * Rename SB-INT:ITERATE to SB-INT:NAMED-LET.
+;;;   * Make SB-PCL use SB-INT and SB-EXT.
+;;;   * Grep for SB-INT: and SB-EXT: prefixes in the pcl/ directory
+;;;     and delete them.
 
 ;;; The caching algorithm implemented:
 ;;;
index ceb778c..ed88c23 100644 (file)
       (when (and (consp form) (eq (car form) name))
        (return-from get-declaration (cdr form))))))
 
-;;; FIXME: This duplicates SB-EXT:*KEYWORD-PACKAGE*.
-(defvar *keyword-package* (find-package 'keyword))
-
-;;; FIXME: This duplicates some of the functionality of SB-EXT:KEYWORDICATE.
-(defun make-keyword (symbol)
-  (intern (symbol-name symbol) *keyword-package*))
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
-
-(defun string-append (&rest strings)
-  (setq strings (copy-list strings))           ;The TI Explorer can't even
-                                               ;RPLACA a &REST arg?
-  (do ((string-loc strings (cdr string-loc)))
-      ((null string-loc)
-       (apply #'concatenate 'string strings))
-    (rplaca string-loc (string (car string-loc)))))
-
-) ; EVAL-WHEN
-
-(defun symbol-append (sym1 sym2 &optional (package *package*))
-  (intern (string-append sym1 sym2) package))
-
 (defmacro collecting-once (&key initial-value)
    `(let* ((head ,initial-value)
           (tail ,(and initial-value `(last head))))
        (loop (when (null .plist-tail.) (return nil))
             (setq ,key (pop .plist-tail.))
             (when (null .plist-tail.)
-              (error "malformed plist in doplist, odd number of elements"))
+              (error "malformed plist, odd number of elements"))
             (setq ,val (pop .plist-tail.))
             (progn ,@bod)))))
 
index d34e346..ddb93ae 100644 (file)
     (+ i f)))
 (assert (= (exercise-valuesify 1.25) 2.25))
 
+;;; A bug inherited from CMU CL screwed up special variable bindings
+;;; inside closures. This was fixed in sbcl-0.6.8.10 by applying the
+;;; patches Douglas Crosher posted to cmucl-imp@cons.org 2000-03-10
+;;; (split across two different messages).
+;;; FIXME: I'd like to find a test case for this..
+
 (sb-ext:quit :unix-status 104) ; success
index 9bf9840..ef9a29e 100644 (file)
@@ -15,4 +15,4 @@
 ;;; versions, and a string like "0.6.5.12" is used for versions which
 ;;; aren't released but correspond only to CVS tags or snapshots.
 
-"0.6.8.9"
+"0.6.8.10"