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 go
In 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.
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
.
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
.
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"