Macros 编写redis json驱动程序时,Monad能否替换宏?

Macros 编写redis json驱动程序时,Monad能否替换宏?,macros,clojure,monads,Macros,Clojure,Monads,在本文中,他列出了您希望使用单子的原因。他的理由之一是: 那么,有什么线索表明一元溶液是可能的呢?在我看来,每当你复制和粘贴代码来定义一个与现有函数相似的新函数时,都可能潜伏着一个monad 这实际上与使用Clojure风格宏的理由非常相似 在本文中,他谈到了编写redis驱动程序生成json时宏的用例。在幻灯片66中,他展示了一个例子 (defmacro defcommand [name params] (let [p (parameters params)] `(defn

在本文中,他列出了您希望使用单子的原因。他的理由之一是:

那么,有什么线索表明一元溶液是可能的呢?在我看来,每当你复制和粘贴代码来定义一个与现有函数相似的新函数时,都可能潜伏着一个monad

这实际上与使用Clojure风格宏的理由非常相似

在本文中,他谈到了编写redis驱动程序生成json时宏的用例。在幻灯片66中,他展示了一个例子

(defmacro defcommand
  [name params]
  (let [p (parameters params)]
    `(defn ~name ~params
我的问题是-在为redis调用而不是宏生成json时,是否可以使用Monad来解决重复代码的问题

假设

  • 我理解在Clojure中选择宏比选择单子更为惯用。对于这个问题,我选择忽略什么是惯用语,而只看什么是可能的
单子和宏在不同的抽象级别上运行

我认为宏是“代码猴子”:每当我发现自己在编写大量样板文件时,我都会花点时间思考宏是否有帮助

另一方面,单子是非常强大的抽象,通常用于在纯功能环境中分离和合成副作用。(我不是单子方面的专家,所以对此持怀疑态度)

底线是,我认为他们正在解决根本不同的问题

如果我们以您提供的编写Redis驱动程序的示例为例,那么任何访问网络的函数都可以通过Monad进行抽象——在本例中,IO和(或)Monad都可以。但不是因为重复,而是因为你的功能有副作用

现在,clojure中的单子可能会变得更加困难:如果您想同时编写两个单子,则需要使用。显然,clojure并没有强制执行这一点,因为它是一种动态语言,所以可以说在动态语言中调试组合的一元代码可能非常困难。像Haskell这样的静态类型系统在这里会有很大的帮助

因此,虽然redis驱动程序肯定可以用一元风格编写,但我相信Aaron在演示文稿中提出的要点是避免重复,因此,我认为宏更适合Clojure

我希望这是有帮助的

编辑

我还应该指出,如果没有Haskell启发的do表示法,Clojure中的Monad将几乎没有用处,这基本上是由宏实现的,它进一步证明了宏处于不同的抽象级别

任何时候复制和粘贴代码以定义新函数 这与现有的类似

我会创建一个高阶函数来消除复制粘贴,就这么简单

现在,宏或单子,甚至一个简单的高阶函数,解决了一个单一的目的,但在不同的概念层次。其目的是“抽象出系统中的通用模式”。 在系统中可以看到模式出现的不同概念级别有:

  • 相同的代码块-使用函数/高阶函数
  • 相同的代码块,但需要某种“编译时”预处理使其抽象为宏
  • “有上下文的盒子中的值”的模式,它符合单子定律-单子。(可能,IO,List——所有这些都是API模式,我们可以在一个带有上下文的框中看到一个值)
我知道这听起来很“抽象”,但一旦你练习了足够多的思考如何在你的系统中抽象出一般的模式,你最终会直觉地知道使用哪种工具来实现哪种模式