Clojure中的宏抽象是什么?

Clojure中的宏抽象是什么?,clojure,macros,Clojure,Macros,我一直在努力思考抽象在函数式编程中的实际意义。我发现的关于我能理解的语言类型的最好的帖子如下。然而,由于我是一个想成为Clojure程序员的人,我想知道宏提供了什么样的抽象。看起来他们和霍夫一起进入了第二阶段,但同时他们也不仅仅是霍夫。我发现第3阶段与表达式问题有关,是Clojure中的协议和多方法。所以我的问题是: 当用Lisp语言实现宏时,你会说你在抽象什么 在Lisp语言中,第3阶段和第4阶段是什么?我并不认为宏是一种抽象,而是更像一个编译器挂钩 大多数语言实现抽象语法树(或AST)。这是

我一直在努力思考抽象在函数式编程中的实际意义。我发现的关于我能理解的语言类型的最好的帖子如下。然而,由于我是一个想成为Clojure程序员的人,我想知道宏提供了什么样的抽象。看起来他们和霍夫一起进入了第二阶段,但同时他们也不仅仅是霍夫。我发现第3阶段与表达式问题有关,是Clojure中的协议和多方法。所以我的问题是:

当用Lisp语言实现宏时,你会说你在抽象什么


在Lisp语言中,第3阶段和第4阶段是什么?

我并不认为宏是一种抽象,而是更像一个编译器挂钩

大多数语言实现抽象语法树(或AST)。这是一种数据结构中程序代码的表示形式。Lisp宏将此AST的一部分公开为可通过宏函数转换的数据。但由于lisp程序本身就是数据结构,因此在lisp程序中宏往往更干净一些,而在Rust或Scala中宏则更干净一些

所以可以说宏只是语言语义的抽象……但我不知道我是否同意这一点。可以说宏是lisp编译器的扩展,但这也不完全正确

事实证明,宏是非常有限的。他们只能看到正在编译的代码的一小部分。换句话说,宏无法看到树的上方,只能看到树的下方。此外,虽然可以对AST中的子级执行深度检查的宏(称为深度行走宏),但这些宏往往很复杂且容易出错(只需查看core.async的go或midje的内容,看看它们有多复杂)。所以我不太愿意称它们为抽象,也许它们是,也许它们只是非常有限的抽象

因此,我认为宏是更强大的Fexprs()和像LLVM这样的项目中更完整的编译器代码转换之间的奇怪混合体。它们提供了一种非常有限的受控方式来在编译时转换代码,仅此而已


最后,一切都归结为“代码就是数据就是代码”的lisp咒语。如果您的代码是数据,那么提供在编译时转换它的方法是有意义的

问得好,但这更适合我。我会说宏抽象像第1阶段,但在编译时。函数转换值时,宏转换代码,而代码才是真正运行的。我同意@TimothyBaldridge回答中的所有部分,我有资格进行评估。我要强调的是,它们是使用Lisp重写Lisp源代码的方法。我认为宏不适合四个抽象列表,因为它们在评估之前就起作用了。然而,从这个意义上讲,宏可能被认为是允许抽象的:您可以使用宏来抽象多个不同函数共有的模式,从宏生成这些函数。这突出了为什么宏通常可以(也应该)避免:HO函数已经允许类似的操作。