Common Lisp the Language 2nd Edition


next up previous contents index
Next: Optimization Up: Series Functions Previous: Collectors

A.2.6. Alteration of Series

change_begin
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)))


change_end



next up previous contents index
Next: Optimization Up: Series Functions Previous: Collectors


AI.Repository@cs.cmu.edu