Suppose I want to write a restart which is only visible for a certain
kind of condition. What's the proper way to write the test function
of the restart? Intuitively I'd write it like this:
(define-condition foo-condition () ())
(defun foo ()
(restart-case
(error 'foo-condition)
(do-nothing ()
:report "Do nothing."
:test (lambda (c)
(typep c 'foo-condition))
'do-nothing-invoked)))
However this doesn't work. E.g. the Allegro debugger doesn't show the
restart at all. CLISP displays the restart, but when I try to invoke
it, CLISP complains that the restart is not active.
It _does_ work if I write the test as:
(lambda (c) (or (not c) (typep c 'foo-condition)))
So, am I supposed to include the (not c) test? Or is this a bug in
those implementations?
Helmut.
Helmut Eller <········@stud3.tuwien.ac.at> writes:
> Suppose I want to write a restart which is only visible for a certain
> kind of condition. What's the proper way to write the test function
> of the restart? Intuitively I'd write it like this:
>
> (define-condition foo-condition () ())
>
> (defun foo ()
> (restart-case
> (error 'foo-condition)
> (do-nothing ()
> :report "Do nothing."
> :test (lambda (c)
> (typep c 'foo-condition))
> 'do-nothing-invoked)))
>
> However this doesn't work. E.g. the Allegro debugger doesn't show the
> restart at all. CLISP displays the restart, but when I try to invoke
> it, CLISP complains that the restart is not active.
>
> It _does_ work if I write the test as:
>
> (lambda (c) (or (not c) (typep c 'foo-condition)))
>
> So, am I supposed to include the (not c) test? Or is this a bug in
> those implementations?
Hmmm. Which version of Allegro. Using 7.0 on GNU/Linux the debugger
(well, okay, the SLIME debugger) shows the restart. I think this has
something to do with how you look for the restart. For instance:
(handler-bind ((foo-condition
#'(lambda (c)
(format t "Looking at ~a; restart ~a and ~a~%"
c
(find-restart 'do-nothing)
(find-restart 'do-nothing c)))))
(foo))
Prints:
Looking at #<FOO-CONDITION @ #x72ddadba>; restart NIL and Do nothing.
Or perhaps more to the point:
(handler-bind ((foo-condition
#'(lambda (c)
(format
t
"Looking at ~a; restarts:~2%~{~a~%~}~%and~2%~{~a~%~}~%"
c
(compute-restarts)
(compute-restarts c)))))
(foo))
Prints:
Looking at #<FOO-CONDITION @ #x72716b52>; restarts:
Abort handling SLIME request.
Abort entirely from this (lisp) process.
and
Do nothing.
Abort handling SLIME request.
Abort entirely from this (lisp) process.
-Peter
--
Peter Seibel ·····@gigamonkeys.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
Peter Seibel <·····@gigamonkeys.com> writes:
> Hmmm. Which version of Allegro. Using 7.0 on GNU/Linux the debugger
> (well, okay, the SLIME debugger) shows the restart. I think this has
> something to do with how you look for the restart. [... snipped]
The same Allegro version here. Yeah, I know that SLIME shows the
restart, but it is still not invokable. SLIME does basically this:
(defun foo2 ()
(handler-bind ((foo-condition
(lambda (c)
(invoke-restart-interactively
(car (compute-restarts c))))))
(restart-case
(error 'foo-condition)
(do-nothing ()
:report "Do nothing."
:test (lambda (c)
(typep c 'foo-condition))
'do-nothing-invoked))))
i.e. uses compute-restarts and then calls invoke-restart.
invoke-restart fails, probably because the restart test returns false.
To reformulate the question: should invoke-restart fail in this situation?