这是一个符合Common Lisp的程序吗?
(handler-bind ((condition (let ((x 0))
(lambda (c)
(declare (ignore c))
(print (incf x))))))
(signal 'condition)
(signal 'condition))SBCL (2.0.5.37)的输出为:
1
1ABCL/CCL/ECL的输出为:
1
2Common Lisp标准定义了哪种行为?
Epilog
这是SBCL中的一个错误,
现在已经修复了
..。
发布于 2021-02-20 02:20:39
还不是很清楚。The The The
等级库说:执行表单在指示的动态环境中处理程序绑定是有效的。
然后说
如果找到合适的类型,则关联的处理程序将在动态环境中运行,在该环境中,这些处理程序绑定都不可见(以避免递归错误)。
如果您将"run“解释为调用函数,则建议在进行绑定时对处理程序表达式求值一次。这是CCL/ABCL/ECL/LispWorks实现,因此状态在闭包中维护。
但SBCL似乎将"run“解释为”评估和调用“的意思。因此,每次运行处理程序时都会创建一个新的闭包,并且状态会丢失。
我怀疑其意图是第一种解释,因为CL没有其他的“惰性”绑定。
如果您将问题中的代码更改为:
(let ((handler
(let ((x 0))
(lambda (c)
(declare (ignore c))
(print (incf x))))))
(handler-bind ((condition handler))
(signal 'condition)
(signal 'condition)))然后,SBCL以与其他实现相同的方式工作。我认为这相当清楚地表明,其他实现采用的解释是预期的解释,而且它还提供了一种实际的变通方法,用于解决SBCL中的错误。
https://stackoverflow.com/questions/66282753
复制相似问题