在clojure宏中使用序列

时间:2014-11-12 20:50:53

标签: macros clojure

我正在读取yaml文件中的数据,这会产生如下数据:

{:test1 (1 2 3)}

我可以查找密钥:test1并获取包含clojure.lang.LazySeq元素的1 2 3。但是当我想在宏中使用这些数据时,它会扩展为函数调用而不是引用列表。

例如:

(defmacro mmerge
  [map1 map2]
  `(assoc ~(merge map1 map2) :merged true))

(mmerge {:test1 (1 2 3)} {:test2 (4 5 6)})

这扩展到:

(clojure.core/assoc {:test2 (4 5 6), :test1 (1 2 3)} :merged true)

是否有可能以某种方式使其发挥作用?

提前致谢

1 个答案:

答案 0 :(得分:5)

如果您编写地图参数,则可以使用函数实现相同的功能。值作为引用列表:

(defn mmerge*
  [map1 map2]
  (assoc (merge map1 map2) :merged true))

(mmerge* {:test1 '(1 2 3)} {:test2 '(4 5 6)})
;= {:merged true, :test2 (4 5 6), :test1 (1 2 3)}

如果您仍然需要宏,则需要引用宏返回的表单中的merge操作的结果(或@fl00r mentioned如果您引用列表,则绝对正确: p):

(defmacro mmerge
  [map1 map2]
  `(assoc '~(merge map1 map2) :merged true))

导致以下宏展开:

(clojure.core/assoc '{:test2 (4 5 6), :test1 (1 2 3)} :merged true)