(Обновлено с отладочной версией макроса из текста вопроса.)
Это должно работать как указано:
(defmacro defmodel [name & field-spec]
`(do (defstruct ~name ~@(take-nth 2 field-spec))
(def ~(symbol (str "*" name "-meta*"))
(reduce #(assoc %1 (first %2) (last %2))
{}
(partition 2 '~field-spec)))))
Ответ на главнуювопрос в том, чтобы использовать ~(symbol (str "*" name "-meta*"))
вместо *~name-meta*
.~
снимает в кавычки следующее выражение в синтаксической кавычке, вставляя его возвращаемое значение в соответствующее место данной структуры списка.
Необходимы были некоторые другие модификации - в частности, defstruct
требует, чтобыключи должны быть переданы ему как отдельные аргументы, а не как один seq (или имя переменной, содержащей такой seq), reduce
для работы здесь требуется явное начальное значение и т. д.
Кстати, если только вынужно придерживаться Clojure 1.1, вы можете использовать 1.2 * defrecord
вместо defstruct
- на самом деле, последний устарел в 1.2.