Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It will help to look at your examples through the lens of <code>macroexpand</code>, an essential tool for debugging macros.</p> <p>Example 1:</p> <pre><code>(defmacro triple-do [form] (list 'do form form form)) user=&gt; (triple-do (println "test")) </code></pre> <p>Remember macros are supposed to return a list that will be executed at runtime. Let's see what this macro returns: </p> <pre><code>(macroexpand '(triple-do (println "test"))) ;; (do (println "test") (println "test") (println "test")) </code></pre> <p>So it doesn't execute the code but rather returns a list that represents the code that will be executed once the macro is expanded. This is similar to trying the following snippet at the REPL:</p> <pre><code>(+ 1 2 3) ;; 6 (list '+ 1 2 3) ;; (+ 1 2 3) </code></pre> <p>With this in mind, let's turn to Example 2:</p> <pre><code>(defmacro triple-do [form] (do form form form)) user=&gt; (triple-do (println "test")) </code></pre> <p>Notice how the macro now doesn't return a list. It simply executes the <code>do</code> form which returns the last statement which is the form passed in. This can be easily seen by expanding the macro:</p> <pre><code>(macroexpand '(triple-do (println "test"))) ;; (println "test") </code></pre> <p>That's why you end up with a single print statement.</p> <p>This should give you a clue about Example 3:</p> <pre><code>(defmacro test-macro [form] (do form (println "hard code test"))) user=&gt; (test-macro (println "hello")) </code></pre> <p>It's a bit trickier but let's expand it nevertheless:</p> <pre><code>(macroexpand '(test-macro (println "hello"))) ;; hard code test &lt;= this gets print before the macro fully expands ;; nil &lt;= the expansion yields nil </code></pre> <p>Again, since you're not returning a list but rather simply executing a <code>do</code> form, it simply runs the <code>println</code> call from within the macro and since <code>println</code> returns nil, that becomes the result of the expansion.</p> <p>To illustrate my point, this is how you'd have to rewrite your macro in order to achieve the desired behaviour:</p> <pre><code>(defmacro test-macro [form] (list 'do form (println "hard code test"))) (test-macro (println "hello")) ;; hard code test ;; hello </code></pre> <p>I hope this clears things for you.</p> <p>Just remember this: <em>macros are supposed to return lists that represent the code you'd like to be executed at runtime</em>.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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