From: Doug Philips
Subject: "getting" restarts...
Date: 
Message-ID: <3E9A38A1.40300@mac.com>
I'm hoping that someone can point me to a previous message that will 
answer this. Unfortunately, googling for it hasn't been very helpful. 
Nor has wading through years old FAQs nor more recent proto-FAQs (such 
as I could find).

I've read through the CLtL2 Conditions chapter. The HyperSpec, and Kent 
Pitman's online articles.

Having done all that, I thought "restarts are for telling the debugger 
how to let the user decide how to proceed in the case of an anomalous 
situation. Unfortunately all the examples I saw were fairly hokey 
(division addition, etc.) and while I think they illustrated 'how' 
restarts work (i.e. named continuations), I was left with the idea that 
restarts were _just_ for user/human intervention.

Then I searched google for comp.lang.lisp figuring that I couldn't have 
been the only person who ever wondered if there were more to it than 
that. I like the condition/signal/handle mechanism: "Bad doo doo 
happened, if you know of a way to continue, please do as I'd rather not 
do it myself (or even "hey, this happened and you might want to know") a 
kind of dynamic binding of procedures with (given the ability of 
handlers to "run code" but still decline, you get mix-ins, before, 
after, all kinds of interesting 'control' structures).

If I am writing code for a server that runs unattended, there won't be a 
user/human to consult when something weird happens. The last thing I 
want is to have my service/application hung waiting for Godot.

But I found a few messages from this year that seem to indicate that 
restarts do have a use in completely programmatic paradigms. I just 
don't understand what they really are.

For example, on Feb 1, Kent Pitman posted a long message which ended:

 >(defun socket-done ()
 >  (or (find-restart 'socket-done)
 >      (error "You are not reading from a socket.")))
 >
 >(defmacro with-line-from-socket ((line socket) &body body)
 >  `(with-simple-restart (socket-done "Forceably stop reading from 
socket.")
 >     (mp:with-timeout (+timeout+ (socket-done))
 >       (let ((,line (read-line ,socket nil)))
 >         (unless ,line (socket-done))
 >         ,@body))))
 >
 >Uh, test them? No I didn't.  Left as an exercise to the reader. ;)
 >Do let me know if you have any questions though.
 >
 >In particular, ask me if it's not obvious why CATCH/THROW should never
 >be used as a replacement for WITH-SIMPLE-RESTART and FIND-RESTART, or
 >if it's confusing that restarts are being used even in the case where
 >there's no error handling going on.

I couldn't find any follow ups to that, though if the content or subject 
changed, I probably missed them. Pointers to articles appreciated.

OK. I do have a question or three, if the offer is still open...
First, regarding: '(unless ,line (socket-done))'
   Since that occurs within the scope of a 'socket-done restart, the 
socket-done call won't do anything except verify the restart is in 
scope, rather than actually invoking the restart. Socket-done "protects 
itself" from being called when a 'socket-done restart is not in scope, 
but it doesn't seem like there is any point in calling it from a macro 
that already knows that.

Second, in the case where socket-done would do a invoke-restart, why 
bother with restart machinery at all? I can see it if the invoker(s) and 
restart handler/definers are in separate code, but in this case, in the 
specific case where one macro knows that the restart is defined, and 
that the restart _is going to_ do a transfer of control, how is that 
different from a catch/throw? Yes, I know body could easily have its own 
restart for 'socket-done, but then it could have a catch for it too, so 
that doesn't seem like it buys anything either way.

I'm willing to admit if I'm being dense, but I would like to become less 
so. Most of CL makes a lot of sense. I guess restarts would make more 
sense to me if they were just for debugger/human intervention...

Thanks, in advance, if appropriate, for any clarification or pointers to 
sources of same.

-D'gou

From: Gabe Garza
Subject: Re: "getting" restarts...
Date: 
Message-ID: <87brz9d5ba.fsf@ix.netcom.com>
Doug Philips <····@mac.com> writes:

> But I found a few messages from this year that seem to indicate that
> restarts do have a use in completely programmatic paradigms. I just
> don't understand what they really are.

I'll give you an example of how I've used non-interactive restarts.

I have a commercial application that depends heavily on an Oracle
database.  The database runs on a Big Sun Box (BSB) hooked up to a
refrigerator-sized box of hard disks.  If the Big Sun Box fails,
there's another BSB, normally idle, that assumes the failed BSB's
workload after an interruption (whose length depends on just how
badly BSB 1 went down).  If a BSB dies, my application can't die--in
fact, it can't loose any data at all.

So, in my Oracle library, I have a RETRY-ORACLE-OPERATION restart.  I
also have a RECONNECT-CONNECTION function that will reconnect an
Oracle connection while preserving the state of all the internal
buffers it uses to store data it has yet to insert and commit.

Gracefully handling the death of a BSB in critical code is simply a
matter of making sure there's a handler for the "the database has
died" errors that sleeps a bit, tries to reconnect the connection, and
invokes the RETRY-ORACLE-OPERATION restart if successful and loops
otherwise (logging all the way so I know what happened, of course).

Restarts seemed much cleaner then going through the whole application
and adding appropriate error checking code for the transactions that
are important enough to warrant it.  

From what I can tell (I'm very interested in other opinions here),
restarts seem to be most useful (although certainly not exclusively
so) when writing code that's meant to be reused.  A condition that's a
fatal error to one application may be "no big deal" to another or a
"just do this instead" type situation to a third.  Restarts seem to
allow the decoupling of error-handling code from the library itself,
which can make things so much more adaptable...

> I'm willing to admit if I'm being dense, but I would like to become
> less so. Most of CL makes a lot of sense. I guess restarts would make
> more sense to me if they were just for debugger/human intervention...

Restarts were one of the last things I started exploring too, and I'm
still a long way from saying I completely "get" all of the condition
system (hopefully this thread will generate some traffic :)).  It's
far more nuanced and powerful then any other such facility I've dealt
with.  One of my bigger "Aha!"'s was when I realized that conditions
weren't the same thing as errors...

Gabe Garza
From: Kaz Kylheku
Subject: Re: "getting" restarts...
Date: 
Message-ID: <cf333042.0304140841.65b55664@posting.google.com>
Doug Philips <····@mac.com> wrote in message news:<··············@mac.com>...
> I'm hoping that someone can point me to a previous message that will 
> answer this. Unfortunately, googling for it hasn't been very helpful. 
> Nor has wading through years old FAQs nor more recent proto-FAQs (such 
> as I could find).

Restarts are easy. Simply, they are functions associated with symbols,
and these associations are associated with active blocks of code in
the dynamic context, meaning that they are set up and torn down
dynamically as blocks of code are entered and terminated.

In this manner, they are almost the same as error handlers, except
that error handlers are identified by conditions rather than symbols,
which are class-like entities with slots and inheritance.

You could hack together your own simple restart-like mechanism using a
dynamic variable:

   (defvar *my-restart* nil)

   (defun call-restart (symbol arg)
     (if (not (symbol-value symbol))
       (error "No ~a restart visible" symbol)
       (funcall (symbol-value symbol) arg))

   (let ((*my-restart* #'(lambda (arg) (print "my restart!"))))
     ;; ...
     (call-restart '*my-restart*))

Of course this simple mechanism doesn't provide the sophistication of
real restarts, like being able to enumerate all of them (see
COMPUTE-RESTARTS).

> Having done all that, I thought "restarts are for telling the debugger 
> how to let the user decide how to proceed in the case of an anomalous 
> situation.

No, restarts are for codifying advice which tells an error handler
that ways of continuing are available. In other words, they provide a
way of continuing a computation at some intermediate point between a
handler and the site of the condition, rather than aborting it
entirely all the way up to the handler.

You don't have to use restarts this way; if you want, you can use them
purely as a control mechanism. They are like throw and catch, except
that they have the ability to return!  So the following two codes do
the same thing in different ways:

  (catch 'foo 
    (throw 'foo 42))

  (block nil
    (restart-bind ((foo #'(lambda (arg)
                            (return arg))))
      (invoke-restart 'foo 42)))

But note that in the restart lambda we had to code our own non-local
return via (block nil ... (return arg) ...). Without that, the lambda
would just return back to the (invoke-restart ...) expression
normally. There is a restart-binding construct called RESTART-CASE
which provides the non-local return behavior implicitly.

This is useful because invoking a restart is usually the last point in
a condition handling protocol, and so it's desirable to do the
non-local jump which unwinds and continues.

> Unfortunately all the examples I saw were fairly hokey 
> (division addition, etc.) and while I think they illustrated 'how' 
> restarts work (i.e. named continuations), I was left with the idea that 
> restarts were _just_ for user/human intervention.

Restarts are a nice way to avoid the user interface decision. They are
for programmatic intervention. The interactive environments found in
Lisp systems provide a default user interface, such that if your code
does not handle an error, you get a menu that shows you the available
restarts, in addition to debugging commands for walking the stack,
etc.

When you are developing some code, you can get by with this built-in
mechanism. Then when you start to get the ``flavor'' of your condition
handling needs, you can start adding some automated protocol. Or bolt
on graphical UI etc.

> Then I searched google for comp.lang.lisp figuring that I couldn't have 
> been the only person who ever wondered if there were more to it than 
> that. I like the condition/signal/handle mechanism: "Bad doo doo 
> happened, if you know of a way to continue, please do as I'd rather not 
> do it myself (or even "hey, this happened and you might want to know") a 
> kind of dynamic binding of procedures with (given the ability of 
> handlers to "run code" but still decline, you get mix-ins, before, 
> after, all kinds of interesting 'control' structures).
> 
> If I am writing code for a server that runs unattended, there won't be a 
> user/human to consult when something weird happens. The last thing I 
> want is to have my service/application hung waiting for Godot.

Yes; this would be the Microsoft way of programming. Call MessageBox,
and obtain advice from the user: Abort, Retry or Fail so when the
operator comes to work in the morning, she goes from machine to
machine and clicks away dialogs.

You see without restarts, it is very hard to separate the user
interface and interactivity concern from the concern for continuing
after errors occur. Restarts let you separate the concern. The code
indicates how it can continue, signals a condition, and delegates the
choice to some other layer.

Without this decoupling, stupid things are done, like calling user
interface functions from low-level middleware. MS-DOS did this; you'd
call a DOS function and it would assume that it can put an Abort,
Retry, Fail message on the screen, regardless of whether the display
adapter is even in a text mode!

> But I found a few messages from this year that seem to indicate that 
> restarts do have a use in completely programmatic paradigms.

Or in mixtures of the two. You might have a handler that evaluates the
available restarts, and based on what is there, can decide whether to
recover automatically, or delegate---perhaps to another handler that
brings up some user interface.

You can also keep the system interactive until, through empirical use,
you ``discover'' some sane protocols for dealing with errors. Then you
codify the behavior that a human being would have followed. ;)

Here is a good potential use for restarts. Suppose you have some
security middleware which must authenticate itself in order to obtain
some network connection. Suppose that the connection is disrupted and
it must log in again. It would be inappropriate for it to bring up the
password dialog, because the user cannot be assumed to be there! But
certainly, when the initial connection is being made, the user *is*
there, and types in his credentials and presents the authentication
token (password, fingerprint, smart card, whatever).

So how do you do this? Instead of calling UI from the authentication
code, you have it indicate an ``authentication needed'' condition, and
then provide a restart through which the credentials can be supplied.
The interactive code is prepared to handle the error, bring up a
dialog, obtain the info, and then invoke the restart. Before it does
that, it caches the information! So the next time the condition
occurs, it can invoke the restart by itself, and thereby supply the
authentication information without bringing up any UI. With some
security mechanisms, it might not be possible: for example, under some
authentication methods, tokens can expire. So for those cases, there
is no way to continue without the intervention of the user.
From: Kent M Pitman
Subject: Re: "getting" restarts...
Date: 
Message-ID: <sfw4r51rus9.fsf@shell01.TheWorld.com>
Doug Philips <····@mac.com> writes:

...
> For example, on Feb 1, Kent Pitman posted a long message which ended:
> 
>  >(defun socket-done ()
>  >  (or (find-restart 'socket-done)
>  >      (error "You are not reading from a socket.")))

Should be


 (defun socket-done ()
   (let ((r (find-restart 'socket-done)))
     (when r (invoke-restart r))
     (error "You are not reading from a socket.")))

>  >
>  >(defmacro with-line-from-socket ((line socket) &body body)
>  >  `(with-simple-restart (socket-done "Forceably stop reading from
> socket.")
>  >     (mp:with-timeout (+timeout+ (socket-done))
>  >       (let ((,line (read-line ,socket nil)))
>  >         (unless ,line (socket-done))
>  >         ,@body))))
>  >
>  >Uh, test them? No I didn't.  Left as an exercise to the reader. ;)
>  >Do let me know if you have any questions though.
>  >
>  >In particular, ask me if it's not obvious why CATCH/THROW should never
>  >be used as a replacement for WITH-SIMPLE-RESTART and FIND-RESTART, or
>  >if it's confusing that restarts are being used even in the case where
>  >there's no error handling going on.
> 
> I couldn't find any follow ups to that, though if the content or
> subject changed, I probably missed them. Pointers to articles
> appreciated.
> 
> OK. I do have a question or three, if the offer is still open...
> First, regarding: '(unless ,line (socket-done))'
>    Since that occurs within the scope of a 'socket-done restart, the
> socket-done call won't do anything except verify the restart is in
> scope, rather than actually invoking the restart. 

You're right. There was a bug.  It indeed must also invoke the restart.

> Socket-done
> "protects itself" from being called when a 'socket-done restart is not
> in scope, but it doesn't seem like there is any point in calling it
> from a macro that already knows that.

Well, you explained the problem yourself.  You had only to go fix the
code. ;)

> Second, in the case where socket-done would do a invoke-restart, why
> bother with restart machinery at all?

You're thinking of it backward.

Look at it historically.  It used to be we'd have written code vaguely
like this.  (I am using modern names for operations, so I don't confuse
you on old-style syntax from prior dialects, but I'm using a set of 
functionalities that were how we'd have written it for lack of better
operations.)

 (defun socket-done ()
   (or (ignore-errors (throw 'socket-done)) ; <-- NOTE ODD USE OF THROW
       (error "You are not reading from a socket.")))

 (defmacro with-line-from-socket ((line socket) &body body)
   `(catch 'socket-done   ; <-- NOTE USE OF CATCH
      (mp:with-timeout (+timeout+ (socket-done))
        (let ((,line (read-line ,socket nil)))
          (unless ,line (socket-done))
           ,@body))))


The problem restarts attempt to solve is that with CATCH/THROW, you cannot
know if the tag is available without actually trying to transfer to it.
That is, in modern parlance, you cannot introspect about the availability
of the tag.  People used to "solve" this problem by doing

 (defvar *reading-from-socket* nil)

 (defun socket-done ()
   (if *reading-from-socket*
       (throw 'socket-done)
       (error "You are not reading from a socket.")))

 (defmacro with-line-from-socket ((line socket) &body body)
   `(catch 'socket-done
      (let ((*reading-from-socket* t))
        (mp:with-timeout (+timeout+ (socket-done))
          (let ((,line (read-line ,socket nil)))
            (unless ,line (socket-done))
             ,@body)))))

This allowed a kind of ad hoc introspection but each user of catch had
to remember to set it up independently, it made for a lot of mostly useless
variables, etc.  What some suggested we needed was the ability to ask
throw-tag-established-p, but there were several problems with that.  Around
that time, for example, various weird variant  kinds of catch operations
had been introduced, so that you could catch all throws, so that you could
use predicates on catch tags, and so on.  I think these were found to be
mostly bad ideas, and we got rid of them.  But they complicated what
throw-tag-established-p would return.  So we didn't go that way.

But, more than this, the primary reason to want to ask the
programmatic question was to offer the tag to a user.  And just as
there is a maxim we sometimes utter, which is "People count from 1,
programs count from 0" (that is, to emphasize the fact that interfaces
should not blindly pass through 0-indexed numbers to human users who
are used to counting from 1), there is a similar kind of rule we in
Lisp have, albeit unspoken, about continuations.  It may suffice for a
program to know a catch tag, but that's a piece of program internal
data.  That's not relevant to a human.  A human wants an English
(i.e., natural language) description of what to do.  That is why
restarts are adorned with additional descriptive information--so that
they are dual use.

Nothing keeps you from just using restarts instead of catch/throw.
e.g.,
 
 (defun socket-done ()
   (let ((r (find-restart 'socket-done)))
     (if r
         (invoke-restart r)
         (error "You are not reading from a socket."))))

 (defmacro with-line-from-socket ((line socket) &body body)
   `(restart-case (let ((*reading-from-socket* t))
                    (mp:with-timeout (+timeout+ (socket-done))
                      (let ((,line (read-line ,socket nil)))
                        (unless ,line (socket-done))
                         ,@body)))
      (socket-done () nil)))

This is adequate to the programming task.  But if you happen to end
up talking to the user because your program has no ability to choose,
you're better off offering the user a choice of restart descriptions
than restart names.  That is, you don't want:

 An error occurred: Bad packet ID.
 Select how to proceed.
  1: Invoke CONTINUE.
  2: Invoke FRED-UTILITIES::SOCKET-DONE.
  3: Invoke CL::ABORT.
  4: Invoke CL::ABORT.

when instead you could have

 An error occurred: Bad packet ID.
 Select how to proceed.
  1: Discard the offending packet.
  2: Discard further text on this socket.
  3: Return to command level in program Browser.
  4: Exit program Browser.

But the point is that this adornment is an after-the-fact thing that is
added so that programs and people can refer to the same thing.

A person might say "gosh, I've seen this happen a lot. it seems to work
to always discard the packet" or "gosh, this always happens with host
foo.  it seems to work to alwys discard their packets, but it never works
for anyone else's."

The programmer might anticipate this and write a handler in the
iniitial version of the program _or_ might later after many debugger
sessions add a handler.  The handler might look like:

 (handler-bind ((bad-packet-id #'(lambda (c)
                                   (let ((r (find-restart 'continue c)))
                                     (when r (invoke-restart r))))))
    ...)

or

 (handler-bind ((bad-packet-id #'(lambda (c)
                                   (when (host= (bad-packet-id-host c) "foo")
                                     (let ((r (find-restart 'continue c)))
                                       (when r (invoke-restart r))))
                                   (abort))))
    ...)
     
These programs effectively take the place of user intervention according
to the two rules I described above in English for how a user would handle
them interactively.

> I can see it if the invoker(s)
> and restart handler/definers are in separate code, but in this case,
> in the specific case where one macro knows that the restart is
> defined, and that the restart _is going to_ do a transfer of control,
> how is that different from a catch/throw?

This is a very astute point.  Again, you are getting it but not realizing
it.  The _entire_ restart protocol is indeed about a protocol, and what
a protocol is a half-program.  What it means to have a protocol  is to write
half the code and to leave the other half open to someone with
jigsaw puzzle precision saying "you can snap in the other half here".

Where you are confusing yourself (and/or I am confusing you):

 - You are not realizing how important that nature of a protocol is.
   You perhaps see me using "small" examples, which tend to collapse
   out this planned-for separation.  the separation is, after all, not
   required.  just as i can demonstrate
    (catch 'foo (throw 'foo 3))
   and you can wonder why block/go is not enough.  I have made the analogy
   many places in the code to catch/throw, not block/go exactly to remind
   you that this separation can be dynamic.  I apologize if I have not
   emphsized that enough.

   You yourself in fact even used catch/throw as your example, so I think
   you know this.  The right question of a confused person is why you
   can't just use block/go, that is, why can't it just be lexical.  And
   then the answer is that if it were lexical, it could not accomodate
   half-programs.  You cannot write half a lexical contour.

 - You are not realizing that just because there are two calls to
   socket-done in the example, they are not the only places you can
   run socket-done.  socket-done might be called dynamically anywhere
   in the body of with-line-from-socket. e.g.,

     (defun my-grep-from-socket (test-string socket &key (multi nil))
       (loop (with-line-from-socket (line socket)
               (check-line test-string line multi))))

     (defun check-line (test-string line multi)
       (cond ((string= test-string "EOF")
              ;; We treat uppercase EOF as a virtual end of file
              (socket-done))
             ((search test-string line)
              (write-line line) ;to *standard-output* for this example
              (unless multi (socket-done)))))

> Yes, I know body could
> easily have its own restart for 'socket-done, but then it could have a
> catch for it too, so that doesn't seem like it buys anything either
> way.

This seems confused in some way I can't entirely sort out.
You can certainly muck arund with trivialities of the definition of 
WITH-LINE-FROM-SOCKET but when you get done, it will either be possible
to call SOCKET-DONE from a function that the WITH-LINE-FROM-SOCKET
is not lexically surounding or it won't.  The intent of all restart stuff
is to dynamically, not lexically, enclose the code where the caller is.

> I'm willing to admit if I'm being dense,

You're being only intermittently dense.  It's plain you've thought hard
about this and it's even plain you have let perfectly good conclusions go
by that you were well capable of recognizing. :)  I'm also sure the 
presentation is also missing some critical detail that would make it clearer,
but it's so uncommon for people to ask about this stuff that it isn't that
I don't know the answers, it's that I don't know the questions!
I appreciate your going through this and I hope you will stick through
this discussion not only until you have an answer but until I understand
why you didn't have the answer at the outset so I can fix future
presentations of this info.

> but I would like to become
> less so. Most of CL makes a lot of sense. I guess restarts would make
> more sense to me if they were just for debugger/human intervention...

They are not.

Think of a handler as a problem solver.  It sniffs at the various restarts
and tries to figure which one to select.  If there is no handler, the person
at the console gets to be the program and do that.  But the intent is FIRST
that the programs get control and then only as a last resort that a person
fills in as a program (not vice versa).  Once the person has done the same
action a few times, it is expected he will wrap the offending program in
an error handler that causes the need for human intervention to not happen.

I call the debugger the "interactive handler" for this reason.  It is simply
doing

  (handler-bind ((error #'(lambda (condition)
                            (let ((all-restarts (compute-restarts condition)))
                              (let ((chosen 
                                      (ask-user-for-a-restart all-restarts)))
                                (invoke-restart-interactively chosen))))))
    all-code-goes-here)


around all of your code.  Your goal is to place an inner handler-bind that
will handle the error before this outer one takes control.  But even this
outer one is a programmatic restart-it just happens to be a program that does
I/O, just as SQRT could be defined by:

 (defun sqrt (x)
   (format t "~&What's the square root of ~S? " x)
   (read))

It's better if it's not.  But sometimes we begin that way when we don't
know what else to do.  This happens more often in error handling than
in main programs because errors are, quite literally, not the normal
situation.  So we write the normal code first.

> Thanks, in advance, if appropriate, for any clarification or pointers
> to sources of same.

Sure.

Your turn.
From: Doug Philips
Subject: Re: "getting" restarts...
Date: 
Message-ID: <3E9B4A2E.6000908@mac.com>
[This turned out to be more hastily written and sent than I wanted, see 
end for more info. Tone is terse only. --Doug]

Kent M Pitman, responding to my message of yesterday, indited:
>> >(defun socket-done ()
>> >  (or (find-restart 'socket-done)
>> >      (error "You are not reading from a socket.")))
> 
> 
> Should be
> 
> 
>  (defun socket-done ()
>    (let ((r (find-restart 'socket-done)))
>      (when r (invoke-restart r))
>      (error "You are not reading from a socket.")))


 > You're right. There was a bug.  It indeed must also invoke the restart.

Ahhhhh. OK. One "problem" of not yet understanding "all this" is in 
distinguishing between incomplete code, and an incomplete understanding 
of good code...

> Look at it historically.

Ah, Pitman-san, I do not have that history... or I have only a 
superficial observers grasp of it.

...

>  (defun socket-done ()
>    (or (ignore-errors (throw 'socket-done)) ; <-- NOTE ODD USE OF THROW
i.e. prevent the non-existance of a catcher from landing us somewhere 
undesired, like in the interactive debugger, or a high level application 
  'catch-all' that would terminate the process/thread/whatever. OK.
>        (error "You are not reading from a socket.")))
> 
>  (defmacro with-line-from-socket ((line socket) &body body)
>    `(catch 'socket-done   ; <-- NOTE USE OF CATCH
>       (mp:with-timeout (+timeout+ (socket-done))
>         (let ((,line (read-line ,socket nil)))
>           (unless ,line (socket-done))
>            ,@body))))
> 
> 
> The problem restarts attempt to solve is that with CATCH/THROW, you cannot
> know if the tag is available without actually trying to transfer to it.
> That is, in modern parlance, you cannot introspect about the availability
> of the tag.

Got that part. Example of alternative solution elided (its in the 
archives for anyone reading this much later and on the news servers for 
any current readers.)

> variables, etc.  What some suggested we needed was the ability to ask
> throw-tag-established-p, but there were several problems with that.  Around
> that time, for example, various weird variant  kinds of catch operations
> had been introduced, so that you could catch all throws, so that you could
> use predicates on catch tags, and so on.  I think these were found to be
> mostly bad ideas, and we got rid of them.  But they complicated what
> throw-tag-established-p would return.  So we didn't go that way.

That doesn't sound familiar from all my readings. It may well be a 
distraction, but it helps understanding motivation for "the way that was 
went" too.

> But, more than this, the primary reason to want to ask the
> programmatic question was to offer the tag to a user.
...
>It may suffice for a
> program to know a catch tag, but that's a piece of program internal
> data.  That's not relevant to a human.  A human wants an English
> (i.e., natural language) description of what to do.  That is why
> restarts are adorned with additional descriptive information--so that
> they are dual use.

OK. This primary reason is what had me confused, it seemed to me, from 
the examples I'd seen, that it was the sole reason. At least the 
examples in the texts I'd read so far.

> Nothing keeps you from just using restarts instead of catch/throw.

(...example elided...)

> But the point is that this adornment is an after-the-fact thing that is
> added so that programs and people can refer to the same thing.

I see/agree that is a good thing.


> A person might say "gosh, I've seen this happen a lot. it seems to work
> to always discard the packet" or "gosh, this always happens with host
> foo.  it seems to work to alwys discard their packets, but it never works
> for anyone else's."
...
> These programs effectively take the place of user intervention according
> to the two rules I described above in English for how a user would handle
> them interactively.

Ahhhh, ok. This is not really very clear from the examples. Or rather 
wasn't clear to me. My understanding had been that the resort to user 
was a last resort. An example like this would have helped me a lot.


>>I can see it if the invoker(s)
>>and restart handler/definers are in separate code, but in this case,
>>in the specific case where one macro knows that the restart is
>>defined, and that the restart _is going to_ do a transfer of control,
>>how is that different from a catch/throw?
> 
> This is a very astute point.  Again, you are getting it but not realizing
> it.  The _entire_ restart protocol is indeed about a protocol, and what
> a protocol is a half-program.  What it means to have a protocol  is to write
> half the code and to leave the other half open to someone with
> jigsaw puzzle precision saying "you can snap in the other half here".

I think you are on to something here in a different way. I didn't really 
come across any convincing examples of this. Either the examples 
demonstrating the mechanism were self contained like this one, or 
completely open ended invoking an interactive user solution. I didn't 
see the middle ground, or rather, I didn't see a convincing example of a 
middle ground. (more on this below).


>  - You are not realizing that just because there are two calls to
>    socket-done in the example, they are not the only places you can
>    run socket-done.  socket-done might be called dynamically anywhere
>    in the body of with-line-from-socket. e.g.,

Indeed. I saw that, but again, that isn't really different from a known 
catch is waiting (and confounded by thinking that find-restart must have 
been doing something more than I thought. I feel like Nomad must have 
felt...)

>>Yes, I know body could
>>easily have its own restart for 'socket-done, but then it could have a
>>catch for it too, so that doesn't seem like it buys anything either
>>way.
> 
> This seems confused in some way I can't entirely sort out.
> You can certainly muck arund with trivialities of the definition of 
> WITH-LINE-FROM-SOCKET but when you get done, it will either be possible
> to call SOCKET-DONE from a function that the WITH-LINE-FROM-SOCKET
> is not lexically surounding or it won't.  The intent of all restart stuff
> is to dynamically, not lexically, enclose the code where the caller is.

Perhaps I was being too terse. I was trying to say that I couldn't see 
any difference in generality to a function called from the body within a 
WITH-LINE-FROM-SOCKET that set up its own 'socket-done restart, to one 
which would do the same with a catch, that is, I didn't see how restarts 
were giving me "more" than catch/throw would have, even _if_ an 
intermediary function in dynamic scope of the outer mechanism wanted to 
intercept the change in flow of control. I think this has turned out to 
be a minor point for other reasons.

> by that you were well capable of recognizing. :)  I'm also sure the 
> presentation is also missing some critical detail that would make it clearer,
> but it's so uncommon for people to ask about this stuff that it isn't that
> I don't know the answers, it's that I don't know the questions!
> I appreciate your going through this and I hope you will stick through
> this discussion not only until you have an answer but until I understand
> why you didn't have the answer at the outset so I can fix future
> presentations of this info.

That would be great!
I think what would have helped me a lot would have been a slightly 
longer example showing a programmatic use of restarts. That is, 
convincing me of the interactive use was done (I might say overdone in 
CLtL2). That book can't be rewritten, and in any event I had other 
problems with using it as my first source of understanding...

>>less so. Most of CL makes a lot of sense. I guess restarts would make
>>more sense to me if they were just for debugger/human intervention...
> 
> They are not.

I believe that, but don't feel I grok it the way I grok "plain" 
signal/handle.../condition constructs.


> Think of a handler as a problem solver.  It sniffs at the various restarts
> and tries to figure which one to select.  If there is no handler, the person
> at the console gets to be the program and do that.  But the intent is FIRST
> that the programs get control and then only as a last resort that a person
> fills in as a program (not vice versa).  Once the person has done the same
> action a few times, it is expected he will wrap the offending program in
> an error handler that causes the need for human intervention to not happen.
...

OK. Here is one other thing that has me a bit confused. I'm going to 
have to back up a little, I think, to explain why (even if just to 
myself ;-)).

The "oldest" way of doing exceptional-case handling was a C-like 
setjmp/longjmp (I don't have the history to rattle off the MacLisp, etc. 
version of that, but I know it exists). That had many many problems. One 
was that there wasn't any way for the catcher to discriminate, too 
little info was available. The condition type solves this problem. Stuff 
your own "subclass" of some condition type chock full of all kinds of 
helpful "here is what's going on, what happened, etc." info so that the 
handler could decide if it wanted to handle. The second problem was in 
being able to decline the non-local flow of control. The third problem 
was that there were only two options, return to the spot of the signal, 
or go somewhere predefined 'by the handler.' Restarts let the signaler 
specify alternate return-to-signaler-context options. I think there is 
still another problem, which is that the handler doesn't have anything 
nearly as rich as a condition object to tell it anything about how it 
can choose from those return-points. It just has the name of the 
restarts. In the case of COMPUTE-RESTARTS I have no programmatic way of 
determining which one to choose if the same named restart is mentioned 
more than once. I can't annotate the condition object with the restart 
info because I don't have it.I have to decide which restart to pick 
based on its name only. The restarts have human readable text, but that 
doesn't serve programmatic uses any more than the old (throw '|Undefined 
Symbol Binding|) did (I paraphrase and exaggerate for effect, but only 
slightly).

So lacking a good example of both halves of a separated protocol 
example, I didn't make the leap I needed to make.


> It's better if it's not.  But sometimes we begin that way when we don't
> know what else to do.  This happens more often in error handling than
> in main programs because errors are, quite literally, not the normal
> situation.  So we write the normal code first.

Indeed. It might have helped (or might not have) if that had also been 
spelled out a bit more. That this is also an incremental

>>Thanks, in advance, if appropriate, for any clarification or pointers
>>to sources of same.
> Sure.

Thanks.

> Your turn.

Taken,but more hastily than I wanted. Maybe offline for a few days, but 
am very interested in continuing this in as timely a fashion as I am able.

-D'gou
From: Doug Philips
Subject: Re: "getting" restarts...
Date: 
Message-ID: <3E9B625A.6030909@mac.com>
This all got very long, I'm going to try to summarize what confusions I 
have left, and hopefully that will be shorter.

I have previously unarticulated set of confusions over restarts:
	a) What are the package name influences on symbols used as restart names?
	b) I don't get what use raw restart values are (such as returned by 
find-restart), and in particular, how I could get one to pass into 
find-restart? That is, there is a restart-name function that gives me 
what, string? but if I have a value of type restart, how would I have 
gotten it if it weren't active? I could save one from when it was active 
and see if it is still active? There doesn't seem to be much info 
(please point me to it if I've missed it) about restart values. Does the 
same actual bit of restart-bind code always create restart values that 
are 'eq' or are the values only 'eq' so long as the same one particular 
instance of a restart is active? That is, if I call a function that 
defines/binds a restart, does that generate a unique restart value every 
time I call it? Is there a reason why I cannot get the restart value 
inside the binding? I suppose I could call FIND-RESTART before doing 
anything else, but that wouldn't really work for 'nil' restarts or 
duplicates... I could call COMPUTE-RESTARTS, but that isn't documented 
to a level specific enough to guarantee that the first 'n' values are 
indeed the 'n' restarts I'd just defined/bound. But I can't really know 
if there are any other restarts on the list put in by the system for its 
own purpose(s), right?


Back into my other confusions, previously semi-articulated... let me try 
another tack and see if this more clearly articulates my confusion:
	Conditions capture state of a non-normal situation.
	Signal tells the system to inform "someone" of a condition.
	Handlers look at a condition and decide to defer or handle it.
	Restarts provide handlers places to go that aren't necesssarily 
lexically visible to the handlers (i.e. handlers have a richer set of 
options).
	Conditions are value rich.
	Restarts are just names (symbols) with additional strings that present 
the human "last resort handler" with more info.
	Programatically I have to choose a restart (from within a handler) 
based on its name alone, I have no way to pick based on intended 
behaviour the way the human can. Code is supposed to guess based on 
recency of establishment which restart is likely to be more helpful. I 
can choose between different restarts based on their names: Prefer 
'gentle-restart to 'drastic-restart (for example). Or prefer 
'abort-protocol to 'turn-off-device... Actually, its worse than that. 
When I write the handler code, that is, handler code in a handler-bind, 
still running in the dynamic context of the signal, I can't 
deterministicly tell where the condition firewall is. I could do a 
lexically local non-local transfer of control, but then its too late. So 
I can't prefer 'restartA over 'restartB except if 'restartB became 
available after the currently running handler was established. That is, 
lets say that I want to prefer 'reset-protocol over 
'renegotiate-connection if both were already available when I was 
established, but if there is a 'reset-protocol available since I (the 
handler) was established, I would like to prefer that instead. Clear as 
mud? I can't immediately conceive of an example for this, but then 
again, I have't been able to conceive of a (convincing) example in much 
simpler cases either. I suppose I could try to gensym a restart in the 
handler, and using the COMPUTE-RESTARTS ordering guarantee try to figure 
out where my firewall would be...
	Another way to put it, lets say the bound-handler would prefer a 
restart that wouldn't invoke a transfer of control past where it was 
bound on the call stack... (i.e. a more local fix is better than a more 
general one, but if I have to pick a more general one, I'd pick 'a over 
'b but if there is an 'a that wouldn't unwind me I'd rather pick that, 
or I'd just rather pick the most recent to the signaller non-parameter 
restart...).


Basically, I think I can now see how a program could use the restart 
protocol, but I still don't see how I might design such a thing that was 
pure programmatic rather than user-interventiony which transitions to 
programattic. A good example is not coming to mind, now that I think I 
understand how the parts work together.

-D'gou (oi, its just getting muddier... ;-) )
From: Doug Philips
Subject: Re: "getting" restarts...
Date: 
Message-ID: <3E9C1C22.3050901@mac.com>
(Sorry for the weird threading, my news server didn't show me this, I 
found it on google. Sigh.)

Gabe Garza (·······@ix.netcom.com) indited:

 >I'll give you an example of how I've used non-interactive restarts.

Thanks. That was very helpful.

 >From what I can tell (I'm very interested in other opinions
 >here), restarts seem to be most useful (although certainly
 >not exclusively so) when writing code that's meant to be
 >reused.  A condition that's a fatal error to one application
 >may be "no big deal" to another or a "just do this instead"
 >type situation to a third.  Restarts seem to allow the
 >decoupling of error-handling code from the library itself,
 >which can make things so much more adaptable...

Hmmm. It seems that there are three things. The signal of a condition, 
the handling, and the restarts. I'm guessing that you mean the divion is 
between the signaller and the handler/restarts. I'm not sure how I'd 
write code that had all three distinct, though I think I can hear Kent 
saying that would be just two separate protocols. ;-) I think...


 >Restarts were one of the last things I started exploring
 >too, and I'm still a long way from saying I completely
 >"get" all of the condition system (hopefully this thread
 >will generate some traffic :)).  It's far more nuanced
 >and powerful then any other such facility I've dealt
 >with.  One of my bigger "Aha!"'s was when I realized that
 >conditions weren't the same thing as errors...

Indeed, I hope it does. Conditions for non-error cases (say logging, or 
I'm not even sure what) seem very enticing.

-D'gou
From: Tim Bradshaw
Subject: Re: "getting" restarts...
Date: 
Message-ID: <ey3istflivw.fsf@cley.com>
Doug asked me if I'd post this example, so ... here it is.

I have an application which is pretty gui-driven - almost everything
happens from menu callbacks.  It needs a way of coping with various
kinds of bad things happening, and continuing (or possibly offering
the option of just expiring).  Obviously if really really bad things
happen - for instance if the code that prompts the user whether they
want to continue gets an error - it needs to just die; but in general
this doesn't happen.

How I do this is that the menu callback code does two things: firstly
it establishes a restart with a known name (not one of the standard
restarts).  Secondly it establishes (with HANDLER-BIND, not
HANDLER-CASE, because the error handler code must run before the stack
has unwound) an error handler which will look for a restart with this
name, and invoke it if the user says this is OK.  The restart
established by the callback code just prints a little message (based
on the condition signalled, which it is passed), and carries on.  This
provides a fallback error handler.

Much (ultimately all) of the code called from the menus establish
their own restarts with the same name, which do something more
useful. For instance one of the menus causes a large amount of data to
be read and parsed from a database.  This data can (and often does)
contain syntax errors.  The code which does this establishes a restart
around the parse of each row which, when invoked, will (a) print the
offending row, and (b) skip it.  Thus, when reading buggy databases,
the error handling code will find *this* restart, and use it instead,
allowing you to skip bogus rows from the database.  None of the menu
code actually does anything to handle errors - this is all done by the
top-level error handler; the menu code just establishes restarts at
points where it knows how it's possible to carry on.

(In real life this is more complex, because there are various kinds of
conditions, some of which are considered too serious to continue from,
and in some cases I need to `wrap' system conditions (like parse
errors from READ) in my own conditions to allow them to be handled
properly.)

--tim
From: Joerg-Cyril Hoehle
Subject: Re: "getting" restarts...
Date: 
Message-ID: <ubryyvbu8.fsf@T-Systems.com>
Tim Bradshaw <···@cley.com> writes:
> it establishes a restart with a known name (not one of the standard
> restarts).  Secondly it establishes (with HANDLER-BIND, not
[...]
> Much (ultimately all) of the code called from the menus establish
> their own restarts with the same name, which do something more
> useful.
                          ^^^^^^^^^^^^^
In my eyes, you short-circuited the two-side protocol that KMP talked
about. Another view on the same thing would talk about an
optimization.

I have a very similar, yet non-GUI setting. My application
(logfile analysis) is rather hierarchic, here are the restarts:
skip-to-next-file
  skip-to-next-line
   ;parsing input
    either ignore-extra-junk-in-input
    or     count-extra-junk-to-last-column
   ;processing input
    either skip-to-next-partial-data-analysis
    or     ignore-this-data-analysis-from-now-on

In fact, I could also use a single name for all of them, because the
error handler does nothing more than jumping to the top-most restart
of those. This is what I think makes sense for a batch job. What do I
need different names then?

Thus, in my eyes, by giving a single name to all your restarts, your
application "optimized" away the different restart point
possibilities. The benefit is a simpler error handler, which just has
to jump to that unique name.

But wouldn't
  (invoke-restart (first (compute-restarts)))
be just as easy in your error handler?
You'd preserve different names, *and* a simple error handler.


>   The code which does this establishes a restart
> around the parse of each row which, when invoked, will (a) print the
> offending row, and (b) skip it.  Thus, when reading buggy databases,
> the error handling code will find *this* restart, and use it instead,
> allowing you to skip bogus rows from the database.
Exactly like in my application.

In interactive REPL mode, I can choose the restarts from the
debugger. In batch mode, the topmost one is chosen.


> (In real life this is more complex, because there are various kinds of
> conditions, some of which are considered too serious to continue from,
> and in some cases I need to `wrap' system conditions (like parse
> errors from READ) in my own conditions to allow them to be handled
> properly.)

Could you please expand on this?
My experience was not to do so (IIYC), because it costs a lot in
performance and clarity of code for little benefit. Users need
meaningful error messages, but I try to find a way to provide
these without resorting to re-raising exceptions under different
names, as would be the case using

 (handler-case
   (arithmetic-error (c)
    (error 'parse-error :file ...))) ; beurk

Instead, I believe (need to investigate/experiment more on this) that
the available restarts (as in (COMPUTE-RESTARTS)) can be used to
provide sensible information to the user, so s/he knows what
part/component of the software went wrong.

E.g. "Error while processing log file xxx" instead of "attempt to add
NIL to a number in FOO" could be produced by scanning the restarts,
instead of wrapping errors.

Only by clicking "View details" in a GUI application should s/he view
the exact condition. A backtrace is then probably also valuable
information to a developer.

Regards,
	Joerg Hoehle
ITC-Security T-Systems / T-Nova GmbH Technology Center
From: Tim Bradshaw
Subject: Re: "getting" restarts...
Date: 
Message-ID: <ey34r4mhl0b.fsf@cley.com>
* Joerg-Cyril Hoehle wrote:

> But wouldn't
>   (invoke-restart (first (compute-restarts)))
> be just as easy in your error handler?
> You'd preserve different names, *and* a simple error handler.

No, because there might be other restarts there which, for instance,
might be intended only for use when I'm debugging the program but not
in production.

>> (In real life this is more complex, because there are various kinds of
>> conditions, some of which are considered too serious to continue from,
>> and in some cases I need to `wrap' system conditions (like parse
>> errors from READ) in my own conditions to allow them to be handled
>> properly.)

> Could you please expand on this?

Sure.  My error framework has, typically, three broad categories (realised as
classes of conditions):

`User errors': these are errors in the syntax of configuration files,
or database errors, or other stuff that the program has to defend
itself against.

`Detected system errors': these are errors in the program itself, but
errors which it has detected.  So the code might say `whoops, I should
not get here, I will signal an error'.  These are bugs, but they are
ones that the program expects in some sense.

`Undetected system errors': these are errors in the program which it
hasn't detected - say it's chuntering along and gets a divide-by-zero
error.  These are serious bugs.

The error handling code treats these differently, both in how it
reports and handles them.  In particular, if it gets an undetected
system error (meaning any error whose class is not one of my classes
really), it doesn't, really, know whether it's safe to carry on
(because it doesn't really know what happened), so it warns the user
about this before offering them the option of continuing, as well as
suggesting they report the bug &c.

The issue then is that there are cases where conditions of classes
that I don't `own' need to be turned into ones that I do.  A sample
case might be: `I'm just about to call READ on user input: an error
here is a user error, even though it will be signalled as an error of
a class that I don't own'.  So in order to punt these things into the
error framework, I need to `wrap' them in errors of classes that I
own.

Typically I do this with code that defines wrapping conditions, which
contain the original condition as a slot, and whose report functions
report the wrapped condition as well (just using the ~A format
directive).

Then I resignal the error with something like:

(handler-bind
    ((error 
      ;; Wrap and resignal
      (lambda (e)
        (weld-user-error 'rep-command-line-parse-error
                         :wrapping e))))
  ...)

--tim
From: Nils Goesche
Subject: Re: "getting" restarts...
Date: 
Message-ID: <lyznmt1bw3.fsf@cartan.de>
Doug Philips <····@mac.com> writes:

> Having done all that, I thought "restarts are for telling the
> debugger how to let the user decide how to proceed in the case of an
> anomalous situation. Unfortunately all the examples I saw were
> fairly hokey (division addition, etc.) and while I think they
> illustrated 'how' restarts work (i.e. named continuations), I was
> left with the idea that restarts were _just_ for user/human
> intervention.

When I wrote a little NNTP library, restarts came as a natural
solution for the AUTH problem: At any time, when you issue a command
to the server, the server may decide that it wants authentication data
first.  You get an error return code, then you have to submit auth
data and repeat the command.  Often the server will never ask for auth
data at all.  My solution was to write a wrapper function for sending
NNTP commands; when a command fails because the server wants auth data
first, I'll signal an NNTP-AUTH-ERROR.  A handler in the client code
will handle it and get user name and password in any way it likes: By
popping up a window asking for it or looking into some config files
first, whatever.  Then it will invoke a restart and the command is
retried and the program continues normally (remembering the auth data
for later use).  While debugging in a listener you can enter user name
and password in the debugger, too, of course.  Works nicely.

Regards,
-- 
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x0655CFA0