0.7.8.47:
authorChristophe Rhodes <csr21@cam.ac.uk>
Sat, 19 Oct 2002 01:30:03 +0000 (01:30 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Sat, 19 Oct 2002 01:30:03 +0000 (01:30 +0000)
Fix CONCATENATE like MAKE-SEQUENCE/MERGE/COERCE
... but don't fix MAP, because it looks hard; write a BUG
entry instead

BUGS
src/code/seq.lisp
tests/seq.impure.lisp
version.lisp-expr

diff --git a/BUGS b/BUGS
index dd7758f..4f7bea2 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -1276,6 +1276,37 @@ WORKAROUND:
   c. Compiler should not warn on an unknown key :ALLOW-OTHER-KEYS.
   d. :ALLOW-OTHER-KEYS should be allowed as an ordinary key parameter.
 
+212: "Sequence functions and circular arguments"
+  COERCE, MERGE and CONCATENATE go into an infinite loop when given
+  circular arguments; it would be good for the user if they could be
+  given an error instead (ANSI 17.1.1 allows this behaviour on the part
+  of the implementation, as conforming code cannot give non-proper
+  sequences to these functions.  MAP also has this problem (and
+  solution), though arguably the convenience of being able to do 
+    (MAP 'LIST '+ FOO '#1=(1 . #1#)) 
+  might be classed as more important (though signalling an error when
+  all of the arguments are circular is probably desireable).
+
+213: "Sequence functions and type checking"
+  a. MAKE-SEQUENCE, COERCE, MERGE and CONCATENATE cannot deal with
+     various complicated, though recognizeable, CONS types [e.g. 
+       (CONS * (CONS * NULL))
+     which according to ANSI should be recognized] (and, in SAFETY 3
+     code, should return a list of LENGTH 2 or signal an error)
+  b. MAP, when given a type argument that is SUBTYPEP LIST, does not
+     check that it will return a sequence of the given type.  Fixing
+     it along the same lines as the others (cf. work done around
+     sbcl-0.7.8.45) is possible, but doing so efficiently didn't look
+     entirely straightforward.
+  c. All of these functions will silently accept a type of the form
+       (CONS INTEGER *)
+     whether or not the return value is of this type.  This is
+     probably permitted by ANSI (see "Exceptional Situations" under
+     ANSI MAKE-SEQUENCE), but the DERIVE-TYPE mechanism does not 
+     know about this escape clause, so code of the form
+       (INTEGERP (CAR (MAKE-SEQUENCE '(CONS INTEGER *) 2)))
+     can erroneously return T.
+
 DEFUNCT CATEGORIES OF BUGS
   IR1-#:
     These labels were used for bugs related to the old IR1 interpreter.
index 93bfa19..9446dc8 100644 (file)
   specified OUTPUT-TYPE-SPEC."
   (let ((type (specifier-type output-type-spec)))
   (cond
+    ((csubtypep type (specifier-type 'list))
+     (cond
+       ((type= type (specifier-type 'list))
+       (apply #'concat-to-list* sequences))
+       ((eq type *empty-type*)
+       (bad-sequence-type-error nil))
+       ((type= type (specifier-type 'null))
+       (if (every (lambda (x) (or (null x)
+                                  (and (vectorp x) (= (length x) 0))))
+                  sequences)
+           'nil
+           (sequence-type-length-mismatch-error type
+                                                ;; FIXME: circular
+                                                ;; list issues.  And
+                                                ;; rightward-drift.
+                                                (reduce #'+
+                                                        (mapcar #'length
+                                                                sequences)))))
+       ((csubtypep (specifier-type '(cons nil t)) type)
+       (if (notevery (lambda (x) (or (null x)
+                                     (and (vectorp x) (= (length x) 0))))
+                     sequences)
+           (apply #'concat-to-list* sequences)
+           (sequence-type-length-mismatch-error type 0)))
+       (t (sequence-type-too-hairy (type-specifier type)))))
     ((csubtypep type (specifier-type 'vector))
      (apply #'concat-to-simple* output-type-spec sequences))
-    ((csubtypep type (specifier-type 'list))
-     (apply #'concat-to-list* sequences))
     (t
      (bad-sequence-type-error output-type-spec)))))
 
index ec6e74f..dc5a6e3 100644 (file)
     ;; MAKE-SEQUENCE
     (assert-type-error (make-sequence 'cons 0))
     (assert-type-error (make-sequence 'null 1))
+    ;; KLUDGE: I'm not certain that this test actually tests for what
+    ;; it should test, in that the type deriver and optimizers might
+    ;; be too smart for the good of an exhaustive test system.
+    ;; However, it makes me feel good.  -- CSR, 2002-10-18
     (assert (null (make-sequence 'null 0)))
     (assert (= (length (make-sequence 'cons 3)) 3))
     ;; and NIL is not a valid type for MAKE-SEQUENCE
     (assert (null (merge 'null () () '<)))
     (assert (= (length (merge 'cons '(1 3) '(2 4) '<)) 4))
     (assert-type-error (merge 'nil () () '<))
-    ;; tests for MAP/CONCATENATE to come.
+    ;; CONCATENATE
+    (assert-type-error (concatenate 'null '(1) "2"))
+    (assert-type-error (concatenate 'cons #() ()))
+    (assert (null (concatenate 'null () #())))
+    (assert (= (length (concatenate 'cons #() '(1) "2 3")) 4))
+    (assert-type-error (concatenate 'nil '(3)))
+    ;; FIXME: tests for MAP to come when some brave soul implements
+    ;; the analogous type checking for MAP/%MAP.
     ))
-
-            
 \f
 ;;; success
 (quit :unix-status 104)
index 5f9e608..9b27384 100644 (file)
@@ -18,4 +18,4 @@
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
 
-"0.7.8.46"
+"0.7.8.47"