language-agnostic - 除了 Logo 和 Emacs Lisp,还有哪些纯动态作用域语言?

标签 language-agnostic lisp programming-languages language-theory logo-lang

有哪些动态范围语言的示例?选择该设计的原因是什么?是因为容易实现吗?

最佳答案

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}

如果像 at 这样的变量是词法范围的,这根本就不起作用。它与 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-PROTECTfinally block 。我也看到过使用 C++ 析构函数完成此操作,主要是作为练习。

关于language-agnostic - 除了 Logo 和 Emacs Lisp,还有哪些纯动态作用域语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1473111/

相关文章:

c++ - 保存 URI 主机名的容器

language-agnostic - 断言()与强制(): Which to choose?

security - 确定何时或何时不转义输出

java - 编程语言中的类和库有什么区别?

lisp - 设置和重置系统变量 - AutoCAD LISP

lambda - LISP 宏失败,崩溃史莱姆

javascript - 如何使用 Ramda 将代码从 Lisp(MIT Schema)翻译成 JavaScript?

iphone - Objective-C 编码准则

c# - C# 是单分派(dispatch)语言还是多分派(dispatch)语言?

c# - 在一个强类型的世界中,为什么 ASP.NET MVC 对命名约定的脆弱依赖不令人不悦?