summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-06-05 06:28:00 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-06-05 06:28:00 -0700
commitcdf097ba3d23921a806b103948e0111fca07595e (patch)
tree22ea4bd1502b6b0b17ce83dd56c6ca212d61a974 /txr.1
parentdcdd3e1bec7786ffc047d0c6f6e1def4497becf8 (diff)
downloadtxr-cdf097ba3d23921a806b103948e0111fca07595e.tar.gz
txr-cdf097ba3d23921a806b103948e0111fca07595e.tar.bz2
txr-cdf097ba3d23921a806b103948e0111fca07595e.zip
doc: new Generalization of Iteration section.
* txr.1: New section added under TXR LISP to introduce the new iteration concept.
Diffstat (limited to 'txr.1')
-rw-r--r--txr.1120
1 files changed, 120 insertions, 0 deletions
diff --git a/txr.1 b/txr.1
index 9690b4c7..2e29a48d 100644
--- a/txr.1
+++ b/txr.1
@@ -12427,6 +12427,126 @@ The lazy versions of these functions such as
do not have this behavior;
they produce lazy lists.
+.SS* Generalization of Iteration
+
+\*(TL implements a unified paradigm for iterating over sequence-like
+container structures and abstract spaces such as bounded and unbounded ranges
+of integers. This concept is based around an iterator abstraction which is
+directly compatible with Lisp cons cell traversal in the sense that when
+iteration takes place over lists, the iterator instance is nothing but a cons
+cell.
+
+An iterator is created using the constructor function
+.code iter-begin
+which takes a single argument. The argument denotes a space to be traversed;
+the iterator provides the means for that traversal.
+
+When the
+.code iter-begin
+function is applied to a list (a
+.code cons
+cell or the
+.code nil
+object), the return value is that object itself. The remaining functions
+in the iterator API then behave like aliases for list processing functions.
+The
+.code iter-more
+function behaves like
+.codn identity ,
+.code iter-item
+behaves like
+.code car
+and
+.code iter-step
+behaves like
+.codn cdr .
+
+For example, the following loops not only produce identical behavior,
+but the
+.code iter
+variable steps through the
+.code cons
+cells in the same manner in both:
+
+.verb
+ ;; print all symbols in the list (a b c d):
+
+ (let ((iter '(a b c d)))
+ (while iter
+ (prinl (car iter))
+ (set iter (cdr iter))))
+
+ ;; likewise:
+
+ (let ((iter (iter-begin '(a b c d))))
+ (while (iter-more iter)
+ (prinl (iter-item iter))
+ (set iter (iter-step iter))))
+.brev
+
+There are three important differences.
+
+Firstly, both examples will still work
+if the list
+.code "(a b c d)"
+is replaced by a different kind of sequence, such as the string
+.str abcd
+or the vector
+.codn "#(a b c d)" .
+However, the former example will not execute efficiently on these objects.
+The reason is that the
+.code cdr
+function will construct successive suffixes of the string and list object.
+That requires not only the allocation of memory, but changes the running time
+complexity of the loop from linear to quadratic.
+
+Secondly, the former example with
+.cod3 car / cdr
+will not work correctly if the sequence is an empty non-list sequence, like
+the null string or empty vector. Rectifying this problem requires the
+.code nullify
+function to be used:
+
+.verb
+ ;; print all symbols in the list (a b c d):
+
+ (let ((iter (nullify "abcd")))
+ (while iter
+ (prinl (car iter))
+ (set iter (cdr iter))))
+.brev
+
+The
+.code nullify
+function converts empty sequences of all kinds into the empty list
+.codn nil .
+
+Thirdly, the second
+example will work even if the input list is replaced with certain objects
+which are not sequences at all:
+
+.verb
+ ;; Print the integers from 0 to 3
+
+ (let ((iter (iter-begin 0..4)))
+ (while (iter-more iter)
+ (prinl (iter-item iter))
+ (set iter (iter-step iter))))
+
+ ;; Print incrementing integers starting at 1,
+ ;; breaking out of the loop after 100.
+
+ (let ((iter (iter-begin 1)))
+ (while (iter-more iter)
+ (if (eql 100 (prinl (iter-item iter)))
+ (return))
+ (set iter (iter-step iter))))
+.brev
+
+In \*(TL, numerous functions that appear as list processing functions in other
+contemporary Lisp dialects, and historically, are actually sequence processing
+functions based on the above iterator paradigm.
+
.SS* Callable Objects
In \*(TL, sequences (strings, vectors and lists) as well as hashes and