(AND) => 'T
(AND x) => x
(AND x . rest) => ((LAMBDA (V R) (IF V (R) 'NIL))
x
(LAMBDA () (AND . rest)))
(The macro rules are not precise duals because of the non-duality between NIL-ness and non-NIL-ness, and the requirement that a successful AND return the actual value of the last argument and not just T.) {Note Tail-Recursive OR}
As yet another example, consider a modification to BLOCK to allow a limited form of assignment statement: if (v := x) appears as a statement in a block, it "assigns" a value to the variable v whose scope is the remainder of the block. Let us assume that such a statement cannot occur as the last statement of a block (it would be useless to have one in that position, as the variable would have a null scope). we can write the rule:
(BLOCK x) => x
(BLOCK (v := x) . rest) => ((LAMBDA (v) (BLOCK . rest)) x)
(BLOCK x . rest) => ((LAMBDA (A B) (B))
x
(LAMBDA () (BLOCK . rest)))
The second subrule states that an "assignment" causes x to be evaluated and then bound to v, and that the variable v is visible to the rest of the block.
We may think of := as a "sub-macro keyword" which is used to mark an expression as suitable for transformation, but only in the context of a certain larger transformation. This idea is easily extended to allow other constructions, such as "simultaneous assignments" of the form
((var1 var2 ... varn) := value1 value2 ... valuen)
which first compute all the values and then assign to all the variables, and "exchange assignments" of the form (X :=: Y), as follows: