Macros: Defining Your OwnCopyright © 2003-2005, Peter Seibel<br>8. Macros: Defining Your Own<br>Now it's time to start writing your own macros. The standard macros I<br>covered in the previous chapter hint at some of the things you can do<br>with macros, but that's just the beginning. Common Lisp doesn't<br>support macros so every Lisp programmer can create their own variants<br>of standard control constructs any more than C supports functions so<br>every C programmer can write trivial variants of the functions in the<br>C standard library. Macros are part of the language to allow you to<br>create abstractions on top of the core language and standard library<br>that move you closer toward being able to directly express the things<br>you want to express.<br>Perhaps the biggest barrier to a proper understanding of macros is,<br>ironically, that they're so well integrated into the language. In<br>many ways they seem like just a funny kind of function--they're<br>written in Lisp, they take arguments and return results, and they<br>allow you to abstract away distracting details. Yet despite these<br>many similarities, macros operate at a different level than functions<br>and create a totally different kind of abstraction.<br>Once you understand the difference between macros and functions, the<br>tight integration of macros in the language will be a huge benefit.<br>But in the meantime, it's a frequent source of confusion for new<br>Lispers. The following story, while not true in a historical or<br>technical sense, tries to alleviate the confusion by giving you a way<br>to think about how macros work.<br>The Story of Mac: A Just-So Story<br>Once upon a time, long ago, there was a company of Lisp programmers.<br>It was so long ago, in fact, that Lisp had no macros. Anything that<br>couldn't be defined with a function or done with a special operator<br>had to be written in full every time, which was rather a drag.<br>Unfortunately, the programmers in this company--though<br>brilliant--were also quite lazy. Often in the middle of their<br>programs--when the tedium of writing a bunch of code got to be too<br>much--they would instead write a note describing the code they needed<br>to write at that place in the program. Even more unfortunately,<br>because they were lazy, the programmers also hated to go back and<br>actually write the code described by the notes. Soon the company had<br>a big stack of programs that nobody could run because they were full<br>of notes about code that still needed to be written.<br>In desperation, the big bosses hired a junior programmer, Mac, whose<br>job was to find the notes, write the required code, and insert it<br>into the program in place of the notes. Mac never ran the<br>programs--they weren't done yet, of course, so he couldn't. But even<br>if they had been completed, Mac wouldn't have known what inputs to<br>feed them. So he just wrote his code based on the contents of the<br>notes and sent it back to the original programmer.<br>With Mac's help, all the programs were soon completed, and the<br>company made a ton of money selling them--so much money that the<br>company could double the size of its programming staff. But for some<br>reason no one thought to hire anyone to help Mac; soon he was single-<br>handedly assisting several dozen programmers. To avoid spending all<br>his time searching for notes in source code, Mac made a small<br>modification to the compiler the programmers used. Thereafter,<br>whenever the compiler hit a note, it would e-mail him the note and<br>wait for him to e-mail back the replacement code. Unfortunately, even<br>with this change, Mac had a hard time keeping up with the<br>programmers. He worked as carefully as he could, but sometimes--<br>especially when the notes weren't clear--he would make mistakes.<br>The programmers noticed, however, that the more precisely they wrote<br>their notes, the more likely it was that Mac would send back correct<br>code. One day, one of the programmers, having a hard time describing<br>in words the code he wanted, included in one of his notes a Lisp<br>program that would generate the code he wanted. That was fine by Mac;<br>he just ran the program and sent the result to the compiler.<br>The next innovation came when a programmer put a note at the top of<br>one of his programs containing a function definition and a comment<br>that said, "Mac, don't write any code here, but keep this function<br>for later; I'm going to use it in some of my other notes." Other<br>notes in the same program said things such as, "Mac, replace this<br>note with the result of running that other function with the symbols<br>x and y as arguments."<br>This technique caught on so quickly that within a few days, most<br>programs contained dozens of notes defining functions that were only<br>used by code in other notes. To make it easy for Mac to pick out the<br>notes containing only definitions that didn't require any immediate<br>response, the programmers tagged them with the standard preface:<br>"Definition for Mac, Read Only." This--as the programmers were still<br>quite lazy--was quickly shortened to "DEF. MAC. R/O" and then<br>"DEFMACRO."<br>Pretty soon, there was no...