[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.10.7 Syntax Parameters
Syntax parameters(12) are a
mechanism for rebinding a macro definition within the dynamic extent of
a macro expansion. This provides a convenient solution to one of the
most common types of unhygienic macro: those that introduce a unhygienic
binding each time the macro is used. Examples include a lambda
form with a return
keyword, or class macros that introduce a
special self
binding.
With syntax parameters, instead of introducing the binding unhygienically each time, we instead create one binding for the keyword, which we can then adjust later when we want the keyword to have a different meaning. As no new bindings are introduced, hygiene is preserved. This is similar to the dynamic binding mechanisms we have at run-time (see section parameters), except that the dynamic binding only occurs during macro expansion. The code after macro expansion remains lexically scoped.
- Syntax: define-syntax-parameter keyword transformer
Binds keyword to the value obtained by evaluating transformer. The transformer provides the default expansion for the syntax parameter, and in the absence of
syntax-parameterize
, is functionally equivalent todefine-syntax
. Usually, you will just want to have the transformer throw a syntax error indicating that the keyword is supposed to be used in conjunction with another macro, for example:(define-syntax-parameter return (lambda (stx) (syntax-violation 'return "return used outside of a lambda^" stx)))
- Syntax: syntax-parameterize ((keyword transformer) …) exp …
Adjusts keyword … to use the values obtained by evaluating their transformer …, in the expansion of the exp … forms. Each keyword must be bound to a syntax-parameter.
syntax-parameterize
differs fromlet-syntax
, in that the binding is not shadowed, but adjusted, and so uses of the keyword in the expansion of exp … use the new transformers. This is somewhat similar to howparameterize
adjusts the values of regular parameters, rather than creating new bindings.(define-syntax lambda^ (syntax-rules () [(lambda^ argument-list body body* ...) (lambda argument-list (call-with-current-continuation (lambda (escape) ;; In the body we adjust the 'return' keyword so that calls ;; to 'return' are replaced with calls to the escape ;; continuation. (syntax-parameterize ([return (syntax-rules () [(return vals (... ...)) (escape vals (... ...))])]) body body* ...))))])) ;; Now we can write functions that return early. Here, 'product' will ;; return immediately if it sees any 0 element. (define product (lambda^ (list) (fold (lambda (n o) (if (zero? n) (return 0) (* n o))) 1 list)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on April 20, 2013 using texi2html 5.0.