如果我错了请纠正我,但是在 Java、C、C++、Python、Javascript 或我使用过的任何其他语言中都没有像 gensym 这样的东西,而且我似乎从来不需要它。为什么它在 Lisp 中是必要的而不是在其他语言中?为了澄清,我正在学习 Common Lisp。
最佳答案
Common Lisp 有一个强大的宏系统。您可以创建新的语法模式,使其完全按照您希望的方式运行。它甚至用自己的语言表达,使语言中的一切都可用,以将代码从您要编写的代码转换为 CL 实际理解的代码。所有具有强大宏系统的语言都提供gensym
或在其宏实现中隐式执行。
在 Common Lisp 中,当您想要编写代码时,您可以使用 gensym
,其中的符号不应与结果中任何其他位置使用的元素相匹配。没有它,就无法保证用户使用宏实现者也使用的符号,并且他们开始干扰并且结果与预期行为不同。它确保同一宏的嵌套扩展不会干扰以前的扩展。使用 Common Lisp 宏系统,可以创建类似于 Scheme syntax-rules
的限制性更强的宏系统。和 syntax-case
.
Scheme 中有几个宏系统。一种带有模式匹配,其中新引入的符号会自动运行,就好像它们是用 gensym
制作的一样。 syntax-case
默认情况下也会生成新符号,就好像它们是用 gensym
生成的一样,并且还有一种减少卫生的方法。您可以使用 syntax-case
创建 CL defmacro
但由于 Scheme 没有 gensym
您将无法使用它创建卫生宏.
Java、C、C++、Python、Javascript 都是Algol dialects除了简单的基于模板的宏外,它们都没有。因此他们没有 gensym
因为他们不需要它。由于在这些语言中引入新语法的唯一方法是希望它的下一个版本能够提供它。
我想到了两种具有强大宏的 Algol 方言。 Nemerle和 Perl6 .它们都采用卫生方法,这意味着引入的变量的行为就好像它们是用 gensym
制作的一样。
在 CL、Scheme、Nemerle、Perl6 中,您无需等待语言特性。你可以自己做!如果 Java 和 PHP 中的新闻尚不可用,则可以使用其中任何一个中的宏轻松实现。
关于lisp - 为什么 lisp 使用 gensym 而其他语言不使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30108137/