Matthew Leach <
mat...@mattleach.net> writes:
> Hi there,
>
> I've been trying my hand with conditions in common lisp, alas, I have
> hit a bit of a snag. I have the following test code.
>
> (define-condition some-warning-type (warning)
> ((msg :initarg :msg :reader msg)))
>
> (defun some-function-to-raise-warning ()
> (+ 2 5)
> (restart-case (warn 'some-warning-type :msg "I have raised a warning.")
> (use-value (value) value)
> (muffle-warning))
> (+ 5 6))
WARN already set up muffle-warning so this is ok but you can just do
CL-USER 11 > (defun some-function-to-raise-warning ()
(+ 2 5)
(restart-case (warn 'some-warning-type :msg "I have raised a warning.")
(use-value (value) value))
(+ 5 6))
SOME-FUNCTION-TO-RAISE-WARNING
> (defun my-main ()
> (handler-bind ((some-warning-type (muffle-warning))))
> (some-function-to-raise-warning))
This has several problems.
> I must be missing something, the way I interpret conditions in my head is
> thus:
>
> * You define your own conditions to represent different conditions that
> you wish to signal.
Ok.
> * You then use (signal) (warn) or (error) to raise a condition.
Ok.
> * The (restart-case) is wrapped around the (signal) function calls to
> specify the different restarts that are available at this point in the
> program.
Ok.
> * the (handler-bind) function is used to set a restart to automatically
> be triggered once the condition is raised.
>
> Is my thinking correct?
No. HANDLER-BIND doesn't set up signal handlers like in POSIX. It
establishes handlers within its context.
So your main function should already be
(defun my-main ()
(handler-bind ((some-warning-type (muffle-warning)))
(some-function-to-raise-warning)))
so that SOME-FUNCTION-TO-RAISE-WARNING runs in it dynamic environment.
But even this would fail since you set up the handler for
SOME-WARNING-TYPE to be the result of running the function
MUFFLE-WARNING which does basically an INVOKE-RESTART of the restart
MUFFLE-WARNING. It's a bit of a pun that the two exists and it is
confusing for beginners.
This works
CL-USER 16 > (defun my-main ()
(handler-bind ((some-warning-type #'muffle-warning))
(some-function-to-raise-warning)))
MY-MAIN
which basically does
CL-USER 23 > (defun my-main ()
(handler-bind ((some-warning-type #'(lambda (condition) (declare (ignore condition)) (invoke-restart 'muffle-warning))))
(some-function-to-raise-warning)))
MY-MAIN