Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!rochester!beta.cs.rochester.edu!user
From: miller@cs.rochester.edu (Brad Miller)
Subject: Re: Help with conditions
Message-ID: <miller-0711941459490001@beta.cs.rochester.edu>
Sender: news@cs.rochester.edu (Usenet news)
Nntp-Posting-Host: beta.cs.rochester.edu
Organization: University of Rochester Computer Science Dept.
References: <miller-0411941554290001@199.89.214.2> <NcaBVc2w165w@sytex.com>
Date: Mon, 07 Nov 1994 14:59:49 -0500
Lines: 91

In article <NcaBVc2w165w@sytex.com>, smcl@sytex.com (Scott McLoughlin) wrote:

> miller@cs.rochester.edu (Brad Miller) writes:
> 
> > the macros do just that. That is, the handler can certainly execute a throw
> > to any dynamically apparent catch, e.g. where the handler was bound. Another
> > thing you can do is look to see if there are available handlers. That would
> > be one way to decide if you want to just handle the event locally before
> > signalling (if you know no handler will answer). I usually do this by
setting
> > up a local handler, signal the error, and if the local handler can
find anoth
> > handler, it returns nil (so the next handler will be called), otherwise,
> > it deals with the "problem" best as it can.
> > 
> 
> Howdy,
>         First. Since the handler established by HANDLER-BIND is 
> executed in the dynamic environment of the call to SIGNAL, I 
> would think that "any dynamically apparent catch" would not
> be restricted to "where the handler was bound".

I did not mean to imply that. "e.g." means "for example".

>         Second, I don't see any facillity for examining 
> currently bound condition handlers: CLtL2, pg. 881 says...
> "When a program does not know how to continue, and no active
> handler is able to advise it, the "interactive condition
> handler," or "debugger," can be entered." RESTARTs seem
> inspectable (I've not looked at this so closely), but no
> HANDLERs.  Of course, CLtL2 is not the final word I 
> suppose.

That's because I was playing fast and loose on the differences between
handlers and restarts: I was trying to give the right intuitions that would
let you run experiments rather than what would actually work.

More precisely, then, what a handler returns doesn't matter, if it returns
it's considered to decline. Handlers, then, can only be used for non-local
exit (or side effects); if you want to return something you need to use a
restart. The naming is counter-intuitive, since restarts CAN return
without a non-local transfer of control, and what it returns IS returned
to the invoker.

"Normally" what you do is have restart points in your code that will capture
control from handlers that will pick a restart to invoke. What I've found to
be useful is to execute handlers only for their side effects, or (similarly)
use restarts for their side effects: the advantage of the former is you need
do nothing special (the handler just returns) the latter lets you explictily
examine if there are available restarts you might care to use to "handle"
the error.

Restarts can be looked up "by name", handlers cannot. If you have a handler,
and want to give any "more global" handlers a chance to handle the error
before you try, you can resignal the condition argument you were passed
(this is explicitly in the dpANS). That will run outer applicable handlers
on the condition argument (and if they accept the condition, they won't return).

Alternatively, you associate restarts with your conditions (see restart-case
or with-condition-restarts), and then find-restart will tell you the
applicable restarts for your condition.

But at any rate, I think this is confusing detail, what you need to know
to get started is you want to "signal" a condition, the condition object 
should contain any lexical information you want your handler to see (since
it will see any dymamic information available, by executing in the signallers
dynamic environment), and either perform a non-local transfer of control, 
e.g. via throw, or perform side-effects that "repair the problem" and return.
The latter is only safe if you know some other handler won't grab control
and do something you don't want to happen. If that's a problem, you have
to be slightly more tricky and use restarts, or set up a catch tag you 
can throw to where you signal the condition.

>         BTW: what is the expected/defacto/mandated 
> behavior when you get a "stack overflow" or some other
> error that might prevent a handler from being evaluated
> in the dynamic context of the signaling function???????

dpANS defines a storage-condition condition type that is signaled when
there are problems with memory management due to implementation limits.

Presumably, an implementation needs to reserve enough memory to invoke
the handler (but the handler would get into trouble if it cons'd).

>         Yes, this is a hairy chapter, but a nice 
> "lispy" exception handling mechanism.
> 
> =============================================
> Scott McLoughlin
> Conscious Computing
> =============================================
