Created
January 7, 2012 01:10
-
-
Save ijp/1573352 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@node Syntax Parameters | |
@subsection Syntax Parameters | |
Syntax parameters@footnote{Described in the paper @cite{Keeping it Clean with | |
Syntax Parameters} by Barzilay, Culpepper and Flatt.} are a mechanism for rebinding a macro | |
definition within the dynamic extent of a macro expansion. It 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 like @ref{SRFI-39, parameters} or | |
@ref{Fluids and Dynamic States, fluids}, except that the dynamic | |
binding only occurs during macro expansion. The code after macro | |
expansion remains lexically scoped. | |
@deffn {Syntax} define-syntax-parameter keyword transformer | |
Binds @var{keyword} to the value obtained by evaluating @var{transformer}. The | |
@var{transformer} provides the default expansion for the syntax parameter, | |
and in the absence of @code{syntax-parameterize}, is functionally equivalent | |
to @code{define-syntax}. Usually, you will just want to have the @var{transformer} | |
throw a syntax error indicating that the @var{keyword} is supposed to be | |
used in conjunction with another macro @pxref{Syntax Parameters Example, example}. | |
@end deffn | |
@deffn {Syntax} syntax-parameterize ((keyword transformer) @dots) exp @dots | |
Adjusts @var{keyword} @dots to use the values obtained by evaluating | |
their @var{transformer} @dots, in the expansion of the @var{exp} @dots forms. Each | |
@var{keyword} must be bound to a syntax-parameter. @code{syntax-parameterize} | |
differs from @code{let-syntax}, in that the binding is not shadowed, but | |
adjusted, and so uses of the keyword in the expansion of exp forms use | |
the new transformers. This is somewhat similar to how @code{parameterize} | |
adjusts the values of regular parameters, rather than creating new | |
bindings. | |
@end deffn | |
@node Syntax Parameters Example | |
@subsubsection Syntax Parameters Example | |
A short example, showing how you can use syntax parameters to create a | |
variant of @code{lambda} that allows early return from the function via the | |
@code{return} keyword. | |
@example | |
(define-syntax-parameter return | |
;; by default we bind 'return' to a macro that merely raises a syntax error | |
(lambda (stx) | |
(syntax-violation 'return "return used outside of a lambda^" stx))) | |
(define-syntax lambda^ | |
(syntax-rules () | |
[(lambda^ argument-list body bodies ...) | |
(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 | |
bodies ...))))])) | |
;; 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))) | |
@end example |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment