8

是什么阻止了像 C 这样的语言拥有 Lisp 宏?在编译过程中的什么时候,C 放弃了操作其代码树的能力?

而且,这具体是解释还是编译问题?

4

4 回答 4

16

语法问题

是的,您可以在命令式语言中使用类似 Lisp 的宏,因为 Lisp 支持命令式编程。C 和 Lisp 中的宏之间的主要区别在于操作源代码树的难易程度:

  • 在 C 中,有声明、声明符、语句、表达式、块、一些不同的控制结构、标签等。新的句法结构可能需要更改解析器。宏将需要构建这些数据结构。

  • 在 Lisp 中,只有 s 表达式。新的句法结构不需要对解析器进行任何更改。只有一种数据结构意味着构建语法树的 API 非常简单易记。

有些语言具有更复杂的语法(如 C),但具有强大的宏功能(如 Lisp)。例如,哈斯克尔。但是,在 Haskell 中编写宏的接口要复杂一些,因为您需要用于创建和应用类型构造函数、表达式、声明、表达式等的函数,而不仅仅是列表的单个构造函数。

Haskell 中宏中的模板有它的类型注解:

[e| ... |] -- expression
[d| ... |] -- declaration
[t| ... |] -- type
[p| ... |] -- pattern

相比之下,Lisp 宏中不需要这些字母edt和。p这些在 Haskell 中是必需的,不是因为 Haskell 是强类型的,而是因为注释使解析器处于正确的状态,因此它可以使用正确的上下文解析内容。同样,Lisp 语法只有一个上下文。

解释与编译

大多数语言可以同时被解释、编译或两者兼而有之。C 可以是其中之一,也可以是两者。Lisp 可以是其中的一个,也可以是两者。宏要求编译器在编译时执行代码,这可以通过解释宏代码或编译宏然后执行它来完成。所以解释型与编译型真的不是问题(在几乎所有关于语言的讨论中都不是问题)。

于 2013-07-29T20:00:52.313 回答
2

对于“类 C”的某些定义,Rust 无疑是一种类 C 语言,它有一个类 Scheme 宏系统

于 2013-07-31T20:06:00.557 回答
1

您可以在 C 中使用一些更强大的预处理器,例如gpp可以用作更强大的cpp替代品,同时保持与它完全兼容。

但是gpp,就像cpp在文本表示上的作品一样,而不是在抽象语法树上。

您可以自定义您的 C 编译器(特别是GCC):例如,通过使用MELT扩展 GCC - 您可以添加自己的内置函数和编译指示,并在编译器中更改优化。

使用 MELT,您主要处理 GCC 内的树和 Gimple 内部表示。

于 2013-08-11T01:26:31.253 回答
1

Haskell 有强大的类型宏:

http://www.haskell.org/ghc/docs/7.0.2/html/users_guide/template-haskell.html

在 C 的情况下,我认为它源于 C 的设计试图保持简单,因此程序的语义很容易理解(不像 C++ 有许多允许创建 DSL 的特性)

于 2013-07-29T20:00:22.163 回答