From SBCL's documentation, we can learn:
Invokes the signal facility on a condition formed from DATUM and ARGUMENTS. If the condition is not handled, NIL is returned.
It does not elaborate on what signal
returns in case of a handled condition.
So, I assumed (guessed), that the handler can somehow determine the return value of the signal function:
(defun countdown (&optional
(start-value 10)
(fail-value 1))
(loop
repeat start-value
for i from 0
collecting
(if (= i fail-value)
(signal "fail-value (~D) hit!" i)
i)))
(defun countdown-progress-indicator-style (&optional
(start-value 10)
(fail-value 1))
(handler-bind
((simple-condition (lambda (c)
(format t "fail (~A)~%" c)
fail-value))) ;; <--- I hoped the return value of the handler is returned by signal!
(countdown start-value fail-value)))
But: even if handled, signal
returns nil
.
(countdown-progress-indicator-style)
fail (fail-value (1) hit!)
(0 NIL 2 3 4 5 6 7 8 9)
Hence, my question, if there is a function or mechanism I missed, which allows the handler to influence signal
's return value.
I think the CLHS explains it nicely: in order to handle a condition, you need to transfer control. This can be all kinds of things, but the usual way is to invoke a restart.
(defun countdown (&optional
(start-value 10)
(fail-value 1))
(loop repeat start-value
for i from 0
collecting
(restart-case
(if (= i fail-value)
(signal "fail-value (~D) hit!" i)
i)
(use-fail-value (fv)
fv))))
(defun countdown-progress-indicator-style (&optional
(start-value 10)
(fail-value 1))
(handler-bind
((simple-condition (lambda (c)
(format t "Handling simple condition~%")
(apply #'format t
(simple-condition-format-control c)
(simple-condition-format-arguments c))
(invoke-restart 'use-fail-value
(first (simple-condition-format-arguments c))))))
(countdown start-value fail-value)))
This somewhat abuses simple-condition
s arguments; you should probably make your own condition, which takes the value explicitly.