annotate lispref/macros.texi @ 36150:46e59561af4c

Display Vars node renamed Display Custom. Include info there about customizing cursor appearance. Clean up aggressive scrolling. Clarify horizontal scrolling discussion. Fix index entries for line number mode.
author Richard M. Stallman <rms@gnu.org>
date Sat, 17 Feb 2001 16:45:37 +0000
parents 89afca54a135
children 79e758f8571a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
1 @c -*-texinfo-*-
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
2 @c This is part of the GNU Emacs Lisp Reference Manual.
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
3 @c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998 Free Software Foundation, Inc.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
4 @c See the file elisp.texi for copying conditions.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
5 @setfilename ../info/macros
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
6 @node Macros, Customization, Functions, Top
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
7 @chapter Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
8 @cindex macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
9
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
10 @dfn{Macros} enable you to define new control constructs and other
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
11 language features. A macro is defined much like a function, but instead
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
12 of telling how to compute a value, it tells how to compute another Lisp
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
13 expression which will in turn compute the value. We call this
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
14 expression the @dfn{expansion} of the macro.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
15
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
16 Macros can do this because they operate on the unevaluated expressions
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
17 for the arguments, not on the argument values as functions do. They can
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
18 therefore construct an expansion containing these argument expressions
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
19 or parts of them.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
20
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
21 If you are using a macro to do something an ordinary function could
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
22 do, just for the sake of speed, consider using an inline function
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
23 instead. @xref{Inline Functions}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
24
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
25 @menu
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
26 * Simple Macro:: A basic example.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
27 * Expansion:: How, when and why macros are expanded.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
28 * Compiling Macros:: How macros are expanded by the compiler.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
29 * Defining Macros:: How to write a macro definition.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
30 * Backquote:: Easier construction of list structure.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
31 * Problems with Macros:: Don't evaluate the macro arguments too many times.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
32 Don't hide the user's variables.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
33 @end menu
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
34
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
35 @node Simple Macro
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
36 @section A Simple Example of a Macro
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
37
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
38 Suppose we would like to define a Lisp construct to increment a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
39 variable value, much like the @code{++} operator in C. We would like to
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
40 write @code{(inc x)} and have the effect of @code{(setq x (1+ x))}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
41 Here's a macro definition that does the job:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
42
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
43 @findex inc
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
44 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
45 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
46 (defmacro inc (var)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
47 (list 'setq var (list '1+ var)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
48 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
49 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
50
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
51 When this is called with @code{(inc x)}, the argument @var{var} is the
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
52 symbol @code{x}---@emph{not} the @emph{value} of @code{x}, as it would
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
53 be in a function. The body of the macro uses this to construct the
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
54 expansion, which is @code{(setq x (1+ x))}. Once the macro definition
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
55 returns this expansion, Lisp proceeds to evaluate it, thus incrementing
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
56 @code{x}.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
57
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
58 @node Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
59 @section Expansion of a Macro Call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
60 @cindex expansion of macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
61 @cindex macro call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
62
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
63 A macro call looks just like a function call in that it is a list which
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
64 starts with the name of the macro. The rest of the elements of the list
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
65 are the arguments of the macro.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
66
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
67 Evaluation of the macro call begins like evaluation of a function call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
68 except for one crucial difference: the macro arguments are the actual
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
69 expressions appearing in the macro call. They are not evaluated before
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
70 they are given to the macro definition. By contrast, the arguments of a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
71 function are results of evaluating the elements of the function call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
72 list.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
73
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
74 Having obtained the arguments, Lisp invokes the macro definition just
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
75 as a function is invoked. The argument variables of the macro are bound
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
76 to the argument values from the macro call, or to a list of them in the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
77 case of a @code{&rest} argument. And the macro body executes and
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
78 returns its value just as a function body does.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
79
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
80 The second crucial difference between macros and functions is that the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
81 value returned by the macro body is not the value of the macro call.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
82 Instead, it is an alternate expression for computing that value, also
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
83 known as the @dfn{expansion} of the macro. The Lisp interpreter
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
84 proceeds to evaluate the expansion as soon as it comes back from the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
85 macro.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
86
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
87 Since the expansion is evaluated in the normal manner, it may contain
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
88 calls to other macros. It may even be a call to the same macro, though
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
89 this is unusual.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
90
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
91 You can see the expansion of a given macro call by calling
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
92 @code{macroexpand}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
93
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
94 @defun macroexpand form &optional environment
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
95 @cindex macro expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
96 This function expands @var{form}, if it is a macro call. If the result
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
97 is another macro call, it is expanded in turn, until something which is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
98 not a macro call results. That is the value returned by
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
99 @code{macroexpand}. If @var{form} is not a macro call to begin with, it
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
100 is returned as given.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
101
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
102 Note that @code{macroexpand} does not look at the subexpressions of
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
103 @var{form} (although some macro definitions may do so). Even if they
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
104 are macro calls themselves, @code{macroexpand} does not expand them.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
105
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
106 The function @code{macroexpand} does not expand calls to inline functions.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
107 Normally there is no need for that, since a call to an inline function is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
108 no harder to understand than a call to an ordinary function.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
109
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
110 If @var{environment} is provided, it specifies an alist of macro
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
111 definitions that shadow the currently defined macros. Byte compilation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
112 uses this feature.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
113
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
114 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
115 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
116 (defmacro inc (var)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
117 (list 'setq var (list '1+ var)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
118 @result{} inc
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
119 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
120
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
121 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
122 (macroexpand '(inc r))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
123 @result{} (setq r (1+ r))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
124 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
125
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
126 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
127 (defmacro inc2 (var1 var2)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
128 (list 'progn (list 'inc var1) (list 'inc var2)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
129 @result{} inc2
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
130 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
131
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
132 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
133 (macroexpand '(inc2 r s))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
134 @result{} (progn (inc r) (inc s)) ; @r{@code{inc} not expanded here.}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
135 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
136 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
137 @end defun
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
138
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
139 @node Compiling Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
140 @section Macros and Byte Compilation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
141 @cindex byte-compiling macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
142
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
143 You might ask why we take the trouble to compute an expansion for a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
144 macro and then evaluate the expansion. Why not have the macro body
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
145 produce the desired results directly? The reason has to do with
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
146 compilation.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
147
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
148 When a macro call appears in a Lisp program being compiled, the Lisp
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
149 compiler calls the macro definition just as the interpreter would, and
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
150 receives an expansion. But instead of evaluating this expansion, it
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
151 compiles the expansion as if it had appeared directly in the program.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
152 As a result, the compiled code produces the value and side effects
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
153 intended for the macro, but executes at full compiled speed. This would
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
154 not work if the macro body computed the value and side effects
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
155 itself---they would be computed at compile time, which is not useful.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
156
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
157 In order for compilation of macro calls to work, the macros must
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
158 already be defined in Lisp when the calls to them are compiled. The
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
159 compiler has a special feature to help you do this: if a file being
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
160 compiled contains a @code{defmacro} form, the macro is defined
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
161 temporarily for the rest of the compilation of that file. To make this
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
162 feature work, you must put the @code{defmacro} in the same file where it
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
163 is used, and before its first use.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
164
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
165 Byte-compiling a file executes any @code{require} calls at top-level
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
166 in the file. This is in case the file needs the required packages for
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
167 proper compilation. One way to ensure that necessary macro definitions
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
168 are available during compilation is to require the files that define
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
169 them (@pxref{Named Features}). To avoid loading the macro definition files
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
170 when someone @emph{runs} the compiled program, write
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
171 @code{eval-when-compile} around the @code{require} calls (@pxref{Eval
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
172 During Compile}).
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
173
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
174 @node Defining Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
175 @section Defining Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
176
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
177 A Lisp macro is a list whose @sc{car} is @code{macro}. Its @sc{cdr} should
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
178 be a function; expansion of the macro works by applying the function
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
179 (with @code{apply}) to the list of unevaluated argument-expressions
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
180 from the macro call.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
181
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
182 It is possible to use an anonymous Lisp macro just like an anonymous
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
183 function, but this is never done, because it does not make sense to pass
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
184 an anonymous macro to functionals such as @code{mapcar}. In practice,
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
185 all Lisp macros have names, and they are usually defined with the
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
186 special form @code{defmacro}.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
187
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
188 @defspec defmacro name argument-list body-forms@dots{}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
189 @code{defmacro} defines the symbol @var{name} as a macro that looks
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
190 like this:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
191
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
192 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
193 (macro lambda @var{argument-list} . @var{body-forms})
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
194 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
195
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
196 (Note that the @sc{cdr} of this list is a function---a lambda expression.)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
197 This macro object is stored in the function cell of @var{name}. The
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
198 value returned by evaluating the @code{defmacro} form is @var{name}, but
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
199 usually we ignore this value.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
200
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
201 The shape and meaning of @var{argument-list} is the same as in a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
202 function, and the keywords @code{&rest} and @code{&optional} may be used
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
203 (@pxref{Argument List}). Macros may have a documentation string, but
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
204 any @code{interactive} declaration is ignored since macros cannot be
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
205 called interactively.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
206 @end defspec
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
207
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
208 @node Backquote
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
209 @section Backquote
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
210 @cindex backquote (list substitution)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
211 @cindex ` (list substitution)
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
212 @findex `
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
213
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
214 Macros often need to construct large list structures from a mixture of
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
215 constants and nonconstant parts. To make this easier, use the @samp{`}
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
216 syntax (usually called @dfn{backquote}).
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
217
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
218 Backquote allows you to quote a list, but selectively evaluate
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
219 elements of that list. In the simplest case, it is identical to the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
220 special form @code{quote} (@pxref{Quoting}). For example, these
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
221 two forms yield identical results:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
222
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
223 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
224 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
225 `(a list of (+ 2 3) elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
226 @result{} (a list of (+ 2 3) elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
227 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
228 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
229 '(a list of (+ 2 3) elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
230 @result{} (a list of (+ 2 3) elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
231 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
232 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
233
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
234 @findex , @r{(with Backquote)}
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
235 The special marker @samp{,} inside of the argument to backquote
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
236 indicates a value that isn't constant. Backquote evaluates the
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
237 argument of @samp{,} and puts the value in the list structure:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
238
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
239 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
240 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
241 (list 'a 'list 'of (+ 2 3) 'elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
242 @result{} (a list of 5 elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
243 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
244 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
245 `(a list of ,(+ 2 3) elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
246 @result{} (a list of 5 elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
247 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
248 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
249
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
250 Substitution with @samp{,} is allowed at deeper levels of the list
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
251 structure also. For example:
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
252
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
253 @example
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
254 @group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
255 (defmacro t-becomes-nil (variable)
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
256 `(if (eq ,variable t)
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
257 (setq ,variable nil)))
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
258 @end group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
259
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
260 @group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
261 (t-becomes-nil foo)
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
262 @equiv{} (if (eq foo t) (setq foo nil))
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
263 @end group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
264 @end example
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
265
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
266 @findex ,@@ @r{(with Backquote)}
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
267 @cindex splicing (with backquote)
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
268 You can also @dfn{splice} an evaluated value into the resulting list,
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
269 using the special marker @samp{,@@}. The elements of the spliced list
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
270 become elements at the same level as the other elements of the resulting
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
271 list. The equivalent code without using @samp{`} is often unreadable.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
272 Here are some examples:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
273
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
274 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
275 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
276 (setq some-list '(2 3))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
277 @result{} (2 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
278 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
279 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
280 (cons 1 (append some-list '(4) some-list))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
281 @result{} (1 2 3 4 2 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
282 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
283 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
284 `(1 ,@@some-list 4 ,@@some-list)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
285 @result{} (1 2 3 4 2 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
286 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
287
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
288 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
289 (setq list '(hack foo bar))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
290 @result{} (hack foo bar)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
291 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
292 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
293 (cons 'use
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
294 (cons 'the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
295 (cons 'words (append (cdr list) '(as elements)))))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
296 @result{} (use the words foo bar as elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
297 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
298 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
299 `(use the words ,@@(cdr list) as elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
300 @result{} (use the words foo bar as elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
301 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
302 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
303
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
304 In old Emacs versions, before version 19.29, @samp{`} used a different
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
305 syntax which required an extra level of parentheses around the entire
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
306 backquote construct. Likewise, each @samp{,} or @samp{,@@} substitution
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
307 required an extra level of parentheses surrounding both the @samp{,} or
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
308 @samp{,@@} and the following expression. The old syntax required
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
309 whitespace between the @samp{`}, @samp{,} or @samp{,@@} and the
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
310 following expression.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
311
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
312 This syntax is still accepted, for compatibility with old Emacs
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
313 versions, but we recommend not using it in new programs.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
314
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
315 @node Problems with Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
316 @section Common Problems Using Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
317
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
318 The basic facts of macro expansion have counterintuitive consequences.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
319 This section describes some important consequences that can lead to
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
320 trouble, and rules to follow to avoid trouble.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
321
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
322 @menu
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
323 * Argument Evaluation:: The expansion should evaluate each macro arg once.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
324 * Surprising Local Vars:: Local variable bindings in the expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
325 require special care.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
326 * Eval During Expansion:: Don't evaluate them; put them in the expansion.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
327 * Repeated Expansion:: Avoid depending on how many times expansion is done.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
328 @end menu
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
329
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
330 @node Argument Evaluation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
331 @subsection Evaluating Macro Arguments Repeatedly
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
332
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
333 When defining a macro you must pay attention to the number of times
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
334 the arguments will be evaluated when the expansion is executed. The
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
335 following macro (used to facilitate iteration) illustrates the problem.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
336 This macro allows us to write a simple ``for'' loop such as one might
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
337 find in Pascal.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
338
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
339 @findex for
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
340 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
341 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
342 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
343 "Execute a simple \"for\" loop.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
344 For example, (for i from 1 to 10 do (print i))."
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
345 (list 'let (list (list var init))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
346 (cons 'while (cons (list '<= var final)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
347 (append body (list (list 'inc var)))))))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
348 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
349 @result{} for
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
350
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
351 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
352 (for i from 1 to 3 do
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
353 (setq square (* i i))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
354 (princ (format "\n%d %d" i square)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
355 @expansion{}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
356 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
357 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
358 (let ((i 1))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
359 (while (<= i 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
360 (setq square (* i i))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
361 (princ (format "%d %d" i square))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
362 (inc i)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
363 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
364 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
365
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
366 @print{}1 1
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
367 @print{}2 4
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
368 @print{}3 9
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
369 @result{} nil
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
370 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
371 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
372
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
373 @noindent
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
374 The arguments @code{from}, @code{to}, and @code{do} in this macro are
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
375 ``syntactic sugar''; they are entirely ignored. The idea is that you
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
376 will write noise words (such as @code{from}, @code{to}, and @code{do})
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
377 in those positions in the macro call.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
378
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
379 Here's an equivalent definition simplified through use of backquote:
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
380
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
381 @smallexample
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
382 @group
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
383 (defmacro for (var from init to final do &rest body)
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
384 "Execute a simple \"for\" loop.
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
385 For example, (for i from 1 to 10 do (print i))."
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
386 `(let ((,var ,init))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
387 (while (<= ,var ,final)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
388 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
389 (inc ,var))))
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
390 @end group
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
391 @end smallexample
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
392
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
393 Both forms of this definition (with backquote and without) suffer from
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
394 the defect that @var{final} is evaluated on every iteration. If
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
395 @var{final} is a constant, this is not a problem. If it is a more
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
396 complex form, say @code{(long-complex-calculation x)}, this can slow
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
397 down the execution significantly. If @var{final} has side effects,
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
398 executing it more than once is probably incorrect.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
399
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
400 @cindex macro argument evaluation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
401 A well-designed macro definition takes steps to avoid this problem by
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
402 producing an expansion that evaluates the argument expressions exactly
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
403 once unless repeated evaluation is part of the intended purpose of the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
404 macro. Here is a correct expansion for the @code{for} macro:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
405
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
406 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
407 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
408 (let ((i 1)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
409 (max 3))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
410 (while (<= i max)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
411 (setq square (* i i))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
412 (princ (format "%d %d" i square))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
413 (inc i)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
414 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
415 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
416
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
417 Here is a macro definition that creates this expansion:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
418
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
419 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
420 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
421 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
422 "Execute a simple for loop: (for i from 1 to 10 do (print i))."
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
423 `(let ((,var ,init)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
424 (max ,final))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
425 (while (<= ,var max)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
426 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
427 (inc ,var))))
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
428 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
429 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
430
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
431 Unfortunately, this fix introduces another problem,
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
432 described in the following section.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
433
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
434 @node Surprising Local Vars
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
435 @subsection Local Variables in Macro Expansions
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
436
27193
89afca54a135 @ifinto -> @ifnottex.
Gerd Moellmann <gerd@gnu.org>
parents: 22138
diff changeset
437 @ifnottex
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
438 In the previous section, the definition of @code{for} was fixed as
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
439 follows to make the expansion evaluate the macro arguments the proper
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
440 number of times:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
441
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
442 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
443 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
444 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
445 "Execute a simple for loop: (for i from 1 to 10 do (print i))."
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
446 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
447 @group
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
448 `(let ((,var ,init)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
449 (max ,final))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
450 (while (<= ,var max)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
451 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
452 (inc ,var))))
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
453 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
454 @end smallexample
27193
89afca54a135 @ifinto -> @ifnottex.
Gerd Moellmann <gerd@gnu.org>
parents: 22138
diff changeset
455 @end ifnottex
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
456
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
457 The new definition of @code{for} has a new problem: it introduces a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
458 local variable named @code{max} which the user does not expect. This
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
459 causes trouble in examples such as the following:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
460
7734
2d4db32cccd5 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents: 7194
diff changeset
461 @smallexample
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
462 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
463 (let ((max 0))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
464 (for x from 0 to 10 do
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
465 (let ((this (frob x)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
466 (if (< max this)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
467 (setq max this)))))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
468 @end group
7734
2d4db32cccd5 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents: 7194
diff changeset
469 @end smallexample
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
470
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
471 @noindent
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
472 The references to @code{max} inside the body of the @code{for}, which
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
473 are supposed to refer to the user's binding of @code{max}, really access
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
474 the binding made by @code{for}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
475
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
476 The way to correct this is to use an uninterned symbol instead of
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
477 @code{max} (@pxref{Creating Symbols}). The uninterned symbol can be
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
478 bound and referred to just like any other symbol, but since it is
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
479 created by @code{for}, we know that it cannot already appear in the
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
480 user's program. Since it is not interned, there is no way the user can
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
481 put it into the program later. It will never appear anywhere except
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
482 where put by @code{for}. Here is a definition of @code{for} that works
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
483 this way:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
484
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
485 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
486 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
487 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
488 "Execute a simple for loop: (for i from 1 to 10 do (print i))."
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
489 (let ((tempvar (make-symbol "max")))
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
490 `(let ((,var ,init)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
491 (,tempvar ,final))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
492 (while (<= ,var ,tempvar)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
493 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
494 (inc ,var)))))
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
495 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
496 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
497
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
498 @noindent
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
499 This creates an uninterned symbol named @code{max} and puts it in the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
500 expansion instead of the usual interned symbol @code{max} that appears
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
501 in expressions ordinarily.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
502
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
503 @node Eval During Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
504 @subsection Evaluating Macro Arguments in Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
505
22138
d4ac295a98b3 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21682
diff changeset
506 Another problem can happen if the macro definition itself
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
507 evaluates any of the macro argument expressions, such as by calling
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
508 @code{eval} (@pxref{Eval}). If the argument is supposed to refer to the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
509 user's variables, you may have trouble if the user happens to use a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
510 variable with the same name as one of the macro arguments. Inside the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
511 macro body, the macro argument binding is the most local binding of this
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
512 variable, so any references inside the form being evaluated do refer to
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
513 it. Here is an example:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
514
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
515 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
516 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
517 (defmacro foo (a)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
518 (list 'setq (eval a) t))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
519 @result{} foo
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
520 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
521 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
522 (setq x 'b)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
523 (foo x) @expansion{} (setq b t)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
524 @result{} t ; @r{and @code{b} has been set.}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
525 ;; @r{but}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
526 (setq a 'c)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
527 (foo a) @expansion{} (setq a t)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
528 @result{} t ; @r{but this set @code{a}, not @code{c}.}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
529
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
530 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
531 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
532
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
533 It makes a difference whether the user's variable is named @code{a} or
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
534 @code{x}, because @code{a} conflicts with the macro argument variable
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
535 @code{a}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
536
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
537 Another problem with calling @code{eval} in a macro definition is that
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
538 it probably won't do what you intend in a compiled program. The
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
539 byte-compiler runs macro definitions while compiling the program, when
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
540 the program's own computations (which you might have wished to access
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
541 with @code{eval}) don't occur and its local variable bindings don't
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
542 exist.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
543
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
544 To avoid these problems, @strong{don't evaluate an argument expression
22138
d4ac295a98b3 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21682
diff changeset
545 while computing the macro expansion}. Instead, substitute the
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
546 expression into the macro expansion, so that its value will be computed
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
547 as part of executing the expansion. This is how the other examples in
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
548 this chapter work.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
549
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
550 @node Repeated Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
551 @subsection How Many Times is the Macro Expanded?
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
552
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
553 Occasionally problems result from the fact that a macro call is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
554 expanded each time it is evaluated in an interpreted function, but is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
555 expanded only once (during compilation) for a compiled function. If the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
556 macro definition has side effects, they will work differently depending
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
557 on how many times the macro is expanded.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
558
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
559 Therefore, you should avoid side effects in computation of the
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
560 macro expansion, unless you really know what you are doing.
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
561
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
562 One special kind of side effect can't be avoided: constructing Lisp
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
563 objects. Almost all macro expansions include constructed lists; that is
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
564 the whole point of most macros. This is usually safe; there is just one
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
565 case where you must be careful: when the object you construct is part of a
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
566 quoted constant in the macro expansion.
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
567
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
568 If the macro is expanded just once, in compilation, then the object is
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
569 constructed just once, during compilation. But in interpreted
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
570 execution, the macro is expanded each time the macro call runs, and this
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
571 means a new object is constructed each time.
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
572
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
573 In most clean Lisp code, this difference won't matter. It can matter
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
574 only if you perform side-effects on the objects constructed by the macro
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
575 definition. Thus, to avoid trouble, @strong{avoid side effects on
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
576 objects constructed by macro definitions}. Here is an example of how
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
577 such side effects can get you into trouble:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
578
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
579 @lisp
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
580 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
581 (defmacro empty-object ()
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
582 (list 'quote (cons nil nil)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
583 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
584
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
585 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
586 (defun initialize (condition)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
587 (let ((object (empty-object)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
588 (if condition
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
589 (setcar object condition))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
590 object))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
591 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
592 @end lisp
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
593
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
594 @noindent
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
595 If @code{initialize} is interpreted, a new list @code{(nil)} is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
596 constructed each time @code{initialize} is called. Thus, no side effect
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
597 survives between calls. If @code{initialize} is compiled, then the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
598 macro @code{empty-object} is expanded during compilation, producing a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
599 single ``constant'' @code{(nil)} that is reused and altered each time
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
600 @code{initialize} is called.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
601
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
602 One way to avoid pathological cases like this is to think of
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
603 @code{empty-object} as a funny kind of constant, not as a memory
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
604 allocation construct. You wouldn't use @code{setcar} on a constant such
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
605 as @code{'(nil)}, so naturally you won't use it on @code{(empty-object)}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
606 either.