10

我想在循环内重新绑定一个特殊变量。现在,通常,这是使用let.

(let ((*read-eval* nil))
  (do-something-here))

但是由于loop宏有这些很好的with子句,我想我可以在那里这样做。该表达式(macroexpand '(loop with *read-eval* = nil))最终将绑定扩展到 a let,因此它肯定会专门用于我的实现。但我在标准中找不到任何表明这是标准化行为的内容。所以,我想,我的问题是:

(loop with *read-eval* = nil
      for i from 1 to 10
      do (something-involving-the-read-function))

修改现有变量是否需要符合要求的实现*read-eval*,或者是否存在创建同名新词法变量的风险?

4

1 回答 1

8

*read-eval*是一个全局特殊变量。没有办法撤消它,即为它创建一个本地词法绑定。

with子句被描述为使用绑定(而不是仅仅设置),这意味着,实际上,一旦循环完成,我们将回到原始值(回答@joshua-tailor 的问题)。

让我们理性思考。(loop with foo = nil ...)肯定会为foo. 因此,为了(loop with *read-eval* = nil ...) 建立该绑定,实现必须检查(在宏扩展或编译时)在运行时是否*read-eval*动态变量。这听起来很疯狂。

于 2015-10-30T02:50:07.943 回答