Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This form:</p> <pre><code>(defmacro test (lst) (dolist (x lst) (print x))) </code></pre> <p>defines a <em>macro</em>, which is a "code transformation function" which gets applied to a form using this macro at macro expansion time. So, after you have defined this macro, when you evaluate this expression:</p> <pre><code>(test (1 2 3)) </code></pre> <p>it first gets read to this list:</p> <pre><code>(test (1 2 3)) </code></pre> <p>Then, since Lisp reads <code>test</code> at the operator position, it gets macro-expanded by passing the argument, which is the literal list <code>(1 2 3)</code>, to the macro expansion function defined above. This means that the following gets evaluated at macro-expansion time:</p> <pre><code>(dolist (x '(1 2 3)) (print x)) </code></pre> <p>So, at macro-expansion time, the three values get printed. Finally, the return value of that form is returned as the code to be compiled and executed. <code>Dolist</code> returns <code>nil</code> here, so this is the code returned:</p> <pre><code>nil </code></pre> <p><code>Nil</code> evaluates to <code>nil</code>, which is returned.</p> <p>Generally, such a macro is not very useful. See "Practical Common Lisp" by Peter Seibel or "On Lisp" by Paul Graham for an introduction to useful macros.</p> <hr> <p><em>Update:</em> Perhaps it is useful to recapitulate the order of reading, expanding, and evaluating Lisp code.</p> <p>First, the REPL takes in a stream of characters: <code>(</code> <code>t</code> <code>e</code> <code>s</code> <code>t</code> <code> </code> <code>(</code> <code>1</code> <code></code> <code>2</code> <code></code> <code>3</code> <code>)</code> <code>)</code>, which it assembles into tokens: <code>(</code> <code>test</code> <code>(</code> <code>1</code> <code>2</code> <code>3</code> <code>)</code> <code>)</code>.</p> <p>Then, this is translated into a tree of symbols: (<code>test</code> (<code>1</code> <code>2</code> <code>3</code>)). There may be so-called <em>reader macros</em> involved in this step. For example, <code>'x</code> is translated to (<code>quote</code> <code>x</code>).</p> <p>Then, from the outside in, each symbol in operator position (i.e., the first position in a form) is examined. If it names a macro, then the corresponding macro function is invoked with the <em>code</em> (i.e., the subtrees of symbols) that is the rest of the form as arguments. The macro function is supposed to return a new form, i.e. <em>code</em>, which replaces the macro form. In your case, the macro <code>test</code> gets the code (<code>1</code> <code>2</code> <code>3</code>) as argument, prints each of the symbols contained within (note that this is even before compile time), and returns <code>nil</code>, throwing its arguments away (the compiler never even sees your little list). The returned code is then examined again for possible macroexpansions.</p> <p>Finally, the expanded code that does not contain any macro invocations anymore is <em>evaluated</em>, i.e. compiled and executed. <code>Nil</code> happens to be a self-evaluating symbol; it evaluates to <code>nil</code>.</p> <p>This is just a rough sketch, but I hope that it clears some things up.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload