Prev Up Next
Users can create their own special forms by defining
macros. A macro is a symbol that has a transformer procedure associated with it. When Scheme
encounters a macro-expression -- ie, a form whose
head is a macro -- , it applies the macro's transformer
to the subforms in the macro-expression, and evaluates
the result of the transformation.
Ideally, a macro specifies a purely textual
transformation from code text to other code text. This
kind of transformation is useful for abbreviating an
involved and perhaps frequently occurring textual
pattern.
A macro is defined using the special form
define-macro (but see sec R.4).
For example, if your Scheme lacks the conditional
special form when, you could define
when as the following macro:
(define-macro when
(lambda (test . branch)
(list 'if test
(cons 'begin branch))))
This defines a when-transformer that would
convert a when-expression into the equivalent
if-expression. With this macro definition in
place, the when-expression
(when (< (pressure tube) 60)
(open-valve tube)
(attach floor-pump tube)
(depress floor-pump 5)
(detach floor-pump tube)
(close-valve tube))
will be converted to another expression, the result
of applying the
when-transformer to the when-expression's
subforms:
(apply
(lambda (test . branch)
(list 'if test
(cons 'begin branch)))
'((< (pressure tube) 60)
(open-valve tube)
(attach floor-pump tube)
(depress floor-pump 5)
(detach floor-pump tube)
(close-valve tube)))
The transformation yields the list
(if (< (pressure tube) 60)
(begin
(open-valve tube)
(attach floor-pump tube)
(depress floor-pump 5)
(detach floor-pump tube)
(close-valve tube)))
Scheme will then evaluate this expression, as it
would any other.
As an additional example, here is the macro-definition
for when's counterpart unless:
(define-macro unless
(lambda (test . branch)
(list 'if
(list 'not test)
(cons 'begin branch))))
Alternatively, we could invoke when inside
unless's definition:
(define-macro unless
(lambda (test . branch)
(cons 'when
(cons (list 'not test) branch))))
Macro expansions can refer to other macros.
Prev Up Next