Jump to content

Page:AITR-474.djvu/41

From Wikisource
This page has been proofread, but needs to be validated.
31

arguments", but we shall continue to be sloppy where no confusion should arise.)

This is a technique which should be understood quite thoroughly, since it is the key to writing correct macro rules without any possibility of conflicts between names used by the user and those needed by the macro. As another example, let us consider the AND and OR constructs as used by most LISP systems. OR evaluates its arguments one by one, in order, returning the first non-NIL value obtained (without evaluating any of the following arguments), or NIL if all arguments produce NIL. AND is the dual to this; it returns NIL if any argument does, and otherwise the value of the last argument. A simple-minded approach to OR would be:

(OR)          => 'NIL
(OR x . rest) => (IF x x (OR . rest))

There is an objection to this, which is that the code for x is duplicated. Not only does this consume extra space, but it can execute erroneously if x has any side-effects. We must arrange to evaluate x only once, and then test its value:

(OR)          => 'NIL
(OR x . rest) => ((LAMBDA (V) (IF V V (OR . rest))) x)

This certainly evaluates x only once, but admits a possible naming conflict between the variable V and any variables used by rest. This is avoided by the same technique used for BLOCK:

(OR)          => 'NIL
(OR x . rest) => ((LAMBDA (V R) (IF V V (R)))
                  x
                  (LAMBDA () (OR . rest)))

Similarly, we can express AND as follows: