Defining Macros
A macro is a binding between a keyword and a syntax transformer. Since it’s difficult to discuss define-syntax without discussing the format of transformers, consider the following example macro definition:
(define-syntax when
(syntax-rules ()
((when condition exp ...)
(if condition
(begin exp ...)))))
(when #t
(display "hey ho\n")
(display "let's go\n"))
⊣ hey ho
⊣ let's goIn this example, the when binding is bound with define-syntax. Syntax transformers are discussed in more depth in Syntax-rules Macros and Support for the syntax-case System.
Syntax: define-syntax keyword transformer
Bind keyword to the syntax transformer obtained by evaluating transformer.
After a macro has been defined, further instances of keyword in Scheme source code will invoke the syntax transformer defined by transformer.
One can also establish local syntactic bindings with let-syntax.
Syntax: let-syntax ((keyword transformer) …) exp1 exp2 …
Bind each keyword to its corresponding transformer while expanding exp1 exp2 ....
A let-syntax binding only exists at expansion-time.
(let-syntax ((unless
(syntax-rules ()
((unless condition exp ...)
(if (not condition)
(begin exp ...))))))
(unless #t
(primitive-exit 1))
"rock rock rock")
⇒ "rock rock rock"A define-syntax form is valid anywhere a definition may appear: at the top-level, or locally. Just as a local define expands out to an instance of letrec, a local define-syntax expands out to letrec-syntax.
Syntax: letrec-syntax ((keyword transformer) …) exp1 exp2 …
Bind each keyword to its corresponding transformer while expanding exp1 exp2 ....
In the spirit of letrec versus let, an expansion produced by transformer may reference a keyword bound by the same letrec-syntax.
(letrec-syntax ((my-or
(syntax-rules ()
((my-or)
#t)
((my-or exp)
exp)
((my-or exp rest ...)
(let ((t exp))
(if t
t
(my-or rest ...)))))))
(my-or #f "rockaway beach"))
⇒ "rockaway beach"