CLtL2 has clarified the distinction between scope and extent。关于词汇和特殊变量,我对它的看法是,词汇变量是“无限范围的词法范围”,而特殊变量是“无限范围的动态扩展”。
我的问题是:一般来说,“词汇和特殊变量”语义是如何实现的?“一般来说”,我的意思是一般性的想法就足够了。鉴于Lisp的悠久历史,必须有许多优化应用于实现这些基本概念。
为了启动讨论,我冒昧地猜测下面。
一切都从环境开始。环境是一系列帧,每个帧是一个将名称映射到地点的表(可以检索和存储其值);每个这样的映射都是名称与地点的绑定。框架由封闭关系链接;内框中的名称可以在外框中遮蔽相同的名称。此外,Common Lisp中的绑定默认为词汇,除非declare
- d / declaim
- ed / proclaim
- ed为特殊。
语义有两个方面:名称查找和新绑定的创建。
创建新绑定。 lambda
表达式,let
/ let*
,labels
/ flet
,macrolet
以及使用它们的宏创建绑定。通过创建新框架并将当前词汇环境设置为新创建的框架的封闭环境来创建词法绑定。特殊绑定(必须显式声明)将新位置推送到为当前包中的名称创建的堆栈顶部(堆栈可能位于名称上的哈希表) - 堆栈用于实现动态范围,以便当构造形式退出时,可以通过弹出堆栈来解构绑定(问题是如何确保如此,也许在引擎盖下有unwind-protect
之类的东西?)。
名称查找。除非明确声明为特殊,否则名称查找默认通过在绑定创建期间建立的框架链接在词法环境中查找。查找过程中的第一个匹配名称获胜。对于特殊名称(必须明确声明),通过查看堆栈顶部来查找查找。
答案 0 :(得分:1)
我认为这个问题可能会迁移到programmers.stackexchange.com,但是StackOverflow上还有其他一些问题可以提供其中一些问题的答案,尽管到目前为止我找不到任何问题都是完全相同的。看看:
另外,对于它的价值,您可能会发现在编译语言中,词汇环境“查找”实际上不需要太多查找,并且可以编译成词法环境中的常量时间内存引用(这是仍然是一种查找,但所有工作都是事先确定的,只有检索需要在运行时进行)。