Clojure中尚未提供的简单但令人信服的宏观示例

时间:2010-09-14 16:58:26

标签: macros clojure

我正在尝试编写一个宏教程,现在我需要一些简单易懂但又引人注目的示例。

问题在于很多明显的事情已经在clojure和contrib中。我觉得“看,我们可以重新实现所有的库函数”可能不是宏为什么如此伟大的最好的论据。

有没有人有任何他们不介意使用的可爱(单行最好)的例子?

以下是本教程的前三部分。目前这有点危险,所以任何关于如何做得更好的评论都会感激不尽。

http://learnclojure.blogspot.com/2010/09/clojure-macro-tutorial-part-i-getting.html

http://learnclojure.blogspot.com/2010/09/clojure-macro-tutorial-part-ii-compiler.html

http://learnclojure.blogspot.com/2010/09/clojure-macro-tutorial-part-ii-syntax.html

2 个答案:

答案 0 :(得分:6)

我正在使用clojure中的一些加密软件。它非常有趣并且使用单元测试使它更有趣,因为我不会对破坏事情感到紧张。问题是所有加密函数每次都会产生不同的结果,因为它们是由相当好的IMHO psudo随机数生成器驱动的。

如何测试随机函数?

当然是绑定宏!

(defmacro with-fake-prng [ & exprs ]
  "replaces the prng with one that produces consisten results"
  `(binding [com.cryptovide.split/get-prng (fn [] (cycle [1 2 3]))
             com.cryptovide.modmath/mody 719
             com.cryptovide.modmath/field-size 10]
       ~@exprs))

然后我将测试函数包装在 (with-fake-prng (deftest mytest ....))

clojure有很多这些“绑定宏”。比如with-out-string等。

我还有一个宏,它将每个命名空间加载到repl中。 (现在我已经换了蛋糕,我不会用这么多)

(defmacro load-all []
  '(use 
   :reload-all
   'com.cryptovide.modmath
    ...  
   'com.cryptovide.gui
   'com.cryptovide.checksum
   'com.cryptovide.log))
ps:永远记住宏观俱乐部的第一条规则

答案 1 :(得分:4)

我会更多地讨论模式:何时以及如何使用宏。例如...

  • 保护资源。示例:bindingwith-open,...
    (let [~x (get-resource)] (try ~@dostuff (finally (release-resource ~x))))
  • 定义事物。示例:defndefsnippet(enlive),defservice(响铃)
  • 宏/驱动程序拆分。特别是这种技术消除了很多宏观痛苦。 喜欢多次评估或捕获。示例:with-bindings
  • 美化丑陋的代码。例如。何时Taming multi-dim arrays