I'm trying to translate the following macro from land of lisp into clojure:
(defmacro tag (name atts &body body) `(progn (print-tag ',name (list ,@(mapcar (lambda (x) `(cons ',(car x) ,(cdr x))) (pairs atts))) nil) ,@body (print-tag ',name nil t))) But I keep getting stuck with atts requiring 1 more level of evaluation. E.g. the following needs to evaluate t#:
(defmacro tag [tname atts & body] `(do (print-tag '~tname '[~@(map (fn [[h# t#]] [h# t#]) (pair atts))] nil) ~@body (print-tag '~tname nil true))) As it produces stuff like:
(tag mytag [color 'blue size 'big]) <mytag color="(quote blue)" size="(quote big)"><\mytag> Where I want the attribute to evaluated. If I use "(eval t#)" in the above I fall foul of problems like this:
(defn mytag [col] (tag mytag [colour col])) java.lang.UnsupportedOperationException: Can't eval locals (NO_SOURCE_FILE:1) Any suggestions?
Why does it seem like one less level of evaluation happens in Clojure?
Definitions of supporting functions:
;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 "<") (when closing (print "\\")) (print name) (doall (map (fn [[h t]] (printf " %s=\"%s\"" h t)) alst)) (print ">")) (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)
pairandprint-tagdefined?pairis the same of(partition 2 seq), right?