From: Kaz Kylheku
Subject: Question about handlers and restarts.
Date: 
Message-ID: <Q3cU7.25426$ip4.459906@news2.calgary.shaw.ca>
Consider these two functions:

(defun restart-from-handler-case ()
  (handler-case
    (restart-case
      (error "e")
      (foo () (print "restarted")))
    (error () (print "error caught, restarting") (invoke-restart 'foo))))

(defun restart-from-handler-bind ()
  (handler-bind
    ((error #'(lambda (cond) 
		(print "error caught, restarting")
		(invoke-restart 'foo))))
    (restart-case
      (error "e")
      (foo () (print "restarted")))))

Is the first one required to work? Or only the second?  Specifically,
should the restart foo be visible from the error clause of handler-case?

I'm thinking not, because in the execution of that clause, the condition
is accepted and the dynamic environment is supposed to be unwound already.

From: Vladimir Zolotykh
Subject: Re: Question about handlers and restarts.
Date: 
Message-ID: <3C21A774.AC35F161@eurocom.od.ua>
Kaz Kylheku wrote:
> 
> Is the first one required to work? Or only the second?  Specifically,
> should the restart foo be visible from the error clause of handler-case?

restart-case evaluates restartable-form in a dynamic environment as CLHS says,
so the first shouldn't work.

-- 
Vladimir Zolotykh                         ······@eurocom.od.ua
From: Kent M Pitman
Subject: Re: Question about handlers and restarts.
Date: 
Message-ID: <sfwd71ai2d4.fsf@shell01.TheWorld.com>
···@ashi.footprints.net (Kaz Kylheku) writes:

> Consider these two functions:
> 
> (defun restart-from-handler-case ()
>   (handler-case
>     (restart-case
>       (error "e")
>       (foo () (print "restarted")))
>     (error () (print "error caught, restarting") (invoke-restart 'foo))))
> 
> (defun restart-from-handler-bind ()
>   (handler-bind
>     ((error #'(lambda (cond) 
> 		(print "error caught, restarting")
> 		(invoke-restart 'foo))))
>     (restart-case
>       (error "e")
>       (foo () (print "restarted")))))
> 
> Is the first one required to work? Or only the second?  Specifically,
> should the restart foo be visible from the error clause of handler-case?
> 
> I'm thinking not, because in the execution of that clause, the condition
> is accepted and the dynamic environment is supposed to be unwound already.

Vladimir Zolotykh is right in his post (though since he didn't quote the 
code it was hard to interpret his message).  CLHS has sample expansions of
these that clarifies the behavior.

Basically, HANDLER-CASE throws first and asks questions later.  This makes
it nearly useless for accessing the most useful of restarts.  In most cases,
the case clause it sets up _is_, for practical purposes, the recovery and
usually offers code that has the effect that a restart would have (though
mostly more blunt since it has less information about context and no ability
to return to the point of error, which has been thrown out of).

The casual user should prefer HANDLER-BIND rather than HANDLER-CASE if they
want to access restarts.  HANDLER-CASE is, like IGNORE-ERRORS, kind of a blunt
tool that mostly accomodates people coming from other languages who think
that the only operation you do on errors is to "contain" them.

By contrast, by the way, RESTART-BIND is almost never useful to the casual
user and exists mostly for esoteric reasons to implement some obscure kinds
of restarts that most people never do (even most people who use restarts,
since most people never use restarts either :-) ... and RESTART-BIND is 
subprimitive to RESTART-CASE, of course.   If you don't know what you're
doing, you probably want RESTART-CASE.