简体   繁体   中英

Is using handler-bind with a stateful closure valid?

Is this a conforming Common Lisp program?

(handler-bind ((condition (let ((x 0))
                            (lambda (c)
                              (declare (ignore c))
                              (print (incf x))))))
  (signal 'condition)
  (signal 'condition))

The output with SBCL (2.0.5.37) is:

1
1

The output with ABCL/CCL/ECL is:

1
2

Which behavior is defined by the Common Lisp standard?


Epilog

This was a bug in SBCL, it is now fixed .

It's not exactly clear. The spec says:

Executes forms in a dynamic environment where the indicated handler bindings are in effect.

and then says

If an appropriate type is found, the associated handler is run in a dynamic environment where none of these handler bindings are visible (to avoid recursive errors).

If you interpret "run" meaning to call the function, that suggests that the handler expressions are evaluted once, when the bindings are made. This is the CCL/ABCL/ECL/LispWorks implementation, so state is maintained in the closure.

But SBCL appears to have intepreted "run" as meaning "evaluated and called". So a new closure is created each time the handler is run, and state is lost.

I suspect the intent was the first interpretation, since CL has no other "lazy" bindings.

If you change the code in the question to this:

(let ((handler
        (let ((x 0))
          (lambda (c)
            (declare (ignore c))
            (print (incf x))))))
  (handler-bind ((condition handler))
    (signal 'condition)
    (signal 'condition)))

then SBCL behaves in the same way as the other implementations. I think this makes it fairly clear that the interpretation taken by the other implementations is the intended one, and it also provides a practical workaround for what, if that interpretation is in fact correct, is a bug in SBCL.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM