[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: KMP's proposal

> ....  What may be controversial is letting a more general
>handler established in an inner condition-bind override a more specific
>handler established farther out.  I think it should work this way, as I
>said in my earlier note, but I'm not sure what the Lisp Machine does or
>what KMP was proposing.

What you want will work on the Lisp Machine. The handler established
in an inner condition-bind whether defined for a general condition
name (like ERROR) or specific condition-name (like FILE-NOT-FOUND)
will overide any handler (specific or general) established farther
out, as long as the condition signalled has a condition name which
matches the one defined for the handler.  (eg, condition
FILE-NOT-FOUND might have condition names FILE-ERROR and ERROR)

>Is a special piece of machinery really needed for this (restart handlers)?  
>Couldn't this be handled easily by Condition-case, with one or more
>of the clauses being a throw to some appropriate outer catch?  Or am
>I missing something? 

CONDITION-CASE would work if you want to ALWAYS do the throw whenever
the particular condition was signalled.  With CONDITION-CALL you could
also test a predicate before deciding to do the throw.  On the Lisp
Machine, a restart handler defines a proceed type which does a throw
to some appropriate outer catch. Restart handlers aren't condition
handlers.  Maybe restart handler is the wrong name.  If a debugger or
condition handler asks for a list of proceed-types, it should include
the ones defined by the restart handlers.  If in the debugger, you
can choose one of these restart proceed types.

What I would like to see is somthing like KMP's special form
(CATCH-ABORT form).  But allow one to define it for a specific


 CATCH-CONDITION-RESTART executes body.  If condition-name is
signalled, and this restart is selected, return NIL as the first value
and Non-Nil as the second value.  If this condition is not signalled,
return the value of the last form in body.  FORMAT-STRING and
FORMAT-ARGS is used to describe the restart (eg, "Return to top-level").


 CONDITION-RESTART executes body.  If condition-name is signalled and
this restart is selected, BODY is executed again from the beginning.
If BODY returns, the values of the last form in it are returned from

Most command-loops would use this with condition-names ABORT and ERROR.

> Can you supply an example where this (classifying conditions or
> proceed options) is needed?  The simpler we keep
> this, the easier it is going to be to come up with something usable.

Classifying conditions allows handlers flexibility in deciding which
conditions they will handle.  A handler might be defined for all
errors or a specific file errors.  You can do this with KMP's proposed
special form DEFINE-SIMPLE-CONDITION.  For example,

   (format t "File ~A not found"  file-name))   

Classifying proceed options could also allow more flexibility.  One
proceed type could be recognized as a substitute for another proceed
type.  DEFINE-PROCEED-TYPE could include another optional arg PARENT.

> The common lisp functions ERROR and CERROR should include a
>   signal-name (condition-type) argument.
> I agree.  It's not obvious to me where such an argument can be inserted
> in a compatible way, however.

My proposal:
 (ERROR condition-name format-string &rest format-args)

 (CERROR proceed-type condition-name format-string format-args)
A DEFINE-PROCEED-TYPE for proceed-type whould contain the

For those not having access to a the Lisp Machine document, here are
the definitions of the special forms I think we should include:

(CONDITION-CASE (var1 var2 ....)
    (condition-name-1  forms...)
    (condition-name-2  forms..)
    (error             forms ...)  ;; for all conditions which are errors
    (:no-error     forms ...)  

This establishes a handler which selects one of its clauses to execute
by comparing condition-name to the condition actually signaled.  The
values of the last form in the clause are returned.  VAR1 is bound to
the condition-object which was signaled.  In the :NO-ERROR clause,
VAR2, etc.. are bound to the values returned by BODY before executing
the :no-error forms.

(CONDITION-CALL  (var1 var2 ...)
    (pred-1  handler-forms....)
    (pred-2  handler-forms ...)

The difference between this and CONDITION-CASE is the predicate in
each clause.  The clauses in a condition-call resemble the clauses of
a COND rather than those of a CASE.

(CATCH-ERROR body ) 
 If an error occurs it returns two values, NIL and NON-NIL.  The second value
indicates the occurence of an error.  If no error occurs, it returns
the value(s) of the last form in body.

 If an error occurs inside BODY, the first value returned is NIL and
the second is NON-NIL.  If no error occurs, the first value returned
is the first return value of the last form in BODY and the second
value is NIL.