DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦1adc734f8⟧ TextFile

    Length: 14696 (0x3968)
    Types: TextFile
    Names: »macros.texinfo«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦c06c473ab⟧ »./UNRELEASED/lispref.tar.Z« 
        └─⟦1b57a2ffe⟧ 
            └─⟦this⟧ »macros.texinfo« 

TextFile

@setfilename ../info/macros
@node Macros, Control Structures, Functions, Top
@chapter Macros
@cindex macros

@dfn{Macros} enable you to define new control constructs and other
language features.  A macro is defined much like a function; but instead
of saying how to compute a value, it says how to compute another Lisp
expression which will compute the value.  We call this expression the
@dfn{expansion} of the macro.

Macros can do this because they operate on the unevaluated expressions
for the arguments, not on the argument values as functions do.
Therefore they can construct an expansion containing these argument
expressions, or parts of them.

@menu
* Simple Macro::
* Expansion::
* Compiling Macros::
* Defining Macros::     
* Backquote::   
* Problems with Macros::
@end menu

@node Simple Macro, Expansion, Macros, Macros
@section A Simple Example of a Macro

Suppose we sould like to define a Lisp construct to increment a variable
value, much like the @code{++} operator in C.  We would like to write
@code{(inc x)} and have the effect of @code{(setq x (1+ x))}.  Here is
how to do it:

@findex inc @r{example}
@example
(defmacro inc (var)
   (list 'setq var (list '1+ var)))
@end example

When called as @code{(inc x)}, the argument @code{var} has the value
@code{x}---@strong{not} the @strong{value} of @code{x}.  The body of the
macro uses this to construct the expansion, which is @code{(setq
x (1+ x))}.  Once the macro definition returns this expansion, Lisp
proceeds to evaluate it, thus incrementing @code{x}.

@node Expansion, Compiling Macros, Simple Macro, Macros
@section Expansion of a Macro Call
@cindex expansion of macros

This section describes in detail the process of expanding a macro call.

A macro call looks just like a function call: it is a list which starts
with the name of the macro.  The rest of the elements of the list are
the arguments of the macro.  

Evaluation of the macro call begins like evaluation of a function call
except for one crucial difference: the arguments of a function are the
values of the elements of the list.  The macro arguments are the actual
expressions appearing in the macro call.

Having obtained the arguments, Lisp invokes the macro just as a function
is invoked.  The argument variables of the macro are bound to the
argument values from the macro call, or to a list of them in the case of
a @code{&rest} argument.  And the macro body executes and returns its
value just as a function body does.  

Now comes the second crucial difference between macros and functions:
the value returned by the macro body is not the value of the macro call.
Instead, it is an alternate expression for computing that value, also
known as the @dfn{expansion} of the macro.  The Lisp interpreter
therefore proceeds to evaluate the expansion as soon as it comes back
from the macro.

Since the expression is evaluated normally, it may contain calls to
other macros.  It may even be a call to the same macro, though this is
unusual.

You can see what a macro call would expand into by means of
@code{macroexpand}:

@defun macroexpand form &optional environment
@cindex macro expansion
This function expands @var{form}, if it is a macro call.  If the result
is another macro call, it is expanded in turn, until something which is
not a macro call results.  That is the value returned by
@code{macroexpand}.  If @var{form} is not a macro call to begin with, it
is returned as given.

Note that @code{macroexpand} does not look at the subexpressions of
@var{form} (although some macro definitions may do so).  If they
are macro calls themselves, @code{macroexpand} will not expand them.

If @var{environment} is provided, it specifies an alist of macro
definitions that shadow the currently defined macros.  This is used
by byte-compilation.

@example
(defmacro inc (var)
    (list 'setq var (list '1+ var)))
     @result{} inc

(macroexpand '(inc r))
     @result{} (setq r (1+ r))

(defmacro inc2 (var1 var2)
    (list 'progn (list 'inc var1) (list 'inc var2)))
     @result{} inc2

(macroexpand '(inc2 r s))
     @result{} (progn (inc r) (inc s))        ; @r{@code{inc} not expanded here.}
@end example
@end defun

@node Compiling Macros, Defining Macros, Expansion, Macros
@section Macros and Byte-Compilation
@cindex byte-compiling macros

You might ask why the trouble of computing an expansion for a macro and
then evaluating it.  Why not have the macro body produce the desired
results directly?  The reason has to do with the Lisp compiler.

When a macro call appears in a Lisp program being compiled, the Lisp
compiler calls the macro definition just as the interpreter would, and
receives an expansion.  But instead of evaluating this expansion, it
compiles it.  As a result, the compiled code produces the value and side
effects that we want, and it executes just as fast as if we had written
the expansion ourselves.  This would be impossible if the macro body
computed the value and side effects itself---they would be computed at
compile time, which is not useful.

In order for compilation of macro calls to work, the macros must be
defined in Lisp when the calls to them are compiled.  The compiler
has a special feature to help you do this: if a file being compiled
contains a @code{defmacro} form, the macro is defined temporarily
for the rest of the compilation of that file.  To use this, you
must define the macro in the same file where it is used, and before
its first use.  Alternatively, you can put your macro definitions in
a separate file and load that file before doing any compilation.

@node Defining Macros, Backquote, Compiling Macros, Macros
@section Defining Macros

  A Lisp macro is a list whose @sc{car} is @code{macro}.  Its @sc{cdr} should
be a function; expansion of the macro works by applying the function
(with @code{apply}) to the list of unevaluated argument-expressions
from the macro call.

  You can use an anonymous Lisp macro just like an anonymous function,
but this is never done, because it does not make sense to pass an
anonymous macro to mapping functions such as @code{mapcar}.  In
practice, all Lisp macros have names, and they are usually defined with
the special form @code{defmacro}.

@defspec defmacro name parameter-list body-forms@dots{}
@code{defmacro} defines the symbol @var{name} as a macro which looks
like this:

@example
(macro lambda @var{parameter-list} . @var{body-forms})
@end example

This macro-object is stored in the function cell of @var{name}.  The
value returned by evaluating the @code{defmacro} form is @var{name}, but
usually we ignore this value.

The shape and meaning of @var{parameter-list} is the same as in a
function, and the keyword @code{&rest} and @code{&optional} may be used
(@pxref{Argument List}).  Macros may have a documentation string, but
any @code{interactive} declaration is ignored since macros cannot be
called interactively.
@end defspec

@node Backquote, Problems with Macros, Defining Macros, Macros
@section Backquote
@cindex backquote (list substitution)

It could prove rather awkward to write macros of significant size,
simply due the number of times the function @code{list} needs to
be called.  To make writing these forms
easier, a macro @samp{`} (pronounced @dfn{backquote}) exists.

  Backquote allows you to quote a list, but selectively evaluate
elements of that list.  In its simplest form, it is identical to
the special form @code{quote}.  In the example below, the two forms
yield identical results.

@example
(` (a list of (+ 2 3) elements))
     @result{} (a list of (+ 2 3) elements)
(quote (a list of (+ 2 3) elements))
     @result{} (a list of (+ 2 3) elements)
@end example

@findex ,
By inserting a special marker,@samp{,}, inside of the argument
to backquote, it is possible to evaluate desired portions of the
argument:

@example
(list 'a 'list 'of (+ 2 3) 'elements)
     @result{} (a list of 5 elements)
(` (a list of (, (+ 2 3)) elements))
     @result{} (a list of 5 elements)
@end example

@findex ,@@
It is also possible to have an evaluated list @dfn{spliced} into the
resulting list by using the special marker @samp{,@@}.  The elements of
the spliced list become elements at the same level as the other elements of the
resulting list.  The equivalent code without using @code{`} is often
unreadable.

@example
(setq some-list '(2 3))
     @result{} (2 3)
(cons 1 (append some-list (list 4)))
     @result{} (1 2 3 4)
(` (1 (,@@ some-list) 4))
     @result{} (1 2 3 (4))

;; @r{A more complex example:}
(cons 'a
  (cons 'list
    (cons 'of (append (list (+ 2 3)) '(elements)))))
     @result{} (a list of 5 elements)
(` (a list of (,@@ (list (+ 2 3))) elements))
     @result{} (a list of 5 (elements))
     @result{} (a list of 5 elements)
@end example

@defmac ` list
This macro returns @var{list} as quote would, except any sublist
beginning with the special marker @samp{,} will have its second
element evaluated, and any sublist beginning with the special
marker @samp{,@@} will have its second element evaluated, and the
result spliced into the list being created.

If any of these specially marked sublists contain more than two
elements, those elements will be ignored.

There are several subtle bugs that should simply be avoided.  The
following forms do not work as one would expect:

@example
(` (a . (, 1)))					; @r{Not @code{(a . 1)}}
     @result{} (a \, 1)                                
(` [a (, 1) c])					; @r{Not @code{[a 1 c]}}
     @error{} Wrong type argument                      
(` (, 2))					; @r{Not 2}
     @result{} (\, 2)                                  

(` (a list of (, (list (+ 2 3))) elements xx))
 @result{} (a list of (5) elements xx)

@end example
@end defmac

@node Problems with Macros,, Backquote, Macros
@section Common Problems Using Macros

When defining a macro you must always pay attention to how many times
the arguments will be evaluated when the expansion is executed.  To
illustrate this problem, here is a macro to facilitate iteration.  This
macro allows us to write a simple ``for'' loop such as one might find in
Pascal.

@findex for @r{example}
@example
(defmacro for (var from init to final do &rest body)
  "Execute a simple \"for\" loop, e.g.,
    (for i from 1 to 10 do (print i))."

  (list 'let (list (list var init))
        (cons 'while (cons (list '<= var final)
                           (append body (list (list 'inc var)))
                           ))))
     @result{} for

(for i from 1 to 3 do
   (setq square (* i i))
   (princ (format "\n%d %d" i square)))
@expansion{}
(let ((i 1))
  (while (<= i 3)
    (setq square (* i i))
    (princ (format "%d      %d" i square))
    (inc i)))

     @print{}1       1
     @print{}2       4
     @print{}3       9
     @result{} nil
@end example

The arguments @code{from}, @code{to}, and @code{do}
in this macro are ``syntactic sugar''; they are entirely ignored.
The idea is that you will write noise words (such as @code{from},
@code{to}, and @code{do}) in those positions in the macro call.

This macro suffers from the defect that @var{final} is evaluated on
every iteration.  If @var{final} is a constant, there's no problem.  If
it had been a more complex form, say @code{(long-complex-calculation
x)}, it would slow down the execution significantly.  If @var{final} has
side effects, executing it more than once could be disastrous.

@cindex macro evaluation
A well-designed macro takes steps to avoid this problem by producing an
expansion that evaluates the argument expressions exactly once unless
they are supposed to be repeated.  Here is a suitable expansion for
the @code{for} macro:

@example
(let ((i 1)
      (max 3))
  (while (<= i max)
    (setq square (* i i))
    (princ (format "%d      %d" i square))
    (inc i)))
@end example

Here is a macro definition that creates this expansion: 

@example
(defmacro for (var from init to final do &rest body)
  "Execute a simple for loop: (for i from 1 to 10 do (print i))."
  (` (let (( (, var) (, init) )
           ( max (, final) ))
       (while (<= (, var) max)
              (,@@ body)
              (inc (, var))
              ))))
@end example

However, this definition has a different problem: it introduces a local
variable named @code{max} which the user does not expect.  This will
cause trouble in examples such as the following:

@example
(let ((max 0))
  (for x from 0 to 10 do
    (let ((this (frob x)))
      (if (< max this)
          (setq max this)))))
@end example

@noindent
where the references to @code{max} inside the body of the @code{for},
which are supposed to refer to the user's binding of @code{max}, will
get instead the binding made by @code{for}.

The way to correct this is to use an uninterned symbol instead of
@code{max} (@pxref{Creating and Interning Symbols}).  The uninterned
symbol can be bound and referred to just like any other symbol; but if
it is created by @code{for}, we know that it cannot appear in the user's
program.  And since it is not interned, there is no way the user can put
it into the program later.  It will not appear anywhere except where put
by @code{for}.  Here is a definition of @code{for} which works this way:

@example
(defmacro for (var from init to final do &rest body)
  "Execute a simple for loop: (for i from 1 to 10 do (print i))."
  (let ((tempvar (make-symbol "max")))
    (` (let (((, var) (, init))
             ((, tempvar) (, final)))
         (while (<= (, var) (, tempvar))
                (,@@ body)
                (inc (, var)))))))
@end example

@noindent
This creates an uninterned symbol named @code{max} and puts it in the
expansion where the canonical, interned symbol @code{max} was used
previously.

Another problem can happen if you evaluate any of the macro argument
expressions during the computation of the expansion: if it is supposed
to refer to the user's variables, you may have trouble if the user
happens to use a variable with the same name as one of the macro
arguments.  The problem is that inside the macro body, the macro
argument binding is the most local binding of this variable, so any
references inside the form being evaluated will refer to it.  Here is an
example:

@example
(defmacro foo (a)
  (list 'setq (eval a) t))
     @result{} foo
(setq x 'b)
(foo x) @expansion{} (setq b t)
     @result{} t                  ; @r{and @code{b} has been set.}
@r{but}
(setq a 'b)
(foo a) @expansion{} (setq 'b t)   ; @r{invalid!}
@error{} Symbol's value is void: b
@end example

Here it makes a difference whether the user types @code{a} or @code{x},
because @code{a} conflicts with the macro argument variable @code{a}.

In general it is better to avoid calling @code{eval} in a macro
definition at all.