Clojure宏总是漏水吗?

时间:2012-05-25 16:01:27

标签: macros clojure

如果您阅读问题macro -> with anonymous functions,您会发现->宏无法与匿名函数配合使用。要正确使用宏,您需要了解实现。从这个意义上说,宏是“漏洞” - API没有完全隐藏实现。

(足够复杂的)Clojure宏是否会泄漏?

[为了比较:C预处理器出现了类似的问题,当粗略地处理宏参数时,可以看到奇怪的副作用。在这种情况下,可以通过将宏参数括在括号中(宏内部)来解决问题。这并没有解决使用具有可变状态的C宏的问题(即每次使用参数都会改变状态),但也许我们可以忽略函数式语言的问题,或者使用let来避免多次评估。

3 个答案:

答案 0 :(得分:5)

您不需要了解实现 - 文档字符串很清楚它是如何工作的。读者宏也有很好的文档记录 - #(...)将扩展为(fn [...] ...)。鉴于这些知识和所提供的信息,很明显,线程匿名函数不起作用。根本不需要理解实现。

答案 1 :(得分:5)

Clojure宏在这个意义上没有泄漏。原因 - >使用#()函数意外地工作的是#()是一个读取器宏,读取器宏在“常规”宏之前展开。所以你需要知道:

  1. 宏应该做什么。 - >实际上是一个非常基本的宏,因为文档几乎可以解释它是如何扩展的。
  2. 如果要将其传递给“普通”宏,读者宏的扩展范围是什么。

答案 2 :(得分:1)

另请注意,如果您将匿名函数包装在parens中,它将起作用:

=> (-> {:a 1 :b 2} :a (#(* 2 %)))
2

写出匿名函数然后宏扩展它很有启发性:

=> (-> {:a 1 :b 2} :a ((fn [el] (* 2 el))))
2

=> (macroexpand-all '(-> {:a 1 :b 2} :a ((fn [el] (* 2 el)))))
((fn* ([el] (* 2 el))) (:a {:a 1, :b 2}))