title: Evaluating macro arguments in clojure
body: <p>I'm trying to translate the following macro from land of lisp into clojure:</p>
  
  <pre><code>(defmacro tag (name atts &amp;body body)
    `(progn (print-tag ',name
                       (list ,@(mapcar (lambda (x)
                                         `(cons ',(car x) ,(cdr x)))
                                       (pairs atts)))
                       nil)
            ,@body
            (print-tag ',name nil t)))
  </code></pre>
  
  <p>But I keep getting stuck with atts requiring 1 more level of evaluation. E.g. the following needs to evaluate t#:</p>
  
  <pre><code>(defmacro tag [tname atts &amp; body]
    `(do (print-tag '~tname '[~@(map (fn [[h# t#]] [h# t#]) (pair atts))] nil)
       ~@body
       (print-tag '~tname nil true)))
  </code></pre>
  
  <p>As it produces stuff like:</p>
  
  <pre><code>(tag mytag [color 'blue size 'big])
  &lt;mytag color="(quote blue)" size="(quote big)"&gt;&lt;\mytag&gt;
  </code></pre>
  
  <p>Where I want the attribute to evaluated. If I use "(eval t#)" in the above I fall foul of problems like this:</p>
  
  <pre><code>(defn mytag [col] (tag mytag [colour col]))
  java.lang.UnsupportedOperationException: Can't eval locals (NO_SOURCE_FILE:1)
  </code></pre>
  
  <p>Any suggestions?</p>
  
  <p>Why does it seem like one less level of evaluation happens in Clojure?</p>
  
  <p>Definitions of supporting functions:</p>
  
  <pre><code>;note doesn't handle nils because I'm dumb
  (defn pair [init-lst]
        (loop [lst init-lst item nil pairs []]
      (if (empty? lst)
        pairs
        (if item
          (recur (rest lst) nil (conj pairs [item (first lst)]))
          (recur (rest lst) (first lst) pairs)))))
  
  (defn print-tag [name alst closing]
        (print "&lt;")
        (when closing
      (print "\\"))
        (print name)
        (doall
        (map (fn [[h t]]
             (printf " %s=\"%s\"" h t))
         alst))
        (print "&gt;"))
  </code></pre>
  
  <p>(For some reason I didn't do the pair function in the same way as the book which means it doesn't handle nils correctly)</p>