Macros Clojure中还没有的简单但引人注目的宏示例

Macros Clojure中还没有的简单但引人注目的宏示例,macros,clojure,Macros,Clojure,我正在尝试编写一个宏教程,现在我需要一些简单易懂但引人注目的示例 问题是clojure和contrib中已经有很多显而易见的东西。我觉得“看,我们可以重新实现所有库函数”可能不是解释宏为何如此伟大的最佳论据 有没有人有任何可爱的(一行是最好的)例子,他们不会介意我使用 以下是本教程的前三部分。目前它有点过时,所以任何关于如何改进它的评论都会受到感激 我正在clojure开发一些加密软件。这真的很有趣,使用单元测试让它更有趣,因为我不担心破坏东西。问题是所有的加密函数每次都会生成不同的结果,因

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

问题是clojure和contrib中已经有很多显而易见的东西。我觉得“看,我们可以重新实现所有库函数”可能不是解释宏为何如此伟大的最佳论据

有没有人有任何可爱的(一行是最好的)例子,他们不会介意我使用

以下是本教程的前三部分。目前它有点过时,所以任何关于如何改进它的评论都会受到感激


我正在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))
然后我将测试函数包装在
中(使用伪prng(deftest mytest…)

clojure有很多这样的“绑定宏”。比如不带字符串的
等等

我还有一个宏,可以将每个名称空间加载到repl中。(我现在不怎么用了,因为我已经改用蛋糕了)


ps:请始终记住宏俱乐部的第一条规则

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

  • 保护资源。示例:
    绑定
    打开
    。。。
    (let [~x (get-resource)] (try ~@dostuff (finally (release-resource ~x))))
  • 定义事物。示例:
    defn
    defsnippet
    (enlive),
    defservice
    (ring)
  • 宏/驱动程序拆分。尤其是这种技术消除了许多宏观痛苦。 比如多重评估或捕获。示例:
    带绑定
  • 美化丑陋的代码。什么时候

很好的例子!另一种选择是使用“依赖注入”框架,这在很多情况下都非常难看。从Clojure 1.3开始,这将不再有效,因为
绑定
只能为声明为动态的变量重新定义映射(您的函数可能不是这样)。相反,我们现在应该将预定义的宏
与redefs一起使用。然而,更重要的一点是:这是宏功能的一个很好的例子。刚才它已经为我们定义好了。当我将这段代码移植到1.4时,我声明get prng、mody和字段大小是动态的。也许我最喜欢的例子,我不确定它在clojure中是否可能(可能是clj cont的有限子集,但完全在scheme中),正在实现
yield
,就像在python中一样,通过
调用/cc
。这是一个强有力的例子,它真正让我们明白了一个事实,即宏可以帮助您在语言中构建最疯狂的结构。
(let [~x (get-resource)] (try ~@dostuff (finally (release-resource ~x))))