1) When using a stateful handler in HANDLER-BIND, the behavior changes whether or not the handler is inlined or bound to a variable first (example below).
2) The preferred behavior as far as I am concerned would be to do as other implementations and allow the normal use of let-over-lambdas like in higher-order functions; this looks more aligned with the standard to me.
$ uname -a
Linux dehli 5.4.0-65-generic #73-Ubuntu SMP Mon Jan 18 17:25:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ sbcl --no-sysinit --no-userinit
This is SBCL 2.1.1.116-ef9328e12, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (let (list)
(let ((handler (let ((x 0)) (lambda (c) (declare (ignore c)) (push (incf x) list)))))
(handler-bind ((condition handler))
(signal 'condition)
(signal 'condition)))
(assert (equalp '(2 1) list)))
1) When using a stateful handler in HANDLER-BIND, the behavior changes whether or not the handler is inlined or bound to a variable first (example below).
2) The preferred behavior as far as I am concerned would be to do as other implementations and allow the normal use of let-over-lambdas like in higher-order functions; this looks more aligned with the standard to me.
For context, see https:/ /stackoverflow. com/questions/ 66282753/ is-using- handler- bind-with- a-stateful- closure- valid
$ uname -a
Linux dehli 5.4.0-65-generic #73-Ubuntu SMP Mon Jan 18 17:25:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ sbcl --no-sysinit --no-userinit ef9328e12, an implementation of ANSI Common Lisp. www.sbcl. org/>.
This is SBCL 2.1.1.116-
More information about SBCL is available at <http://
SBCL is free software, provided as is, with absolutely no warranty.
(lambda (c)
(declare (ignore c))
(push (incf x) list)))))
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (let (list)
(let ((handler (let ((x 0))
(handler-bind ((condition handler))
(signal 'condition)
(signal 'condition)))
(assert (equalp '(2 1) list)))
(let (list)
(lambda (c)
(declare (ignore c))
(push (incf x) list)))))
(handler-bind ((condition (let ((x 0))
(signal 'condition)
(signal 'condition))
(assert (equalp '(1 1) list)))
NIL POINT :LINUX LOCAL-NICKNAMES :SB-CORE- COMPRESSION :SB-LDB
* NIL
* *features*
(:X86-64 :GENCGC :64-BIT :ANSI-CL :COMMON-LISP :ELF :IEEE-FLOATING-
:LITTLE-ENDIAN :PACKAGE-
:SB-PACKAGE-LOCKS :SB-THREAD :SB-UNICODE :SBCL :UNIX)
Here above, the first test behaves as I expect it to, the handler mutates its local state and push a different value in LIST each time it is executed.
In the second test, it is as-if the let-over-lambda was evaluated anew each time.
Thank you.