Next: baselib transformers, Previous: baselib quasiquotation, Up: baselib [Index]
The let-syntax
and letrec-syntax
forms bind keywords.
Like a begin
form, a let-syntax
or letrec-syntax
form may appear in a definition context, in which case it is treated as
a definition, and the forms in the body must also be definitions. A
let-syntax
or letrec-syntax
form may also appear in an
expression context, in which case the forms within their bodies must be
expressions.
?bindings must have the form:
((?keyword ?expression) …)
Each ?keyword is an identifier, and each ?expression is an
expression that evaluates, at macro–expansion time, to a
transformer. Transformers may be created by syntax-rules
or identifier-syntax
or by one of the other mechanisms described
in Syntax–case. It is a syntax violation for
?keyword to appear more than once in the list of keywords being
bound.
The ?forms are expanded in the syntactic environment obtained by
extending the syntactic environment of the let-syntax
form with
macros whose keywords are the ?keywords, bound to the specified
transformers. Each binding of a ?keyword has the ?forms as
its region.
The ?forms of a let-syntax
form are treated, whether in
definition or expression context, as if wrapped in an implicit
begin
. Thus definitions in the result of expanding the
?forms have the same region as any definition appearing in place
of the let-syntax
form would have.
Implementation responsibilities: The implementation should detect if the value of ?expression cannot possibly be a transformer.
(let-syntax ((when (syntax-rules () ((when test stmt1 stmt2 ...) (if test (begin stmt1 stmt2 ...)))))) (let ((if #t)) (when if (set! if 'now)) if)) ⇒ now (let ((x 'outer)) (let-syntax ((m (syntax-rules () ((m) x)))) (let ((x 'inner)) (m)))) ⇒ outer (let () (let-syntax ((def (syntax-rules () ((def stuff ...) (define stuff ...))))) (def foo 42)) foo) ⇒ 42 (let () (let-syntax ()) 5) ⇒ 5
Same as for let-syntax
.
The ?forms are expanded in the syntactic environment obtained by
extending the syntactic environment of the letrec-syntax
form
with macros whose keywords are the ?keywords, bound to the
specified transformers. Each binding of a ?keyword has the
?bindings as well as the ?forms within its region, so the
transformers can transcribe forms into uses of the macros introduced by
the letrec-syntax
form.
The ?forms of a letrec-syntax
form are treated, whether in
definition or expression context, as if wrapped in an implicit
begin
. Thus definitions in the result of expanding the
?forms have the same region as any definition appearing in place
of the letrec-syntax
form would have.
Implementation responsibilities: The implementation should detect if the value of ?expression cannot possibly be a transformer.
(letrec-syntax ((my-or (syntax-rules () ((my-or) #f) ((my-or e) e) ((my-or e1 e2 ...) (let ((temp e1)) (if temp temp (my-or e2 ...))))))) (let ((x #f) (y 7) (temp 8) (let odd?) (if even?)) (my-or x (let temp) (if y) y))) ⇒ 7
The following example highlights how let-syntax
and
letrec-syntax
differ.
(let ((f (lambda (x) (+ x 1)))) (let-syntax ((f (syntax-rules () ((f x) x))) (g (syntax-rules () ((g x) (f x))))) (list (f 1) (g 1)))) ⇒ (1 2) (let ((f (lambda (x) (+ x 1)))) (letrec-syntax ((f (syntax-rules () ((f x) x))) (g (syntax-rules () ((g x) (f x))))) (list (f 1) (g 1)))) ⇒ (1 1)
The two expressions are identical except that the let-syntax
form
in the first expression is a letrec-syntax
form in the second.
In the first expression, the ‘f’ occurring in ‘g’ refers to
the let
–bound variable ‘f’, whereas in the second it refers
to the keyword f
whose binding is established by the
letrec-syntax
form.
Next: baselib transformers, Previous: baselib quasiquotation, Up: baselib [Index]