Jump to content

Page:AITR-474.djvu/62

From Wikisource
This page has been proofread, but needs to be validated.
52
(LAMBDA (A B C)
        ((LAMBDA (Q1 Q2 Q3)
                 (LIST (/ (+ Q1 Q2) Q3)
                       (/ (- Q1 Q2) Q3)))
         (- B)
         (SQRT (- (^ B 2) (* 4 A C)))
         (* 2 A)))

(There would be no problem of conflicting names as there is for macro rules, because we are operating on code for which all variables have already been renamed; Q1, Q2, and Q3 can be chosen as the next variables in the renaming sequence.)

This approach doesn't always work if side-effects are present; the abstracted (!) common subexpression may be evaluated too soon, or the wrong number of times. This can be solved by wrapping (LAMBDA () ⭙) around the common subexpression, and replacing references by a combination instead of a simple variable reference. For example:

(IF (HAIRYP X)
    (BLOCK (PRINT '|Here is some hair:|)
           (PRINT X)
           (PRINT '|End of hair.|))
    (BLOCK (PRINT '|This one is bald:|)
           (PRINT X)
           (PRINT '|End of baldness.|)))

We could not transform it into this:

((LAMBDA (Q1)
         (IF (HAIRYP X)
             (BLOCK (PRINT '|Here is some hair:|)
                    Q1
                    (PRINT '|End of hair.|))
             (BLOCK (PRINT '|This one is bald:|)
                    Q1
                    (PRINT '|End of baldness.|))))
 (PRINT X))

because x would be printed before the appropriate leading message. Instead, we