是什么阻止了像 C 这样的语言拥有 Lisp 宏?在编译过程中的什么时候,C 放弃了操作其代码树的能力?
而且,这具体是解释还是编译问题?
是什么阻止了像 C 这样的语言拥有 Lisp 宏?在编译过程中的什么时候,C 放弃了操作其代码树的能力?
而且,这具体是解释还是编译问题?
是的,您可以在命令式语言中使用类似 Lisp 的宏,因为 Lisp 支持命令式编程。C 和 Lisp 中的宏之间的主要区别在于操作源代码树的难易程度:
在 C 中,有声明、声明符、语句、表达式、块、一些不同的控制结构、标签等。新的句法结构可能需要更改解析器。宏将需要构建这些数据结构。
在 Lisp 中,只有 s 表达式。新的句法结构不需要对解析器进行任何更改。只有一种数据结构意味着构建语法树的 API 非常简单易记。
有些语言具有更复杂的语法(如 C),但具有强大的宏功能(如 Lisp)。例如,哈斯克尔。但是,在 Haskell 中编写宏的接口要复杂一些,因为您需要用于创建和应用类型构造函数、表达式、声明、表达式等的函数,而不仅仅是列表的单个构造函数。
Haskell 中宏中的模板有它的类型注解:
[e| ... |] -- expression
[d| ... |] -- declaration
[t| ... |] -- type
[p| ... |] -- pattern
相比之下,Lisp 宏中不需要这些字母e
、d
、t
和。p
这些在 Haskell 中是必需的,不是因为 Haskell 是强类型的,而是因为注释使解析器处于正确的状态,因此它可以使用正确的上下文解析内容。同样,Lisp 语法只有一个上下文。
大多数语言可以同时被解释、编译或两者兼而有之。C 可以是其中之一,也可以是两者。Lisp 可以是其中的一个,也可以是两者。宏要求编译器在编译时执行代码,这可以通过解释宏代码或编译宏然后执行它来完成。所以解释型与编译型真的不是问题(在几乎所有关于语言的讨论中都不是问题)。
对于“类 C”的某些定义,Rust 无疑是一种类 C 语言,它有一个类 Scheme 宏系统。
Haskell 有强大的类型宏:
http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/template-haskell.html
在 C 的情况下,我认为它源于 C 的设计试图保持简单,因此程序的语义很容易理解(不像 C++ 有许多允许创建 DSL 的特性)