有哪些动态作用域语言的例子?为什么选择这种设计?是因为它易于实现吗?
有哪些动态作用域语言的例子?为什么选择这种设计?是因为它易于实现吗?
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的规则重写系统中特别有效,如果没有现有定义,它会将变量保留为未评估的(作为符号表达式)。Module
结构可以模拟词法作用域,但实际上是使用新的、独特的符号重写表达式(如果您预测下一个独特符号将是什么,在大多数情况下这很容易导致冲突)。这意味着......Module[{x = 4},
Table[x * t, {t, 5}]]
Block[{x$134 = 4},
Table[x$134 * t, {t, 5}]
lexical-let
的结构(实际上是一个Lisp宏),用来模拟词法作用域。但是,与ELisp或Mathematica的虚假词法不同,真正的词法作用域在编译语言时具有性能优势,因为您需要一些映射来表示动态变量及其当前值,这意味着需要进行查找(通过哈希表或属性列表等)和额外的间接层。UNWIND-PROTECT
或finally
块这样的东西。我也看到过使用C++析构函数来实现这个目的,主要是作为练习。(let ((*standard-output* *some-other-stream*))
(stuff))
fish
shell是一个值得注意的例外。 - UTF_or_Death好的,有许多网站讨论了优缺点,这里不再赘述。
一种有趣的语言,它具有某些类似于动态作用域的特性是XSLT;虽然XSLT的模板、变量等都是词法作用域的,但XSLT当然是关于XML的 - 当前在xml树中的位置是“动态作用域”,因此上下文节点是全局的,XPath表达式的求值不是按照XSLT的词法作用域进行,而是按照它的动态评估进行。
m4具有pushdef/popdef,这是一种典型的动态作用域实现。