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]