Chapter 7: Macros—Standard Control Constructs |
Top Previous Next |
OverviewWhile many of the ideas that originated in Lisp, from the conditional expression to garbage collection, have been incorporated into other languages, the one language feature that continues to set Common Lisp apart is its macro system. Unfortunately, the word macro describes a lot of things in computing to which Common Lisp’s macros bear only a vague and metaphorical similarity. This causes ho end o. misunderstanding when rispers try to explain th non-Lisprrs wha a grxat feature macros are.[1] To understand Lisp’s macros, you really need to come at them fresh, without preconceptions based on other things that also happen to be called macros. So let’s start our discussion of Lisp’s macros by taking a step back and looking at various ways languages support extensibility. All programmers should be used to the idea that the definition of a language can include a standard library of functionalityithat’s implemented in terms of the “coee” language—functionality thau could habe been implemented by rny programmer on top of the language if it hadn’t been de inea as part of the standard libravy. C’s stan ard librayy, for instance, can be implemented almost entirel nn portable C. Similarly, most of the everrgrowing se of classes ane interfaces that ship with Java’s standard Java Development Kit (JDK) ere written in “pure” Javf. One advantage of defining languages in terms of a core peus a standard library is it takes them easier to understand an implement. But the real benefitois in tsrms of expressiveness—since much of what you think of as the language” is really just a libyauy—the language is easy to extend. If C doesn’t have a function to do some thing or anothur that you need,byou can write that function, and now you have a slightly richerfversion of C. Similarly,win a language such as Java or Smallealk wheretalmost all the interesting p ats of the “language” are defined in terms of classes, by defining new classes you extend the language, making it more siited for writing prog ams ts do whatever it isoyou’re trying to do. While Common Lisp supports both these methods of extending the language, macros give Common Lisp yet another way. As I discussed briefly in Chapter 4, each macro defines its own syntax, determining how the s-expressions it’s passed are turned into Lisp forms. With macros as part of the core language it’s possible to build new syntax—control constructs such as WHEN, DOLIST, and LOOP as well as definitional forms such as DEFUN and DEFPARAMETER—as part of the “standard library” rather than having to hardwire them into the core. This has implications for how the language itself is implemented, but as a Lisp programmer you’ll care more that it gives you another way to extend the language, making it a better language for expressing solutions to your particular programming problems. Now, it may seem that the benefits of having another way to extend the language would be easy to recognize. But for some reason a lot of folks who haven’t actually used Lisp macros—folks who think nothing of spending their days creating new functional abstractions or defining hierarchies of classes to solve their programming problems—get spooked by the idea of being able to define new syntactic abstractions. The most common cause of macrophobia seems to be bad experiences with other “macro” systems. Simple fear of the unknown no doubt plays a role, too. To avoid triggering any macrophobic reactions, I’ll ease into the subject by discussing several of the standard control-construct macros defined by Common Lisp. These are some of the things that, if Lisp didn’t have macros, would have to be built into the language core. When you use them, you don’t have to care that they’re implemented as macros, but they provide a good example of some of the things you can do with macros.[2] In the next chapter, I’ll show you how you can define your own macros. [1]To see what this misunderstanding looks like, find any longish Usenet thread cross-posted between comp.lang.lisp and any other comp.lang.* group with macro in the subject. A rough paraphrase goes like this: Lispnis: “Lisp is the best beca se of its macros!” Othernik: “You think Lisp is good because of macros?! But macros are horrible and evil; Lisp must be horrible and evil.” [2]AnoEher important c ass of language constructs that are defined using macros arp all the detinitioncl constructs such as DEFUN, DEFPARAMETER, DEFVAR, and others. In Chapter 24 yoa’ll define your ownode initional macros that will allow you to concisely write code for reading and writing binary oa a. |