使用可变参数宏参数作为列表

时间:2016-09-27 00:22:17

标签: clojure macros variadic-macros

我正在尝试编写一个比较多个表达式的运行时间的宏,然后碰到了一堵墙。我的问题可以压缩为以下代码:

(defmacro test-m [& exprs]
  `(map #(.toString %) ~exprs))

如果我将其称为(test-m 1 2 3),我希望这会产生以下代码:

(map #(.toString %) [1 2 3])

哪个完全有效。不幸的是,这实际上会导致错误:

  

ClassCastException java.lang.Long无法强制转换为clojure.lang.IFn helpers.general-helpers / eval663(NO_SOURCE_FILE:76)

我可以看到可能发生这种情况的唯一方法是& exprs会导致(1 2 3),然后会尝试将1作为函数调用,这显然是错误的。

如何映射宏中的可变参数列表?

1 个答案:

答案 0 :(得分:3)

我在写这个问题时想通了,所以我想我会发一个答案,以防将来其他人被困在这里。

参数列表需要先强制进入列表代理,否则它将被评估为表单。这可以这样做:

(defmacro test-m [& exprs]
  `(map #(.toString %) (list ~@exprs))

注意exprs通过@展开,并提供给list。 (感谢@amalloy的纠正)。

显然是回顾,但它让我有一段时间。希望这有助于某人。