Оценка аргументов макроса в clojure

Я пытаюсь перевести следующий макрос из land of lisp в 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)))

) Но я все время застреваю с аттсами, требующими еще 1 уровень оценки. Например, следующие потребности для оценки 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)))

Поскольку он производит такие вещи, как:

(tag mytag [color 'blue size 'big])
<mytag color="(quote blue)" size="(quote big)"><\mytag>

Где я хочу, чтобы атрибут оценивался. Если я использую "(eval t #)" в приведенном выше примере, я сталкиваюсь с такими проблемами, как это:

(defn mytag [col] (tag mytag [colour col]))
java.lang.UnsupportedOperationException: Can't eval locals (NO_SOURCE_FILE:1)

Любой предложения?

Почему кажется, что в Clojure на один уровень оценки меньше?

Определения вспомогательных функций:

;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 ">"))

(По какой-то причине я не выполнял парную функцию так же, как в книге, которая означает, что он неправильно обрабатывает nils)

5
задан Joshua Taylor 17 February 2015 в 17:52
поделиться