2012-05-25 26 views
4

如果您阅读macro -> with anonymous functions的问题,您会发现->宏与匿名函数不兼容。要正确使用宏,您需要了解实现。从这个意义上说,这个宏是“漏洞”的 - 实现并没有被API完全隐藏。Clojure宏是否总是泄漏?

Clojure宏是否总是出现漏洞?

[用于比较:C预处理器出现类似的问题,当宏观参数被不小心处理时可以看到奇怪的副作用。在这种情况下,问题可以通过将宏参数放在括号内(宏内部)来解决。这并不能解决使用具有可变状态的C宏的问题(即每次使用参数变异的状态),但也许我们可以忽略功能语言的问题,或者使用let来避免多重评估。]

回答

5

你不需要理解实现 - 文档字符串对于它的工作原理非常清晰。阅读器宏也有很好的文档记录 - #(...)将扩展到(fn [..] ...)。鉴于这些知识和所提供的信息文档字符串,很明显线程匿名函数将无法工作。根本不需要理解实现。

+1

thanks - does http://stackoverflow.com/a/10758139/181772解释事情好吗? –

5

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

  1. 宏应该做什么。 - >实际上是一个非常基本的宏,因为这些文档几乎解释了它如何扩展。
  2. 如果您想将它传递给“普通”宏,读者宏将扩展到什么位置。
1

还要注意的是,如果你在括号包装匿名功能,将工作:

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

写了匿名函数,然后macroexpanding是照明:

=> (-> {: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}))