summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-06-05 21:11:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-06-05 21:11:34 -0700
commit78737373eb4142158181ad4305ab21936b487833 (patch)
treec904646d51631a13bbd47671e2354497680730eb /txr.1
parenteb2d229637284ac6b8822357ce59c007742c825c (diff)
downloadtxr-78737373eb4142158181ad4305ab21936b487833.tar.gz
txr-78737373eb4142158181ad4305ab21936b487833.tar.bz2
txr-78737373eb4142158181ad4305ab21936b487833.zip
doc: update nullify documentation.
* txr.1: Nullify documentation updated and clarified, with examples.
Diffstat (limited to 'txr.1')
-rw-r--r--txr.1110
1 files changed, 71 insertions, 39 deletions
diff --git a/txr.1 b/txr.1
index 663bff26..4d36cde8 100644
--- a/txr.1
+++ b/txr.1
@@ -33191,62 +33191,94 @@ The
function returns
.code nil
if
-.meta obj
-is an empty sequence.
+.meta iterable
+denotes an empty sequence.
Otherwise, if
-.meta obj
+.meta iterable
is not an empty sequence, or isn't a sequence, then
-.meta obj
+.meta iterable
itself is returned.
If
-.meta obj
-is a structure, then
-.meta obj
-is returned if it doesn't support the
+.meta iterable
+is a structure object which supports the
.code nullify
-method, even if it has other methods such as
-.code length
-by which it could be inferred that it represents an empty sequence.
-
-If
-.meta obj
-has a
+method, then that method is called. If it returns
+.code nil
+then
+.code nil
+is returned. If the
.code nullify
-method, then the
+method returns a substitute object other than the
+.meta iterable
+object itself, then
.code nullify
-function invokes that method and returns whatever value
-that method returns.
+is invoked on that returned substitute object.
Note: the
.code nullify
function is a helper to support unoptimized generic
-programming over sequences. Thanks to the generic behavior of
+traversal of sequences. Thanks to the generalized behavior of
.codn cdr ,
-any sequence can be traversed using
-.code cdr
-functions, checking for the
-.code nil
-value as a terminator. This, however, breaks for empty sequences which are not
-lists, because they are not equal to
-.codn nil :
-to
-.code car
-and
+non-list sequences can be traversed using
+.codn cdr ,
+similarly to proper lists, by checking for
.code cdr
-they look like
-a one-element sequence containing
+returning the terminating value
.codn nil .
+However, empty non-list sequences are handled incorrectly because
+since they are not the
+.code nil
+object, they look non-empty under this paradigm of traversal.
The
.code nullify
-function reduces all empty
-sequences to
-.codn nil ,
-thereby correcting the behavior of code which traverses
-sequences using
-.codn cdr ,
-and tests for termination with
-.codn nil .
+function provides a correction: if the input sequence is filtered
+through
+.code nullify
+then the subsequent list-like iteration works correctly.
+
+Examples:
+
+.verb
+ ;; Incorrect for empty strings:
+
+ (defun print-chars (string)
+ (while string
+ (prinl (pop string))))
+
+ ;; Corrected with nullify:
+
+ (defun print-chars (string)
+ (let ((s (nullify string)))
+ (while s
+ (prinl (pop s)))))
+.brev
+
+Note: optimized generic iteration is available in the form of iteration
+based on
+.code iter-begin
+rather than
+.cod3 car / cdr
+and
+.codn nullify .
+
+Examples:
+
+.verb
+ ;; Efficient with iterators,
+ ;; at the cost of verbosity:
+
+ (defun print-chars (string)
+ (let ((i (iter-begin string)))
+ (while (iter-more i)
+ (prinl (iter-item s))
+ (set s (iter-step s)))))
+
+ ;; Using mapping function built on iterators:
+
+ (defun print-chars (string)
+ [mapdo prinl string])
+.brev
.SS* Open Sequence Traversal