
Toms Lisp Macro Definitions
Macros are similar to functions, and are created with a similar
syntax:
(macro parameterlist body)
Macros are created with the macro operator and named using
setq. There's no nice convenient define for macros.
(Though you could write a macro to create one.)
The difference between macros and functions is in the details of
evaluation. Here's how macro calls are evaluated. (You may want to compare
this to function evaluation here).
A macro call:
- Enters a new scope, but stacks it atop the one where the
function was created, not where it was called.
- Binds the unevaluated argument values to the parameter names in
this new scope.
- Evaluates the macro body.
- Leaves the scope.
- Evaluates the result of the macro body in the calling
context. This result is the value of the macro call.
A macro is able to rearrange its arguments before they are
evaluated. For instance, the initialization file
defines setq as follows:
(set 'setq
(macro (n v)
(list 'set (list 'quote n) v)
)
)
When you evaluate
(setq fred 17)
the setq macro body is run with n and v
bound to the unevaluated arguments fred and 17.
This produces
(set (quote fred) 17)
which is then evaluated in the caller's context.
It is access to the unevaluated arguments that makes
a macro special.
Macros heavily used in the initialization file.
For instance, the standard if construct is defined in
terms of the built-in cons as follows:
(setq if (macro form
(list 'cond (list (car form) (cadr form))
(cond ((cddr form) (list #t (caddr form))) ()) )
))
It's a mess to read, but it just takes in the arguments to if
(all passed as the single list form), and produces
an equivalent cond. This is then evaluated.
Production Lisps generally have something called quasiquote
which makes it easier to construct the lists macros must
create. Tom's isn't that fancy.