我一直在努力思考抽象实际在函数式编程中的含义。我发现的最好的帖子是我能理解的语言类型,如下4 abstractions。但是,因为我是一个想成为Clojure的程序员,所以我想知道宏提供了什么样的抽象。它们似乎与HOF一起适合第二阶段,但与此同时它们更像是一个HOF。我发现阶段3与表达式问题有关,并且是Clojure中的协议和多种方法。所以我的问题是:
当用Lisp语言实现一个宏时,你会说你在抽象吗?
第3阶段和第4阶段将采用Lisp语言?
答案 0 :(得分:2)
我并不真正将宏视为抽象,而是将其视为编译器钩子。
大多数语言都实现了所谓的抽象语法树(或AST)。这是一种数据结构中程序代码的表示。 Lisp宏将此AST的部分公开为可通过宏函数转换的数据。但是由于lisp程序本身就是数据结构,因此在lisp程序中宏往往会更清晰,然后它们会在Rust或Scala中。
所以可以说宏只是语言语义的抽象......但我不知道我同意这一点。可以说宏是lisp编译器的扩展,但这也不完全正确。
事实证明,宏非常有限。他们只能看到正在编译的代码的一小部分。换句话说,一个宏无法看到树,只能向下看。此外,虽然可以对AST中的子项执行深度检查的宏(称为深度行走宏),但这些宏往往很复杂且容易出错(只需看看core.async的内容或者midje的内容,看看如何复杂这些可以获得)。所以我犹豫地称他们为抽象,也许他们是,也许他们只是非常有限的抽象。
因此,我认为宏是强大的Fexprs(http://en.wikipedia.org/wiki/Fexpr)与在LLVM等项目中发现的更完整的编译器代码转换之间的奇怪组合。它们提供了一种非常有限的受控方式来在编译时转换代码,就是它。
最后,所有这些都归结为“代码就是数据就是代码”的口号。如果您的代码是数据,那么在编译时提供转换它的方法是有意义的。