Clojure:定义使用Carret(^ {})元数据语法的宏

时间:2014-06-03 12:39:31

标签: macros clojure

我正在尝试定义这样的宏:

(defmacro foo-macro
  "[name] is the name of the function to define
   [meta-data] is the map that defines the meta-data of the function"
  [name meta-data]
  (let [vals (gensym "label-")]
    `(def ~name
       ^@~meta-data
       (fn [~vals] (eval nil)))))

但是,我收到了这个编译错误:

  

未处理的java.lang.IllegalArgumentException元数据必须是   符号,关键字,字符串或地图

我认为这很正常。但是,我不确定如何使这样的宏工作,或者甚至可能。

注意:我不想使用with-meta 。阅读其他问题解决方案的修订版,以了解原因:Clojure: issues getting the symbol of a function in a looping context

我使用with-meta的唯一原因是,如果您有办法让它返回非AFunc标识符。

1 个答案:

答案 0 :(得分:0)

抱歉,我确实想要使用with-meta,您只想在宏中使用它,而不是在您返回的代码中使用它。

通过阅读^{:foo :bar} (fn [])获得的表单与评估(with-meta `(fn []))时获得的表单大致相同,因此您希望在宏中执行以下操作:评估{{ 1}}生成代码时调用。

with-meta

调用(defmacro foo-macro "[name] is the name of the function to define [meta-data] is the map that defines the meta-data of the function" [name meta-data] (let [vals (gensym "label-")] `(def ~name ~(with-meta `(fn [~vals] (eval nil)) meta-data)))) 可以为您提供所需内容:(foo-macro fn-name {:foo "bar"})返回(meta fn-name)的函数,在打印时会显示{:foo "bar"}之类的内容。