Document extensible sequence protocol
authorChristophe Rhodes <c.rhodes@gold.ac.uk>
Thu, 5 Sep 2013 16:29:02 +0000 (17:29 +0100)
committerChristophe Rhodes <c.rhodes@gold.ac.uk>
Thu, 5 Sep 2013 16:30:33 +0000 (17:30 +0100)
Based on patch by Jan Moringen from lp#994528

NEWS
doc/manual/Makefile
doc/manual/beyond-ansi.texinfo
doc/manual/docstrings.lisp
doc/manual/intro.texinfo
src/code/seq.lisp
src/pcl/sequence.lisp

diff --git a/NEWS b/NEWS
index 900995a..1f9de42 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,11 @@
 ;;;; -*- coding: utf-8; fill-column: 78 -*-
 changes relative to sbcl-1.1.11:
   * enhancement: Add sb-bsd-sockets:socket-shutdown, for calling
-    shutdown(3). (lp#1207483 patch by Jan Moringen)
-  * optimization: EQUAL transform is smarter.
-    (lp#1220084 thanks to Elias Martenson)
+    shutdown(3). (thanks to Jan Moringen, lp#1207483)
+  * enhancement: document extensible sequences.  (thanks to Jan Moringen,
+    lp#994528)
+  * optimization: EQUAL transform is smarter.  (thanks to Elias Martenson,
+    lp#1220084)
   * bug fix: probe-file now can access symlinks to pipes and sockets in
     /proc/pid/fd on Linux. (reported by Eric Schulte)
   * bug fix: SBCL can now be built on Solaris x86-64.
index 2f15a72..e82c172 100644 (file)
@@ -19,7 +19,7 @@ MODULES=':sb-md5 :sb-queue :sb-concurrency :sb-rotate-byte :sb-grovel \
          :sb-sprof :sb-bsd-sockets :sb-cover :sb-posix'
 # List of package names that docstring docs will be created for.
 PACKAGES=":COMMON-LISP :SB-ALIEN :SB-DEBUG :SB-EXT :SB-GRAY :SB-MOP \
-         :SB-PCL :SB-SYS \
+          :SB-PCL :SB-SYS :SB-SEQUENCE \
           :SB-PROFILE :SB-THREAD :SB-MD5 :SB-QUEUE :SB-ROTATE-BYTE  \
           :SB-SPROF :SB-BSD-SOCKETS :SB-COVER :SB-POSIX :SB-CONCURRENCY"
 
@@ -110,7 +110,7 @@ tempfiles-stamp:
        touch tempfiles-stamp
 
 .PHONY: clean
-clean: 
+clean:
        rm -f *~ *.bak *.orig \#*\# .\#* texput.log *.fasl
        rm -rf $(HTMLDIRS) $(DOCSTRINGDIR)
        rm -f  $(HTMLFILES)
index 39f871f..75b1433 100644 (file)
@@ -7,20 +7,21 @@ ANSI standard. SBCL doesn't support as many extensions as CMUCL, but
 it still has quite a few.  @xref{Contributed Modules}.
 
 @menu
-* Reader Extensions::           
-* Package-Local Nicknames::     
-* Package Variance::            
-* Garbage Collection::          
-* Metaobject Protocol::         
-* Support For Unix::            
-* Customization Hooks for Users::  
-* Tools To Help Developers::    
-* Resolution of Name Conflicts::  
-* Hash Table Extensions::       
-* Random Number Generation::    
-* Miscellaneous Extensions::    
-* Stale Extensions::            
-* Efficiency Hacks::            
+* Reader Extensions::
+* Package-Local Nicknames::
+* Package Variance::
+* Garbage Collection::
+* Metaobject Protocol::
+* Extensible Sequences::
+* Support For Unix::
+* Customization Hooks for Users::
+* Tools To Help Developers::
+* Resolution of Name Conflicts::
+* Hash Table Extensions::
+* Random Number Generation::
+* Miscellaneous Extensions::
+* Stale Extensions::
+* Efficiency Hacks::
 @end menu
 
 @node Reader Extensions
@@ -69,7 +70,7 @@ Options are extended to include
 
 @itemize
 @item
-@code{:local-nicknames} @var{(local-nickname actual-package-name)}*
+@code{:local-nicknames (@var{local-nickname} @var{actual-package-name})*}
 
 The package has the specified local nicknames for the corresponding
 actual packages.
@@ -362,14 +363,218 @@ to the constant @code{+slot-unbound+}.
 
 @end itemize
 
+@node Extensible Sequences
+@comment  node-name,  next,  previous,  up
+@section Extensible Sequences
+
+@menu
+* Iterator Protocol::
+* Simple Iterator Protocol::
+@end menu
+
+ANSI Common Lisp has a class @code{sequence} with subclasses @code{list} and
+@code{vector} on which the ``sequence functions'' like @code{find},
+@code{subseq}, etc. operate. As an extension to the ANSI specification,
+SBCL allows additional subclasses of @code{sequence} to be defined
+@footnote{A motivation, rationale and additional examples for the design
+of this extension can be found in the paper @cite{Rhodes, Christophe
+(2007): User-extensible sequences in Common Lisp} available for download
+at
+@url{http://www.doc.gold.ac.uk/~mas01cr/papers/ilc2007/sequences-20070301.pdf}.}.
+@tindex @cl{sequence}
+@tindex @cl{vector}
+@findex @cl{find}
+@findex @cl{subseq}
+
+Users of this extension just make instances of @cl{sequence} subclasses
+and transparently operate on them using sequence functions:
+@lisp
+(coerce (subseq (make-instance 'my-sequence) 5 10) 'list)
+@end lisp
+From this perspective, no distinction between builtin and user-defined
+@code{sequence} subclasses should be necessary.
+@findex @cl{coerce}
+@findex @cl{subseq}
+@findex @cl{make-instance}
+@tindex @cl{list}
+
+Providers of the extension, that is of user-defined @code{sequence}
+subclasses, have to adhere to a ``sequence protocol'' which consists of
+a set of generic functions in the @code{sequence} package.
+@c
+A minimal @code{sequence} subclass has to specify @code{standard-object} and
+@code{sequence} as its superclasses and has to be the specializer of the
+@code{sequence} parameter of methods on at least the following generic
+functions:
+@tindex @cl{sequence}
+@tindex @cl{standard-object}
+
+@include fun-sb-sequence-length.texinfo
+@include fun-sb-sequence-elt.texinfo
+@include fun-sb-sequence-setf-elt.texinfo
+@include fun-sb-sequence-adjust-sequence.texinfo
+@include fun-sb-sequence-make-sequence-like.texinfo
+
+@code{make-sequence-like} is needed for functions returning
+freshly-allocated sequences such as @code{subseq} or
+@code{copy-seq}. @code{adjust-sequence} is needed for functions which
+destructively modify their arguments such as @code{delete}. In fact, all
+other sequence functions can be implemented in terms of the above
+functions and actually are, if no additional methods are
+defined. However, relying on these generic implementations, in
+particular not implementing the iterator protocol can incur a high
+performance penalty @xref{Iterator Protocol}.
+@tindex @cl{sequence}
+@findex @sequence{make-sequence-like}
+@findex @cl{subseq}
+@findex @cl{copy-seq}
+@findex @sequence{adjust-sequence}
+
+In addition to the mandatory functions above, methods on the following
+sequence functions can be defined:
+
+@include fun-sb-sequence-emptyp.texinfo
+
+@itemize
+@item
+@code{sb-sequence:count}, @code{sb-sequence:count-if}, @code{sb-sequence:count-if-not}
+
+@item
+@code{sb-sequence:find}, @code{sb-sequence:find-if}, @code{sb-sequence:find-if-not}
+
+@item
+@code{sb-sequence:position}, @code{sb-sequence:position-if}, @code{sb-sequence:position-if-not}
+
+@item
+@code{sb-sequence:subseq}
+
+@item
+@code{sb-sequence:copy-seq}
+
+@item
+@code{sb-sequence:fill}
+
+@item
+@code{sb-sequence:nsubstitute}, @code{sb-sequence:nsubstitute-if},
+@code{sb-sequence:nsubstitute-if-not}, @code{sb-sequence:substitute},
+@code{sb-sequence:substitute-if}, @code{sb-sequence:substitute-if-not}
+
+@item
+@code{sb-sequence:replace}
+
+@item
+@code{sb-sequence:nreverse}, @code{sb-sequence:reverse}
+
+@item
+@code{sb-sequence:reduce}
+
+@item
+@code{sb-sequence:mismatch}
+
+@item
+@code{sb-sequence:search}
+
+@item
+@code{sb-sequence:delete}, @code{sb-sequence:delete-if}, @code{sb-sequence:delete-if-not},
+@code{sb-sequence:remove}, @code{sb-sequence:remove-if}, @code{sb-sequence:remove-if-not},
+
+@item
+@code{sb-sequence:delete-duplicates}, @code{sb-sequence:remove-duplicates}
+
+@item
+@code{sb-sequence:sort}, @code{sb-sequence:stable-sort}
+@end itemize
+
+In the spirit of @code{dolist}, generic sequences can be traversed using
+the macro
+@findex @cl{dolist}
+
+@include macro-sb-sequence-dosequence.texinfo
+
+@node Iterator Protocol
+@comment  node-name,  next,  previous,  up
+@subsection Iterator Protocol
+
+The iterator protocol allows subsequently accessing some or all elements
+of a sequence in forward or reverse direction. Users first call
+@code{make-sequence-iterator} to create an iteration state and
+receive functions to query and mutate it. These functions allow, among
+other things, moving to, retrieving or modifying elements of the
+sequence. An iteration state consists of a state object, a limit object,
+a from-end indicator and the following six functions to query or mutate
+this state:
+@findex @sequence{make-sequence-iterator}
+@deffn {Function} @code{step function} sequence iterator from-end
+Moves the iterator one position forward or backward in the associated
+sequence depending on the iteration direction.
+@end deffn
+@deffn {Function} @code{endp function} sequence iterator limit from-end
+Returns non-@code{nil} when the iterator has reached the end of the
+associated sequence with respect to the iteration direction.
+@end deffn
+@deffn {Function} @code{element function} sequence iterator
+Returns the sequence element associated to the current position of the
+iteration.
+@end deffn
+@deffn {Function} @code{setf element function} new-value sequence iterator
+Destructively modifies the associates sequence by replacing the sequence
+element associated to the current iteration position with a new value.
+@end deffn
+@deffn {Function} @code{index function} sequence iterator
+Returns the position of the iteration in the associated sequence.
+@end deffn
+@deffn {Function} @code{copy function} sequence iterator
+Returns a copy of the iteration state which can be mutated independently
+of the copied iteration state.
+@end deffn
+
+An iterator is created by calling:
+
+@include fun-sb-sequence-make-sequence-iterator.texinfo
+
+Note that @code{make-sequence-iterator} calls
+@code{make-simple-sequence-iterator} when there is no specialized
+method for a particular @code{sequence} subclass. @xref{Simple Iterator
+Protocol}.
+@findex @sequence{make-sequence-iterator}
+@findex @sequence{make-simple-sequence-iterator}
+@tindex @cl{sequence}
+
+The following convenience macros simplify traversing sequences using
+iterators:
+
+@include macro-sb-sequence-with-sequence-iterator.texinfo
+@include macro-sb-sequence-with-sequence-iterator-functions.texinfo
+
+@node Simple Iterator Protocol
+@comment  node-name,  next,  previous,  up
+@subsection Simple Iterator Protocol
+
+For cases in which the full flexibility and performance of the general
+sequence iterator protocol is not required, there is a simplified
+sequence iterator protocol consisting of a few generic functions which
+can be specialized for iterator classes:
+
+@include fun-sb-sequence-iterator-step.texinfo
+@include fun-sb-sequence-iterator-endp.texinfo
+@include fun-sb-sequence-iterator-element.texinfo
+@include fun-sb-sequence-setf-iterator-element.texinfo
+@include fun-sb-sequence-iterator-index.texinfo
+@include fun-sb-sequence-iterator-copy.texinfo
+
+Iterator objects implementing the above simple iteration protocol are
+created by calling the following generic function:
+
+@include fun-sb-sequence-make-simple-sequence-iterator.texinfo
+
 @node  Support For Unix
 @comment  node-name,  next,  previous,  up
 @section Support For Unix
 
 @menu
-* Command-line arguments::      
-* Querying the process environment::  
-* Running external programs::   
+* Command-line arguments::
+* Querying the process environment::
+* Running external programs::
 @end menu
 
 @node Command-line arguments
index 8bd36b0..0648230 100644 (file)
@@ -847,6 +847,10 @@ package, as well as for the package itself."
 (defun write-package-macro (package)
   (let* ((package-name (package-shortest-name package))
          (macro-name (package-macro-name package)))
+    ;; KLUDGE: SB-SEQUENCE has a shorter nickname SEQUENCE, but we
+    ;; want to document the SB- variant.
+    (when (eql (find-package "SB-SEQUENCE") (find-package package))
+      (setf package-name "SB-SEQUENCE"))
     (write-packageish-macro package-name macro-name)))
 
 (defun write-packageish-macro (package-name macro-name)
index 3bc0efb..f494e19 100644 (file)
@@ -8,13 +8,13 @@ not on behavior which is common to all implementations of ANSI Common
 Lisp.
 
 @menu
-* ANSI Conformance::            
-* Extensions::                  
-* Idiosyncrasies::              
-* Development Tools::           
-* More SBCL Information::       
-* More Common Lisp Information::  
-* History and Implementation of SBCL::  
+* ANSI Conformance::
+* Extensions::
+* Idiosyncrasies::
+* Development Tools::
+* More SBCL Information::
+* More Common Lisp Information::
+* History and Implementation of SBCL::
 @end menu
 
 
@@ -65,6 +65,10 @@ non-blocking IO on multiple streams without using threads.
 @code{sb-mop} package provides a metaobject protocol for the Common
 Lisp Object System as described in @cite{Art of Metaobject Protocol}.
 
+@item Extensible Sequences
+SBCL allows users to define subclasses of the @code{sequence}
+class. @xref{Extensible Sequences}.
+
 @item Native Threads
 SBCL has native threads on x86/Linux, capable of taking advantage
 of SMP on multiprocessor machines. @xref{Threading}.
@@ -149,11 +153,11 @@ deals with choices that the ANSI standard leaves to the
 implementation.
 
 @menu
-* Declarations::                
-* FASL Format::                 
-* Compiler-only Implementation::  
-* Defining Constants::          
-* Style Warnings::              
+* Declarations::
+* FASL Format::
+* Compiler-only Implementation::
+* Defining Constants::
+* Style Warnings::
 @end menu
 
 @node Declarations
@@ -230,7 +234,7 @@ compiling and loading reasonable code like
 runs into this undefined behavior. Many implementations of Common Lisp
 try to help the programmer around this annoyance by silently accepting
 the undefined code and trying to do what the programmer probably
-meant. 
+meant.
 
 SBCL instead treats the undefined behavior as an error. Often such
 code can be rewritten in portable ANSI Common Lisp which has the
@@ -257,13 +261,13 @@ SBCL gives style warnings about various kinds of perfectly legal code,
 e.g.
 
 @itemize
-  
+
 @item
 @code{defmethod} without a preceding @code{defgeneric};
-  
+
 @item
 multiple @code{defun}s of the same symbol in different units;
-  
+
 @item
 special variables not named in the conventional @code{*foo*} style,
 and lexical variables unconventionally named in the @code{*foo*} style
@@ -291,9 +295,9 @@ case, but still isn't as of SBCL 0.7.6.)
 @section Development Tools
 
 @menu
-* Editor Integration::          
-* Language Reference::          
-* Generating Executables::      
+* Editor Integration::
+* Language Reference::
+* Generating Executables::
 @end menu
 
 @node Editor Integration
@@ -310,7 +314,7 @@ Currently @dfn{SLIME}@footnote{Historically, the ILISP package at
 @uref{http://ilisp.cons.org/} provided similar functionality, but it
 does not support modern SBCL versions.} (Superior Lisp Interaction
 Mode for Emacs) together with Emacs is recommended for use with
-SBCL, though other options exist as well. 
+SBCL, though other options exist as well.
 
 SLIME can be downloaded from
 @uref{http://www.common-lisp.net/project/slime/}.
@@ -342,10 +346,10 @@ sb-ext:save-lisp-and-die}.
 @section More SBCL Information
 
 @menu
-* SBCL Homepage::               
-* Online Documentation::        
-* Additional Documentation Files::  
-* Internals Documentation::     
+* SBCL Homepage::
+* Online Documentation::
+* Additional Documentation Files::
+* Internals Documentation::
 @end menu
 
 @node SBCL Homepage
@@ -420,9 +424,9 @@ it is not installed by default.
 @section More Common Lisp Information
 
 @menu
-* Internet Community::          
-* Third-party Libraries::       
-* Common Lisp Books::           
+* Internet Community::
+* Third-party Libraries::
+* Common Lisp Books::
 @end menu
 
 @node Internet Community
@@ -465,7 +469,7 @@ learn about Common Lisp, some books stand out:
 @item Practical Common Lisp, by Peter Seibel
 An excellent introduction to the language, covering both the basics
 and ``advanced topics'' like macros, CLOS, and packages. Available
-both in print format and on the web: @uref{http://www.gigamonkeys.com/book/}. 
+both in print format and on the web: @uref{http://www.gigamonkeys.com/book/}.
 
 @item Paradigms Of Artificial Intelligence Programming, by Peter Norvig
 Good information on general Common Lisp programming, and many
@@ -559,7 +563,7 @@ the @code{eval} function only truly ``interprets'' a few easy kinds of
 forms, such as symbols which are @code{boundp}. More complicated forms
 are evaluated by calling @code{compile} and then calling @code{funcall}
 on the returned result.
-  
+
 The direct ancestor of SBCL is the x86 port of CMUCL. This port was in
 some ways the most cobbled-together of all the CMUCL ports, since a
 number of strange changes had to be made to support the register-poor
index 2cd9d52..54c7c02 100644 (file)
@@ -798,24 +798,27 @@ many elements are copied."
 \f
 ;;;; CONCATENATE
 
-(defmacro sb!sequence:dosequence ((e sequence &optional return) &body body)
+(defmacro sb!sequence:dosequence ((element sequence &optional return) &body body)
+  #!+sb-doc
+  "Executes BODY with ELEMENT subsequently bound to each element of
+  SEQUENCE, then returns RETURN."
   (multiple-value-bind (forms decls) (parse-body body :doc-string-allowed nil)
     (let ((s sequence)
           (sequence (gensym "SEQUENCE")))
       `(block nil
         (let ((,sequence ,s))
           (seq-dispatch ,sequence
-            (dolist (,e ,sequence ,return) ,@body)
-            (do-vector-data (,e ,sequence ,return) ,@body)
+            (dolist (,element ,sequence ,return) ,@body)
+            (do-vector-data (,element ,sequence ,return) ,@body)
             (multiple-value-bind (state limit from-end step endp elt)
                 (sb!sequence:make-sequence-iterator ,sequence)
               (do ((state state (funcall step ,sequence state from-end)))
                   ((funcall endp ,sequence state limit from-end)
-                   (let ((,e nil))
+                   (let ((,element nil))
                      ,@(filter-dolist-declarations decls)
-                     ,e
+                     ,element
                      ,return))
-                (let ((,e (funcall elt ,sequence state)))
+                (let ((,element (funcall elt ,sequence state)))
                   ,@decls
                   (tagbody
                      ,@forms))))))))))
index 89912ad..f3a0cae 100644 (file)
 (defgeneric sequence:emptyp (sequence)
   (:method ((s list)) (null s))
   (:method ((s vector)) (zerop (length s)))
-  (:method ((s sequence)) (zerop (length s))))
+  (:method ((s sequence)) (zerop (length s)))
+  #+sb-doc
+  (:documentation
+   "Returns T if SEQUENCE is an empty sequence and NIL
+   otherwise. Signals an error if SEQUENCE is not a sequence."))
 
 (defgeneric sequence:length (sequence)
   (:method ((s list)) (length s))
   (:method ((s vector)) (length s))
-  (:method ((s sequence)) (sequence::protocol-unimplemented s)))
+  (:method ((s sequence)) (sequence::protocol-unimplemented s))
+  #+sb-doc
+  (:documentation
+   "Returns the length of SEQUENCE or signals a PROTOCOL-UNIMPLEMENTED
+   error if the sequence protocol is not implemented for the class of
+   SEQUENCE."))
 
 (defgeneric sequence:elt (sequence index)
   (:method ((s list) index) (elt s index))
   (:method ((s vector) index) (elt s index))
-  (:method ((s sequence) index) (sequence::protocol-unimplemented s)))
+  (:method ((s sequence) index) (sequence::protocol-unimplemented s))
+  #+sb-doc
+  (:documentation
+   "Returns the element at position INDEX of SEQUENCE or signals a
+   PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not
+   implemented for the class of SEQUENCE."))
 
 (defgeneric (setf sequence:elt) (new-value sequence index)
   (:argument-precedence-order sequence new-value index)
   (:method (new-value (s list) index) (setf (elt s index) new-value))
   (:method (new-value (s vector) index) (setf (elt s index) new-value))
   (:method (new-value (s sequence) index)
-    (sequence::protocol-unimplemented s)))
+    (sequence::protocol-unimplemented s))
+  #+sb-doc
+  (:documentation
+   "Replaces the element at position INDEX of SEQUENCE with NEW-VALUE
+   and returns NEW-VALUE or signals a PROTOCOL-UNIMPLEMENTED error if
+   the sequence protocol is not implemented for the class of
+   SEQUENCE."))
 
 (defgeneric sequence:make-sequence-like
     (sequence length &key initial-element initial-contents)
       (t (make-array length :element-type (array-element-type s)))))
   (:method ((s sequence) length &key initial-element initial-contents)
     (declare (ignore initial-element initial-contents))
-    (sequence::protocol-unimplemented s)))
+    (sequence::protocol-unimplemented s))
+  #+sb-doc
+  (:documentation
+   "Returns a freshly allocated sequence of length LENGTH and of the
+   same class as SEQUENCE. Elements of the new sequence are
+   initialized to INITIAL-ELEMENT, if supplied, initialized to
+   INITIAL-CONTENTS if supplied, or identical to the elements of
+   SEQUENCE if neither is supplied. Signals a PROTOCOL-UNIMPLEMENTED
+   error if the sequence protocol is not implemented for the class of
+   SEQUENCE."))
 
 (defgeneric sequence:adjust-sequence
     (sequence length &key initial-element initial-contents)
       (t (apply #'adjust-array s length args))))
   (:method (new-value (s sequence) &rest args)
     (declare (ignore args))
-    (sequence::protocol-unimplemented s)))
+    (sequence::protocol-unimplemented s))
+  #+sb-doc
+  (:documentation
+   "Return destructively modified SEQUENCE or a freshly allocated
+   sequence of the same class as SEQUENCE of length LENGTH. Elements
+   of the returned sequence are initialized to INITIAL-ELEMENT, if
+   supplied, initialized to INITIAL-CONTENTS if supplied, or identical
+   to the elements of SEQUENCE if neither is supplied. Signals a
+   PROTOCOL-UNIMPLEMENTED error if the sequence protocol is not
+   implemented for the class of SEQUENCE."))
+
 \f
 ;;;; iterator protocol
 
     (declare (ignore from-end start end))
     (error 'type-error
            :datum s
-           :expected-type 'sequence)))
+           :expected-type 'sequence))
+  #+sb-doc
+  (:documentation
+   "Returns a sequence iterator for SEQUENCE or, if START and/or END
+   are supplied, the subsequence bounded by START and END as nine
+   values:
+
+   1. iterator state
+   2. limit
+   3. from-end
+   4. step function
+   5. endp function
+   6. element function
+   7. setf element function
+   8. index function
+   9. copy state function
+
+   If FROM-END is NIL, the constructed iterator visits the specified
+   elements in the order in which they appear in SEQUENCE. Otherwise,
+   the elements are visited in the opposite order."))
 
 ;;; the simple protocol: the simple iterator returns three values,
 ;;; STATE, LIMIT and FROM-END.
     (let ((end (or end (length s))))
       (if from-end
           (values (1- end) (1- start) from-end)
-          (values start end nil)))))
+          (values start end nil))))
+  #+sb-doc
+  (:documentation
+   "Returns a sequence iterator for SEQUENCE, START, END and FROM-END
+   as three values:
+
+   1. iterator state
+   2. limit
+   3. from-end
+
+   The returned iterator can be used with the generic iterator
+   functions ITERATOR-STEP, ITERATOR-ENDP, ITERATOR-ELEMENT, (SETF
+   ITERATOR-ELEMENT), ITERATOR-INDEX and ITERATOR-COPY."))
 
 (defgeneric sequence:iterator-step (sequence iterator from-end)
   (:method ((s list) iterator from-end)
   (:method ((s sequence) iterator from-end)
     (if from-end
         (1- iterator)
-        (1+ iterator))))
+        (1+ iterator)))
+  #+sb-doc
+  (:documentation
+   "Moves ITERATOR one position forward or backward in SEQUENCE
+   depending on the iteration direction encoded in FROM-END."))
 
 (defgeneric sequence:iterator-endp (sequence iterator limit from-end)
   (:method ((s list) iterator limit from-end)
   (:method ((s vector) iterator limit from-end)
     (= iterator limit))
   (:method ((s sequence) iterator limit from-end)
-    (= iterator limit)))
+    (= iterator limit))
+  #+sb-doc
+  (:documentation
+   "Returns non-NIL when ITERATOR has reached LIMIT (which may
+   correspond to the end of SEQUENCE) with respect to the iteration
+   direction encoded in FROM-END."))
 
 (defgeneric sequence:iterator-element (sequence iterator)
   (:method ((s list) iterator)
   (:method ((s vector) iterator)
     (aref s iterator))
   (:method ((s sequence) iterator)
-    (elt s iterator)))
+    (elt s iterator))
+  #+sb-doc
+  (:documentation
+   "Returns the element of SEQUENCE associated to the position of
+   ITERATOR."))
 
 (defgeneric (setf sequence:iterator-element) (new-value sequence iterator)
   (:method (o (s list) iterator)
   (:method (o (s vector) iterator)
     (setf (aref s iterator) o))
   (:method (o (s sequence) iterator)
-    (setf (elt s iterator) o)))
+    (setf (elt s iterator) o))
+  #+sb-doc
+  (:documentation
+   "Destructively modifies SEQUENCE by replacing the sequence element
+   associated to position of ITERATOR with NEW-VALUE."))
 
 (defgeneric sequence:iterator-index (sequence iterator)
   (:method ((s list) iterator)
     ;; Apple implementation in Dylan...)
     (loop for l on s for i from 0 when (eq l iterator) return i))
   (:method ((s vector) iterator) iterator)
-  (:method ((s sequence) iterator) iterator))
+  (:method ((s sequence) iterator) iterator)
+  #+sb-doc
+  (:documentation
+   "Returns the position of ITERATOR in SEQUENCE."))
 
 (defgeneric sequence:iterator-copy (sequence iterator)
   (:method ((s list) iterator) iterator)
   (:method ((s vector) iterator) iterator)
-  (:method ((s sequence) iterator) iterator))
+  (:method ((s sequence) iterator) iterator)
+  #+sb-doc
+  (:documentation
+   "Returns a copy of ITERATOR which also traverses SEQUENCE but can
+   be mutated independently of ITERATOR."))
 
 (defmacro sequence:with-sequence-iterator
-    ((&rest vars) (s &rest args &key from-end start end) &body body)
+    ((&rest vars) (sequence &rest args &key from-end start end) &body body)
+  #+sb-doc
+  "Executes BODY with the elements of VARS bound to the iteration
+  state returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE and
+  ARGS. Elements of VARS may be NIL in which case the corresponding
+  value returned by MAKE-SEQUENCE-ITERATOR is ignored."
   (declare (ignore from-end start end))
   (let* ((ignored '())
          (vars (mapcar (lambda (x)
                                  (push name ignored)
                                  name)))
                        vars)))
-   `(multiple-value-bind (,@vars) (sequence:make-sequence-iterator ,s ,@args)
+   `(multiple-value-bind (,@vars) (sequence:make-sequence-iterator ,sequence ,@args)
       (declare (type function ,@(nthcdr 3 vars))
                (ignore ,@ignored))
       ,@body)))
 
 (defmacro sequence:with-sequence-iterator-functions
     ((step endp elt setf index copy)
-     (s &rest args &key from-end start end)
+     (sequence &rest args &key from-end start end)
      &body body)
+  #+sb-doc
+  "Executes BODY with the names STEP, ENDP, ELT, SETF, INDEX and COPY
+  bound to local functions which execute the iteration state query and
+  mutation functions returned by MAKE-SEQUENCE-ITERATOR for SEQUENCE
+  and ARGS. STEP, ENDP, ELT, SETF, INDEX and COPY have dynamic
+  extent."
   (declare (ignore from-end start end))
   (let ((nstate (gensym "STATE")) (nlimit (gensym "LIMIT"))
         (nfrom-end (gensym "FROM-END-")) (nstep (gensym "STEP"))
         (ncopy (gensym "COPY")))
     `(sequence:with-sequence-iterator
          (,nstate ,nlimit ,nfrom-end ,nstep ,nendp ,nelt ,nsetf ,nindex ,ncopy)
-       (,s ,@args)
-       (flet ((,step () (setq ,nstate (funcall ,nstep ,s ,nstate ,nfrom-end)))
-              (,endp () (funcall ,nendp ,s ,nstate ,nlimit ,nfrom-end))
-              (,elt () (funcall ,nelt ,s ,nstate))
-              (,setf (new-value) (funcall ,nsetf new-value ,s ,nstate))
-              (,index () (funcall ,nindex ,s ,nstate))
-              (,copy () (funcall ,ncopy ,s ,nstate)))
+       (,sequence,@args)
+       (flet ((,step () (setq ,nstate (funcall ,nstep ,sequence,nstate ,nfrom-end)))
+              (,endp () (funcall ,nendp ,sequence,nstate ,nlimit ,nfrom-end))
+              (,elt () (funcall ,nelt ,sequence,nstate))
+              (,setf (new-value) (funcall ,nsetf new-value ,sequence,nstate))
+              (,index () (funcall ,nindex ,sequence,nstate))
+              (,copy () (funcall ,ncopy ,sequence,nstate)))
          (declare (truly-dynamic-extent #',step #',endp #',elt
                                   #',setf #',index #',copy))
          ,@body))))