• 沒有找到結果。

When Nothing Else Will Do

在文檔中 Bottom-upDesign Preface (頁 115-118)

When to Use Macros

8.1 When Nothing Else Will Do

interesting) class of borderline cases, in which an operator might justifiably be written as a function or a macro. For these situations, Section 8.2 gives the arguments for and against macros. Finally, having considered what macros are capable of doing, we turn in Section 8.3 to a related question: what kinds of things do people do with them?

8.1 When Nothing Else Will Do

It’s a general principle of good design that if you find similar code appearing at several points in a program, you should write a subroutine and replace the similar sequences of code with calls to the subroutine. When we apply this principle to Lisp programs, we have to decide whether the “subroutine” should be a function or a macro.

In some cases it’s easy to decide to write a macro instead of a function, because only a macro can do what’s needed. A function like 1+ could conceivably

106

8.1 WHEN NOTHING ELSE WILL DO 107

be written as either a function or a macro:

(defun 1+ (x) (+ 1 x)) (defmacro 1+ (x) ‘(+ 1 ,x))

But while, from Section 7.3, could only be defined as a macro:

(defmacro while (test &body body)

‘(do ()

((not ,test)) ,@body))

There is no way to duplicate the behavior of this macro with a function. The definition of while splices the expressions passed as body into the body of a do, where they will be evaluated only if the test expression returns nil. No function could do that; in a function call, all the arguments are evaluated before the function is even invoked.

When you do need a macro, what do you need from it? Macros can do two things that functions can’t: they can control (or prevent) the evaluation of their arguments, and they are expanded right into the calling context. Any application which requires macros requires, in the end, one or both of these properties.

The informal explanation that “macros don’t evaluate their arguments” is slightly wrong. It would be more precise to say that macros control the evaluation of the arguments in the macro call. Depending on where the argument is placed in the macro’s expansion, it could be evaluated once, many times, or not at all.

Macros use this control in four major ways:

1. Transformation. The Common Lisp setf macro is one of a class of macros which pick apart their arguments before evaluation. A built-in access func-tion will often have a converse whose purpose is to set what the access function retrieves. The converse of car is rplaca, of cdr, rplacd, and so on. With setf we can use calls to such access functions as if they were variables to be set, as in (setf (car x) ’a), which could expand into (progn (rplaca x ’a) ’a).

To perform this trick, setf has to look inside its first argument. To know that the case above requires rplaca, setf must be able to see that the first argument is an expression beginning with car. Thus setf, and any other operator which transforms its arguments, must be written as a macro.

2. Binding. Lexical variables must appear directly in the source code. The first argument to setq is not evaluated, for example, so anything built on setq must be a macro which expands into a setq, rather than a function which

calls it. Likewise for operators like let, whose arguments are to appear as parameters in a lambda expression, for macros like do which expand into lets, and so on. Any new operator which is to alter the lexical bindings of its arguments must be written as a macro.

3. Conditional evaluation. All the arguments to a function are evaluated. In constructs like when, we want some arguments to be evaluated only under certain conditions. Such flexibility is only possible with macros.

4. Multiple evaluation. Not only are the arguments to a function all evaluated, they are all evaluated exactly once. We need a macro to define a construct like do, where certain arguments are to be evaluated repeatedly.

There are also several ways to take advantage of the inline expansion of macros.

It’s important to emphasize that the expansions thus appear in the lexical context of the macro call, since two of the three uses for macros depend on that fact. They are:

5. Using the calling environment. A macro can generate an expansion con-taining a variable whose binding comes from the context of the macro call.

The behavior of the following macro:

(defmacro foo (x)

‘(+ ,x y))

depends on the binding of y where foo is called.

This kind of lexical intercourse is usually viewed more as a source of con-tagion than a source of pleasure. Usually it would be bad style to write such a macro. The ideal of functional programming applies as well to macros:

the preferred way to communicate with a macro is through its parameters.

Indeed, it is so rarely necessary to use the calling environment that most of the time it happens, it happens by mistake. (See Chapter 9.) Of all the macros in this book, only the continuation-passing macros (Chapter 20) and some parts of theATNcompiler (Chapter 23) use the calling environment in this way.

6. Wrapping a new environment. A macro can also cause its arguments to be evaluated in a new lexical environment. The classic example is let, which could be implemented as a macro on lambda (page 144). Within the body of an expression like (let ((y 2)) (+ x y)), y will refer to a new variable.

在文檔中 Bottom-upDesign Preface (頁 115-118)