CLtL2澄清了范围和范围之间的区别。关于词法变量和特殊变量,我的看法是,词法变量是"不确定范围的词法范围",而特殊变量是"动态扩展的无限范围"
我的问题是:"词法和特殊变量"语义通常是如何在引擎盖下实现的我所说的"一般"是指一个一般的想法就足够了。鉴于Lisp有着悠久的历史,在实现这些基本概念时一定会有许多优化。
为了开始讨论,我大胆猜测如下。
一切都始于环境。环境是一个帧序列,每个帧都是一个将名称映射到位置的表(其值可以检索和存储);每个这样的映射都是一个名称与一个地方的绑定。框架通过封闭关系连接;内部框架中的名称可以在外部框架中覆盖相同的名称。此外,除非declare
-d/declaim
-ed/proclaim
-ed是特殊的,否则Common Lisp中的绑定默认为词法绑定。
语义有两个方面:名称查找和创建新绑定。
-
创建新绑定。
lambda
表达式、let
/let*
、labels
/flet
、macrolet
以及使用它们的宏创建绑定。词法绑定是通过创建一个新的框架并将当前的词法环境作为新创建的框架的封闭环境来创建的。一个特殊的绑定(必须显式声明)将一个新的位置推到为当前包中的名称创建的堆栈的顶部(堆栈可能可以通过名称的哈希表来定位)——堆栈用于实现动态范围,因此当构建表单退出时,绑定可以通过弹出堆栈来解构(问题是如何确保这一点,也许在引擎盖下有unwind-protect
之类的东西?)。 -
名称查找。除非明确声明为特殊,否则名称查找默认为在词法环境中查找——通过在绑定创建过程中建立的帧链接。查找过程中第一个匹配的名称获胜。对于特殊名称(必须明确声明),查找是通过查看堆栈的顶部来实现的。
我认为这个问题可能会迁移到programmers.stackexchange.com,但StackOverflow上还有一些其他问题可以回答其中一些问题,尽管到目前为止我还没有发现完全重复的问题。看看:
- 词汇范围界定是如何实现的
- 有可能在词法范围内实现硬实时吗
- SICP';词汇与动态范围界定;s环境评价模型
此外,值得一提的是,你可能会发现,在编译语言中,词汇环境"查找"实际上不需要太多查找,并且可以编译为词汇环境中的恒定时间内存引用(这仍然是一种查找,但所有工作都是预先确定的,只需要在运行时进行检索)。