Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>At macro expansion time, <code>cdr</code> is not evaluated. So <code>(count-true t t nil)</code> hits an infinite expansion like this:</p> <pre><code>(count-true t t nil) =&gt; (1+ (count-true (cdr (t t t nil)))) =&gt; (1+ (1+ (count-true (cdr (cdr (t t t nil)))))) =&gt; (1+ (1+ (1+ (count-true (cdr (cdr (cdr (t t t nil)))))))) =&gt; ... </code></pre> <p>Well, actually this happens for both recursive branches at once. So it blows up even faster than the example.</p> <p>A better idea? </p> <ol> <li><p>Trying writing the same thing as a function first. Figure out where you have to put the lambdas to delay evaluation. Then abstract the function into a macro so you can leave out the lambdas.</p> <p>The point of writing a function first, by the way, is that sometimes you'll find that a function is good enough. Writing a macro where a function would do is a mistake.</p></li> <li><p>Generally, when you write macros in Common Lisp, start with a <code>loop</code> rather than recursion. Recursive macros are tricky (and usually wrong :). </p></li> </ol> <p>Edit:</p> <p>Here is a more correct (but much longer) example:</p> <pre><code>(count-true t nil) =&gt; (cond ((null '(t nil)) 0) ((car '(t nil)) (1+ (count-true (cdr '(t nil))))) (T (count-true (cdr '(t nil))))) =&gt; (cond ((null '(t nil)) 0) ((car '(t nil)) (1+ (1+ (count-true (cdr (cdr '(t nil))))))) (T (count-true (cdr (cdr '(t nil)))))) =&gt; (cond ((null '(t nil)) 0) ((car '(t nil)) (1+ (1+ (1+ (count-true (cdr (cdr (cdr '(t nil))))))))) (T (count-true (cdr (cdr (cdr '(t nil))))))) =&gt; (cond ((null '(t nil)) 0) ((car '(t nil)) (1+ (1+ (1+ (1+ (count-true (cdr (cdr (cdr (cdr '(t nil))))))))))) (T (count-true (cdr (cdr (cdr (cdr '(t nil)))))))) </code></pre>
 

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