
Pascal Costanza <pc@p-cos.net> writes:
On 6 Dec 2006, at 11:12, Christophe Rhodes wrote:
[ I think I basically agree with you; some comments below ]
Pascal Costanza <pc@p-cos.net> writes:
I think that an implementation providing a non-list non-vector sequence would have to document its behaviour, so it falls in the realm of language extension or implementation-defined behaviour.
OK, it's still the case that you are only relaxing the requirements, but you are not making it explicit what it means when some code it outside of the domain of lists and vectors. With the current ANSI CL spec, a conforming program can rely on the fact that the functions in the Sequence Dictionary always work as expected when the objects passed are of type sequence (!).
Up to a point. Depending on how carefully you read, you might find that in fact some or most of them are implicitly defined only on lists and vectors, in wording that is new since CLtL2 (and apparently editorial rather than decided upon in an issue).
OK, apparently my wording wasn't very clear. What I meant is this: Actually just because these functions are defined only on lists and vectors _and_ the only kinds of sequences you can create in ANSI CL are lists and vectors, everything is well-specified.
I didn't understand this from your post, and in fact I think this way of looking at things is in error. I believe that the majority of the functions in the Sequences chapter of ANSI CL are in fact specified to work on sequences, not on objects of type (or list vector): if you pass a sequence of whatever type to FIND, POSITION, COUNT, DELETE, REMOVE, SORT, SUBSTITUTE, and so on, then it should work as expected. The exceptions are: * MAKE-SEQUENCE, MERGE, MAP, COERCE and CONCATENATE. In this case, in fact, any sequence argument can be an arbitrary sequence; it is purely the _type specifier_ argument which must designate a subtype of list or a subtype of vector. It is this restriction on the type specifier that I am attempting to remove in CDR 3. * ELT, (SETF ELT) and LENGTH. As pointed out by Nikodemus, these functions formally accept a /proper sequence/, which the glossary defines as a proper list or a vector, and also as a sequence which is not an improper list. These two definitions are the same if sequence is just (or list vector), but I think the intent is clear in the case where there are more kinds of sequences, so I haven't worried about this case too much.
I am not sure whether implementations that adopt CDR 3 would still be conforming, though. The error terminology in ANSI CL implies that conforming programs can rely on the fact that sequence functions signal errors when they are passed what are neither lists nor vectors. With CDR 3, they cannot rely on this anymore.
But that's actually the whole point of CDR 3, as far as I understand it.
CDR 3 raises a single case where a program could tell the difference between a CDR-3-supporting implementation and a straight ANSI CL one: where a designator for a non-list non-vector sequence type is passed to the MAKE-SEQUENCE family of functions. However, this test case (as described in the document, or possibly only in my draft for an update; I reproduce it below[*]) only makes a difference in implementations which extend the sequence type: which is currently zero implementations, unless you count my experimental SBCL code. So, in that sense, yes, there is a distinction between CDR 3 and not, but it is not one that has arisen in practice until now. [*] In an implementation not supporting CDR 3, (assert (typep (ignore-errors (make-sequence *x* 8)) '(or list vector))) will never trigger the assertion, no matter what *X* is. In an implementation supporting CDR 3, the assertion /may/ be triggered if other elements of the implementation are so arranged: including allowing other sequence types. Cheers, Christophe