Macros
======

At its best, programming in Lisp is an iterative process of building up a language appropriate to the problem at hand, and then solving the problem in that language. Defining new procedures is part of that, but Lisp also allows the user to extend its syntax, with its famous macros.

Macros are syntactic extensions which cause the expression that they appear in to be transformed in some way before being evaluated. In expressions that are intended for macro transformation, the identifier that names the relevant macro must appear as the first element, like this:

     (MACRO-NAME MACRO-ARGS ...)

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.

Defining Macros
---------------

A macro is a binding between a keyword and a syntax transformer. Since it's difficult to discuss define-syntax without discussing the format of transformers, consider the following example macro definition:

     (define-syntax when
       (syntax-rules ()
         ((when condition exp ...)
          (if condition
              (begin exp ...)))))

     (when #t
       (display "hey ho\n")
       (display "let's go\n"))
     -| hey ho
     -| let's go

In this example, the when binding is bound with define-syntax. Syntax transformers are discussed in more depth in Syntax Rules and Syntax Case.

 -- Syntax: define-syntax keyword transformer
     Bind KEYWORD to the syntax transformer obtained by evaluating TRANSFORMER.

     After a macro has been defined, further instances of KEYWORD in Scheme source code will invoke the syntax transformer defined by TRANSFORMER.

One can also establish local syntactic bindings with let-syntax.

 -- Syntax: let-syntax ((keyword transformer) ...) exp...
     Bind KEYWORD... to TRANSFORMER... while expanding EXP....

     A let-syntax binding only exists at expansion-time.

          (let-syntax ((unless
                        (syntax-rules ()
                          ((unless condition exp ...)
                           (if (not condition)
                               (begin exp ...))))))
            (unless #t
              (primitive-exit 1))
            "rock rock rock")
          => "rock rock rock"

A define-syntax form is valid anywhere a definition may appear: at the top-level, or locally. Just as a local define expands out to an instance of letrec, a local define-syntax expands out to letrec-syntax.

 -- Syntax: letrec-syntax ((keyword transformer) ...) exp...
     Bind KEYWORD... to TRANSFORMER... while expanding EXP....

     In the spirit of letrec versus let, an expansion produced by TRANSFORMER may reference a KEYWORD bound by the same LETREC-SYNTAX.

          (letrec-syntax ((my-or
                           (syntax-rules ()
                             ((my-or)
                              #t)
                             ((my-or exp)
                              exp)
                             ((my-or exp rest ...)
                              (let ((t exp))
                                (if exp
                                    exp
                                    (my-or rest ...)))))))
            (my-or #f "rockaway beach"))
          => "rockaway beach"

Syntax-rules Macros
-------------------

syntax-rules macros are simple, pattern-driven syntax transformers, with a beauty worthy of Scheme.

 -- Syntax: syntax-rules literals (pattern template)...
     A syntax-rules macro consists of three parts: the literals (if any), the patterns, and as many templates as there are patterns.

     When the syntax expander sees the invocation of a syntax-rules macro, it matches the expression against the patterns, in order, and rewrites the expression using the template from the first matching pattern. If no pattern matches, a syntax error is signalled.

Patterns
........

We have already seen some examples of patterns in the previous section: (unless condition exp ...), (my-or exp), and so on. A pattern is structured like the expression that it is to match. It can have nested structure as well, like (let ((var val) ...) exp exp* ...). Broadly speaking, patterns are made of lists, improper lists, vectors, identifiers, and datums. Users can match a sequence of patterns using the ellipsis (...).

Identifiers in a pattern are called literals if they are present in the syntax-rules literals list, and pattern variables otherwise. When building up the macro output, the expander replaces instances of a pattern variable in the template with the matched subexpression.

     (define-syntax kwote
       (syntax-rules ()
         ((kwote exp)
          (quote exp))))
     (kwote (foo . bar))
     => (foo . bar)

An improper list of patterns matches as rest arguments do:

     (define-syntax let1
       (syntax-rules ()
         ((_ (var val) . exps)
          (let ((var val)) . exps))))

However this definition of let1 probably isn't what you want, as the tail pattern EXPS will match non-lists, like (let1 (foo 'bar) . baz). So often instead of using improper lists as patterns, ellipsized patterns are better. Instances of a pattern variable in the template must be followed by an ellipsis.

     (define-syntax let1
       (syntax-rules ()
         ((_ (var val) exp ...)
          (let ((var val)) exp ...))))

This let1 probably still doesn't do what we want, because the body matches sequences of zero expressions, like (let1 (foo 'bar)). In this case we need to assert we have at least one body expression. A common idiom for this is to name the ellipsized pattern variable with an asterisk:

     (define-syntax let1
       (syntax-rules ()
         ((_ (var val) exp exp* ...)
          (let ((var val)) exp exp* ...))))

A vector of patterns matches a vector whose contents match the patterns, including ellipsizing and tail patterns.

     (define-syntax letv
       (syntax-rules ()
         ((_ #((var val) ...) exp exp* ...)
          (let ((var val) ...) exp exp* ...))))
     (letv #((foo 'bar)) foo)
     => foo

Literals are used to match specific datums in an expression, like the use of => and else in cond expressions.

     (define-syntax cond1
       (syntax-rules (=> else)
         ((cond1 test => fun)
          (let ((exp test))
            (if exp (fun exp) #f)))
         ((cond1 test exp exp* ...)
          (if test (begin exp exp* ...)))
         ((cond1 else exp exp* ...)
          (begin exp exp* ...))))

     (define (square x) (* x x))
     (cond1 10 => square)
     => 100
     (let ((=> #t))
       (cond1 10 => square))
     => #<procedure square (x)>

A literal matches an input expression if the input expression is an identifier with the same name as the literal, and both are unbound (Language lawyers probably see the need here for use of literal-identifier=? rather than free-identifier=?, and would probably be correct. Patches accepted.).

If a pattern is not a list, vector, or an identifier, it matches as a literal, with equal?.

     (define-syntax define-matcher-macro
       (syntax-rules ()
         ((_ name lit)
          (define-syntax name
            (syntax-rules ()
             ((_ lit) #t)
             ((_ else) #f))))))

     (define-matcher-macro is-literal-foo? "foo")

     (is-literal-foo? "foo")
     => #t
     (is-literal-foo? "bar")
     => #f
     (let ((foo "foo"))
       (is-literal-foo? foo))
     => #f

The last example indicates that matching happens at expansion-time, not at run-time.

Syntax-rules macros are always used as (MACRO . ARGS), and the MACRO will always be a symbol. Correspondingly, a syntax-rules pattern must be a list (proper or improper), and the first pattern in that list must be an identifier. Incidentally it can be any identifier -- it doesn't have to actually be the name of the macro. Thus the following three are equivalent:

     (define-syntax when
       (syntax-rules ()
         ((when c e ...)
          (if c (begin e ...)))))

     (define-syntax when
       (syntax-rules ()
         ((_ c e ...)
          (if c (begin e ...)))))

     (define-syntax when
       (syntax-rules ()
         ((something-else-entirely c e ...)
          (if c (begin e ...)))))

For clarity, use one of the first two variants. Also note that since the pattern variable will always match the macro itself (e.g., cond1), it is actually left unbound in the template.

Hygiene
.......

syntax-rules macros have a magical property: they preserve referential transparency. When you read a macro definition, any free bindings in that macro are resolved relative to the macro definition; and when you read a macro instantiation, all free bindings in that expression are resolved relative to the expression.

This property is sometimes known as 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 macro expansion.

Consider the definition of my-or from the previous section:

     (define-syntax my-or
       (syntax-rules ()
         ((my-or)
          #t)
         ((my-or exp)
          exp)
         ((my-or exp rest ...)
          (let ((t exp))
            (if exp
                exp
                (my-or rest ...))))))

A naive expansion of (let ((t #t)) (my-or #f t)) would yield:

     (let ((t #t))
       (let ((t #f))
         (if t t t)))
     => #f

Which clearly is not what we want. Somehow the t in the definition is distinct from the t at the site of use; and it is indeed this distinction that is maintained by the syntax expander, when expanding hygienic macros.

This discussion is mostly relevant in the context of traditional Lisp macros (see Defmacros), which do not preserve referential transparency. Hygiene adds to the expressive power of Scheme.

Further Information
...................

For a formal definition of syntax-rules and its pattern language, see Macros (Revised(5) Report on the Algorithmic Language Scheme).

syntax-rules macros are simple and clean, but do they have limitations. They do not lend themselves to expressive error messages: patterns either match or they don't. Their ability to generate code is limited to template-driven expansion; often one needs to define a number of helper macros to get real work done. Sometimes one wants to introduce a binding into the lexical context of the generated code; this is impossible with syntax-rules. Relatedly, they cannot programmatically generate identifiers.

The solution to all of these problems is to use syntax-case if you need its features. But if for some reason you're stuck with syntax-rules, you might enjoy Joe Marshall's syntax-rules Primer for the Merely Eccentric (http://sites.google.com/site/evalapply/eccentric.txt).

Support for the syntax-case System
----------------------------------

Lisp-style Macro Definitions
----------------------------

In Lisp-like languages, the traditional way to define macros is very similar to procedure definitions.  The key differences are that the macro definition body should return a list that describes the transformed expression, and that the definition is marked as a macro definition (rather than a procedure definition) by the use of a different definition keyword: in Lisp, defmacro rather than defun, and in Scheme, define-macro rather than define.

Guile supports this style of macro definition using both defmacro and define-macro.  The only difference between them is how the macro name and arguments are grouped together in the definition:

     (defmacro NAME (ARGS ...) BODY ...)

is the same as

     (define-macro (NAME ARGS ...) BODY ...)

The difference is analogous to the corresponding difference between Lisp's defun and Scheme's define.

false-if-exception, from the boot-9.scm file in the Guile distribution, is a good example of macro definition using defmacro:

     (defmacro false-if-exception (expr)
       `(catch #t
               (lambda () ,expr)
               (lambda args #f)))

The effect of this definition is that expressions beginning with the identifier false-if-exception are automatically transformed into a catch expression following the macro definition specification. For example:

     (false-if-exception (open-input-file "may-not-exist"))
     ==
     (catch #t
            (lambda () (open-input-file "may-not-exist"))
            (lambda args #f))

 -- Scheme Procedure: cons-source xorig x y
 -- C Function: scm_cons_source (xorig, x, y)
     Create and return a new pair whose car and cdr are X and Y. Any source properties associated with XORIG are also associated with the new pair.

Identifier Macros
-----------------

Eval-when
---------

Internal Macros
---------------

Internally, Guile represents macros using a disjoint type.

 -- Scheme Procedure: make-syntax-transformer name type binding

 -- Scheme Procedure: macro? obj
 -- C Function: scm_macro_p (obj)
     Return #t if OBJ is a regular macro, a memoizing macro, a syntax transformer, or a syntax-case macro.

 -- Scheme Procedure: macro-type m
 -- C Function: scm_macro_type (m)
     Return one of the symbols syntax, macro, macro!, or syntax-case, depending on whether M is a syntax transformer, a regular macro, a memoizing macro, or a syntax-case macro, respectively.  If M is not a macro, #f is returned.

 -- Scheme Procedure: macro-name m
 -- C Function: scm_macro_name (m)
     Return the name of the macro M.

 -- Scheme Procedure: macro-transformer m
 -- C Function: scm_macro_transformer (m)
     Return the transformer of the macro M.

 -- Scheme Procedure: macro-binding m
 -- C Function: scm_macro_binding (m)
     Return the binding of the macro M.