0.7.9.29:
[sbcl.git] / src / code / array.lisp
index f3ee81b..10f81e8 100644 (file)
 
 ;;; These functions are only needed by the interpreter, 'cause the
 ;;; compiler inlines them.
-(macrolet ((def-frob (name)
+(macrolet ((def (name)
             `(progn
                (defun ,name (array)
                  (,name array))
                (defun (setf ,name) (value array)
                  (setf (,name array) value)))))
-  (def-frob %array-fill-pointer)
-  (def-frob %array-fill-pointer-p)
-  (def-frob %array-available-elements)
-  (def-frob %array-data-vector)
-  (def-frob %array-displacement)
-  (def-frob %array-displaced-p))
+  (def %array-fill-pointer)
+  (def %array-fill-pointer-p)
+  (def %array-available-elements)
+  (def %array-data-vector)
+  (def %array-displacement)
+  (def %array-displaced-p))
 
 (defun %array-rank (array)
   (%array-rank array))
           (fixnum index))
   (%check-bound array bound index))
 
-;;; the guts of the WITH-ARRAY-DATA macro (except when DEFTRANSFORM
-;;; %WITH-ARRAY-DATA takes over)
 (defun %with-array-data (array start end)
-  (declare (array array) (type index start) (type (or index null) end))
-  ;; FIXME: The VALUES declaration here is correct, but as of SBCL
-  ;; 0.6.6, the corresponding runtime assertion is implemented
-  ;; horribly inefficiently, with a full call to %TYPEP for every
-  ;; call to this function. As a quick fix, I commented it out,
-  ;; but the proper fix would be to fix up type checking.
-  ;;
-  ;; A simpler test case for the optimization bug is
-  ;;   (DEFUN FOO (X)
-  ;;     (DECLARE (TYPE INDEXOID X))
-  ;;     (THE (VALUES INDEXOID)
-  ;;       (VALUES X)))
-  ;; which also compiles to a full call to %TYPEP.
-  #+nil (declare (values (simple-array * (*)) index index index))
-  (let* ((size (array-total-size array))
-        (end (cond (end
-                    (unless (<= end size)
-                      (error "End ~D is greater than total size ~D."
-                             end size))
-                    end)
-                   (t size))))
-    (when (> start end)
-      (error "Start ~D is greater than end ~D." start end))
-    (do ((data array (%array-data-vector data))
-        (cumulative-offset 0
-                           (+ cumulative-offset
-                              (%array-displacement data))))
-       ((not (array-header-p data))
-        (values (the (simple-array * (*)) data)
-                (the index (+ cumulative-offset start))
-                (the index (+ cumulative-offset end))
-                (the index cumulative-offset)))
-      (declare (type index cumulative-offset)))))
+  (%with-array-data-macro array start end :fail-inline? t))
+
+(defun %data-vector-and-index (array index)
+  (if (array-header-p array)
+      (%with-array-data array index nil)
+      (values array index)))
+
+;;; It'd waste space to expand copies of error handling in every
+;;; inline %WITH-ARRAY-DATA, so we have them call this function
+;;; instead. This is just a wrapper which is known never to return.
+(defun failed-%with-array-data (array start end)
+  (declare (notinline %with-array-data))
+  (%with-array-data array start end)
+  (bug "called FAILED-%WITH-ARRAY-DATA with valid array parameters?"))
 \f
 ;;;; MAKE-ARRAY
 
 (eval-when (:compile-toplevel :execute)
-  (sb!xc:defmacro pick-type (type &rest specs)
-    `(cond ,@(mapcar #'(lambda (spec)
-                        `(,(if (eq (car spec) t)
+  (sb!xc:defmacro pick-vector-type (type &rest specs)
+    `(cond ,@(mapcar (lambda (spec)
+                      `(,(if (eq (car spec) t)
                              t
                              `(subtypep ,type ',(car spec)))
-                          ,@(cdr spec)))
+                        ,@(cdr spec)))
                     specs))))
 
 ;;; These functions are used in the implementation of MAKE-ARRAY for
 ;;; MAKE-ARRAY for any non-simple array. Thus, there's some value to
 ;;; making this somewhat efficient, at least not doing full calls to
 ;;; SUBTYPEP in the easy cases.
-(defun %vector-type-code (type)
+(defun %vector-widetag-and-n-bits (type)
   (case type
     ;; Pick off some easy common cases.
     ;;
     ;; on smarter compiler transforms which do the calculation once
     ;; and for all in any reasonable user programs.)
     ((t)
-     (values #.sb!vm:simple-vector-type #.sb!vm:word-bits))
-    ((character base-char)
-     (values #.sb!vm:simple-string-type #.sb!vm:byte-bits))
+     (values #.sb!vm:simple-vector-widetag #.sb!vm:n-word-bits))
+    ((character base-char standard-char)
+     (values #.sb!vm:simple-string-widetag #.sb!vm:n-byte-bits))
     ((bit)
-     (values #.sb!vm:simple-bit-vector-type 1))
+     (values #.sb!vm:simple-bit-vector-widetag 1))
     ;; OK, we have to wade into SUBTYPEPing after all.
     (t
-     (pick-type type
-       (base-char (values #.sb!vm:simple-string-type #.sb!vm:byte-bits))
-       (bit (values #.sb!vm:simple-bit-vector-type 1))
+     ;; FIXME: The data here are redundant with
+     ;; *SPECIALIZED-ARRAY-ELEMENT-TYPE-PROPERTIES*.
+     (pick-vector-type type
+       (base-char (values #.sb!vm:simple-string-widetag #.sb!vm:n-byte-bits))
+       (bit (values #.sb!vm:simple-bit-vector-widetag 1))
        ((unsigned-byte 2)
-       (values #.sb!vm:simple-array-unsigned-byte-2-type 2))
+       (values #.sb!vm:simple-array-unsigned-byte-2-widetag 2))
        ((unsigned-byte 4)
-       (values #.sb!vm:simple-array-unsigned-byte-4-type 4))
+       (values #.sb!vm:simple-array-unsigned-byte-4-widetag 4))
        ((unsigned-byte 8)
-       (values #.sb!vm:simple-array-unsigned-byte-8-type 8))
+       (values #.sb!vm:simple-array-unsigned-byte-8-widetag 8))
        ((unsigned-byte 16)
-       (values #.sb!vm:simple-array-unsigned-byte-16-type 16))
+       (values #.sb!vm:simple-array-unsigned-byte-16-widetag 16))
        ((unsigned-byte 32)
-       (values #.sb!vm:simple-array-unsigned-byte-32-type 32))
+       (values #.sb!vm:simple-array-unsigned-byte-32-widetag 32))
        ((signed-byte 8)
-       (values #.sb!vm:simple-array-signed-byte-8-type 8))
+       (values #.sb!vm:simple-array-signed-byte-8-widetag 8))
        ((signed-byte 16)
-       (values #.sb!vm:simple-array-signed-byte-16-type 16))
+       (values #.sb!vm:simple-array-signed-byte-16-widetag 16))
        ((signed-byte 30)
-       (values #.sb!vm:simple-array-signed-byte-30-type 32))
+       (values #.sb!vm:simple-array-signed-byte-30-widetag 32))
        ((signed-byte 32)
-       (values #.sb!vm:simple-array-signed-byte-32-type 32))
-       (single-float (values #.sb!vm:simple-array-single-float-type 32))
-       (double-float (values #.sb!vm:simple-array-double-float-type 64))
+       (values #.sb!vm:simple-array-signed-byte-32-widetag 32))
+       (single-float (values #.sb!vm:simple-array-single-float-widetag 32))
+       (double-float (values #.sb!vm:simple-array-double-float-widetag 64))
        #!+long-float
        (long-float
-       (values #.sb!vm:simple-array-long-float-type #!+x86 96 #!+sparc 128))
+       (values #.sb!vm:simple-array-long-float-widetag
+               #!+x86 96 #!+sparc 128))
        ((complex single-float)
-       (values #.sb!vm:simple-array-complex-single-float-type 64))
+       (values #.sb!vm:simple-array-complex-single-float-widetag 64))
        ((complex double-float)
-       (values #.sb!vm:simple-array-complex-double-float-type 128))
+       (values #.sb!vm:simple-array-complex-double-float-widetag 128))
        #!+long-float
        ((complex long-float)
-       (values #.sb!vm:simple-array-complex-long-float-type
+       (values #.sb!vm:simple-array-complex-long-float-widetag
                #!+x86 192
                #!+sparc 256))
-       (t (values #.sb!vm:simple-vector-type #.sb!vm:word-bits))))))
-(defun %complex-vector-type-code (type)
+       (t (values #.sb!vm:simple-vector-widetag #.sb!vm:n-word-bits))))))
+(defun %complex-vector-widetag (type)
   (case type
     ;; Pick off some easy common cases.
     ((t)
-     #.sb!vm:complex-vector-type)
+     #.sb!vm:complex-vector-widetag)
     ((character base-char)
-     #.sb!vm:complex-string-type) 
+     #.sb!vm:complex-string-widetag) 
     ((bit)
-     #.sb!vm:complex-bit-vector-type)
+     #.sb!vm:complex-bit-vector-widetag)
     ;; OK, we have to wade into SUBTYPEPing after all.
     (t
-     (pick-type type
-       (base-char #.sb!vm:complex-string-type)
-       (bit #.sb!vm:complex-bit-vector-type)
-       (t #.sb!vm:complex-vector-type)))))
+     (pick-vector-type type
+       (base-char #.sb!vm:complex-string-widetag)
+       (bit #.sb!vm:complex-bit-vector-widetag)
+       (t #.sb!vm:complex-vector-widetag)))))
 
 (defun make-array (dimensions &key
                              (element-type t)
       (error "can't specify :DISPLACED-INDEX-OFFSET without :DISPLACED-TO"))
     (if (and simple (= array-rank 1))
        ;; Its a (simple-array * (*))
-       (multiple-value-bind (type bits) (%vector-type-code element-type)
+       (multiple-value-bind (type n-bits)
+           (%vector-widetag-and-n-bits element-type)
          (declare (type (unsigned-byte 8) type)
-                  (type (integer 1 256) bits))
+                  (type (integer 1 256) n-bits))
          (let* ((length (car dimensions))
                 (array (allocate-vector
                         type
                         length
-                        (ceiling (* (if (= type sb!vm:simple-string-type)
+                        (ceiling (* (if (= type sb!vm:simple-string-widetag)
                                         (1+ length)
                                         length)
-                                    bits)
-                                 sb!vm:word-bits))))
+                                    n-bits)
+                                 sb!vm:n-word-bits))))
            (declare (type index length))
            (when initial-element-p
              (fill array initial-element))
                (error "can't specify both :INITIAL-ELEMENT and ~
                :INITIAL-CONTENTS"))
              (unless (= length (length initial-contents))
-               (error "There are ~D elements in the :INITIAL-CONTENTS, but ~
-                      the vector length is ~D."
+               (error "There are ~W elements in the :INITIAL-CONTENTS, but ~
+                      the vector length is ~W."
                       (length initial-contents)
                       length))
              (replace array initial-contents))
                          initial-contents initial-element initial-element-p)))
               (array (make-array-header
                       (cond ((= array-rank 1)
-                             (%complex-vector-type-code element-type))
-                            (simple sb!vm:simple-array-type)
-                            (t sb!vm:complex-array-type))
+                             (%complex-vector-widetag element-type))
+                            (simple sb!vm:simple-array-widetag)
+                            (t sb!vm:complex-array-widetag))
                       array-rank)))
          (cond (fill-pointer
                 (unless (= array-rank 1)
                            (unless (and (fixnump fill-pointer)
                                         (>= fill-pointer 0)
                                         (<= fill-pointer length))
-                                   (error "invalid fill-pointer ~D"
-                                          fill-pointer))
+                             ;; FIXME: should be TYPE-ERROR?
+                             (error "invalid fill-pointer ~W"
+                                    fill-pointer))
                            fill-pointer))))
                 (setf (%array-fill-pointer-p array) t))
                (t
                     (t
                      (unless (typep contents 'sequence)
                        (error "malformed :INITIAL-CONTENTS: ~S is not a ~
-                               sequence, but ~D more layer~:P needed."
+                               sequence, but ~W more layer~:P needed."
                               contents
                               (- (length dimensions) axis)))
                      (unless (= (length contents) (car dims))
                        (error "malformed :INITIAL-CONTENTS: Dimension of ~
-                               axis ~D is ~D, but ~S is ~D long."
+                               axis ~W is ~W, but ~S is ~W long."
                               axis (car dims) contents (length contents)))
                      (if (listp contents)
                          (dolist (content contents)
     
 (defun hairy-data-vector-ref (array index)
   (with-array-data ((vector array) (index index) (end))
-    (declare (ignore end) (optimize (safety 3)))
+    (declare (ignore end))
     (etypecase vector .
               #.(mapcar (lambda (type)
                           (let ((atype `(simple-array ,type (*))))
                                                index))))
                         *specialized-array-element-types*))))
 
+;;; (Ordinary DATA-VECTOR-REF usage compiles into a vop, but
+;;; DATA-VECTOR-REF is also FOLDABLE, and this ordinary function
+;;; definition is needed for the compiler to use in constant folding.)
+(defun data-vector-ref (array index)
+  (hairy-data-vector-ref array index))
+
 (defun hairy-data-vector-set (array index new-value)
   (with-array-data ((vector array) (index index) (end))
-    (declare (ignore end) (optimize (safety 3)))
+    (declare (ignore end))
     (etypecase vector .
               #.(mapcar (lambda (type)
                           (let ((atype `(simple-array ,type (*))))
                               (data-vector-set (the ,atype vector)
                                                index
                                                (the ,type
-                                                 new-value)))))
+                                                 new-value))
+                              ;; For specialized arrays, the return
+                              ;; from data-vector-set would have to
+                              ;; be reboxed to be a (Lisp) return
+                              ;; value; instead, we use the
+                              ;; already-boxed value as the return.
+                              new-value)))
                         *specialized-array-element-types*))))
 
 (defun %array-row-major-index (array subscripts
           (list subscripts))
   (let ((rank (array-rank array)))
     (unless (= rank (length subscripts))
-      (error "wrong number of subscripts, ~D, for array of rank ~D"
+      (error "wrong number of subscripts, ~W, for array of rank ~W"
             (length subscripts) rank))
     (if (array-header-p array)
        (do ((subs (nreverse subscripts) (cdr subs))
            (declare (fixnum index dim))
            (unless (< -1 index dim)
              (if invalid-index-error-p
-                 (error "invalid index ~D~[~;~:; on axis ~:*~D~] in ~S"
-                        index axis array)
+                 (error 'simple-type-error
+                        :format-control "invalid index ~W~[~;~:; on axis ~:*~W~] in ~S"
+                        :format-arguments (list index axis array)
+                        :datum index
+                        :expected-type `(integer 0 (,dim)))
                  (return-from %array-row-major-index nil)))
            (incf result (* chunk-size index))
            (setf chunk-size (* chunk-size dim))))
-       (let ((index (first subscripts)))
-         (unless (< -1 index (length (the (simple-array * (*)) array)))
+       (let ((index (first subscripts))
+             (length (length (the (simple-array * (*)) array))))
+         (unless (< -1 index length)
            (if invalid-index-error-p
-               (error "invalid index ~D in ~S" index array)
+               ;; FIXME: perhaps this should share a format-string
+               ;; with INVALID-ARRAY-INDEX-ERROR or
+               ;; INDEX-TOO-LARGE-ERROR?
+               (error 'simple-type-error
+                      :format-control "invalid index ~W in ~S"
+                      :format-arguments (list index array)
+                      :datum index
+                      :expected-type `(integer 0 (,length)))
                (return-from %array-row-major-index nil)))
          index))))
 
 (defun array-in-bounds-p (array &rest subscripts)
   #!+sb-doc
-  "Returns T if the Subscipts are in bounds for the Array, Nil otherwise."
+  "Return T if the Subscipts are in bounds for the Array, Nil otherwise."
   (if (%array-row-major-index array subscripts nil)
       t))
 
 
 (defun aref (array &rest subscripts)
   #!+sb-doc
-  "Returns the element of the Array specified by the Subscripts."
+  "Return the element of the Array specified by the Subscripts."
   (row-major-aref array (%array-row-major-index array subscripts)))
 
 (defun %aset (array &rest stuff)
 
 (defun row-major-aref (array index)
   #!+sb-doc
-  "Returns the element of array corressponding to the row-major index. This is
+  "Return the element of array corressponding to the row-major index. This is
    SETF'able."
   (declare (optimize (safety 1)))
   (row-major-aref array index))
 
 (defun svref (simple-vector index)
   #!+sb-doc
-  "Returns the Index'th element of the given Simple-Vector."
+  "Return the INDEX'th element of the given Simple-Vector."
   (declare (optimize (safety 1)))
   (aref simple-vector index))
 
 
 (defun bit (bit-array &rest subscripts)
   #!+sb-doc
-  "Returns the bit from the Bit-Array at the specified Subscripts."
+  "Return the bit from the BIT-ARRAY at the specified SUBSCRIPTS."
   (declare (type (array bit) bit-array) (optimize (safety 1)))
   (row-major-aref bit-array (%array-row-major-index bit-array subscripts)))
 
 
 (defun sbit (simple-bit-array &rest subscripts)
   #!+sb-doc
-  "Returns the bit from the Simple-Bit-Array at the specified Subscripts."
+  "Return the bit from SIMPLE-BIT-ARRAY at the specified SUBSCRIPTS."
   (declare (type (simple-array bit) simple-bit-array) (optimize (safety 1)))
   (row-major-aref simple-bit-array
                  (%array-row-major-index simple-bit-array subscripts)))
 
 (defun array-element-type (array)
   #!+sb-doc
-  "Returns the type of the elements of the array"
-  (let ((type (get-type array)))
+  "Return the type of the elements of the array"
+  (let ((widetag (widetag-of array)))
     (macrolet ((pick-element-type (&rest stuff)
-                `(cond ,@(mapcar #'(lambda (stuff)
-                                     (cons
-                                      (let ((item (car stuff)))
-                                        (cond ((eq item t)
-                                               t)
-                                              ((listp item)
-                                               (cons 'or
-                                                     (mapcar #'(lambda (x)
-                                                                 `(= type ,x))
-                                                             item)))
-                                              (t
-                                               `(= type ,item))))
-                                      (cdr stuff)))
-                                                  stuff))))
+                `(cond ,@(mapcar (lambda (stuff)
+                                   (cons
+                                    (let ((item (car stuff)))
+                                      (cond ((eq item t)
+                                             t)
+                                            ((listp item)
+                                             (cons 'or
+                                                   (mapcar (lambda (x)
+                                                             `(= widetag ,x))
+                                                           item)))
+                                            (t
+                                             `(= widetag ,item))))
+                                    (cdr stuff)))
+                                 stuff))))
+      ;; FIXME: The data here are redundant with
+      ;; *SPECIALIZED-ARRAY-ELEMENT-TYPE-PROPERTIES*.
       (pick-element-type
-       ((sb!vm:simple-string-type sb!vm:complex-string-type) 'base-char)
-       ((sb!vm:simple-bit-vector-type sb!vm:complex-bit-vector-type) 'bit)
-       (sb!vm:simple-vector-type t)
-       (sb!vm:simple-array-unsigned-byte-2-type '(unsigned-byte 2))
-       (sb!vm:simple-array-unsigned-byte-4-type '(unsigned-byte 4))
-       (sb!vm:simple-array-unsigned-byte-8-type '(unsigned-byte 8))
-       (sb!vm:simple-array-unsigned-byte-16-type '(unsigned-byte 16))
-       (sb!vm:simple-array-unsigned-byte-32-type '(unsigned-byte 32))
-       (sb!vm:simple-array-signed-byte-8-type '(signed-byte 8))
-       (sb!vm:simple-array-signed-byte-16-type '(signed-byte 16))
-       (sb!vm:simple-array-signed-byte-30-type '(signed-byte 30))
-       (sb!vm:simple-array-signed-byte-32-type '(signed-byte 32))
-       (sb!vm:simple-array-single-float-type 'single-float)
-       (sb!vm:simple-array-double-float-type 'double-float)
+       ((sb!vm:simple-string-widetag sb!vm:complex-string-widetag) 'base-char)
+       ((sb!vm:simple-bit-vector-widetag
+        sb!vm:complex-bit-vector-widetag) 'bit)
+       (sb!vm:simple-vector-widetag t)
+       (sb!vm:simple-array-unsigned-byte-2-widetag '(unsigned-byte 2))
+       (sb!vm:simple-array-unsigned-byte-4-widetag '(unsigned-byte 4))
+       (sb!vm:simple-array-unsigned-byte-8-widetag '(unsigned-byte 8))
+       (sb!vm:simple-array-unsigned-byte-16-widetag '(unsigned-byte 16))
+       (sb!vm:simple-array-unsigned-byte-32-widetag '(unsigned-byte 32))
+       (sb!vm:simple-array-signed-byte-8-widetag '(signed-byte 8))
+       (sb!vm:simple-array-signed-byte-16-widetag '(signed-byte 16))
+       (sb!vm:simple-array-signed-byte-30-widetag '(signed-byte 30))
+       (sb!vm:simple-array-signed-byte-32-widetag '(signed-byte 32))
+       (sb!vm:simple-array-single-float-widetag 'single-float)
+       (sb!vm:simple-array-double-float-widetag 'double-float)
        #!+long-float
-       (sb!vm:simple-array-long-float-type 'long-float)
-       (sb!vm:simple-array-complex-single-float-type '(complex single-float))
-       (sb!vm:simple-array-complex-double-float-type '(complex double-float))
+       (sb!vm:simple-array-long-float-widetag 'long-float)
+       (sb!vm:simple-array-complex-single-float-widetag
+       '(complex single-float))
+       (sb!vm:simple-array-complex-double-float-widetag
+       '(complex double-float))
        #!+long-float
-       (sb!vm:simple-array-complex-long-float-type '(complex long-float))
-       ((sb!vm:simple-array-type sb!vm:complex-vector-type
-                                sb!vm:complex-array-type)
+       (sb!vm:simple-array-complex-long-float-widetag '(complex long-float))
+       ((sb!vm:simple-array-widetag
+        sb!vm:complex-vector-widetag
+        sb!vm:complex-array-widetag)
        (with-array-data ((array array) (start) (end))
          (declare (ignore start end))
          (array-element-type array)))
        (t
-       (error "~S is not an array." array))))))
+       (error 'type-error :datum array :expected-type 'array))))))
 
 (defun array-rank (array)
   #!+sb-doc
 
 (defun array-dimension (array axis-number)
   #!+sb-doc
-  "Returns the length of dimension AXIS-NUMBER of ARRAY."
+  "Return the length of dimension AXIS-NUMBER of ARRAY."
   (declare (array array) (type index axis-number))
   (cond ((not (array-header-p array))
         (unless (= axis-number 0)
           (error "Vector axis is not zero: ~S" axis-number))
         (length (the (simple-array * (*)) array)))
        ((>= axis-number (%array-rank array))
-        (error "~D is too big; ~S only has ~D dimension~:P."
+        (error "Axis number ~W is too big; ~S only has ~D dimension~:P."
                axis-number array (%array-rank array)))
        (t
         (%array-dimension array axis-number))))
             :format-control "~S is not an array with a fill pointer."
             :format-arguments (list vector))))
 
+;;; FIXME: It'd probably make sense to use a MACROLET to share the
+;;; guts of VECTOR-PUSH between VECTOR-PUSH-EXTEND. Such a macro
+;;; should probably be based on the VECTOR-PUSH-EXTEND code (which is
+;;; new ca. sbcl-0.7.0) rather than the VECTOR-PUSH code (which dates
+;;; back to CMU CL).
 (defun vector-push (new-el array)
   #!+sb-doc
   "Attempt to set the element of ARRAY designated by its fill pointer
                           vector
                           &optional
                           (extension (1+ (length vector))))
-  #!+sb-doc
-  "This is like Vector-Push except that if the fill pointer gets too
-   large, the Vector is extended rather than Nil being returned."
   (declare (vector vector) (fixnum extension))
   (let ((fill-pointer (fill-pointer vector)))
     (declare (fixnum fill-pointer))
 
 (defun vector-pop (array)
   #!+sb-doc
-  "Attempts to decrease the fill pointer by 1 and return the element
-   pointer to by the new fill pointer. If the original value of the fill
-   pointer is 0, an error occurs."
+  "Decrease the fill pointer by 1 and return the element pointed to by the
+  new fill pointer."
   (declare (vector array))
   (let ((fill-pointer (fill-pointer array)))
     (declare (fixnum fill-pointer))
                           initial-contents fill-pointer
                           displaced-to displaced-index-offset)
   #!+sb-doc
-  "Adjusts the Array's dimensions to the given Dimensions and stuff."
+  "Adjust ARRAY's dimensions to the given DIMENSIONS and stuff."
   (let ((dimensions (if (listp dimensions) dimensions (list dimensions))))
     (cond ((/= (the fixnum (length (the list dimensions)))
               (the fixnum (array-rank array)))
   (unless (array-header-p vector)
     (macrolet ((frob (name &rest things)
                 `(etypecase ,name
-                   ,@(mapcar #'(lambda (thing)
-                                 `(,(car thing)
-                                   (fill (truly-the ,(car thing) ,name)
-                                         ,(cadr thing)
-                                         :start new-length)))
+                   ,@(mapcar (lambda (thing)
+                               (destructuring-bind (type-spec fill-value)
+                                   thing
+                                 `(,type-spec
+                                   (fill (truly-the ,type-spec ,name)
+                                         ,fill-value
+                                         :start new-length))))
                              things))))
+      ;; FIXME: The associations between vector types and initial
+      ;; values here are redundant with
+      ;; *SPECIALIZED-ARRAY-ELEMENT-TYPE-PROPERTIES*.
       (frob vector
        (simple-vector 0)
-       (simple-base-string #.default-init-char)
+       (simple-base-string #.*default-init-char-form*)
        (simple-bit-vector 0)
        ((simple-array (unsigned-byte 2) (*)) 0)
        ((simple-array (unsigned-byte 4) (*)) 0)
 
 (defun zap-array-data-aux (old-data old-dims offset new-data new-dims)
   (declare (fixnum offset))
-  (let ((limits (mapcar #'(lambda (x y)
-                           (declare (fixnum x y))
-                           (1- (the fixnum (min x y))))
+  (let ((limits (mapcar (lambda (x y)
+                         (declare (fixnum x y))
+                         (1- (the fixnum (min x y))))
                        old-dims new-dims)))
     (macrolet ((bump-index-list (index limits)
                 `(do ((subscripts ,index (cdr subscripts))