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.