循环宏中的Common Lisp绑定

时间:2015-10-30 02:22:50

标签: loops common-lisp let dynamic-scope

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

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

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

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

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

1 个答案:

答案 0 :(得分:8)

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

with子句被描述为使用bindings(而不仅仅是设置),这意味着,实际上,一旦完成循环,我们就会#39 ;回到原来的价值(回答@ joshua-tailor'的问题)。

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