1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

syntax parameters doc formatting

* doc/ref/api-macros.texi (Syntax Parameters): Some copy-editing on
  Ian's lovely syntax-parameters documentation.
This commit is contained in:
Andy Wingo 2012-01-08 14:36:17 +01:00
parent 4f5fb35194
commit 866ecf54c0

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*- @c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual. @c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011 @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011, 2012
@c Free Software Foundation, Inc. @c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions. @c See the file guile.texi for copying conditions.
@ -865,31 +865,32 @@ wrapping in @code{#'} syntax forms.
@node Syntax Parameters @node Syntax Parameters
@subsection Syntax Parameters @subsection Syntax Parameters
Syntax parameters@footnote{Described in the paper @cite{Keeping it Clean with Syntax parameters@footnote{Described in the paper @cite{Keeping it Clean
Syntax Parameters} by Barzilay, Culpepper and Flatt.} are a mechanism for rebinding a macro with Syntax Parameters} by Barzilay, Culpepper and Flatt.} are a
definition within the dynamic extent of a macro expansion. It provides mechanism for rebinding a macro definition within the dynamic extent of
a convenient solution to one of the most common types of unhygienic a macro expansion. This provides a convenient solution to one of the
macro: those that introduce a unhygienic binding each time the macro most common types of unhygienic macro: those that introduce a unhygienic
is used. Examples include a @code{lambda} form with a @code{return} keyword, or binding each time the macro is used. Examples include a @code{lambda}
class macros that introduce a special @code{self} binding. form with a @code{return} keyword, or class macros that introduce a
special @code{self} binding.
With syntax parameters, instead of introducing the binding With syntax parameters, instead of introducing the binding
unhygienically each time, we instead create one binding for the unhygienically each time, we instead create one binding for the keyword,
keyword, which we can then adjust later when we want the keyword to which we can then adjust later when we want the keyword to have a
have a different meaning. As no new bindings are introduced, hygiene different meaning. As no new bindings are introduced, hygiene is
is preserved. This is similar to the dynamic binding mechanisms we preserved. This is similar to the dynamic binding mechanisms we have at
have at run-time like @ref{SRFI-39, parameters} or run-time (@pxref{SRFI-39, parameters}), except that the dynamic binding
@ref{Fluids and Dynamic States, fluids}, except that the dynamic only occurs during macro expansion. The code after macro expansion
binding only occurs during macro expansion. The code after macro remains lexically scoped.
expansion remains lexically scoped.
@deffn {Syntax} define-syntax-parameter keyword transformer @deffn {Syntax} define-syntax-parameter keyword transformer
Binds @var{keyword} to the value obtained by evaluating @var{transformer}. The Binds @var{keyword} to the value obtained by evaluating
@var{transformer} provides the default expansion for the syntax parameter, @var{transformer}. The @var{transformer} provides the default expansion
and in the absence of @code{syntax-parameterize}, is functionally equivalent for the syntax parameter, and in the absence of
to @code{define-syntax}. Usually, you will just want to have the @var{transformer} @code{syntax-parameterize}, is functionally equivalent to
throw a syntax error indicating that the @var{keyword} is supposed to be @code{define-syntax}. Usually, you will just want to have the
used in conjunction with another macro, for example: @var{transformer} throw a syntax error indicating that the @var{keyword}
is supposed to be used in conjunction with another macro, for example:
@example @example
(define-syntax-parameter return (define-syntax-parameter return
(lambda (stx) (lambda (stx)
@ -899,31 +900,30 @@ used in conjunction with another macro, for example:
@deffn {Syntax} syntax-parameterize ((keyword transformer) @dots{}) exp @dots{} @deffn {Syntax} syntax-parameterize ((keyword transformer) @dots{}) exp @dots{}
Adjusts @var{keyword} @dots{} to use the values obtained by evaluating Adjusts @var{keyword} @dots{} to use the values obtained by evaluating
their @var{transformer} @dots{}, in the expansion of the @var{exp} @dots{} their @var{transformer} @dots{}, in the expansion of the @var{exp}
forms. Each @var{keyword} must be bound to a @dots{} forms. Each @var{keyword} must be bound to a syntax-parameter.
syntax-parameter. @code{syntax-parameterize} differs from @code{syntax-parameterize} differs from @code{let-syntax}, in that the
@code{let-syntax}, in that the binding is not shadowed, but adjusted, binding is not shadowed, but adjusted, and so uses of the keyword in the
and so uses of the keyword in the expansion of exp forms use the new expansion of @var{exp} @dots{} use the new transformers. This is
transformers. This is somewhatsimilar to how @code{parameterize} somewhat similar to how @code{parameterize} adjusts the values of
adjusts the values of regular parameters, rather than creating new regular parameters, rather than creating new bindings.
bindings.
@example @example
(define-syntax lambda^ (define-syntax lambda^
(syntax-rules () (syntax-rules ()
[(lambda^ argument-list body bodies ...) [(lambda^ argument-list body body* ...)
(lambda argument-list (lambda argument-list
(call-with-current-continuation (call-with-current-continuation
(lambda (escape) (lambda (escape)
;; in the body we adjust the 'return' keyword so that calls ;; In the body we adjust the 'return' keyword so that calls
;; to 'return' are replaced with calls to the escape continuation ;; to 'return' are replaced with calls to the escape
;; continuation.
(syntax-parameterize ([return (syntax-rules () (syntax-parameterize ([return (syntax-rules ()
[(return vals (... ...)) [(return vals (... ...))
(escape vals (... ...))])]) (escape vals (... ...))])])
body body body* ...))))]))
bodies ...))))]))
;; now we can write functions that return early. Here, 'product' will ;; Now we can write functions that return early. Here, 'product' will
;; return immediately if it sees any 0 element. ;; return immediately if it sees any 0 element.
(define product (define product
(lambda^ (list) (lambda^ (list)