diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/elisp/expansion.html | |
new repository
Diffstat (limited to 'devdocs/elisp/expansion.html')
| -rw-r--r-- | devdocs/elisp/expansion.html | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/devdocs/elisp/expansion.html b/devdocs/elisp/expansion.html new file mode 100644 index 00000000..b3ad6cb3 --- /dev/null +++ b/devdocs/elisp/expansion.html @@ -0,0 +1,32 @@ + <h3 class="section">Expansion of a Macro Call</h3> <p>A macro call looks just like a function call in that it is a list which starts with the name of the macro. The rest of the elements of the list are the arguments of the macro. </p> <p>Evaluation of the macro call begins like evaluation of a function call except for one crucial difference: the macro arguments are the actual expressions appearing in the macro call. They are not evaluated before they are given to the macro definition. By contrast, the arguments of a function are results of evaluating the elements of the function call list. </p> <p>Having obtained the arguments, Lisp invokes the macro definition just as a function is invoked. The argument variables of the macro are bound to the argument values from the macro call, or to a list of them in the case of a <code>&rest</code> argument. And the macro body executes and returns its value just as a function body does. </p> <p>The second crucial difference between macros and functions is that the value returned by the macro body is an alternate Lisp expression, also known as the <em>expansion</em> of the macro. The Lisp interpreter proceeds to evaluate the expansion as soon as it comes back from the macro. </p> <p>Since the expansion is evaluated in the normal manner, it may contain calls to other macros. It may even be a call to the same macro, though this is unusual. </p> <p>Note that Emacs tries to expand macros when loading an uncompiled Lisp file. This is not always possible, but if it is, it speeds up subsequent execution. See <a href="how-programs-do-loading">How Programs Do Loading</a>. </p> <p>You can see the expansion of a given macro call by calling <code>macroexpand</code>. </p> <dl> <dt id="macroexpand">Function: <strong>macroexpand</strong> <em>form &optional environment</em> +</dt> <dd> + <p>This function expands <var>form</var>, if it is a macro call. If the result is another macro call, it is expanded in turn, until something which is not a macro call results. That is the value returned by <code>macroexpand</code>. If <var>form</var> is not a macro call to begin with, it is returned as given. </p> <p>Note that <code>macroexpand</code> does not look at the subexpressions of <var>form</var> (although some macro definitions may do so). Even if they are macro calls themselves, <code>macroexpand</code> does not expand them. </p> <p>The function <code>macroexpand</code> does not expand calls to inline functions. Normally there is no need for that, since a call to an inline function is no harder to understand than a call to an ordinary function. </p> <p>If <var>environment</var> is provided, it specifies an alist of macro definitions that shadow the currently defined macros. Byte compilation uses this feature. </p> <div class="example"> <pre class="example">(defmacro inc (var) + (list 'setq var (list '1+ var))) +</pre> + +<pre class="example">(macroexpand '(inc r)) + ⇒ (setq r (1+ r)) +</pre> + +<pre class="example">(defmacro inc2 (var1 var2) + (list 'progn (list 'inc var1) (list 'inc var2))) +</pre> + +<pre class="example">(macroexpand '(inc2 r s)) + ⇒ (progn (inc r) (inc s)) ; <span class="roman"><code>inc</code> not expanded here.</span> +</pre> +</div> </dd> +</dl> <dl> <dt id="macroexpand-all">Function: <strong>macroexpand-all</strong> <em>form &optional environment</em> +</dt> <dd> +<p><code>macroexpand-all</code> expands macros like <code>macroexpand</code>, but will look for and expand all macros in <var>form</var>, not just at the top-level. If no macros are expanded, the return value is <code>eq</code> to <var>form</var>. </p> <p>Repeating the example used for <code>macroexpand</code> above with <code>macroexpand-all</code>, we see that <code>macroexpand-all</code> <em>does</em> expand the embedded calls to <code>inc</code>: </p> <div class="example"> <pre class="example">(macroexpand-all '(inc2 r s)) + ⇒ (progn (setq r (1+ r)) (setq s (1+ s))) +</pre> +</div> </dd> +</dl> <dl> <dt id="macroexpand-1">Function: <strong>macroexpand-1</strong> <em>form &optional environment</em> +</dt> <dd><p>This function expands macros like <code>macroexpand</code>, but it only performs one step of the expansion: if the result is another macro call, <code>macroexpand-1</code> will not expand it. </p></dd> +</dl><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Expansion.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Expansion.html</a> + </p> +</div> |
