Clojure中过时的符号

时间:2012-12-25 18:08:50

标签: clojure

有没有办法在Clojure中将符号标记为过时?

我可以使用Lein这样的东西,效果很好。

https://github.com/technomancy/leiningen/blob/1.x/src/leiningen/core.clj#L13

但它只在调用函数时发出警告。我真的很喜欢编译器在编译代码时选择它,而不是在调用它时。

当然,我可以定义符号,然后编译器将选择该符号 起来,但这让我无法提供任何信息,例如为什么或什么时候 该符号已被弃用。

所有这些都适用于DSL,其中条款的弃用和过时将以合理的速率发生。

2 个答案:

答案 0 :(得分:1)

关于使用宏的评论中已有一些内容,但正如有人指出的那样,这可以排除将该函数用作HOF。你可以解决这个问题,虽然可能治愈并不比疾病更糟糕。例如,假设您的功能是

(defn foo* [x y] (+ x y))

然后而不是写

(defmacro foo [x y] (warn) `(foo* x y))
(foo 1 2)
(map foo [5 6] [7 8])

你可以让macroexpansion 返回一个函数,当然可以像任何其他函数一样使用它:

(defmacro foo [] (warn) `foo*)
((foo) 1 2)
(map (foo) [5 6] [7 8])

可能不值得尴尬,但确实提供了一种方法来抱怨每当使用弃用的功能同时仍然保持使用HOF的可能性。

答案 1 :(得分:0)

这实际上取决于您的DSL设计方式。如果您可以设计DSL以使每个表单必须包含在go或类似的调用中,那么您可以编写此go宏来执行以下操作:

  1. macroexpand-all(从clojure.walk)到传递的表格
  2. 在上面返回的表单上使用postwalk(来自clojure.walk),并通过查看某些全球已弃用符号列表来检查是否已弃用所遇到的任何符号。您可能需要对符号执行resolve以获取符号的名称空间限定名称。
  3. 如果找到任何已弃用的符号,则为打印消息。
  4. 按原样返回输入表格。
  5. 然后,此go宏可用于DSL的其他预处理,因为这是您执行DSL的入口点。

    注意:您可能需要提供解决方案,其中用户使用其中一个不推荐使用的符号使用相同的名称,但根据您的DSL设计,可能不需要这样做。