trivial extensible sequences
1.0.0Portability library for the extensible sequences protocol.
About
This package provides a portability layer for the extensible sequences standard extension to Common Lisp. Extensible sequences allow you to create your own sequence types that integrate with the rest of the functions and operations that interact with sequences.
The extensible sequences protocol is defined in 'User-extensible sequences in Common Lisp' by Christophe Rhodes[1]. Also see the SBCL manual. Please refer to the above documents as well as the sequence operations in the hyperspec for documentation.
How To
The basic operation is rather simple. All the functionality is defined in the org.shirakumo.trivial-extensible-sequences
package – you may want to use a package-local-nickname to alias it to sequences
.
First, create a subclass of sequence
. This will be your new sequence type. For this how-to, we'll define a sequence type that can represent any value as a sequence of length 1.
(defclass value-as-sequence (sequences:sequence)
((value :initarg :value :initform (error "VALUE required.") :accessor value)))
Then you should add methods on length
, elt
, (setf elt)
, adjust-sequence
and make-sequence-like
.
(defmethod sequences:length ((sequence value-as-sequence))
1)
(defmethod sequences:elt ((sequence value-as-sequence) index)
(check-type index (integer 0 0))
(value sequence))
(defmethod (setf sequences:elt) (value (sequence value-as-sequence) index)
(check-type index (integer 0 0))
(setf (value sequence) value))
(defmethod sequences:adjust-sequence ((sequence value-as-sequence) length &key initial-contents initial-element)
(check-type length (integer 1 1))
(when initial-contents
(setf (value sequence) (elt initial-contents 0)))
sequence)
(defmethod sequences:make-sequence-like ((sequence value-as-sequence) length &key initial-contents initial-element)
(check-type length (integer 1 1))
(make-instance 'value-as-sequence
:value (or (elt initial-contents 0) initial-element (value sequence))))
If you leave out any of these functions, some of the sequence operators will not work and will instead signal a protocol-unimplemented
error on use. If you do provide a method on each, then all the sequence operators should work out of the box using generic implementations. If you would like to speed up a particular operation for your sequence type, you can also define a specific implementation by adding a method to that function.
Also useful is to explicitly support the iterator protocol, which should allow most default operations to be performed much faster. To do so you only need to define a method on make-sequence-iterator
. This method should return 9 values:
An iteration state value.
A value describing the limit of iteration, if any.
The from-end value.
A step function of three arguments: the sequence, the state value, the from-end value. The function should return the new state value.
An end predicate of four arguments: the sequence, the state value, the limit value, the from-end value. The function should return a generalised boolean describing whether the iteration has reached the end of the sequence.
An element read function of two arguments: the sequence, the state value.
An element write function of three arguments: the new value to store, the sequence, the state value.
An index function of two arguments: the sequence, the state value. The function should return the current iteration index, starting from zero.
An iterator copy function of two arguments: the sequence, the state value. The function should return a "fresh" iteration value.
Here's what it might look like for our relatively useless example sequence type:
(defmethod sequences:make-sequence-iterator ((sequence value-as-sequence) &key start end from-end)
(values 0 1 from-end
(lambda (seq state from-end) (1+ state))
(lambda (seq state limit from-end) (< state limit))
(lambda (seq state) (value seq))
(lambda (value seq state) (setf (value seq) value))
(lambda (seq state) state)
(lambda (seq state) state)))
Obviously for more complicated sequences the functions and state could be more interesting than this. Note that you can use iterators more easily using with-sequence-iterator
, with-sequence-iterator-funcntions
, and dosequence
.
Implementation Support
The following implementations have native support for extensible sequences. On those implementations, this package will merely be an alias for the implementation's sequences package.
ABCL
SBCL
On any other implementation, this package provides a fallback implementation of the protocol. The protocol should work completely with the following caveats:
You must use the functions provided by this package to handle your sequences, rather than the ones from the
cl
package.Custom sequences defined with a subclass will not actually be a subtype of
cl:sequence
.The fallback protocol will be slower than what the implementation could provide.
Meaning you can still make things work most of the time, but with some heavy caveats. For this reason, please contact your implementation maintainers and request for the protocol to be implemented natively. The source code of the fallback implementation, as well as SBCL's own implementation are licensed liberally and should serve as a good basis.
System Information
Definition Index
-
ORG.SHIRAKUMO.TRIVIAL-EXTENSIBLE-SEQUENCES
No documentation provided.-
EXTERNAL CONDITION PROTOCOL-UNIMPLEMENTED
This error is signaled if a sequence operation is applied to an instance of a sequence class that does not support the operation.
-
EXTERNAL FUNCTION PROTOCOL-UNIMPLEMENTED
- OPERATION
- SEQUENCE
No documentation provided. -
EXTERNAL GENERIC-FUNCTION ADJUST-SEQUENCE
- SEQUENCE
- LENGTH
- &KEY
- INITIAL-ELEMENT
- INITIAL-CONTENTS
Return destructively modified SEQUENCE or a freshly allocated sequence of the same class as SEQUENCE of length LENGTH. Elements of the returned sequence are initialized to INITIAL-ELEMENT, if supplied, initialized to INITIAL-CONTENTS if supplied, or identical to the elements of SEQUENCE if neither is supplied. Signals a PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not implemented for the class of SEQUENCE.
-
EXTERNAL GENERIC-FUNCTION CONCATENATE
- RESULT-PROTOTYPE
- &REST
- SEQUENCES
Implements CL:CONCATENATE for extended sequences. RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:CONCATENATE but receives a prototype instance of an extended sequence class instead of a type specifier. By dispatching on RESULT-PROTOTYPE, methods on this generic function specify how extended sequence classes act when they are specified as the result type in a CL:CONCATENATE call. RESULT-PROTOTYPE may not be fully initialized and thus should only be used for dispatch and to determine its class.
-
EXTERNAL GENERIC-FUNCTION COPY-SEQ
- SEQUENCE
No documentation provided. -
EXTERNAL GENERIC-FUNCTION COUNT
- ITEM
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- TEST
- TEST-NOT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION COUNT-IF
- PRED
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION COUNT-IF-NOT
- PRED
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION DELETE
- ITEM
- SEQUENCE
- &KEY
- FROM-END
- TEST
- TEST-NOT
- START
- END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION DELETE-DUPLICATES
- SEQUENCE
- &KEY
- FROM-END
- TEST
- TEST-NOT
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION DELETE-IF
- PREDICATE
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION DELETE-IF-NOT
- PREDICATE
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION ELT
- SEQUENCE
- INDEX
Returns the element at position INDEX of SEQUENCE or signals a PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not implemented for the class of SEQUENCE.
-
EXTERNAL GENERIC-FUNCTION (SETF ELT)
- NEW-VALUE
- SEQUENCE
- INDEX
Replaces the element at position INDEX of SEQUENCE with NEW-VALUE and returns NEW-VALUE or signals a PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not implemented for the class of SEQUENCE.
-
EXTERNAL GENERIC-FUNCTION EMPTYP
- SEQUENCE
Returns T if SEQUENCE is an empty sequence and NIL otherwise. Signals an error if SEQUENCE is not a sequence.
-
EXTERNAL GENERIC-FUNCTION FILL
- SEQUENCE
- ITEM
- &KEY
- START
- END
No documentation provided. -
EXTERNAL GENERIC-FUNCTION FIND
- ITEM
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- TEST
- TEST-NOT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION FIND-IF
- PRED
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION FIND-IF-NOT
- PRED
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION ITERATOR-COPY
- SEQUENCE
- ITERATOR
Returns a copy of ITERATOR which also traverses SEQUENCE but can be mutated independently of ITERATOR.
-
EXTERNAL GENERIC-FUNCTION ITERATOR-ELEMENT
- SEQUENCE
- ITERATOR
Returns the element of SEQUENCE associated to the position of ITERATOR.
-
EXTERNAL GENERIC-FUNCTION (SETF ITERATOR-ELEMENT)
- NEW-VALUE
- SEQUENCE
- ITERATOR
Destructively modifies SEQUENCE by replacing the sequence element associated to position of ITERATOR with NEW-VALUE.
-
EXTERNAL GENERIC-FUNCTION ITERATOR-ENDP
- SEQUENCE
- ITERATOR
- LIMIT
- FROM-END
Returns non-NIL when ITERATOR has reached LIMIT (which may correspond to the end of SEQUENCE) with respect to the iteration direction encoded in FROM-END.
-
EXTERNAL GENERIC-FUNCTION ITERATOR-INDEX
- SEQUENCE
- ITERATOR
Returns the position of ITERATOR in SEQUENCE.
-
EXTERNAL GENERIC-FUNCTION ITERATOR-STEP
- SEQUENCE
- ITERATOR
- FROM-END
Moves ITERATOR one position forward or backward in SEQUENCE depending on the iteration direction encoded in FROM-END.
-
EXTERNAL GENERIC-FUNCTION LENGTH
- SEQUENCE
Returns the length of SEQUENCE or signals a PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not implemented for the class of SEQUENCE.
-
EXTERNAL GENERIC-FUNCTION MAKE-SEQUENCE-ITERATOR
- SEQUENCE
- &KEY
- FROM-END
- START
- END
Returns a sequence iterator for SEQUENCE or, if START and/or END are supplied, the subsequence bounded by START and END as nine values: 1. iterator state 2. limit 3. from-end 4. step function 5. endp function 6. element function 7. setf element function 8. index function 9. copy state function If FROM-END is NIL, the constructed iterator visits the specified elements in the order in which they appear in SEQUENCE. Otherwise, the elements are visited in the opposite order.
-
EXTERNAL GENERIC-FUNCTION MAKE-SEQUENCE-LIKE
- SEQUENCE
- LENGTH
- &KEY
- INITIAL-ELEMENT
- INITIAL-CONTENTS
Returns a freshly allocated sequence of length LENGTH and of the same class as SEQUENCE. Elements of the new sequence are initialized to INITIAL-ELEMENT, if supplied, initialized to INITIAL-CONTENTS if supplied, or identical to the elements of SEQUENCE if neither is supplied. Signals a PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not implemented for the class of SEQUENCE.
-
EXTERNAL GENERIC-FUNCTION MAKE-SIMPLE-SEQUENCE-ITERATOR
- SEQUENCE
- &KEY
- FROM-END
- START
- END
Returns a sequence iterator for SEQUENCE, START, END and FROM-END as three values: 1. iterator state 2. limit 3. from-end The returned iterator can be used with the generic iterator functions ITERATOR-STEP, ITERATOR-ENDP, ITERATOR-ELEMENT, (SETF ITERATOR-ELEMENT), ITERATOR-INDEX and ITERATOR-COPY.
-
EXTERNAL GENERIC-FUNCTION MAP
- RESULT-PROTOTYPE
- FUNCTION
- SEQUENCE
- &REST
- SEQUENCES
Implements CL:MAP for extended sequences. RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:MAP but receives a prototype instance of an extended sequence class instead of a type specifier. By dispatching on RESULT-PROTOTYPE, methods on this generic function specify how extended sequence classes act when they are specified as the result type in a CL:MAP call. RESULT-PROTOTYPE may not be fully initialized and thus should only be used for dispatch and to determine its class. Another difference to CL:MAP is that FUNCTION is a function, not a function designator.
-
EXTERNAL GENERIC-FUNCTION MERGE
- RESULT-PROTOTYPE
- SEQUENCE1
- SEQUENCE2
- PREDICATE
- &KEY
- KEY
Implements CL:MERGE for extended sequences. RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:MERGE but receives a prototype instance of an extended sequence class instead of a type specifier. By dispatching on RESULT-PROTOTYPE, methods on this generic function specify how extended sequence classes act when they are specified as the result type in a CL:MERGE call. RESULT-PROTOTYPE may not be fully initialized and thus should only be used for dispatch and to determine its class. Another difference to CL:MERGE is that PREDICATE is a function, not a function designator.
-
EXTERNAL GENERIC-FUNCTION MISMATCH
- SEQUENCE1
- SEQUENCE2
- &KEY
- FROM-END
- START1
- END1
- START2
- END2
- TEST
- TEST-NOT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION NREVERSE
- SEQUENCE
No documentation provided. -
EXTERNAL GENERIC-FUNCTION NSUBSTITUTE
- NEW
- OLD
- SEQUENCE
- &KEY
- START
- END
- FROM-END
- TEST
- TEST-NOT
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION NSUBSTITUTE-IF
- NEW
- PREDICATE
- SEQUENCE
- &KEY
- START
- END
- FROM-END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION NSUBSTITUTE-IF-NOT
- NEW
- PREDICATE
- SEQUENCE
- &KEY
- START
- END
- FROM-END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION POSITION
- ITEM
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- TEST
- TEST-NOT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION POSITION-IF
- PRED
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION POSITION-IF-NOT
- PRED
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION PROTOCOL-UNIMPLEMENTED-OPERATION
- CONDITION
No documentation provided. -
EXTERNAL GENERIC-FUNCTION REDUCE
- FUNCTION
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- INITIAL-VALUE
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION REMOVE
- ITEM
- SEQUENCE
- &KEY
- FROM-END
- TEST
- TEST-NOT
- START
- END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION REMOVE-DUPLICATES
- SEQUENCE
- &KEY
- FROM-END
- TEST
- TEST-NOT
- START
- END
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION REMOVE-IF
- PREDICATE
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION REMOVE-IF-NOT
- PREDICATE
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION REPLACE
- SEQUENCE1
- SEQUENCE2
- &KEY
- START1
- END1
- START2
- END2
No documentation provided. -
EXTERNAL GENERIC-FUNCTION REVERSE
- SEQUENCE
No documentation provided. -
EXTERNAL GENERIC-FUNCTION SEARCH
- SEQUENCE1
- SEQUENCE2
- &KEY
- FROM-END
- START1
- END1
- START2
- END2
- TEST
- TEST-NOT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION SORT
- SEQUENCE
- PREDICATE
- &KEY
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION STABLE-SORT
- SEQUENCE
- PREDICATE
- &KEY
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION SUBSEQ
- SEQUENCE
- START
- &OPTIONAL
- END
No documentation provided. -
EXTERNAL GENERIC-FUNCTION SUBSTITUTE
- NEW
- OLD
- SEQUENCE
- &KEY
- START
- END
- FROM-END
- TEST
- TEST-NOT
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION SUBSTITUTE-IF
- NEW
- PREDICATE
- SEQUENCE
- &KEY
- START
- END
- FROM-END
- COUNT
- KEY
No documentation provided. -
EXTERNAL GENERIC-FUNCTION SUBSTITUTE-IF-NOT
- NEW
- PREDICATE
- SEQUENCE
- &KEY
- START
- END
- FROM-END
- COUNT
- KEY
No documentation provided. -
EXTERNAL MACRO DOSEQUENCE
- ELEMENT
- SEQUENCE
- &OPTIONAL
- RETURN
- &BODY
- BODY
Executes BODY with ELEMENT subsequently bound to each element of SEQUENCE, then returns RETURN.
-
EXTERNAL MACRO WITH-SEQUENCE-ITERATOR
- &OPTIONAL
- ITERATOR
- LIMIT
- FROM-END-P
- STEP
- ENDP
- ELEMENT
- SET-ELEMENT
- INDEX
- COPY
- SEQUENCE
- &KEY
- FROM-END
- START
- END
- &BODY
- BODY
Executes BODY with the elements of VARS bound to the iteration state returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE and ARGS. Elements of VARS may be NIL in which case the corresponding value returned by MAKE-SEQUENCE-ITERATOR is ignored.
-
EXTERNAL MACRO WITH-SEQUENCE-ITERATOR-FUNCTIONS
- STEP
- ENDP
- ELT
- SETF
- INDEX
- COPY
- SEQUENCE
- &REST
- ARGS
- &KEY
- FROM-END
- START
- END
- &BODY
- BODY
Executes BODY with the names STEP, ENDP, ELT, SETF, INDEX and COPY bound to local functions which execute the iteration state query and mutation functions returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE and ARGS. STEP, ENDP, ELT, SETF, INDEX and COPY have dynamic extent.
-