@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010
-@c Free Software Foundation, Inc.
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011,
+@c 2012, 2013, 2014 Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@node Macros
@end lisp
@cindex macro expansion
+@cindex domain-specific language
+@cindex embedded domain-specific language
+@cindex DSL
+@cindex EDSL
Macro expansion is a separate phase of evaluation, run before code is
interpreted or compiled. A macro is a program that runs on programs, translating
-an embedded language into core Scheme.
+an embedded language into core Scheme@footnote{These days such embedded
+languages are often referred to as @dfn{embedded domain-specific
+languages}, or EDSLs.}.
@menu
* Defining Macros:: Binding macros, globally and locally.
* Syntax Rules:: Pattern-driven macros.
* Syntax Case:: Procedural, hygienic macros.
+* Syntax Transformer Helpers:: Helpers for use in procedural macros.
* Defmacros:: Lisp-style macros.
* Identifier Macros:: Identifier macros.
+* Syntax Parameters:: Syntax Parameters.
* Eval When:: Affecting the expand-time environment.
* Internal Macros:: Macros as first-class values.
@end menu
One can also establish local syntactic bindings with @code{let-syntax}.
-@deffn {Syntax} let-syntax ((keyword transformer) ...) exp...
-Bind @var{keyword...} to @var{transformer...} while expanding @var{exp...}.
+@deffn {Syntax} let-syntax ((keyword transformer) @dots{}) exp1 exp2 @dots{}
+Bind each @var{keyword} to its corresponding @var{transformer} while
+expanding @var{exp1} @var{exp2} @enddots{}.
A @code{let-syntax} binding only exists at expansion-time.
of @code{letrec}, a local @code{define-syntax} expands out to
@code{letrec-syntax}.
-@deffn {Syntax} letrec-syntax ((keyword transformer) ...) exp...
-Bind @var{keyword...} to @var{transformer...} while expanding @var{exp...}.
+@deffn {Syntax} letrec-syntax ((keyword transformer) @dots{}) exp1 exp2 @dots{}
+Bind each @var{keyword} to its corresponding @var{transformer} while
+expanding @var{exp1} @var{exp2} @enddots{}.
In the spirit of @code{letrec} versus @code{let}, an expansion produced by
@var{transformer} may reference a @var{keyword} bound by the
exp)
((my-or exp rest ...)
(let ((t exp))
- (if exp
- exp
+ (if t
+ t
(my-or rest ...)))))))
(my-or #f "rockaway beach"))
@result{} "rockaway beach"
@code{syntax-rules} macros are simple, pattern-driven syntax transformers, with
a beauty worthy of Scheme.
-@deffn {Syntax} syntax-rules literals (pattern template)...
+@deffn {Syntax} syntax-rules literals (pattern template) @dots{}
Create a syntax transformer that will rewrite an expression using the rules
embodied in the @var{pattern} and @var{template} clauses.
@end deffn
((_ #((var val) ...) exp exp* ...)
(let ((var val) ...) exp exp* ...))))
(letv #((foo 'bar)) foo)
-@result{} foo
+@result{} bar
@end example
Literals are used to match specific datums in an expression, like the use of
This property is sometimes known as @dfn{hygiene}, and it does aid in code
cleanliness. In your macro definitions, you can feel free to introduce temporary
-variables, without worrying about inadvertantly introducing bindings into the
+variables, without worrying about inadvertently introducing bindings into the
macro expansion.
Consider the definition of @code{my-or} from the previous section:
exp)
((my-or exp rest ...)
(let ((t exp))
- (if exp
- exp
+ (if t
+ t
(my-or rest ...))))))
@end example
(@pxref{Defmacros}), which do not preserve referential transparency. Hygiene
adds to the expressive power of Scheme.
+@subsubsection Shorthands
+
+One often ends up writing simple one-clause @code{syntax-rules} macros.
+There is a convenient shorthand for this idiom, in the form of
+@code{define-syntax-rule}.
+
+@deffn {Syntax} define-syntax-rule (keyword . pattern) [docstring] template
+Define @var{keyword} as a new @code{syntax-rules} macro with one clause.
+@end deffn
+
+Cast into this form, our @code{when} example is significantly shorter:
+
+@example
+(define-syntax-rule (when c e ...)
+ (if c (begin e ...)))
+@end example
+
+@subsubsection Reporting Syntax Errors in Macros
+
+@deffn {Syntax} syntax-error message [arg ...]
+Report an error at macro-expansion time. @var{message} must be a string
+literal, and the optional @var{arg} operands can be arbitrary expressions
+providing additional information.
+@end deffn
+
+@code{syntax-error} is intended to be used within @code{syntax-rules}
+templates. For example:
+
+@example
+(define-syntax simple-let
+ (syntax-rules ()
+ ((_ (head ... ((x . y) val) . tail)
+ body1 body2 ...)
+ (syntax-error
+ "expected an identifier but got"
+ (x . y)))
+ ((_ ((name val) ...) body1 body2 ...)
+ ((lambda (name ...) body1 body2 ...)
+ val ...))))
+@end example
+
+@subsubsection Specifying a Custom Ellipsis Identifier
+
+When writing macros that generate macro definitions, it is convenient to
+use a different ellipsis identifier at each level. Guile allows the
+desired ellipsis identifier to be specified as the first operand to
+@code{syntax-rules}, as specified by SRFI-46 and R7RS. For example:
+
+@example
+(define-syntax define-quotation-macros
+ (syntax-rules ()
+ ((_ (macro-name head-symbol) ...)
+ (begin (define-syntax macro-name
+ (syntax-rules ::: ()
+ ((_ x :::)
+ (quote (head-symbol x :::)))))
+ ...))))
+(define-quotation-macros (quote-a a) (quote-b b) (quote-c c))
+(quote-a 1 2 3) @result{} (a 1 2 3)
+@end example
+
@subsubsection Further Information
For a formal definition of @code{syntax-rules} and its pattern language, see
@code{syntax-case} macros are procedural syntax transformers, with a power
worthy of Scheme.
-@deffn {Syntax} syntax-case syntax literals (pattern [guard] exp)...
+@deffn {Syntax} syntax-case syntax literals (pattern [guard] exp) @dots{}
Match the syntax object @var{syntax} against the given patterns, in order. If a
@var{pattern} matches, return the result of evaluating the associated @var{exp}.
@end deffn
Since @code{syntax} appears frequently in macro-heavy code, it has a special
reader macro: @code{#'}. @code{#'foo} is transformed by the reader into
-@code{(syntax foo)}, just as @code{'foo} is tranformed into @code{(quote foo)}.
+@code{(syntax foo)}, just as @code{'foo} is transformed into @code{(quote foo)}.
The pattern language used by @code{syntax-case} is conveniently the same
language used by @code{syntax-rules}. Given this, Guile actually defines
@code{syntax-case} it is easy:
@deffn {Scheme Procedure} identifier? syntax-object
-Returns @code{#t} iff @var{syntax-object} is an identifier.
+Returns @code{#t} if @var{syntax-object} is an identifier, or @code{#f}
+otherwise.
@end deffn
@example
(if it then else)))))))
@end example
-The reason that this one doesn't work is that there are really two environments
-at work here -- the environment of pattern variables, as bound by
-@code{syntax-case}, and the environment of lexical variables, as bound by normal
-Scheme. Here we need to introduce a piece of Scheme's environment into that of
-the syntax expander, and we can do so using @code{syntax-case} itself:
+The reason that this one doesn't work is that there are really two
+environments at work here -- the environment of pattern variables, as
+bound by @code{syntax-case}, and the environment of lexical variables,
+as bound by normal Scheme. The outer let form establishes a binding in
+the environment of lexical variables, but the inner let form is inside a
+syntax form, where only pattern variables will be substituted. Here we
+need to introduce a piece of the lexical environment into the pattern
+variable environment, and we can do so using @code{syntax-case} itself:
@example
;; works, but is obtuse
However there are easier ways to write this. @code{with-syntax} is often
convenient:
-@deffn {Syntax} with-syntax ((pat val)...) exp...
+@deffn {Syntax} with-syntax ((pat val) @dots{}) exp @dots{}
Bind patterns @var{pat} from their corresponding values @var{val}, within the
-lexical context of @var{exp...}.
+lexical context of @var{exp} @enddots{}.
@example
;; better
(newline))))))
@end example
-Finally, we should mention the following helper procedures defined by the core
-of @code{syntax-case}:
+Readers interested in further information on @code{syntax-case} macros should
+see R. Kent Dybvig's excellent @cite{The Scheme Programming Language}, either
+edition 3 or 4, in the chapter on syntax. Dybvig was the primary author of the
+@code{syntax-case} system. The book itself is available online at
+@uref{http://scheme.com/tspl4/}.
+
+@subsubsection Custom Ellipsis Identifiers for syntax-case Macros
+
+When writing procedural macros that generate macro definitions, it is
+convenient to use a different ellipsis identifier at each level. Guile
+supports this for procedural macros using the @code{with-ellipsis}
+special form:
+
+@deffn {Syntax} with-ellipsis ellipsis body @dots{}
+@var{ellipsis} must be an identifier. Evaluate @var{body} in a special
+lexical environment such that all macro patterns and templates within
+@var{body} will use @var{ellipsis} as the ellipsis identifier instead of
+the usual three dots (@code{...}).
+@end deffn
+
+For example:
+
+@example
+(define-syntax define-quotation-macros
+ (lambda (x)
+ (syntax-case x ()
+ ((_ (macro-name head-symbol) ...)
+ #'(begin (define-syntax macro-name
+ (lambda (x)
+ (with-ellipsis :::
+ (syntax-case x ()
+ ((_ x :::)
+ #'(quote (head-symbol x :::)))))))
+ ...)))))
+(define-quotation-macros (quote-a a) (quote-b b) (quote-c c))
+(quote-a 1 2 3) @result{} (a 1 2 3)
+@end example
+
+Note that @code{with-ellipsis} does not affect the ellipsis identifier
+of the generated code, unless @code{with-ellipsis} is included around
+the generated code.
+
+@node Syntax Transformer Helpers
+@subsection Syntax Transformer Helpers
+
+As noted in the previous section, Guile's syntax expander operates on
+syntax objects. Procedural macros consume and produce syntax objects.
+This section describes some of the auxiliary helpers that procedural
+macros can use to compare, generate, and query objects of this data
+type.
@deffn {Scheme Procedure} bound-identifier=? a b
-Returns @code{#t} iff the syntax objects @var{a} and @var{b} refer to the same
-lexically-bound identifier.
+Return @code{#t} if the syntax objects @var{a} and @var{b} refer to the
+same lexically-bound identifier, or @code{#f} otherwise.
@end deffn
@deffn {Scheme Procedure} free-identifier=? a b
-Returns @code{#t} iff the syntax objects @var{a} and @var{b} refer to the same
-free identifier.
+Return @code{#t} if the syntax objects @var{a} and @var{b} refer to the
+same free identifier, or @code{#f} otherwise.
@end deffn
@deffn {Scheme Procedure} generate-temporaries ls
Return a list of temporary identifiers as long as @var{ls} is long.
@end deffn
-Readers interested in further information on @code{syntax-case} macros should
-see R. Kent Dybvig's excellent @cite{The Scheme Programming Language}, either
-edition 3 or 4, in the chapter on syntax. Dybvig was the primary author of the
-@code{syntax-case} system. The book itself is available online at
-@uref{http://scheme.com/tspl4/}.
+@deffn {Scheme Procedure} syntax-source x
+Return the source properties that correspond to the syntax object
+@var{x}. @xref{Source Properties}, for more information.
+@end deffn
+
+Guile also offers some more experimental interfaces in a separate
+module. As was the case with the Large Hadron Collider, it is unclear
+to our senior macrologists whether adding these interfaces will result
+in awesomeness or in the destruction of Guile via the creation of a
+singularity. We will preserve their functionality through the 2.0
+series, but we reserve the right to modify them in a future stable
+series, to a more than usual degree.
+
+@example
+(use-modules (system syntax))
+@end example
+
+@deffn {Scheme Procedure} syntax-module id
+Return the name of the module whose source contains the identifier
+@var{id}.
+@end deffn
+
+@deffn {Scheme Procedure} syntax-local-binding id
+Resolve the identifer @var{id}, a syntax object, within the current
+lexical environment, and return two values, the binding type and a
+binding value. The binding type is a symbol, which may be one of the
+following:
+
+@table @code
+@item lexical
+A lexically-bound variable. The value is a unique token (in the sense
+of @code{eq?}) identifying this binding.
+@item macro
+A syntax transformer, either local or global. The value is the
+transformer procedure.
+@item pattern-variable
+A pattern variable, bound via @code{syntax-case}. The value is an
+opaque object, internal to the expander.
+@item ellipsis
+An internal binding, bound via @code{with-ellipsis}. The value is the
+(anti-marked) local ellipsis identifier.
+@item displaced-lexical
+A lexical variable that has gone out of scope. This can happen if a
+badly-written procedural macro saves a syntax object, then attempts to
+introduce it in a context in which it is unbound. The value is
+@code{#f}.
+@item global
+A global binding. The value is a pair, whose head is the symbol, and
+whose tail is the name of the module in which to resolve the symbol.
+@item other
+Some other binding, like @code{lambda} or other core bindings. The
+value is @code{#f}.
+@end table
+
+This is a very low-level procedure, with limited uses. One case in
+which it is useful is to build abstractions that associate auxiliary
+information with macros:
+
+@example
+(define aux-property (make-object-property))
+(define-syntax-rule (with-aux aux value)
+ (let ((trans value))
+ (set! (aux-property trans) aux)
+ trans))
+(define-syntax retrieve-aux
+ (lambda (x)
+ (syntax-case x ()
+ ((x id)
+ (call-with-values (lambda () (syntax-local-binding #'id))
+ (lambda (type val)
+ (with-syntax ((aux (datum->syntax #'here
+ (and (eq? type 'macro)
+ (aux-property val)))))
+ #''aux)))))))
+(define-syntax foo
+ (with-aux 'bar
+ (syntax-rules () ((_) 'foo))))
+(foo)
+@result{} foo
+(retrieve-aux foo)
+@result{} bar
+@end example
+
+@code{syntax-local-binding} must be called within the dynamic extent of
+a syntax transformer; to call it otherwise will signal an error.
+@end deffn
+
+@deffn {Scheme Procedure} syntax-locally-bound-identifiers id
+Return a list of identifiers that were visible lexically when the
+identifier @var{id} was created, in order from outermost to innermost.
+
+This procedure is intended to be used in specialized procedural macros,
+to provide a macro with the set of bound identifiers that the macro can
+reference.
+
+As a technical implementation detail, the identifiers returned by
+@code{syntax-locally-bound-identifiers} will be anti-marked, like the
+syntax object that is given as input to a macro. This is to signal to
+the macro expander that these bindings were present in the original
+source, and do not need to be hygienically renamed, as would be the case
+with other introduced identifiers. See the discussion of hygiene in
+section 12.1 of the R6RS, for more information on marks.
+
+@example
+(define (local-lexicals id)
+ (filter (lambda (x)
+ (eq? (syntax-local-binding x) 'lexical))
+ (syntax-locally-bound-identifiers id)))
+(define-syntax lexicals
+ (lambda (x)
+ (syntax-case x ()
+ ((lexicals) #'(lexicals lexicals))
+ ((lexicals scope)
+ (with-syntax (((id ...) (local-lexicals #'scope)))
+ #'(list (cons 'id id) ...))))))
+
+(let* ((x 10) (x 20)) (lexicals))
+@result{} ((x . 10) (x . 20))
+@end example
+@end deffn
+
@node Defmacros
@subsection Lisp-style Macro Definitions
more easily.
@deffn {Syntax} identifier-syntax exp
-Returns a macro transformer that will replace occurences of the macro with
+Returns a macro transformer that will replace occurrences of the macro with
@var{exp}.
@end deffn
(set! foo @var{val})
;; expands via
(foo-transformer #'(set! foo @var{val}))
-;; iff foo-transformer is a "variable transformer"
+;; if foo-transformer is a "variable transformer"
@end example
As the example notes, the transformer procedure must be explicitly
@end example
@end deffn
-There is an extension to identifer-syntax which allows it to handle the
+There is an extension to identifier-syntax which allows it to handle the
@code{set!} case as well:
@deffn {Syntax} identifier-syntax (var exp1) ((set! var val) exp2)
@end deffn
+@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. 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 @code{lambda}
+form with a @code{return} keyword, or class macros that introduce a
+special @code{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 (@pxref{SRFI-39, parameters}), 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, for example:
+@example
+(define-syntax-parameter return
+ (lambda (stx)
+ (syntax-violation 'return "return used outside of a lambda^" stx)))
+@end 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 @var{exp} @dots{} use the new transformers. This is
+somewhat similar to how @code{parameterize} adjusts the values of
+regular parameters, rather than creating new bindings.
+
+@example
+(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)))
+@end example
+@end deffn
+
+
@node Eval When
@subsection Eval-when
@deffn {Scheme Procedure} macro? obj
@deffnx {C Function} scm_macro_p (obj)
-Return @code{#t} iff @var{obj} is a syntax transformer.
+Return @code{#t} if @var{obj} is a syntax transformer, or @code{#f}
+otherwise.
Note that it's a bit difficult to actually get a macro as a first-class object;
simply naming it (like @code{case}) will produce a syntax error. But it is