Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

muffle-warning not active.

25 views
Skip to first unread message

Matthew Leach

unread,
Dec 31, 2011, 8:39:29 AM12/31/11
to
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))

(defun my-main ()
(handler-bind ((some-warning-type (muffle-warning))))
(some-function-to-raise-warning))

The file loads fine, however, when I invoke (mymain), a error condition
is raised:

No restart MUFFLE-WARNING is active.
[Condition of type SB-INT:SIMPLE-CONTROL-ERROR]

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.

* You then use (signal) (warn) or (error) to raise a condition.

* The (restart-case) is wrapped around the (signal) function calls to
specify the different restarts that are available at this point in the
program.

* the (handler-bind) function is used to set a restart to automatically
be triggered once the condition is raised.

Is my thinking correct?

Many thanks,
Matt

Kaz Kylheku

unread,
Dec 31, 2011, 11:54:26 AM12/31/11
to
On 2011-12-31, Matthew Leach <mat...@mattleach.net> wrote:
> (defun my-main ()
> (handler-bind ((some-warning-type (muffle-warning))))
> (some-function-to-raise-warning))

You have

(defun my-main ()
form1
form2)

Where form1 is (handler-bind ...), and form2 is your function call that
signals the warning.

The function call is not wrapped inside the handler-bind.

Your correct indentation even shows this, which leads me to suspect
that you might be thinking that handler-bind establishes something
for the remaining forms in the same progn.

Try:

(defun my-main ()
(handler-bind ((some-warning-type (muffle-warning)))
(some-function-to-raise-warning)))

> * The (restart-case) is wrapped around the (signal) function calls to
> specify the different restarts that are available at this point in the
> program.
>
> * the (handler-bind) function is used to set a restart to automatically
> be triggered once the condition is raised.

Handler-bind is a macro which is wrapped around code to specify the
different handlers that are available at this point in the program.

Lieven Marchand

unread,
Dec 31, 2011, 4:43:12 PM12/31/11
to
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
0 new messages