Common Lisp the Language, 2nd Edition
Next: Optimization
Up: Series Functions
Previous: Collectors
Series that come from scanning data structures such as lists and vectors
are closely linked to these structures. The function alter
can be used to modify the underlying data structure with reference to
the series derived from it. (Conversely, it is possible to modify a
series by destructively modifying the data structure it is derived from.
However, given the lazy evaluation nature of series, the effects of such
modifications can be very hard to predict. As a result, this kind of
modification is inadvisable.)
[Function]
alter
destinations
items
alter
changes the series destinations so that
it contains the elements in the series items. More importantly,
in the manner of setf
, the data structure that underlies
destinations is changed so that if the series
destinations were to be regenerated, the new values would be
obtained. The alteration process stops as soon as either input runs out
of elements. The value nil
is always returned. In the
example below each negative element in a list is replaced with its
square.
(let* ((data (list 1 -2 3 4 -5 6))
(x (choose-if #'minusp (scan data))))
(alter x (#M* x x))
data)
=> (1 4 3 4 25 6)
alter
can be applied only to series that are
alterable. scan
, scan-alist
,
scan-multiple
, scan-plist
, and
scan-lists-of-lists-fringe
produce alterable series.
However, the alterability of the output of
scan-lists-of-lists-fringe
is incomplete. If
scan-lists-of-lists-fringe
is applied to an object that is
a leaf, altering the output series does not change the object.
In general, the output of a transducer is alterable as long as the
elements of the output come directly from the elements of an input that
is alterable. In particular, the outputs of choose
,
choose-if
, split
, split-if
,
cotruncate
, until
, until-if
, and
subseries
are alterable as long as the corresponding inputs
are alterable.
[Function]
to-alter
items
alter-fn
&rest
args
Given a series items, to-alter
returns an
alterable series A containing the same elements. The argument
alter-fn is a function. The remaining arguments are all series.
Let these series be S1, …, Sn. If
there are n arguments after alter-fn,
alter-fn must accept n+1 inputs. If
(alter
A
B
)
is later encountered, the expression
(map-fn t
alter-fn
B
S1
...
Sn
)
is implicitly evaluated. For each element in B,
alter-fn should make appropriate changes in the data structure
underlying A.
As an example, consider the following definition of a series function that scans the elements of a list. Alteration is performed by changing cons cells in the list being scanned.
(defun scan-list (list)
(declare (optimizable-series-function))
(let ((sublists (scan-sublists list)))
(to-alter (#Mcar sublists)
#'(lambda (new parent) (setf (car parent) new))
sublists)))
Next: Optimization
Up: Series Functions
Previous: Collectors
AI.Repository@cs.cmu.edu