@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 Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
-@page
@node Macros
@section 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.
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:
(@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 Further Information
For a formal definition of @code{syntax-rules} and its pattern language, see
It is not strictly necessary for a @code{syntax-case} expression to return a
syntax object, because @code{syntax-case} expressions can be used in helper
functions, or otherwise used outside of syntax expansion itself. However a
-syntax transformer procedure must return a syntax object, so most uses of
+syntax transformer procedure must return a syntax object, so most uses of
@code{syntax-case} do end up returning syntax objects.
Here in this case, the form that built the return value was @code{(syntax (+ exp
1))}. The interesting thing about this is that within a @code{syntax}
-expression, any appearance of a pattern variable is substitued into the
+expression, any appearance of a pattern variable is substituted into the
resulting syntax object, carrying with it all relevant metadata from the source
expression, such as lexical identity and source location.
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
@end deffn
@example
+;; relying on previous add1 definition
(define-syntax add1!
(lambda (x)
(syntax-case x ()
(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
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
As the example notes, the transformer procedure must be explicitly
marked as being a ``variable transformer'', as most macros aren't
-written to discriminate on the form in the operand position.
+written to discriminate on the form in the operator position.
@deffn {Scheme Procedure} make-variable-transformer transformer
Mark the @var{transformer} procedure as being a ``variable
@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)