[fset-ticket] Unexpected behaviour of SEQ class

thomas.bartscher@googlemail.com thomas.bartscher at gmail.com
Mon Nov 12 12:22:27 UTC 2012


The documentation says
"A seq can hold character strings interspersed with occasional
non-characters quite efficiently; each non-character will force only one
leaf vector to be a non-string. (Similarly, a seq can hold strings of
base-chars interspersed with the occasional extended-char quite
efficiently.)"
The problem is that the following code fails nevertheless:

(defun test ()
  (let* ((seq (seq 1 #\a))
     (str-seq (seq #\a))
     (seq2 (subseq seq 1)))
    (format t "(equal str-seq seq2) => ~A~%"
        (equal? str-seq seq2))
    (format t "(format nil \"...\" (convert 'string str-seq)) => ~A~%"
        (format nil "~A"
            (convert 'string str-seq)))
    (format t "(format nil \"...\" (convert 'string seq2)) => ~A~%"
        (format nil "~A"
            (convert 'string seq2)))))

This is because the contents of the SEQ sequence are stored as a vector
with element-type T, SUBSEQ on SEQ doesn't change the vector into a string
and (CONVERT 'STRING ...) checks whether the contents of any SEQ are stored
as a string and returns an error otherwise.
The resulting error message isn't very helpful either:

The value NIL is not of type CHARACTER.
   [Condition of type TYPE-ERROR]

I forgot where the NIL comes from but this isn't obviously connected to the
invocation of (CONVERT 'STRING ...) on SEQ in any way. It get's even worse
because SEQ doesn't contain NIL anywhere.

I don't know much about optimization so I am reluctant in trying to write a
fix.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/fset-ticket/attachments/20121112/424ae804/attachment.html>


More information about the Fset-ticket mailing list