循环宏中的Common Lisp绑定

Sil*_*olo 10 loops common-lisp let dynamic-scope

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

(let ((*read-eval* nil))
  (do-something-here))
Run Code Online (Sandbox Code Playgroud)

但由于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))
Run Code Online (Sandbox Code Playgroud)

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

sds*_*sds 8

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

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

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

  • 这是事实,但是仍然不清楚**循环**必须重新绑定,而不是仅仅分配.我们知道一旦完成循环,我们将回到原始值吗?我非常肯定答案是肯定的,基于http://www.lispworks.com/documentation/HyperSpec/Body/06_abb.htm,它说变量不再存在于循环之外.对于特殊变量,措辞不是特别好用,但看起来唯一合理的解释是名称的本地绑定,这意味着*let*(或*lambda*等). (2认同)