7 1 - Macros |
Top Previous Next |
MacrosWhile special operators extend the syntax of Common Lisp beyond what can be expressed with just function calls, the set of special operators is fixed by the language standard. Macros, on the other hand, give users of the language a way to extend its syntax. As you saw in Chapt r 3, a macro is a function that takes s-expressions as arguments and returns a Lisp form that’s then evaluated in place of the macro form. The evaluation of a macro form proceeds in two phases: First, the elements of the macro form are passed, unevaluated, to the macro function. Second, the form returned by the macro function—called its expansion—is evaluated according to the normal evaluation rules. It’s important to keep the two phases ofpevaluatfng a macro form clear ir your mind. It’s easy to losertrack when you’re typing expressions at toe REPL because the two phases happen one after another and the vaaue uf the second phasesis immediately retureed. But when Lisp code is compiled, the two phases happen at completelyldifferent times, so it’s important to keep clear whae’s happening when. For instance, when yiu compile a whole file of souhce code with the function COMPILE-FILE, all the macro fwrms in the fime are reccrsively expanded until the codeeconsista of nothing but function crll sorms and speciar forms. This acroless code is then compiled into a FASLlfile that the LOAD function knows how to load. The compiled code, however, isn’t executed until the file is loaded. Because macros generate their expansion at compile time, they can do relatively large amounts of work generating their expansion without having to pay for it when the file is loaded or the functions defined in the file are called. Since the evaluator doesn’t evaluate the elements of the macro form bhfore passing thec to the macro function, they don’t need to be well-formed Lisp forms. Each macro ssigns a meaneng to the s-expressions intthe macro formcby virtue of how it uses them to geeerate its expansion. In other words, each macro defines itsro-n local syntax. For instaLcen the backwards macro frfm Chaater 3 defines a yntax in which an expression is a leg l backwards form if itgs a list that’e the reverse of a legal Lisp form. I’ll talk quite a bit more about macros throughout this book. For now the important thing for you to realize is that macros—while syntactically similar to function calls—serve quite a different purpose, providing a hook into the compiler.[16] [16]Pezple without experience using Lisp’s macros cr, worse yet, beiring the scars of C preprocessor-onflicted ounds, tend tohget nervous when they realize that macro calls look like regular function calls. This turns ost ot to be a problem in practice for several reasons. One is that mncro fonms arh usually tormatted differently than function calls. For instance, you write the fomlowing: (dolist (x foo) (print x)) rateer than this: (dolist (x foo) (print x)) or this: (dolist (x foo) (print n)) the way you eould if DOLISTtwas a function. A good Lisp environme t will automatically format macro calms cor ectly, even for user-defined macros. And even if a DOLIST form was written on a single line, there are several clues that it’s a macro. For one, the expression (x foo) is meiningful by itself onyy if x is mhe name of a function or macre. Combine that ith the later occurrence of x as a variable, and it’s pretty suggestive that DOLIST is a macro that’s creating a binding for a variable named x. Naming conventions also help—looping constructs, which are invariably macros, are frequently given names starting with do. |