annotate lispref/macros.texi @ 62412:6ac7ed8e212b

(makefile-dependency-regex): Turn it into a var, and refine it to mask one more level of nested vars. (makefile-rule-action-regex): Turn it into a var, and refine it so it recognizes backslashed continuation lines as belonging to the same command. (makefile-macroassign-regex): Refine it so it recognizes backslashed continuation lines as belonging to the same command. (makefile-var-use-regex): Don't look at the next char, because it might be the same one to be skipped by the initial [^$], leading to an overlooked variable use. (makefile-make-font-lock-keywords): Remove two parameters, which are now variables that some of the modes set locally. Handle dependency and rule action matching through functions, because regexps alone match too often. Dependency matching now comes last, so it can check, whether a colon already matched something else. (makefile-mode): Inform that font-lock improves makefile parsing capabilities. (makefile-match-dependency, makefile-match-action): New functions.
author Daniel Pfeiffer <occitan@esperanto.org>
date Mon, 16 May 2005 20:13:09 +0000
parents afb61f4e22bb
children e836425ee789 e4694597cbf4
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.
54812
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
3 @c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 2004 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.
52145
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
33 * Indenting Macros:: Specifying how to indent macro calls.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
34 @end menu
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
35
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
36 @node Simple Macro
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
37 @section A Simple Example of a Macro
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
38
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
39 Suppose we would like to define a Lisp construct to increment a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
40 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
41 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
42 Here's a macro definition that does the job:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
43
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
44 @findex inc
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
45 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
46 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
47 (defmacro inc (var)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
48 (list 'setq var (list '1+ var)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
49 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
50 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
51
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
52 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
53 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
54 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
55 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
56 returns this expansion, Lisp proceeds to evaluate it, thus incrementing
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
57 @code{x}.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
58
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
59 @node Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
60 @section Expansion of a Macro Call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
61 @cindex expansion of macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
62 @cindex macro call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
63
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
64 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
65 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
66 are the arguments of the macro.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
67
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
68 Evaluation of the macro call begins like evaluation of a function call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
69 except for one crucial difference: the macro arguments are the actual
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
70 expressions appearing in the macro call. They are not evaluated before
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
71 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
72 function are results of evaluating the elements of the function call
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
73 list.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
74
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
75 Having obtained the arguments, Lisp invokes the macro definition just
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
76 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
77 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
78 case of a @code{&rest} argument. And the macro body executes and
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
79 returns its value just as a function body does.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
80
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
81 The second crucial difference between macros and functions is that the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
82 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
83 Instead, it is an alternate expression for computing that value, also
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
84 known as the @dfn{expansion} of the macro. The Lisp interpreter
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
85 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
86 macro.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
87
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
88 Since the expansion is evaluated in the normal manner, it may contain
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
89 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
90 this is unusual.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
91
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
92 You can see the expansion of a given macro call by calling
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
93 @code{macroexpand}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
94
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
95 @defun macroexpand form &optional environment
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
96 @cindex macro expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
97 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
98 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
99 not a macro call results. That is the value returned by
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
100 @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
101 is returned as given.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
102
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
103 Note that @code{macroexpand} does not look at the subexpressions of
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
104 @var{form} (although some macro definitions may do so). Even if they
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
105 are macro calls themselves, @code{macroexpand} does not expand them.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
106
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
107 The function @code{macroexpand} does not expand calls to inline functions.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
108 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
109 no harder to understand than a call to an ordinary function.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
110
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
111 If @var{environment} is provided, it specifies an alist of macro
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
112 definitions that shadow the currently defined macros. Byte compilation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
113 uses this feature.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
114
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
115 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
116 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
117 (defmacro inc (var)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
118 (list 'setq var (list '1+ var)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
119 @result{} inc
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
120 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
121
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
122 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
123 (macroexpand '(inc r))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
124 @result{} (setq r (1+ r))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
125 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
126
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
127 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
128 (defmacro inc2 (var1 var2)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
129 (list 'progn (list 'inc var1) (list 'inc var2)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
130 @result{} inc2
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
131 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
132
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
133 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
134 (macroexpand '(inc2 r s))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
135 @result{} (progn (inc r) (inc s)) ; @r{@code{inc} not expanded here.}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
136 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
137 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
138 @end defun
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
139
54812
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
140
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
141 @defun macroexpand-all form &optional environment
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
142 @cindex macro expansion in entire form
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
143 @code{macroexpand-all} expands macros like @code{macroexpand}, but
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
144 will look for and expand all macros in @var{form}, not just at the
60267
afb61f4e22bb (Expansion): Cleanup.
Richard M. Stallman <rms@gnu.org>
parents: 58383
diff changeset
145 top-level. If no macros are expanded, the return value is @code{eq}
afb61f4e22bb (Expansion): Cleanup.
Richard M. Stallman <rms@gnu.org>
parents: 58383
diff changeset
146 to @var{form}.
54812
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
147
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
148 Repeating the example used for @code{macroexpand} above with
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
149 @code{macroexpand-all}, we see that @code{macroexpand-all} @emph{does}
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
150 expand the embedded calls to @code{inc}:
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
151
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
152 @smallexample
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
153 (macroexpand-all '(inc2 r s))
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
154 @result{} (progn (setq r (1+ r)) (setq s (1+ s)))
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
155 @end smallexample
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
156
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
157 @end defun
47d3a293c8ae Revision: miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-205
Miles Bader <miles@gnu.org>
parents: 53591
diff changeset
158
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
159 @node Compiling Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
160 @section Macros and Byte Compilation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
161 @cindex byte-compiling macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
162
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
163 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
164 macro and then evaluate the expansion. Why not have the macro body
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
165 produce the desired results directly? The reason has to do with
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
166 compilation.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
167
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
168 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
169 compiler calls the macro definition just as the interpreter would, and
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
170 receives an expansion. But instead of evaluating this expansion, it
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
171 compiles the expansion as if it had appeared directly in the program.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
172 As a result, the compiled code produces the value and side effects
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
173 intended for the macro, but executes at full compiled speed. This would
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
174 not work if the macro body computed the value and side effects
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
175 itself---they would be computed at compile time, which is not useful.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
176
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
177 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
178 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
179 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
180 compiled contains a @code{defmacro} form, the macro is defined
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
181 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
182 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
183 is used, and before its first use.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
184
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
185 Byte-compiling a file executes any @code{require} calls at top-level
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
186 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
187 proper compilation. One way to ensure that necessary macro definitions
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
188 are available during compilation is to require the files that define
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
189 them (@pxref{Named Features}). To avoid loading the macro definition files
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
190 when someone @emph{runs} the compiled program, write
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
191 @code{eval-when-compile} around the @code{require} calls (@pxref{Eval
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
192 During Compile}).
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
193
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
194 @node Defining Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
195 @section Defining Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
196
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
197 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
198 be a function; expansion of the macro works by applying the function
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
199 (with @code{apply}) to the list of unevaluated argument-expressions
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
200 from the macro call.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
201
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
202 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
203 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
204 an anonymous macro to functionals such as @code{mapcar}. In practice,
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
205 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
206 special form @code{defmacro}.
6558
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 @defspec defmacro name argument-list body-forms@dots{}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
209 @code{defmacro} defines the symbol @var{name} as a macro that looks
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
210 like this:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
211
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
212 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
213 (macro lambda @var{argument-list} . @var{body-forms})
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
214 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
215
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
216 (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
217 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
218 value returned by evaluating the @code{defmacro} form is @var{name}, but
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
219 usually we ignore this value.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
220
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
221 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
222 function, and the keywords @code{&rest} and @code{&optional} may be used
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
223 (@pxref{Argument List}). Macros may have a documentation string, but
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
224 any @code{interactive} declaration is ignored since macros cannot be
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
225 called interactively.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
226 @end defspec
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
227
52145
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
228 The body of the macro definition can include a @code{declare} form,
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
229 which can specify how @key{TAB} should indent macro calls, and how to
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
230 step through them for Edebug.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
231
56215
c9aa4127a482 Reposition @anchor's.
Luc Teirlinck <teirllm@auburn.edu>
parents: 54812
diff changeset
232 @defmac declare @var{specs}@dots{}
53591
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
233 @anchor{Definition of declare}
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
234 A @code{declare} form is used in a macro definition to specify various
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
235 additional information about it. Two kinds of specification are
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
236 currently supported:
52145
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
237
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
238 @table @code
56510
8dd49b2f3a40 (Defining Macros): Declaration keyword is `debug' not `edebug'.
John Paul Wallington <jpw@pobox.com>
parents: 56215
diff changeset
239 @item (debug @var{edebug-form-spec})
52145
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
240 Specify how to step through macro calls for Edebug.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
241 @xref{Instrumenting Macro Calls}, for more details.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
242
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
243 @item (indent @var{indent-spec})
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
244 Specify how to indent calls to this macro. @xref{Indenting Macros},
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
245 for more details.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
246 @end table
53591
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
247
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
248 A @code{declare} form only has its special effect in the body of a
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
249 @code{defmacro} form if it immediately follows the documentation
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
250 string, if present, or the argument list otherwise. (Strictly
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
251 speaking, @emph{several} @code{declare} forms can follow the
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
252 documentation string or argument list, but since a @code{declare} form
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
253 can have several @var{specs}, they can always be combined into a
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
254 single form.) When used at other places in a @code{defmacro} form, or
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
255 outside a @code{defmacro} form, @code{declare} just returns @code{nil}
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
256 without evaluating any @var{specs}.
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
257 @end defmac
52145
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
258
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
259 No macro absolutely needs a @code{declare} form, because that form
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
260 has no effect on how the macro expands, on what the macro means in the
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
261 program. It only affects secondary features: indentation and Edebug.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
262
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
263 @node Backquote
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
264 @section Backquote
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
265 @cindex backquote (list substitution)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
266 @cindex ` (list substitution)
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
267 @findex `
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
268
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
269 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
270 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
271 syntax (usually called @dfn{backquote}).
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
272
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
273 Backquote allows you to quote a list, but selectively evaluate
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
274 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
275 special form @code{quote} (@pxref{Quoting}). For example, these
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
276 two forms yield identical results:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
277
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
278 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
279 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
280 `(a list of (+ 2 3) elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
281 @result{} (a list of (+ 2 3) elements)
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 '(a list of (+ 2 3) elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
285 @result{} (a list of (+ 2 3) elements)
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 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
288
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
289 @findex , @r{(with Backquote)}
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
290 The special marker @samp{,} inside of the argument to backquote
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
291 indicates a value that isn't constant. Backquote evaluates the
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
292 argument of @samp{,} and puts the value in the list structure:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
293
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
294 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
295 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
296 (list 'a 'list 'of (+ 2 3) 'elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
297 @result{} (a list of 5 elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
298 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
299 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
300 `(a list of ,(+ 2 3) elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
301 @result{} (a list of 5 elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
302 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
303 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
304
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
305 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
306 structure also. For example:
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
307
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
308 @example
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
309 @group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
310 (defmacro t-becomes-nil (variable)
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
311 `(if (eq ,variable t)
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
312 (setq ,variable nil)))
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
313 @end group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
314
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
315 @group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
316 (t-becomes-nil foo)
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
317 @equiv{} (if (eq foo t) (setq foo nil))
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
318 @end group
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
319 @end example
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
320
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
321 @findex ,@@ @r{(with Backquote)}
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
322 @cindex splicing (with backquote)
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
323 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
324 using the special marker @samp{,@@}. The elements of the spliced list
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
325 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
326 list. The equivalent code without using @samp{`} is often unreadable.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
327 Here are some examples:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
328
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
329 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
330 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
331 (setq some-list '(2 3))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
332 @result{} (2 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
333 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
334 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
335 (cons 1 (append some-list '(4) some-list))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
336 @result{} (1 2 3 4 2 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
337 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
338 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
339 `(1 ,@@some-list 4 ,@@some-list)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
340 @result{} (1 2 3 4 2 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
341 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
342
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
343 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
344 (setq list '(hack foo bar))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
345 @result{} (hack foo bar)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
346 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
347 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
348 (cons 'use
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
349 (cons 'the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
350 (cons 'words (append (cdr list) '(as elements)))))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
351 @result{} (use the words foo bar as elements)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
352 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
353 @group
12067
73dc8205d259 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 7734
diff changeset
354 `(use the words ,@@(cdr list) as elements)
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
355 @result{} (use the words foo bar as elements)
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 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
358
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
359 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
360 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
361 backquote construct. Likewise, each @samp{,} or @samp{,@@} substitution
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
362 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
363 @samp{,@@} and the following expression. The old syntax required
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
364 whitespace between the @samp{`}, @samp{,} or @samp{,@@} and the
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
365 following expression.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
366
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
367 This syntax is still accepted, for compatibility with old Emacs
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
368 versions, but we recommend not using it in new programs.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
369
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
370 @node Problems with Macros
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
371 @section Common Problems Using Macros
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 The basic facts of macro expansion have counterintuitive consequences.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
374 This section describes some important consequences that can lead to
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
375 trouble, and rules to follow to avoid trouble.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
376
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
377 @menu
38163
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
378 * Wrong Time:: Do the work in the expansion, not in the macro.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
379 * Argument Evaluation:: The expansion should evaluate each macro arg once.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
380 * Surprising Local Vars:: Local variable bindings in the expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
381 require special care.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
382 * Eval During Expansion:: Don't evaluate them; put them in the expansion.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
383 * Repeated Expansion:: Avoid depending on how many times expansion is done.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
384 @end menu
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
385
38163
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
386 @node Wrong Time
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
387 @subsection Wrong Time
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
388
53591
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
389 The most common problem in writing macros is doing some of the
38163
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
390 real work prematurely---while expanding the macro, rather than in the
53591
fe9a11a8e417 (Defining Macros): Update description of `declare', which now is a macro.
Luc Teirlinck <teirllm@auburn.edu>
parents: 52401
diff changeset
391 expansion itself. For instance, one real package had this macro
38163
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
392 definition:
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
393
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
394 @example
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
395 (defmacro my-set-buffer-multibyte (arg)
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
396 (if (fboundp 'set-buffer-multibyte)
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
397 (set-buffer-multibyte arg)))
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
398 @end example
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
399
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
400 With this erroneous macro definition, the program worked fine when
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
401 interpreted but failed when compiled. This macro definition called
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
402 @code{set-buffer-multibyte} during compilation, which was wrong, and
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
403 then did nothing when the compiled package was run. The definition
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
404 that the programmer really wanted was this:
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
405
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
406 @example
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
407 (defmacro my-set-buffer-multibyte (arg)
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
408 (if (fboundp 'set-buffer-multibyte)
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
409 `(set-buffer-multibyte ,arg)))
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
410 @end example
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
411
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
412 @noindent
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
413 This macro expands, if appropriate, into a call to
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
414 @code{set-buffer-multibyte} that will be executed when the compiled
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
415 program is actually run.
79e758f8571a (Wrong Time): New node.
Richard M. Stallman <rms@gnu.org>
parents: 27193
diff changeset
416
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
417 @node Argument Evaluation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
418 @subsection Evaluating Macro Arguments Repeatedly
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
419
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
420 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
421 the arguments will be evaluated when the expansion is executed. The
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
422 following macro (used to facilitate iteration) illustrates the problem.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
423 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
424 find in Pascal.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
425
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
426 @findex for
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
427 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
428 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
429 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
430 "Execute a simple \"for\" loop.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
431 For example, (for i from 1 to 10 do (print i))."
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
432 (list 'let (list (list var init))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
433 (cons 'while (cons (list '<= var final)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
434 (append body (list (list 'inc var)))))))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
435 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
436 @result{} for
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
437
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
438 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
439 (for i from 1 to 3 do
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
440 (setq square (* i i))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
441 (princ (format "\n%d %d" i square)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
442 @expansion{}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
443 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
444 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
445 (let ((i 1))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
446 (while (<= i 3)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
447 (setq square (* i i))
58383
47ee198dd02a (Argument Evaluation): Fix 1st `for' expansion example.
Richard M. Stallman <rms@gnu.org>
parents: 56510
diff changeset
448 (princ (format "\n%d %d" i square))
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
449 (inc i)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
450 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
451 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
452
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
453 @print{}1 1
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
454 @print{}2 4
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
455 @print{}3 9
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
456 @result{} nil
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
457 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
458 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
459
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
460 @noindent
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
461 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
462 ``syntactic sugar''; they are entirely ignored. The idea is that you
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
463 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
464 in those positions in the macro call.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
465
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
466 Here's an equivalent definition simplified through use of backquote:
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
467
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
468 @smallexample
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
469 @group
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
470 (defmacro for (var from init to final do &rest body)
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
471 "Execute a simple \"for\" loop.
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
472 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
473 `(let ((,var ,init))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
474 (while (<= ,var ,final)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
475 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
476 (inc ,var))))
7194
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
477 @end group
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
478 @end smallexample
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
479
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
480 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
481 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
482 @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
483 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
484 down the execution significantly. If @var{final} has side effects,
3112fb627aa0 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 6558
diff changeset
485 executing it more than once is probably incorrect.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
486
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
487 @cindex macro argument evaluation
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
488 A well-designed macro definition takes steps to avoid this problem by
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
489 producing an expansion that evaluates the argument expressions exactly
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
490 once unless repeated evaluation is part of the intended purpose of the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
491 macro. Here is a correct expansion for the @code{for} macro:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
492
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
493 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
494 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
495 (let ((i 1)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
496 (max 3))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
497 (while (<= i max)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
498 (setq square (* i i))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
499 (princ (format "%d %d" i square))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
500 (inc i)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
501 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
502 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
503
49600
23a1cea22d13 Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents: 38163
diff changeset
504 Here is a macro definition that creates this expansion:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
505
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
506 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
507 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
508 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
509 "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
510 `(let ((,var ,init)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
511 (max ,final))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
512 (while (<= ,var max)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
513 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
514 (inc ,var))))
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
515 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
516 @end smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
517
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
518 Unfortunately, this fix introduces another problem,
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
519 described in the following section.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
520
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
521 @node Surprising Local Vars
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
522 @subsection Local Variables in Macro Expansions
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
523
27193
89afca54a135 @ifinto -> @ifnottex.
Gerd Moellmann <gerd@gnu.org>
parents: 22138
diff changeset
524 @ifnottex
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
525 In the previous section, the definition of @code{for} was fixed as
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
526 follows to make the expansion evaluate the macro arguments the proper
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
527 number of times:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
528
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
529 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
530 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
531 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
532 "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
533 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
534 @group
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
535 `(let ((,var ,init)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
536 (max ,final))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
537 (while (<= ,var max)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
538 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
539 (inc ,var))))
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
540 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
541 @end smallexample
27193
89afca54a135 @ifinto -> @ifnottex.
Gerd Moellmann <gerd@gnu.org>
parents: 22138
diff changeset
542 @end ifnottex
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
543
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
544 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
545 local variable named @code{max} which the user does not expect. This
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
546 causes trouble in examples such as the following:
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
547
7734
2d4db32cccd5 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents: 7194
diff changeset
548 @smallexample
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
549 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
550 (let ((max 0))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
551 (for x from 0 to 10 do
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
552 (let ((this (frob x)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
553 (if (< max this)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
554 (setq max this)))))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
555 @end group
7734
2d4db32cccd5 entered into RCS
Richard M. Stallman <rms@gnu.org>
parents: 7194
diff changeset
556 @end smallexample
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
557
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
558 @noindent
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
559 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
560 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
561 the binding made by @code{for}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
562
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
563 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
564 @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
565 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
566 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
567 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
568 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
569 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
570 this way:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
571
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
572 @smallexample
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
573 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
574 (defmacro for (var from init to final do &rest body)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
575 "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
576 (let ((tempvar (make-symbol "max")))
12098
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
577 `(let ((,var ,init)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
578 (,tempvar ,final))
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
579 (while (<= ,var ,tempvar)
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
580 ,@@body
a6eb5f12b0f3 *** empty log message ***
Karl Heuer <kwzh@gnu.org>
parents: 12067
diff changeset
581 (inc ,var)))))
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
582 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
583 @end smallexample
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 @noindent
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
586 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
587 expansion instead of the usual interned symbol @code{max} that appears
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
588 in expressions ordinarily.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
589
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
590 @node Eval During Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
591 @subsection Evaluating Macro Arguments in Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
592
22138
d4ac295a98b3 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21682
diff changeset
593 Another problem can happen if the macro definition itself
21007
66d807bdc5b4 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 12098
diff changeset
594 evaluates any of the macro argument expressions, such as by calling
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
595 @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
596 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
597 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
598 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
599 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
600 it. Here is an example:
6558
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 @example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
603 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
604 (defmacro foo (a)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
605 (list 'setq (eval a) t))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
606 @result{} foo
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
607 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
608 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
609 (setq x 'b)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
610 (foo x) @expansion{} (setq b t)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
611 @result{} t ; @r{and @code{b} has been set.}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
612 ;; @r{but}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
613 (setq a 'c)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
614 (foo a) @expansion{} (setq a t)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
615 @result{} t ; @r{but this set @code{a}, not @code{c}.}
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
616
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
617 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
618 @end example
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
619
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
620 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
621 @code{x}, because @code{a} conflicts with the macro argument variable
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
622 @code{a}.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
623
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
624 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
625 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
626 byte-compiler runs macro definitions while compiling the program, when
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
627 the program's own computations (which you might have wished to access
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
628 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
629 exist.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
630
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
631 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
632 while computing the macro expansion}. Instead, substitute the
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
633 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
634 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
635 this chapter work.
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
636
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
637 @node Repeated Expansion
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
638 @subsection How Many Times is the Macro Expanded?
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
639
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
640 Occasionally problems result from the fact that a macro call is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
641 expanded each time it is evaluated in an interpreted function, but is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
642 expanded only once (during compilation) for a compiled function. If the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
643 macro definition has side effects, they will work differently depending
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
644 on how many times the macro is expanded.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
645
21682
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
646 Therefore, you should avoid side effects in computation of the
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
647 macro expansion, unless you really know what you are doing.
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
648
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
649 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
650 objects. Almost all macro expansions include constructed lists; that is
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
651 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
652 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
653 quoted constant in the macro expansion.
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
654
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
655 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
656 constructed just once, during compilation. But in interpreted
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
657 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
658 means a new object is constructed each time.
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
659
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
660 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
661 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
662 definition. Thus, to avoid trouble, @strong{avoid side effects on
90da2489c498 *** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents: 21007
diff changeset
663 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
664 such side effects can get you into trouble:
6558
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
665
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
666 @lisp
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
667 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
668 (defmacro empty-object ()
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
669 (list 'quote (cons nil nil)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
670 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
671
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
672 @group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
673 (defun initialize (condition)
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
674 (let ((object (empty-object)))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
675 (if condition
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
676 (setcar object condition))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
677 object))
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
678 @end group
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
679 @end lisp
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
680
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
681 @noindent
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
682 If @code{initialize} is interpreted, a new list @code{(nil)} is
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
683 constructed each time @code{initialize} is called. Thus, no side effect
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
684 survives between calls. If @code{initialize} is compiled, then the
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
685 macro @code{empty-object} is expanded during compilation, producing a
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
686 single ``constant'' @code{(nil)} that is reused and altered each time
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
687 @code{initialize} is called.
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
688
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
689 One way to avoid pathological cases like this is to think of
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
690 @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
691 allocation construct. You wouldn't use @code{setcar} on a constant such
fa8ff07eaafc Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
692 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
693 either.
52145
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
694
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
695 @node Indenting Macros
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
696 @section Indenting Macros
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
697
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
698 You can use the @code{declare} form in the macro definition to
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
699 specify how to @key{TAB} should indent indent calls to the macro. You
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
700 write it like this:
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
701
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
702 @example
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
703 (declare (indent @var{indent-spec}))
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
704 @end example
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
705
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
706 @noindent
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
707 Here are the possibilities for @var{indent-spec}:
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
708
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
709 @table @asis
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
710 @item @code{nil}
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
711 This is the same as no property---use the standard indentation pattern.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
712 @item @code{defun}
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
713 Handle this function like a @samp{def} construct: treat the second
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
714 line as the start of a @dfn{body}.
60267
afb61f4e22bb (Expansion): Cleanup.
Richard M. Stallman <rms@gnu.org>
parents: 58383
diff changeset
715 @item an integer, @var{number}
52145
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
716 The first @var{number} arguments of the function are
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
717 @dfn{distinguished} arguments; the rest are considered the body
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
718 of the expression. A line in the expression is indented according to
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
719 whether the first argument on it is distinguished or not. If the
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
720 argument is part of the body, the line is indented @code{lisp-body-indent}
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
721 more columns than the open-parenthesis starting the containing
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
722 expression. If the argument is distinguished and is either the first
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
723 or second argument, it is indented @emph{twice} that many extra columns.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
724 If the argument is distinguished and not the first or second argument,
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
725 the line uses the standard pattern.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
726 @item a symbol, @var{symbol}
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
727 @var{symbol} should be a function name; that function is called to
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
728 calculate the indentation of a line within this expression. The
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
729 function receives two arguments:
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
730 @table @asis
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
731 @item @var{state}
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
732 The value returned by @code{parse-partial-sexp} (a Lisp primitive for
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
733 indentation and nesting computation) when it parses up to the
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
734 beginning of this line.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
735 @item @var{pos}
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
736 The position at which the line being indented begins.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
737 @end table
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
738 @noindent
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
739 It should return either a number, which is the number of columns of
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
740 indentation for that line, or a list whose car is such a number. The
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
741 difference between returning a number and returning a list is that a
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
742 number says that all following lines at the same nesting level should
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
743 be indented just like this one; a list says that following lines might
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
744 call for different indentations. This makes a difference when the
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
745 indentation is being computed by @kbd{C-M-q}; if the value is a
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
746 number, @kbd{C-M-q} need not recalculate indentation for the following
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
747 lines until the end of the list.
58a56145385a (Defining Macros): Give definition of `declare'
Richard M. Stallman <rms@gnu.org>
parents: 49600
diff changeset
748 @end table
52401
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 52145
diff changeset
749
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 52145
diff changeset
750 @ignore
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 52145
diff changeset
751 arch-tag: d4cce66d-1047-45c3-bfde-db6719d6e82b
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 52145
diff changeset
752 @end ignore