# Scheme Programming/Macros

Macros are said to be what makes Lisp Lisp. Other programming languages, notably C and C++, have macros, but they're not like Lisp macros. In C, the macro preprocessor allows you to do limited textual substitution on snippets of C code. Sometimes, this produces working C code, while other times it can result in invisible misplaced braces or semicolons that the compiler can't quite pinpoint.
Lisp macros are full-blown Lisp procedures, with the full power of any other Lisp procedure. Instead of text, they get lists that represent the bits of code that you want to change. The return value of a macro is a list representing the new program. Scheme supports three types of macro. When it comes to understanding what's going on, the easiest of these three types of macro is Lisp's original type of macro, known as defmacro in Common Lisp, EMACS Lisp, and SCM. Other Scheme implementations call this form define-macro, while still other implementations, notably Racket, reject it as being too primitive.
To use macros in SCM, you must first evaluate this form:
Other Scheme implementations generally do not require this step.
A simple macro can illustrate what's going on. We want it to do something that would be impossible to do with a procedure. So we'll implement a macro that works like a `begin` form, but runs the code within it in reverse order:
Every time you write this:
...the macro code above gets called at compile time, and the code inside the backwards block is passed as the body argument. The backwards macro reverses this code and conses the symbol begin to the beginning of the result, creating a begin form:
Your program will execute as if that begin form was what you wrote in your program. Macros can do absolutely anything to the code in their arguments. Here is a more useful macro:
Then you can write this program:
The while loop checks if the conditional expression is true, and if it is, it executes the body over and over until the condition becomes false. In the above code, the condition becomes false when counter reaches a value of 0.
There is just one small problem with defmacro. The loop procedure that our while loop uses for recursion is visible to the code in the body when you use a while loop. You could set it to something else, and then the loop would break. You might do this accidentally:
Lisp provides a solution to this, called gensym in Common Lisp and most Scheme implementations. However, in SCM, this procedure is called gentemp. It generates a symbol that is guaranteed not to appear anywhere else in the program. You can use it to generate a name to use instead of loop. Fixing the while macro, it now looks like this:

## Hygienic Macros: syntax-rules

Scheme introduces hygienic macros to the Lisp world. When writing this kind of macro, it is impossible to accidentally introduce variable names that the code you're altering can change. However, to write them, we must abandon the concept of code being made out of simple lists.
There are two kinds of hygienic macros, but only the less powerful of the two is supported by SCM. Syntax-rules macros rely on pattern-matching to define the valid ways to invoke the macro, and templates to define the output code. There are some macros that cannot be defined with syntax-rules. Here's the while loop again, defined with syntax-rules instead of defmacro:
If you refer to loop within the body if this version of while, it refers to a different loop from the one shown in the template. It is impossible to define a variable with syntax-rules that code from outside the macro can see.
The form that says (_ condition . body) is the pattern. _ is a wildcard. Anything can match it, and its value is not bound to anything. In this case, it is standing in the place where the word while goes. condition and body are pattern variables. They're not real variables. They won't have value at runtime, only within the template. Due to dotted-list notation, body is matched in the cdr position, which means it's all the forms that come after the body.
Scheme's cond form can be implemented with this macro system. In most implementations, cond is in fact a macro. A typical cond definition looks like this:
my-cond works like Racket's version of cond in that (cond) is legal and has an unspecified return value, and unlike SCM's cond in which (cond) is illegal. The (else) at the top in parentheses is the list of literals. They have to match exactly in the code in order to match the pattern. In other words, where you see else in the pattern, it only matches if the word else is found there.

## Now let's make a REAL macro

What if you could pattern-match regular lists at runtime in the same manner that you can pattern-match syntax at compile-time when using syntax-rules? Then, if you had a list and you wanted to capture the first two elements (or do something else if it wasn't really a list or if it didn't have two elements), you could write something like this:
The macro supports literals just like syntax-rules. The only thing that's not supported is the wildcard operator. Every value matched will be bound to something.
We'll use syntax-rules because in the end, the pattern matching provided by it does more to make this job easier than does the Turing completeness of defmacro. When we're done, we'll be able to use the same kind of pattern matching in defmacro macros as well, by using this macro within its body. The only thing we'll be missing in defmacro then will be hygiene.

### How pattern matching works

Implementing something like this using syntax-rules will require two macros. One macro will match a single pattern, and evaluate an expression if it succeeds, or return a failure value if it fails.
The match-pattern macro requires five arguments:
The pattern contains the names of variables in the positions you hope to find them in some candidate structure. So if the pattern is (a . b), for example, then you're trying to bind a to the car of a list, and b to its cdr. If a and b are not literals, then this pattern can be matched against match-value by generating the following code:
maybe-car is a special version of car that won't raise an error if it's called on a non-pair. Instead of assuming that match-value will be a list, maybe-car makes it possible to check, without us having to write (if (pair? match-value) ...) every time.
If the car of the list matches, the match-pattern macro is used again on both the cdr of the data and the cdr of the pattern (which is tl in the code snippet above). This way, tl can be either another pattern, or a variable.
If maybe-car or maybe-cdr encounter something that isn't a list, they return fail-value, which we then check for and return if it's found. That way, if any call to maybe-car or maybe-cdr evaluates to fail-value, then the entire match-pattern also evaluates to fail-value.
The macro will use exists-in? from the Looping chapter to implement the literals. If an identifier in the pattern is found in the literals, then that identifier is interpreted as a symbol, and that position in the structure must be that identifier or fail-value will be returned. The failure-value will be provided from outside the macro. Ultimately, we'll generate a failure value at runtime using (gentemp) (or (gensym)) on any Scheme implementation except SCM).
This example shows what it does:
The second case fails because a is defined as a literal, so there must be an actual a symbol in there for the pattern to match.
The failure-value makes it possible to evaluate a chain of these in a cond form, which makes it possible to write a multi-pattern match macro that mirrors syntax-rules.
An example:
To demonstrate the use of this macro in conjunction with defmacro, let's define my-cond again using defmacro:
And that is what macros can do.