使用包含类型提示的宏生成Clojure代码

时间:2012-08-12 03:55:15

标签: clojure macros metaprogramming code-generation type-hinting

我正在尝试使用类型提示生成一些Clojure代码,但是每当我构建一些代码时,类型提示似乎都会消失(在编译代码时它们也不起作用)

e.g。

`(let [^BufferedImage b (create-buffered-image)] 
   (.getRGB b 0 0))

=> (clojure.core/let [user/b (user/create-buffered-image)] (.getRGB user/b 0 0))

我不确定为什么类型提示正在消失,但我认为它与读者处理metatdata的方式有关。

在生成的代码中创建正确的类型提示的正确方法是什么?

1 个答案:

答案 0 :(得分:32)

这个问题有两个答案。要回答你的具体问题:在刚发布的实际代码中,没有错:它工作得很好。 (set! *print-meta* true)然后重试,您将看到元数据注释。它通常不会打印。

但是,一般来说,这不是从宏观做事的正确方法,不久之后你就会遇到麻烦。请记住,您不希望宏评估表单上的元数据,您希望宏发出的表单上的元数据。因此,更准确的解决方案是在要附加元数据的符号或表单上使用with-meta - 或者,如果它们是用户提供的表单,则通常应使用vary-meta以便您不要丢弃他们明确添加的元数据。例如,

(defmacro with-image [name & body]
  (let [tagged-name (vary-meta name assoc :tag `BufferedImage)
    `(let [~tagged-name (create-buffered-image)
       ~@body)))

(with-image i (.getRGB i 0 0))