159 lines
8.4 KiB
HTML
159 lines
8.4 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
|
|
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
|
|
<HEAD>
|
|
<TITLE>7.9. Structure Traversal and Side Effects</TITLE>
|
|
</HEAD>
|
|
<BODY>
|
|
<meta name="description" value=" Structure Traversal and Side Effects">
|
|
<meta name="keywords" value="clm">
|
|
<meta name="resource-type" value="document">
|
|
<meta name="distribution" value="global">
|
|
<P>
|
|
<b>Common Lisp the Language, 2nd Edition</b>
|
|
<BR> <HR><A NAME=tex2html2671 HREF="node93.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html2669 HREF="node76.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html2663 HREF="node91.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html2673 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html2674 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
|
<B> Next:</B> <A NAME=tex2html2672 HREF="node93.html"> Multiple Values</A>
|
|
<B>Up:</B> <A NAME=tex2html2670 HREF="node76.html"> Control Structure</A>
|
|
<B> Previous:</B> <A NAME=tex2html2664 HREF="node91.html"> The ``Program Feature''</A>
|
|
<HR> <P>
|
|
<H1><A NAME=SECTION001190000000000000000>7.9. Structure Traversal and Side Effects</A></H1>
|
|
<P>
|
|
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
|
|
<A NAME=STRUCTURETRAVERSALSECTION>X3J13</A> voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) <A NAME=7645> </A>
|
|
to restrict side effects during the course
|
|
of a built-in operation that can execute user-supplied code while
|
|
traversing a data structure.
|
|
<P>
|
|
Consider the following example:
|
|
<P><pre>
|
|
(let ((x '(apples peaches pumpkin pie)))
|
|
(dolist (z x)
|
|
(when (eq z 'peaches)
|
|
(setf (cddr x) '(mango kumquat)))
|
|
(format t " S " (car z))))
|
|
</pre><P>
|
|
Depending on the details of the implementation of <tt>dolist</tt>,
|
|
this bit of code could easily print
|
|
<P><pre>
|
|
apples peaches mango kumquat
|
|
</pre><P>
|
|
(which is perhaps what was intended), but it might as easily print
|
|
<P><pre>
|
|
apples peaches pumpkin pie
|
|
</pre><P>
|
|
Here is a plausible implementation of <tt>dolist</tt> that
|
|
produces the first result:
|
|
<P><pre>
|
|
(defmacro dolist ((var listform &optional (resultform ''nil))
|
|
&body body)
|
|
(let ((tailvar (gensym "DOLIST")))
|
|
`(do ((,tailvar ,listform (cdr ,tailvar)))
|
|
((null ,tailvar) ,resultform)
|
|
(let ((,var (car ,tailvar))) ,@body))
|
|
</pre><P>
|
|
But here is a plausible implementation of <tt>dolist</tt> that
|
|
produces the second result:
|
|
<P><pre>
|
|
(defmacro dolist ((var listform &optional (resultform ''nil))
|
|
&body body)
|
|
(let ((tailvar (gensym "DOLIST")))
|
|
`(do ((,tailvar ,listform))
|
|
((null ,tailvar) ,resultform)
|
|
(let ((,var (pop ,tailvar))) ,@body))
|
|
</pre><P>
|
|
<P>
|
|
The X3J13 recognizes and legitimizes varying implementation practices:
|
|
in general it is an error for code executed during a ``structure-traversing''
|
|
operation to destructively modify the structure in a way that might
|
|
affect the ongoing traversal operation. The committee identified in particular
|
|
the following special cases.
|
|
<P>
|
|
For list traversal operations, the <i>cdr</i> chain
|
|
may not be destructively modified.
|
|
<P>
|
|
For array traversal operations, the array may not be adjusted
|
|
(see <tt>adjust-array</tt>) and its fill pointer, if any, may not be modified.
|
|
<P>
|
|
For hash table operations (such as <tt>with-hash-table-iterator</tt>
|
|
and <tt>maphash</tt>), new entries may not be added or deleted,
|
|
<i>except</i> that the very entry being processed by user code
|
|
may be changed or deleted.
|
|
<P>
|
|
For package symbol operations (for example, <tt>with-package-iterator</tt>
|
|
and <tt>do-symbols</tt>), new symbols may not be interned in,
|
|
nor symbols uninterned from, the packages being traversed or
|
|
any packages they use, <i>except</i> that the very symbol
|
|
being processed by user code may be uninterned.
|
|
<P>
|
|
X3J13 noted that this vote is intended to clarify restrictions
|
|
on the use of structure traversal operations that are not themselves
|
|
inherently destructive; for example, it applies to <tt>map</tt> and <tt>dolist</tt>.
|
|
Destructive operators such as <tt>delete</tt> require even more complicated
|
|
restrictions and are addressed by a separate proposal.
|
|
<P>
|
|
The X3J13 vote did not specify a complete list of the operations to which these
|
|
restrictions apply. Table <A HREF="node92.html#TRAVERSALOPERATIONSTABLE">7-1</A>
|
|
shows what I believe to be a complete list of operations
|
|
that traverse structures and take user code as a body (in the case of
|
|
macros) or as a functional argument (in the case of functions).
|
|
<P>
|
|
In addition, note that user code should not modify list
|
|
structure that might be undergoing interpretation by the evaluator,
|
|
whether explicitly invoked via <tt>eval</tt> or implicitly invoked,
|
|
for example as in the case of a hook function (a <tt>defstruct</tt>
|
|
print function, the value of <tt>*evalhook*</tt> or <tt>*applyhook*</tt>, etc.)
|
|
that happens to be a closure of interpreted code. Similarly, <tt>defstruct</tt>
|
|
print functions and other hooks should not perform side effects
|
|
on data structures being printed or being processed by <tt>format</tt>, or on a
|
|
string given to <tt>make-string-input-stream</tt>. You get the idea;
|
|
be sensible.
|
|
<P>
|
|
Note that an operation such as <tt>mapcar</tt> or <tt>dolist</tt> traverses
|
|
not only <i>cdr</i> pointers (in order to chase down the list)
|
|
but also <i>car</i> pointers (in order to obtain the elements themselves).
|
|
The restriction against modification appears to apply to all these pointers.
|
|
<P>
|
|
<A NAME=TRAVERSALOPERATIONSTABLE> </A><listing>
|
|
Table 7-1: Structure Traversal Operations Subject to Side Effect Restrictions
|
|
-----------------------------------------------------------------------------
|
|
adjoin maphash reduce
|
|
assoc mapl remove
|
|
assoc-if maplist remove-duplicates
|
|
assoc-if-not member remove-if
|
|
count member-if remove-if-not
|
|
count-if member-if-not search
|
|
count-if-not merge set-difference
|
|
delete mismatch set-exclusive-or
|
|
delete-duplicates nintersection some
|
|
delete-if notany sort
|
|
delete-if-not notevery stable-sort
|
|
do-all-symbols nset-difference sublis
|
|
do-external-symbols nset-exclusive-or subsetp
|
|
do-symbols nsublis subst
|
|
dolist nsubst subst-if
|
|
eval nsubst-if subst-if-not
|
|
every nsubst-if-not substitute
|
|
find nsubstitute substitute-if
|
|
find-if nsubstitute-if substitute-if-not
|
|
find-if-not nsubstitute-if-not tree-equal
|
|
intersection nunion union
|
|
certain loop clauses position with-hash-table-iterator
|
|
map position-if with-input-from-string
|
|
mapc position-if-not with-output-to-string
|
|
mapcan rassoc with-package-iterator
|
|
mapcar rassoc-if
|
|
mapcon rassoc-if-not
|
|
-----------------------------------------------------------------------------
|
|
</listing>
|
|
|
|
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
|
|
<P>
|
|
<BR> <HR><A NAME=tex2html2671 HREF="node93.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html2669 HREF="node76.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html2663 HREF="node91.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html2673 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html2674 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
|
|
<B> Next:</B> <A NAME=tex2html2672 HREF="node93.html"> Multiple Values</A>
|
|
<B>Up:</B> <A NAME=tex2html2670 HREF="node76.html"> Control Structure</A>
|
|
<B> Previous:</B> <A NAME=tex2html2664 HREF="node91.html"> The ``Program Feature''</A>
|
|
<HR> <P>
|
|
<HR>
|
|
<P><ADDRESS>
|
|
AI.Repository@cs.cmu.edu
|
|
</ADDRESS>
|
|
</BODY>
|