有哪些动态范围语言的示例?选择该设计的原因是什么?是因为容易实现吗?
最佳答案
Mathematica 是另一种通过 Block
结构动态定义范围的语言。这在使用公式时实际上非常有用。它允许你写类似的东西
In[1]:= expr = a*t^2 + b*t+ c;
In[2]:= Block[{a = 1, b = -1, c = 2}, Table[expr, {t, 5}]]
Out[2]= {2, 4, 8, 14, 22}
如果像 a
和 t
这样的变量是词法范围的,这根本就不起作用。它与 Mathematica 的规则重写系统配合得特别好,如果变量没有现成的定义,除其他事项外,该系统将使变量保持未计算状态(作为符号表达式)。
Mathematica 可以使用 Module
构造来伪造词法范围,但这实际上是根据新的、据称唯一的符号重写表达式(如果你预测下一个唯一符号是什么,你可能会导致冲突将是,这在大多数情况下很容易)。这意味着
Module[{x = 4},
Table[x * t, {t, 5}]]
会变成这样:
Block[{x$134 = 4},
Table[x$134 * t, {t, 5}]
Emacs Lisp,在它的一个库中,有一个名为 lexical-let
的构造(实际上是一个 Lisp 宏),它使用完全相同的技巧来伪造词法范围。
当你编译你的语言时,真正的词法范围有性能优势,这是 ELisp 或 Mathematica 的假词法所没有的,因为你需要动态变量和它的当前值之间的一些映射,这意味着做查找(通过哈希表或属性列表或其他东西)和附加的间接层。
编辑:如果您只有词法变量,您可以通过在进入作用域时存储全局词法变量的原始值并保证在退出作用域时恢复旧值来伪造动态作用域范围。为了确保这一点,您需要类似 Lisp 的 UNWIND-PROTECT
或 finally
block 。我也看到过使用 C++ 析构函数完成此操作,主要是作为练习。
关于language-agnostic - 除了 Logo 和 Emacs Lisp,还有哪些纯动态作用域语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1473111/