├── README.md ├── trivial-extensible-sequences.asd ├── staple.ext.lisp ├── LICENSE ├── api.lisp ├── README.mess ├── fallback.lisp └── docs └── index.html /README.md: -------------------------------------------------------------------------------- 1 | # This repository has [moved](https://shinmera.com/projects/trivial-extensible-sequences)! 2 | Due to Microsoft's continued enshittification of the platform this repository has been moved to [Codeberg](https://shinmera.com/projects/trivial-extensible-sequences) in August of 2025. It will not receive further updates or patches. **Issues and pull requests will not be looked at here either**, please submit your patches and issue tickets on Codeberg, or send them directly via good old email patches to [shirakumo@tymoon.eu](mailto:shirakumo@tymoon.eu). 3 | 4 | Thanks. -------------------------------------------------------------------------------- /trivial-extensible-sequences.asd: -------------------------------------------------------------------------------- 1 | (asdf:defsystem trivial-extensible-sequences 2 | :version "1.0.0" 3 | :license "zlib" 4 | :author "Yukari Hafner " 5 | :maintainer "Yukari Hafner " 6 | :description "Portability library for the extensible sequences protocol." 7 | :homepage "https://shinmera.com/docs/trivial-extensible-sequences/" 8 | :bug-tracker "https://shinmera.com/project/trivial-extensible-sequences/issues" 9 | :source-control (:git "https://shinmera.com/project/trivial-extensible-sequences.git") 10 | :serial T 11 | :components ((:file "api") 12 | (:file "fallback" :if-feature (:not (:or :sbcl :abcl :clasp)))) 13 | :depends-on ((:feature :abcl (:require :extensible-sequences)))) 14 | -------------------------------------------------------------------------------- /staple.ext.lisp: -------------------------------------------------------------------------------- 1 | (asdf:load-system :staple-markless) 2 | 3 | (defpackage #:org.shirakumo.trivial-extensible-sequences.doc 4 | (:use #:cl) 5 | (:local-nicknames (#:sequences #:org.shirakumo.trivial-extensible-sequences))) 6 | 7 | (defclass simple-page* (staple:simple-page) ()) 8 | 9 | (defmethod staple:document-package ((page simple-page*)) 10 | (find-package '#:org.shirakumo.trivial-extensible-sequences.doc)) 11 | 12 | (defmethod staple:packages ((_ (eql (asdf:find-system :trivial-extensible-sequences)))) 13 | (list (find-package '#:org.shirakumo.trivial-extensible-sequences))) 14 | 15 | (defmethod staple:page-type ((_ (eql (asdf:find-system :trivial-extensible-sequences)))) 16 | 'simple-page*) 17 | 18 | #+sbcl 19 | (defmethod staple:definition-wanted-p ((_ definitions:source-transform) page) NIL) 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Yukari Hafner 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /api.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.trivial-extensible-sequences 2 | #-(or abcl ccl clasp ecl sbcl (and lispworks (not (or lispworks6 lispworks7)))) 3 | (:nicknames #:sequence) 4 | (:use #+sbcl #:sb-sequence 5 | #+(or abcl clasp) #:sequence) 6 | #+(or sbcl abcl clasp) 7 | (:import-from #:cl #:sequence) 8 | (:export 9 | #:sequence 10 | #:length 11 | #:elt 12 | #:adjust-sequence 13 | #:make-sequence-like 14 | #:protocol-unimplemented 15 | #:protocol-unimplemented-operation 16 | #:emptyp 17 | #:count 18 | #:count-if 19 | #:count-if-not 20 | #:find 21 | #:find-if 22 | #:find-if-not 23 | #:position 24 | #:position-if 25 | #:position-if-not 26 | #:subseq 27 | #:copy-seq 28 | #:fill 29 | #:map 30 | #:nsubstitute 31 | #:nsubstitute-if 32 | #:nsubstitute-if-not 33 | #:substitute 34 | #:substitute-if 35 | #:substitute-if-not 36 | #:replace 37 | #:nreverse 38 | #:reverse 39 | #:concatenate 40 | #:reduce 41 | #:mismatch 42 | #:search 43 | #:delete 44 | #:delete-if 45 | #:delete-if-not 46 | #:remove 47 | #:remove-if 48 | #:remove-if-not 49 | #:delete-duplicates 50 | #:remove-duplicates 51 | #:sort 52 | #:stable-sort 53 | #:merge 54 | #:dosequence 55 | #:make-sequence-iterator 56 | #:with-sequence-iterator 57 | #:with-sequence-iterator-functions 58 | #:iterator-step 59 | #:iterator-endp 60 | #:iterator-element 61 | #:iterator-index 62 | #:iterator-copy 63 | #:make-simple-sequence-iterator)) 64 | -------------------------------------------------------------------------------- /README.mess: -------------------------------------------------------------------------------- 1 | ## About 2 | 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. 3 | 4 | The extensible sequences protocol is defined in 'User-extensible sequences in Common Lisp' by Christophe Rhodes[1]. Also see the "SBCL manual"(http://www.sbcl.org/manual/#Extensible-Sequences). Please refer to the above documents as well as the sequence operations in the hyperspec for documentation. 5 | 6 | [1] https://research.gold.ac.uk/id/eprint/2344/1/sequences-20070301.pdf 7 | 8 | ## How To 9 | 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``. 10 | 11 | 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. 12 | 13 | ::: lisp 14 | (defclass value-as-sequence (sequences:sequence standard-object) 15 | ((value :initarg :value :initform (error "VALUE required.") :accessor value))) 16 | ::: 17 | 18 | Note that a ``sequence`` is not by default a ``standard-object`` hence why we include it explicitly in the superclass list. 19 | 20 | Next you should add methods on ``length``, ``elt``, ``(setf elt)``, ``adjust-sequence`` and ``make-sequence-like``. 21 | 22 | ::: lisp 23 | (defmethod sequences:length ((sequence value-as-sequence)) 24 | 1) 25 | 26 | (defmethod sequences:elt ((sequence value-as-sequence) index) 27 | (check-type index (integer 0 0)) 28 | (value sequence)) 29 | 30 | (defmethod (setf sequences:elt) (value (sequence value-as-sequence) index) 31 | (check-type index (integer 0 0)) 32 | (setf (value sequence) value)) 33 | 34 | (defmethod sequences:adjust-sequence ((sequence value-as-sequence) length &key initial-contents initial-element) 35 | (check-type length (integer 1 1)) 36 | (when initial-contents 37 | (setf (value sequence) (elt initial-contents 0))) 38 | sequence) 39 | 40 | (defmethod sequences:make-sequence-like ((sequence value-as-sequence) length &key initial-contents initial-element) 41 | (check-type length (integer 1 1)) 42 | (make-instance 'value-as-sequence 43 | :value (or (elt initial-contents 0) initial-element (value sequence)))) 44 | ::: 45 | 46 | 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. 47 | 48 | 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: 49 | 50 | 1. An iteration state value. 51 | 2. A value describing the limit of iteration, if any. 52 | 3. The from-end value. 53 | 4. A step function of three arguments: the sequence, the state value, the from-end value. The function should return the new state value. 54 | 5. 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. 55 | 6. An element read function of two arguments: the sequence, the state value. 56 | 7. An element write function of three arguments: the new value to store, the sequence, the state value. 57 | 8. An index function of two arguments: the sequence, the state value. The function should return the current iteration index, starting from zero. 58 | 9. An iterator copy function of two arguments: the sequence, the state value. The function should return a "fresh" iteration value. 59 | 60 | Here's what it might look like for our relatively useless example sequence type: 61 | 62 | ::: lisp 63 | (defmethod sequences:make-sequence-iterator ((sequence value-as-sequence) &key start end from-end) 64 | (values 0 1 from-end 65 | (lambda (seq state from-end) (1+ state)) 66 | (lambda (seq state limit from-end) (< state limit)) 67 | (lambda (seq state) (value seq)) 68 | (lambda (value seq state) (setf (value seq) value)) 69 | (lambda (seq state) state) 70 | (lambda (seq state) state))) 71 | ::: 72 | 73 | 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-functions``, and ``dosequence``. 74 | 75 | ## Implementation Support 76 | 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. 77 | 78 | - ABCL 79 | - Clasp 80 | - SBCL 81 | 82 | On any other implementation, this package provides a //fallback// implementation of the protocol. The protocol should work completely with the following caveats: 83 | 84 | - You must use the functions provided by this package to handle your sequences, rather than the ones from the ``cl`` package. 85 | - Custom sequences defined with a subclass will not actually be a subtype of ``cl:sequence``. 86 | - The fallback protocol will be slower than what the implementation could provide. 87 | 88 | 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"(https://github.com/sbcl/sbcl/blob/master/src/pcl/sequence.lisp) are licensed liberally and should serve as a good basis. 89 | -------------------------------------------------------------------------------- /fallback.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.trivial-extensible-sequences.fallback 2 | (:use #:cl) 3 | #+(or abcl ccl clasp ecl sbcl (and lispworks (not (or lispworks6 lispworks7)))) 4 | (:local-nicknames (#:sequence #:org.shirakumo.trivial-extensible-sequences)) 5 | (:shadow #:step #:endp)) 6 | (in-package #:org.shirakumo.trivial-extensible-sequences.fallback) 7 | 8 | ;;;; Core Protocol 9 | (defclass sequence:sequence () 10 | ()) 11 | 12 | (defgeneric sequence:length (sequence) 13 | (:method (thing) 14 | (protocol-unimplemented 'sequence:length thing)) 15 | (:method ((sequence list)) 16 | (length sequence)) 17 | (:method ((sequence vector)) 18 | (length sequence))) 19 | 20 | (defgeneric sequence:elt (sequence index) 21 | (:method (thing index) 22 | (declare (ignore index)) 23 | (protocol-unimplemented 'sequence:elt thing)) 24 | (:method ((sequence list) index) 25 | (elt sequence index)) 26 | (:method ((sequence vector) index) 27 | (elt sequence index))) 28 | 29 | (defgeneric (setf sequence:elt) (new-value sequence index) 30 | (:method (new-value thing index) 31 | (declare (ignore new-value index)) 32 | (protocol-unimplemented '(setf sequence:elt) thing)) 33 | (:method (new-value (sequence list) index) 34 | (setf (elt sequence index) new-value)) 35 | (:method (new-value (sequence vector) index) 36 | (setf (elt sequence index) new-value))) 37 | 38 | (defgeneric sequence:adjust-sequence (sequence length &key initial-element initial-contents) 39 | (:method (thing length &key initial-element initial-contents) 40 | (declare (ignore initial-element initial-contents)) 41 | (protocol-unimplemented 'sequence:adjust-sequence thing)) 42 | (:method ((sequence vector) length &rest args) 43 | (apply #'adjust-array sequence length args)) 44 | (:method ((sequence list) length &key initial-element (initial-contents NIL contents-p)) 45 | (when (< 0 length) 46 | (loop for cons = sequence then (cdr cons) 47 | for i from 1 below length 48 | while (cdr cons) 49 | finally (cond ((< i length) 50 | (setf (cdr cons) (make-list (- length i) :initial-element initial-element))) 51 | ((= i length) 52 | (setf (cdr cons) NIL)))) 53 | (when contents-p 54 | (replace sequence initial-contents)) 55 | sequence))) 56 | 57 | (defgeneric sequence:make-sequence-like (sequence length &key initial-element initial-contents) 58 | (:method (thing length &key initial-element initial-contents) 59 | (declare (ignore initial-element initial-contents)) 60 | (protocol-unimplemented 'sequence:make-sequence-like thing)) 61 | (:method ((sequence vector) length &rest args) 62 | (if (loop for cons on args by #'cddr 63 | thereis (or (eql :initial-element (car cons)) 64 | (eql :initial-contents (car cons)))) 65 | (apply #'make-array length args) 66 | (replace (make-array length) sequence))) 67 | (:method ((sequence list) length &key initial-element (initial-contents NIL contents-p)) 68 | (if contents-p 69 | (replace (make-list length) initial-contents) 70 | (make-list length :initial-element initial-element)))) 71 | 72 | (define-condition sequence:protocol-unimplemented (type-error) 73 | ((protocol :initarg :protocol :reader sequence:protocol-unimplemented-operation)) 74 | (:report (lambda (c s) (format s "The sequence protocol function ~s is not implemented for~% ~a" 75 | (sequence:protocol-unimplemented-operation c) (type-error-datum c))))) 76 | 77 | (defun protocol-unimplemented (protocol datum) 78 | (error 'sequence:protocol-unimplemented 79 | :protocol protocol 80 | :datum datum 81 | :epected-type '(or sequence sequence:sequence))) 82 | 83 | ;;; Iterator Protocol 84 | (defgeneric sequence:make-sequence-iterator (sequence &key start end from-end) 85 | (:method (sequence &rest args) 86 | (multiple-value-bind (iterator limit from-end) (apply #'sequence:make-simple-sequence-iterator sequence args) 87 | (values iterator limit from-end 88 | #'sequence:iterator-step 89 | #'sequence:iterator-endp 90 | #'sequence:iterator-element 91 | #'(setf sequence:iterator-element) 92 | #'sequence:iterator-index 93 | #'sequence:iterator-copy)))) 94 | 95 | (defmacro sequence:with-sequence-iterator ((&whole vars 96 | &optional iterator limit from-end-p 97 | step endp element set-element index copy) 98 | (sequence &key from-end (start 0) end) &body body) 99 | (declare (ignore iterator limit from-end-p step endp element set-element index copy)) 100 | (let* ((ignored ()) 101 | (vars (loop for var in vars 102 | for gensym = (gensym) 103 | collect (or var 104 | (prog1 gensym 105 | (push gensym ignored)))))) 106 | `(multiple-value-bind ,vars (sequence:make-sequence-iterator ,sequence :start ,start :end ,end :from-end ,from-end) 107 | (declare (ignore ,@ignored)) 108 | ,@body))) 109 | 110 | (defmacro sequence:with-sequence-iterator-functions ((step endp elt setf index copy) 111 | (sequence &rest args &key from-end start end) 112 | &body body) 113 | (declare (ignore from-end start end)) 114 | (let ((nstate (gensym "STATE")) (nlimit (gensym "LIMIT")) 115 | (nfrom-end (gensym "FROM-END-")) (nstep (gensym "STEP")) 116 | (nendp (gensym "ENDP")) (nelt (gensym "ELT")) 117 | (nsetf (gensym "SETF")) (nindex (gensym "INDEX")) 118 | (ncopy (gensym "COPY")) (new-value (gensym "NEW-VALUE"))) 119 | `(sequence:with-sequence-iterator 120 | (,nstate ,nlimit ,nfrom-end ,nstep ,nendp ,nelt ,nsetf ,nindex ,ncopy) 121 | (,sequence ,@args) 122 | (flet ((,step () (setq ,nstate (funcall ,nstep ,sequence ,nstate ,nfrom-end))) 123 | (,endp () (funcall ,nendp ,sequence ,nstate ,nlimit ,nfrom-end)) 124 | (,elt () (funcall ,nelt ,sequence ,nstate)) 125 | (,setf (,new-value) (funcall ,nsetf ,new-value ,sequence ,nstate)) 126 | (,index () (funcall ,nindex ,sequence ,nstate)) 127 | (,copy () (funcall ,ncopy ,sequence ,nstate))) 128 | (declare (ignorable #',setf #',index #',copy)) 129 | ,@body)))) 130 | 131 | ;;; Simple Iterator Protocol 132 | ;; Taken from SBCL's extensible sequences implementation 133 | (defvar *exhausted* (make-symbol "EXHAUSTED")) 134 | 135 | (defgeneric sequence:make-simple-sequence-iterator 136 | (sequence &key from-end start end) 137 | (:method ((s list) &key from-end (start 0) end) 138 | (if from-end 139 | (let* ((termination (if (= start 0) *exhausted* (nthcdr (1- start) s))) 140 | (init (if (<= (or end (length s)) start) 141 | termination 142 | (if end (last s (- (length s) (1- end))) (last s))))) 143 | (values init termination t)) 144 | (cond 145 | ((not end) (values (nthcdr start s) nil nil)) 146 | (t (let ((st (nthcdr start s))) 147 | (values st (nthcdr (- end start) st) nil)))))) 148 | (:method ((s vector) &key from-end (start 0) end) 149 | (let ((end (or end (length s)))) 150 | (if from-end 151 | (values (1- end) (1- start) t) 152 | (values start end nil)))) 153 | (:method ((s sequence:sequence) &key from-end (start 0) end) 154 | (let ((end (or end (length s)))) 155 | (if from-end 156 | (values (1- end) (1- start) from-end) 157 | (values start end nil))))) 158 | 159 | (defgeneric sequence:iterator-step (sequence iterator from-end) 160 | (:method ((s list) iterator from-end) 161 | (if from-end 162 | (if (eq iterator s) 163 | *exhausted* 164 | (do* ((xs s (cdr xs))) 165 | ((eq (cdr xs) iterator) xs))) 166 | (cdr iterator))) 167 | (:method ((s vector) iterator from-end) 168 | (if from-end 169 | (1- iterator) 170 | (1+ iterator))) 171 | (:method ((s sequence:sequence) iterator from-end) 172 | (if from-end 173 | (1- iterator) 174 | (1+ iterator)))) 175 | 176 | (defgeneric sequence:iterator-endp (sequence iterator limit from-end) 177 | (:method ((s list) iterator limit from-end) 178 | (eq iterator limit)) 179 | (:method ((s vector) iterator limit from-end) 180 | (= iterator limit)) 181 | (:method ((s sequence:sequence) iterator limit from-end) 182 | (= iterator limit))) 183 | 184 | (defgeneric sequence:iterator-element (sequence iterator) 185 | (:method ((s list) iterator) 186 | (car iterator)) 187 | (:method ((s vector) iterator) 188 | (aref s iterator)) 189 | (:method ((s sequence:sequence) iterator) 190 | (sequence:elt s iterator))) 191 | 192 | (defgeneric (setf sequence:iterator-element) (new-value sequence iterator) 193 | (:method (o (s list) iterator) 194 | (setf (car iterator) o)) 195 | (:method (o (s vector) iterator) 196 | (setf (aref s iterator) o)) 197 | (:method (o (s sequence:sequence) iterator) 198 | (setf (sequence:elt s iterator) o))) 199 | 200 | (defgeneric sequence:iterator-index (sequence iterator) 201 | (:method ((s list) iterator) 202 | ;; FIXME: this sucks. (In my defence, it is the equivalent of the 203 | ;; Apple implementation in Dylan...) 204 | (loop for l on s for i from 0 when (eq l iterator) return i)) 205 | (:method ((s vector) iterator) iterator) 206 | (:method ((s sequence:sequence) iterator) iterator)) 207 | 208 | (defgeneric sequence:iterator-copy (sequence iterator) 209 | (:method ((s list) iterator) iterator) 210 | (:method ((s vector) iterator) iterator) 211 | (:method ((s sequence:sequence) iterator) iterator)) 212 | 213 | ;;;; Default Functions 214 | (defgeneric sequence:emptyp (sequence) 215 | (:method ((sequence sequence:sequence)) 216 | (= 0 (sequence:length sequence))) 217 | (:method ((null null)) T) 218 | (:method ((cons cons)) NIL) 219 | (:method ((vector vector)) (= 0 (length vector)))) 220 | 221 | (defun test (test test-not) 222 | (cond (test-not 223 | (complement test-not)) 224 | (test 225 | test) 226 | (T 227 | #'eql))) 228 | 229 | (defun coerce-to (type sequence) 230 | (case type 231 | (list (sequence:make-sequence-like '() (sequence:length sequence) :initial-contents sequence)) 232 | (vector (sequence:make-sequence-like #() (sequence:length sequence) :initial-contents sequence)) 233 | (T (sequence:make-sequence-like (allocate-instance type) (sequence:length sequence) :initial-contents sequence)))) 234 | 235 | (defmacro with-sequence-arguments ((&rest defs) &body body) 236 | `(let ,(loop for def in defs 237 | collect (case def 238 | (test `(,def (test test test-not))) 239 | (start `(,def (or start 0))) 240 | (end `(,def (or end (sequence:length sequence)))) 241 | (key `(,def (or key #'identity))) 242 | (count `(,def (or count most-positive-fixnum))) 243 | (T def))) 244 | ,@body)) 245 | 246 | (defmacro do-iteration ((sequence &optional result) &body body) 247 | `(sequence:with-sequence-iterator-functions (step endp selt (setf selt) idx copy) 248 | (,sequence :from-end from-end :start (or start 0) :end (or end (sequence:length ,sequence))) 249 | (declare (ignorable #'selt)) 250 | (loop until (endp) 251 | do (progn ,@body) 252 | (step) 253 | finally (return ,result)))) 254 | 255 | (defgeneric sequence:count (item sequence &key key test test-not start end from-end) 256 | (:method (item (sequence sequence:sequence) &key key test test-not start end from-end) 257 | (with-sequence-arguments ((count 0) test key) 258 | (do-iteration (sequence count) 259 | (when (funcall test item (funcall key (selt))) 260 | (incf count))))) 261 | (:method (item (sequence sequence) &rest args) 262 | (apply #'count item sequence args))) 263 | 264 | (defgeneric sequence:count-if (pred sequence &key key start end from-end) 265 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 266 | (with-sequence-arguments ((count 0) key) 267 | (do-iteration (sequence count) 268 | (when (funcall pred (funcall key (selt))) 269 | (incf count))))) 270 | (:method (pred (sequence sequence) &rest args) 271 | (apply #'count-if pred sequence args))) 272 | 273 | (defgeneric sequence:count-if-not (pred sequence &key key start end from-end) 274 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 275 | (with-sequence-arguments ((count 0) key) 276 | (do-iteration (sequence count) 277 | (unless (funcall pred (funcall key (selt))) 278 | (incf count))))) 279 | (:method (pred (sequence sequence) &rest args) 280 | (apply #'count-if-not pred sequence args))) 281 | 282 | (defgeneric sequence:find (item sequence &key key test test-not start end from-end) 283 | (:method (item (sequence sequence:sequence) &key key test test-not start end from-end) 284 | (with-sequence-arguments (test key) 285 | (do-iteration (sequence) 286 | (let ((elt (selt))) 287 | (when (funcall test item (funcall key elt)) 288 | (return elt)))))) 289 | (:method (item (sequence sequence) &rest args) 290 | (apply #'find item sequence args))) 291 | 292 | (defgeneric sequence:find-if (pred sequence &key key start end from-end) 293 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 294 | (with-sequence-arguments (key) 295 | (do-iteration (sequence) 296 | (let ((elt (selt))) 297 | (when (funcall pred (funcall key elt)) 298 | (return elt)))))) 299 | (:method (pred (sequence sequence) &rest args) 300 | (apply #'find-if pred sequence args))) 301 | 302 | (defgeneric sequence:find-if-not (pred sequence &key key start end from-end) 303 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 304 | (with-sequence-arguments (key) 305 | (do-iteration (sequence) 306 | (let ((elt (selt))) 307 | (unless (funcall pred (funcall key elt)) 308 | (return elt)))))) 309 | (:method (pred (sequence sequence) &rest args) 310 | (apply #'find-if-not pred sequence args))) 311 | 312 | (defgeneric sequence:position (item sequence &key key test test-not start end from-end) 313 | (:method (item (sequence sequence:sequence) &key key test test-not start end from-end) 314 | (with-sequence-arguments (test key) 315 | (do-iteration (sequence) 316 | (when (funcall test item (funcall key (selt))) 317 | (return (idx)))))) 318 | (:method (pred (sequence sequence) &rest args) 319 | (apply #'position pred sequence args))) 320 | 321 | (defgeneric sequence:position-if (pred sequence &key key start end from-end) 322 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 323 | (with-sequence-arguments (key) 324 | (do-iteration (sequence) 325 | (when (funcall pred (funcall key (selt))) 326 | (return (idx)))))) 327 | (:method (pred (sequence sequence) &rest args) 328 | (apply #'position-if pred sequence args))) 329 | 330 | (defgeneric sequence:position-if-not (pred sequence &key key start end from-end) 331 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 332 | (with-sequence-arguments (key) 333 | (do-iteration (sequence) 334 | (unless (funcall pred (funcall key (selt))) 335 | (return (idx)))))) 336 | (:method (pred (sequence sequence) &rest args) 337 | (apply #'position-if-not pred sequence args))) 338 | 339 | (defgeneric sequence:subseq (sequence start &optional end) 340 | (:method ((sequence sequence:sequence) start &optional end) 341 | (let* ((from-end NIL) 342 | (head (cons NIL NIL)) 343 | (tail head)) 344 | (do-iteration (sequence) 345 | (setf tail (setf (cdr tail) (cons (selt) NIL)))) 346 | (let ((contents (cdr head))) 347 | (sequence:make-sequence-like sequence (length contents) :initial-contents contents)))) 348 | (:method ((sequence sequence) start &optional end) 349 | (subseq sequence start end))) 350 | 351 | (defgeneric sequence:copy-seq (sequence) 352 | (:method ((sequence sequence:sequence)) 353 | (sequence:make-sequence-like sequence (sequence:length sequence))) 354 | (:method ((sequence sequence)) 355 | (copy-seq sequence))) 356 | 357 | (defgeneric sequence:fill (sequence item &key start end) 358 | (:method ((sequence sequence:sequence) item &key start end) 359 | (let ((from-end NIL)) 360 | (do-iteration (sequence sequence) 361 | (setf (selt) item)))) 362 | (:method ((sequence sequence) item &rest args) 363 | (apply #'fill sequence item args))) 364 | 365 | (defgeneric sequence:map (prototype function sequence &rest sequences) 366 | (:method ((prototype sequence:sequence) function sequence &rest sequences) 367 | (let* ((sequences (list* sequence sequences)) 368 | (iterators (loop for sequence in sequences 369 | collect (list* sequence (multiple-value-list (sequence:make-sequence-iterator sequence))))) 370 | (mapped (loop while (loop for iterator in iterators 371 | for (sequence it limit from-end step endp) = iterator 372 | never (funcall endp sequence it limit from-end)) 373 | collect (let ((els (loop for iterator in iterators 374 | for (sequence it limit from-end step endp elt) = iterator 375 | collect (funcall elt sequence it)))) 376 | (apply function els)) 377 | do (loop for iterator in iterators 378 | for (sequence it limit from-end step) = iterator 379 | do (setf (second iterator) (funcall step sequence it from-end)))))) 380 | (sequence:make-sequence-like prototype (length mapped) :initial-contents mapped))) 381 | (:method ((prototype sequence) function sequence &rest sequences) 382 | (apply #'map (type-of prototype) function sequence sequences))) 383 | 384 | (defgeneric sequence:nsubstitute (new old sequence &key key test test-not start end from-end count) 385 | (:method (new old (sequence sequence:sequence) &key key test test-not start end from-end count) 386 | (with-sequence-arguments (key test count) 387 | (do-iteration (sequence sequence) 388 | (when (funcall test old (funcall key (selt))) 389 | (setf (selt) new) 390 | (when (= 0 (decf count)) (loop-finish)))))) 391 | (:method (new old (sequence sequence) &rest args) 392 | (apply #'nsubstitute new old sequence args))) 393 | 394 | (defgeneric sequence:nsubstitute-if (new pred sequence &key key start end from-end count) 395 | (:method (new pred (sequence sequence:sequence) &key key start end from-end count) 396 | (with-sequence-arguments (key count) 397 | (do-iteration (sequence sequence) 398 | (when (funcall pred (funcall key (selt))) 399 | (setf (selt) new) 400 | (when (= 0 (decf count)) (loop-finish)))))) 401 | (:method (new pred (sequence sequence) &rest args) 402 | (apply #'nsubstitute-if new pred sequence args))) 403 | 404 | (defgeneric sequence:nsubstitute-if-not (new pred sequence &key key start end from-end count) 405 | (:method (new pred (sequence sequence:sequence) &key key start end from-end count) 406 | (with-sequence-arguments (key count) 407 | (do-iteration (sequence sequence) 408 | (unless (funcall pred (funcall key (selt))) 409 | (setf (selt) new) 410 | (when (= 0 (decf count)) (loop-finish)))))) 411 | (:method (new pred (sequence sequence) &rest args) 412 | (apply #'nsubstitute-if-not new pred sequence args))) 413 | 414 | (defgeneric sequence:substitute (new old sequence &key key test test-not start end from-end count) 415 | (:method (new old (sequence sequence:sequence) &key key test test-not start end from-end count) 416 | (with-sequence-arguments (key test count) 417 | (let ((sequence (sequence:copy-seq sequence))) 418 | (do-iteration (sequence sequence) 419 | (when (funcall test old (funcall key (selt))) 420 | (setf (selt) new) 421 | (when (= 0 (decf count)) (loop-finish))))))) 422 | (:method (new old (sequence sequence) &rest args) 423 | (apply #'substitute new old sequence args))) 424 | 425 | (defgeneric sequence:substitute-if (new pred sequence &key key start end from-end count) 426 | (:method (new pred (sequence sequence:sequence) &key key start end from-end count) 427 | (with-sequence-arguments (key count) 428 | (let ((sequence (sequence:copy-seq sequence))) 429 | (do-iteration (sequence sequence) 430 | (when (funcall pred (funcall key (selt))) 431 | (setf (selt) new) 432 | (when (= 0 (decf count)) (loop-finish))))))) 433 | (:method (new pred (sequence sequence) &rest args) 434 | (apply #'substitute-if new pred sequence args))) 435 | 436 | (defgeneric sequence:substitute-if-not (new pred sequence &key key start end from-end count) 437 | (:method (new pred (sequence sequence:sequence) &key key start end from-end count) 438 | (with-sequence-arguments (key count) 439 | (let ((sequence (sequence:copy-seq sequence))) 440 | (do-iteration (sequence sequence) 441 | (unless (funcall pred (funcall key (selt))) 442 | (setf (selt) new) 443 | (when (= 0 (decf count)) (loop-finish))))))) 444 | (:method (new pred (sequence sequence) &rest args) 445 | (apply #'substitute-if-not new pred sequence args))) 446 | 447 | (defgeneric sequence:replace (sequence1 sequence2 &key start1 end1 start2 end2) 448 | (:method (sequence1 sequence2 &key start1 end1 start2 end2) 449 | (let* ((start1 (or start1 0)) 450 | (start2 (or start2 0)) 451 | (end1 (or end1 (sequence:length sequence1))) 452 | (end2 (or end2 (sequence:length sequence2))) 453 | (length (min (- end1 start1) (- end2 start2))) 454 | (start start1) 455 | (end (+ start length)) 456 | (from-end NIL)) 457 | (sequence:with-sequence-iterator-functions (step2 endp2 elt2 (setf elt2) idx2 copy2) 458 | (sequence2 :start start2 :end (+ start2 length)) 459 | (declare (ignore #'endp2)) 460 | (do-iteration (sequence1 sequence1) 461 | (setf (selt) (elt2)) 462 | (step2))))) 463 | (:method ((a sequence) (b sequence) &rest args) 464 | (apply #'replace a b args))) 465 | 466 | (defgeneric sequence:nreverse (sequence) 467 | (:method ((sequence sequence:sequence)) 468 | (sequence:with-sequence-iterator-functions (step endp selt (setf selt) idx copy) 469 | (sequence :from-end T) 470 | (loop for length from 0 471 | until (endp) 472 | collect (selt) into contents 473 | do (step) 474 | finally (return (sequence:replace sequence contents))))) 475 | (:method ((sequence sequence)) 476 | (nreverse sequence))) 477 | 478 | (defgeneric sequence:reverse (sequence) 479 | (:method ((sequence sequence:sequence)) 480 | (sequence:with-sequence-iterator-functions (step endp selt (setf selt) idx copy) 481 | (sequence :from-end T) 482 | (loop for length from 0 483 | until (endp) 484 | collect (selt) into contents 485 | do (step) 486 | finally (return (sequence:make-sequence-like sequence length :initial-contents contents))))) 487 | (:method ((sequence sequence)) 488 | (reverse sequence))) 489 | 490 | (defgeneric sequence:concatenate (result-prototype &rest sequences) 491 | (:method ((prototype sequence:sequence) &rest sequences) 492 | (let ((new (make-array 0 :adjustable T :fill-pointer T))) 493 | (dolist (sequence sequences) 494 | (sequence:with-sequence-iterator-functions (step endp selt (setf selt) idx copy) (sequence) 495 | (loop until (endp) 496 | do (vector-push-extend (selt) new) 497 | (step)))) 498 | (sequence:make-sequence-like prototype (length new) :initial-contents new))) 499 | (:method ((prototype sequence) &rest sequences) 500 | (apply #'concatenate (type-of prototype) sequences))) 501 | 502 | (defgeneric sequence:reduce (function sequence &key initial-value key start end from-end) 503 | (:method (func (sequence sequence:sequence) &key (initial-value NIL ip) key start end from-end) 504 | (with-sequence-arguments ((result initial-value) key start end) 505 | (unless ip 506 | (cond (from-end 507 | (decf end) 508 | (setf result (funcall key (sequence:elt sequence end)))) 509 | (T 510 | (setf result (funcall key (sequence:elt sequence start))) 511 | (incf start)))) 512 | (if (and (not ip) (sequence:emptyp sequence)) 513 | (funcall func) 514 | (do-iteration (sequence result) 515 | (setf result (funcall func result (funcall key (selt)))))))) 516 | (:method (func (sequence sequence) &rest args) 517 | (apply #'reduce func sequence args))) 518 | 519 | (defgeneric sequence:mismatch (sequence1 sequence2 &key key test test-not start1 end1 start2 end2 from-end) 520 | (:method (sequence1 sequence2 &rest args) 521 | ;; FIXME: Implement without copying 522 | (apply #'mismatch (coerce-to 'vector sequence1) (coerce-to 'vector sequence2) args)) 523 | (:method ((a sequence) (b sequence) &rest args) 524 | (apply #'mismatch a b args))) 525 | 526 | (defgeneric sequence:search (sequence1 sequence2 &key key test test-not start1 end1 start2 end2 from-end) 527 | (:method (sequence1 sequence2 &rest args) 528 | ;; FIXME: Implement without copying 529 | (apply #'search (coerce-to 'vector sequence1) (coerce-to 'vector sequence2) args)) 530 | (:method ((a sequence) (b sequence) &rest args) 531 | (apply #'search a b args))) 532 | 533 | (defgeneric sequence:delete (item sequence &key key test test-not start end from-end) 534 | (:method (item (sequence sequence:sequence) &key key test test-not start end from-end) 535 | (let ((new (make-array (sequence:length sequence) :fill-pointer 0))) 536 | (with-sequence-arguments (key test) 537 | (do-iteration (sequence) 538 | (unless (funcall test item (funcall key (selt))) 539 | (vector-push (selt) new)))) 540 | (sequence:adjust-sequence sequence (length new) :initial-contents new))) 541 | (:method (item (sequence sequence) &rest args) 542 | (apply #'delete item sequence args))) 543 | 544 | (defgeneric sequence:delete-if (pred sequence &key key start end from-end) 545 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 546 | (let ((new (make-array (sequence:length sequence) :fill-pointer 0))) 547 | (with-sequence-arguments (key) 548 | (do-iteration (sequence) 549 | (unless (funcall pred (funcall key (selt))) 550 | (vector-push (selt) new)))) 551 | (sequence:adjust-sequence sequence (length new) :initial-contents new))) 552 | (:method (pred (sequence sequence) &rest args) 553 | (apply #'delete-if pred sequence args))) 554 | 555 | (defgeneric sequence:delete-if-not (pred sequence &key key start end from-end) 556 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 557 | (let ((new (make-array (sequence:length sequence) :fill-pointer 0))) 558 | (with-sequence-arguments (key) 559 | (do-iteration (sequence) 560 | (when (funcall pred (funcall key (selt))) 561 | (vector-push (selt) new)))) 562 | (sequence:adjust-sequence sequence (length new) :initial-contents new))) 563 | (:method (pred (sequence sequence) &rest args) 564 | (apply #'delete-if-not pred sequence args))) 565 | 566 | (defgeneric sequence:remove (item sequence &key key test test-not start end from-end) 567 | (:method (item (sequence sequence:sequence) &key key test test-not start end from-end) 568 | (let ((new (make-array (sequence:length sequence) :fill-pointer 0))) 569 | (with-sequence-arguments (key test) 570 | (do-iteration (sequence) 571 | (unless (funcall test item (funcall key (selt))) 572 | (vector-push (selt) new)))) 573 | (sequence:make-sequence-like sequence (length new) :initial-contents new))) 574 | (:method (item (sequence sequence) &rest args) 575 | (apply #'remove item sequence args))) 576 | 577 | (defgeneric sequence:remove-if (pred sequence &key key start end from-end) 578 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 579 | (let ((new (make-array (sequence:length sequence) :fill-pointer 0))) 580 | (with-sequence-arguments (key) 581 | (do-iteration (sequence) 582 | (unless (funcall pred (funcall key (selt))) 583 | (vector-push (selt) new)))) 584 | (sequence:make-sequence-like sequence (length new) :initial-contents new))) 585 | (:method (pred (sequence sequence) &rest args) 586 | (apply #'remove-if pred sequence args))) 587 | 588 | (defgeneric sequence:remove-if-not (pred sequence &key key start end from-end) 589 | (:method (pred (sequence sequence:sequence) &key key start end from-end) 590 | (let ((new (make-array (sequence:length sequence) :fill-pointer 0))) 591 | (with-sequence-arguments (key) 592 | (do-iteration (sequence) 593 | (when (funcall pred (funcall key (selt))) 594 | (vector-push (selt) new)))) 595 | (sequence:make-sequence-like sequence (length new) :initial-contents new))) 596 | (:method (pred (sequence sequence) &rest args) 597 | (apply #'remove-if-not pred sequence args))) 598 | 599 | (defgeneric sequence:delete-duplicates (sequence &key key test test-not start end from-end) 600 | (:method ((sequence sequence:sequence) &rest args) 601 | ;; FIXME: Implement without copying 602 | (let ((new (coerce-to 'list sequence))) 603 | (setf new (apply #'remove-duplicates new args)) 604 | (sequence:adjust-sequence sequence (length new) :initial-contents new))) 605 | (:method ((sequence sequence) &rest args) 606 | (apply #'delete-duplicates sequence args))) 607 | 608 | (defgeneric sequence:remove-duplicates (sequence &key key test test-not start end from-end) 609 | (:method ((sequence sequence:sequence) &rest args) 610 | ;; FIXME: Implement without copying 611 | (let ((new (coerce-to 'list sequence))) 612 | (setf new (apply #'remove-duplicates new args)) 613 | (sequence:make-sequence-like sequence (length new) :initial-contents new))) 614 | (:method ((sequence sequence) &rest args) 615 | (apply #'remove-duplicates sequence args))) 616 | 617 | (defgeneric sequence:sort (sequence pred &key key) 618 | (:method ((sequence sequence:sequence) pred &rest args) 619 | ;; FIXME: Implement without copying 620 | (let ((sorted (apply #'sort (coerce-to 'list sequence) pred args))) 621 | (sequence:adjust-sequence sequence (sequence:length sequence) :initial-contents sorted))) 622 | (:method ((sequence sequence) pred &rest args) 623 | (apply #'sort sequence pred args))) 624 | 625 | (defgeneric sequence:stable-sort (sequence pred &key key) 626 | (:method ((sequence sequence:sequence) pred &rest args) 627 | ;; FIXME: Implement without copying 628 | (let ((sorted (apply #'stable-sort (coerce-to 'list sequence) pred args))) 629 | (sequence:adjust-sequence sequence (sequence:length sequence) :initial-contents sorted))) 630 | (:method ((sequence sequence) pred &rest args) 631 | (apply #'stable-sort sequence pred args))) 632 | 633 | (defgeneric sequence:merge (prototype sequence1 sequence2 predicate &key key) 634 | (:method (prototype sequence1 sequence2 predicate &rest args) 635 | ;; FIXME: Implement without copying 636 | (let ((new (apply #'merge 'vector (coerce-to 'vector sequence2) (coerce-to 'vector sequence2) predicate args))) 637 | (sequence:make-sequence-like prototype (length new) :initial-contents new))) 638 | (:method (prototype (a sequence) (b sequence) pred &rest args) 639 | (apply #'merge prototype a b pred args))) 640 | 641 | (defmacro sequence:dosequence ((element sequence &optional return) &body body) 642 | (let ((step (gensym "STEP")) (endp (gensym "ENDP")) (elt (gensym "ELT")) 643 | (setf (gensym "SETF")) (index (gensym "INDEX")) (copy (gensym "COPY"))) 644 | `(sequence:with-sequence-iterator-functions (,step ,endp ,elt ,setf ,index ,copy) (,sequence) 645 | (declare (ignore #',setf #',index #',copy)) 646 | (loop until (,endp) 647 | for ,element = (,elt) 648 | do (progn 649 | ,@body 650 | (,step)) 651 | finally (return ,return))))) 652 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Trivial Extensible Sequences

trivial extensible sequences

1.0.0

Portability 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)
  2 |   ((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))
  3 |   1)
  4 | 
  5 | (defmethod sequences:elt ((sequence value-as-sequence) index)
  6 |   (check-type index (integer 0 0))
  7 |   (value sequence))
  8 | 
  9 | (defmethod (setf sequences:elt) (value (sequence value-as-sequence) index)
 10 |   (check-type index (integer 0 0))
 11 |   (setf (value sequence) value))
 12 | 
 13 | (defmethod sequences:adjust-sequence ((sequence value-as-sequence) length &key initial-contents initial-element)
 14 |   (check-type length (integer 1 1))
 15 |   (when initial-contents
 16 |     (setf (value sequence) (elt initial-contents 0)))
 17 |   sequence)
 18 | 
 19 | (defmethod sequences:make-sequence-like ((sequence value-as-sequence) length &key initial-contents initial-element)
 20 |   (check-type length (integer 1 1))
 21 |   (make-instance 'value-as-sequence
 22 |                  :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:

  1. An iteration state value.

  2. A value describing the limit of iteration, if any.

  3. The from-end value.

  4. A step function of three arguments: the sequence, the state value, the from-end value. The function should return the new state value.

  5. 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.

  6. An element read function of two arguments: the sequence, the state value.

  7. An element write function of three arguments: the new value to store, the sequence, the state value.

  8. An index function of two arguments: the sequence, the state value. The function should return the current iteration index, starting from zero.

  9. 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)
 23 |   (values 0 1 from-end
 24 |           (lambda (seq state from-end) (1+ state))
 25 |           (lambda (seq state limit from-end) (< state limit))
 26 |           (lambda (seq state) (value seq))
 27 |           (lambda (value seq state) (setf (value seq) value))
 28 |           (lambda (seq state) state)
 29 |           (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

1.0.0
Nicolas Hafner
zlib

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
             30 |    instance of a sequence class that does not support the
             31 |    operation.
          • EXTERNAL GENERIC-FUNCTION

            ADJUST-SEQUENCE

              • SEQUENCE
              • LENGTH
              • &KEY
              • INITIAL-ELEMENT
              • INITIAL-CONTENTS
              Return destructively modified SEQUENCE or a freshly allocated
               32 |    sequence of the same class as SEQUENCE of length LENGTH. Elements
               33 |    of the returned sequence are initialized to INITIAL-ELEMENT, if
               34 |    supplied, initialized to INITIAL-CONTENTS if supplied, or identical
               35 |    to the elements of SEQUENCE if neither is supplied. Signals a
               36 |    PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not
               37 |    implemented for the class of SEQUENCE.
            • EXTERNAL GENERIC-FUNCTION

              CONCATENATE

                • RESULT-PROTOTYPE
                • &REST
                • SEQUENCES
                Implements CL:CONCATENATE for extended sequences.
                 38 | 
                 39 |     RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:CONCATENATE
                 40 |     but receives a prototype instance of an extended sequence class
                 41 |     instead of a type specifier. By dispatching on RESULT-PROTOTYPE,
                 42 |     methods on this generic function specify how extended sequence
                 43 |     classes act when they are specified as the result type in a
                 44 |     CL:CONCATENATE call. RESULT-PROTOTYPE may not be fully initialized
                 45 |     and thus should only be used for dispatch and to determine its
                 46 |     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
                                   47 |    PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not
                                   48 |    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
                                     49 |    and returns NEW-VALUE or signals a PROTOCOL-UNIMPLEMENTED error if
                                     50 |    the sequence protocol is not implemented for the class of
                                     51 |    SEQUENCE.
                                  • EXTERNAL GENERIC-FUNCTION

                                    EMPTYP

                                      • SEQUENCE
                                      Returns T if SEQUENCE is an empty sequence and NIL
                                       52 |    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
                                                 53 |    be mutated independently of ITERATOR.
                                              • EXTERNAL GENERIC-FUNCTION

                                                ITERATOR-ELEMENT

                                                  • SEQUENCE
                                                  • ITERATOR
                                                  Returns the element of SEQUENCE associated to the position of
                                                   54 |    ITERATOR.
                                                • EXTERNAL GENERIC-FUNCTION

                                                  (SETF ITERATOR-ELEMENT)

                                                    • NEW-VALUE
                                                    • SEQUENCE
                                                    • ITERATOR
                                                    Destructively modifies SEQUENCE by replacing the sequence element
                                                     55 |    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
                                                       56 |    correspond to the end of SEQUENCE) with respect to the iteration
                                                       57 |    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
                                                           58 |    depending on the iteration direction encoded in FROM-END.
                                                        • EXTERNAL GENERIC-FUNCTION

                                                          LENGTH

                                                            • SEQUENCE
                                                            Returns the length of SEQUENCE or signals a PROTOCOL-UNIMPLEMENTED
                                                             59 |    error if the sequence protocol is not implemented for the class of
                                                             60 |    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
                                                               61 |    are supplied, the subsequence bounded by START and END as nine
                                                               62 |    values:
                                                               63 | 
                                                               64 |    1. iterator state
                                                               65 |    2. limit
                                                               66 |    3. from-end
                                                               67 |    4. step function
                                                               68 |    5. endp function
                                                               69 |    6. element function
                                                               70 |    7. setf element function
                                                               71 |    8. index function
                                                               72 |    9. copy state function
                                                               73 | 
                                                               74 |    If FROM-END is NIL, the constructed iterator visits the specified
                                                               75 |    elements in the order in which they appear in SEQUENCE. Otherwise,
                                                               76 |    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
                                                                 77 |    same class as SEQUENCE. Elements of the new sequence are
                                                                 78 |    initialized to INITIAL-ELEMENT, if supplied, initialized to
                                                                 79 |    INITIAL-CONTENTS if supplied, or identical to the elements of
                                                                 80 |    SEQUENCE if neither is supplied. Signals a PROTOCOL-UNIMPLEMENTED
                                                                 81 |    error if the sequence protocol is not implemented for the class of
                                                                 82 |    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
                                                                   83 |    as three values:
                                                                   84 | 
                                                                   85 |    1. iterator state
                                                                   86 |    2. limit
                                                                   87 |    3. from-end
                                                                   88 | 
                                                                   89 |    The returned iterator can be used with the generic iterator
                                                                   90 |    functions ITERATOR-STEP, ITERATOR-ENDP, ITERATOR-ELEMENT, (SETF
                                                                   91 |    ITERATOR-ELEMENT), ITERATOR-INDEX and ITERATOR-COPY.
                                                                • EXTERNAL GENERIC-FUNCTION

                                                                  MAP

                                                                    • RESULT-PROTOTYPE
                                                                    • FUNCTION
                                                                    • SEQUENCE
                                                                    • &REST
                                                                    • SEQUENCES
                                                                    Implements CL:MAP for extended sequences.
                                                                     92 | 
                                                                     93 |     RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:MAP but
                                                                     94 |     receives a prototype instance of an extended sequence class
                                                                     95 |     instead of a type specifier. By dispatching on RESULT-PROTOTYPE,
                                                                     96 |     methods on this generic function specify how extended sequence
                                                                     97 |     classes act when they are specified as the result type in a CL:MAP
                                                                     98 |     call. RESULT-PROTOTYPE may not be fully initialized and thus
                                                                     99 |     should only be used for dispatch and to determine its class.
                                                                    100 | 
                                                                    101 |     Another difference to CL:MAP is that FUNCTION is a function, not a
                                                                    102 |     function designator.
                                                                  • EXTERNAL GENERIC-FUNCTION

                                                                    MERGE

                                                                      • RESULT-PROTOTYPE
                                                                      • SEQUENCE1
                                                                      • SEQUENCE2
                                                                      • PREDICATE
                                                                      • &KEY
                                                                      • KEY
                                                                      Implements CL:MERGE for extended sequences.
                                                                      103 | 
                                                                      104 |     RESULT-PROTOTYPE corresponds to the RESULT-TYPE of CL:MERGE but
                                                                      105 |     receives a prototype instance of an extended sequence class
                                                                      106 |     instead of a type specifier. By dispatching on RESULT-PROTOTYPE,
                                                                      107 |     methods on this generic function specify how extended sequence
                                                                      108 |     classes act when they are specified as the result type in a
                                                                      109 |     CL:MERGE call. RESULT-PROTOTYPE may not be fully initialized and
                                                                      110 |     thus should only be used for dispatch and to determine its class.
                                                                      111 | 
                                                                      112 |     Another difference to CL:MERGE is that PREDICATE is a function,
                                                                      113 |     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

                                                                                      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
                                                                                                                    114 |   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
                                                                                                                      115 |   state returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE and
                                                                                                                      116 |   ARGS. Elements of VARS may be NIL in which case the corresponding
                                                                                                                      117 |   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
                                                                                                                        118 |   bound to local functions which execute the iteration state query and
                                                                                                                        119 |   mutation functions returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE
                                                                                                                        120 |   and ARGS. STEP, ENDP, ELT, SETF, INDEX and COPY have dynamic
                                                                                                                        121 |   extent.
                                                                                                                    --------------------------------------------------------------------------------