Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Note that the macros <code>ZERO-P</code> and <code>REF-OF</code> are expanded when you evaluate, compile or load the <code>DEFUN</code> for <code>NORMALIZE</code>. Their arguments are the <em>symbols</em> <code>INDEXES</code> and <code>INDEX</code>, and both of those are not <code>NIL</code>, so the <code>IF</code>s in the <code>REF-OF</code> forms will all take the first branch and expand into <code>AREF</code> forms where <code>INDICES</code> and <code>INDEX</code> can't be bound to <code>NIL</code>. In short, you've gotten evaluation time and macroexpansion time confused, which is an easy thing to do when you are just starting with macros.</p> <p>However, when you call the function <code>NORMALIZE</code> with only one argument, the variables <code>INDICES</code> and <code>INDEX</code> are bound to a default value of <code>NIL</code>, so <code>AREF</code> complains that it's getting invalid arguments.</p> <p>The best solution I can offer you is to just make <code>ZERO-P</code> and <code>REF-OF</code> into functions instead of macros. They'll work just fine as functions, and you shouldn't make something a macro unless you're sure it needs to be a macro. If you really do want to keep them as macros, give default values to <code>INDICES</code> and <code>INDEX</code> that make sense and get rid of the optional values in <code>REF-OF</code> and <code>ZERO-P</code>---I'm pretty sure having <code>INDEX</code> default to 0 and <code>INDICES</code> default to <code>#(0 1 2)</code> will work.</p> <p><strong>EDIT to add:</strong> Wanting to avoid function call overhead is almost certainly not a good reason to use macros in Lisp. In the first place, you shouldn't even worry about function call overhead until after you've done some profiling and testing. In the second place, if you do have a problem with function call overhead, you should <code>DECLARE</code> the functions in question <code>INLINE</code> instead of using macros to do the inlining. </p> <p><strong>EDITed</strong> again to add: If your functions are being expanded inline, your compiler should be able to figure out that it can replace</p> <pre><code>(cond ((eq :x :x) 'foo) ((eq :x :y) 'bar) ((eq :x :z) 'quux) (t (error "~A is not one of :X, :Y or :Z" :x)) </code></pre> <p>with</p> <pre><code>'foo </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