perm filename CLERHA.MSG[COM,LSP]6 blob sn#807409 filedate 1986-01-30 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	Introduction
C00005 ENDMK
C⊗;
Introduction
Welcome to the Common Lisp Error Handling Subgroup.
In order to mail to this group, send to the address:

		CL-Error-handling@su-ai.arpa

Capitalization is not necessary, and if you are directly on the ARPANET,
you can nickname SU-AI.ARPA as SAIL. An archive of messages is kept on
SAIL in the file:

			   CLERHA.MSG[COM,LSP]

You can read this file or FTP it away without logging in to SAIL.

To communicate with the moderator, send to the address:

		CL-Error-handling-request@su-ai.arpa

Here is a list of the people who are currently on the mailing list:

Person			Affiliation	Net Address

Thomas Gruber		Univ. of Mass.	gruber.UMass-CS@csnet-relay
Kent Pitman		MIT		kmp@mc
Dave Matthews		HP		matthews.hplabs@csnet-relay (I hope)
Walter VanRoggen	DEC		wvanroggen@dec-marlboro
Jim Large		PERQ		Jim.Large@cmu-cs-spice
Mary Fontana		TI		fontana.ti-csl@csnet-relay
Carl Hewitt		MIT		hewitt-common-error@mc
Jerry Barber		Gold Hill	jerryb@mc
Bob Kerns		Symbolics	rwk@mc
Alice Hartley		BBN		hartley@bbn
David Moon		Symbolics	moon@scrc-stonybrook
Eric Benson		Lucid		eb@su-ai
Dan Weinreb		Symbolics	DLW@scrc-stonybrook

The first order of business is for each of us to ask people we know who may
be interested in this subgroup if they would like to be added to this list.

Next, we ought to consider who might wish to be the chairman of this subgroup.
Before this happens, I think we ought to wait until the list is more nearly
complete. 

∂23-Sep-84  1612	RPG  	Introduction  
To:   cl-error-handling@SU-AI.ARPA    
Welcome to the Common Lisp Error Handling Subgroup.
In order to mail to this group, send to the address:

		CL-Error-handling@su-ai.arpa

Capitalization is not necessary, and if you are directly on the ARPANET,
you can nickname SU-AI.ARPA as SAIL. An archive of messages is kept on
SAIL in the file:

			   CLERHA.MSG[COM,LSP]

You can read this file or FTP it away without logging in to SAIL.

To communicate with the moderator, send to the address:

		CL-Error-handling-request@su-ai.arpa

Here is a list of the people who are currently on the mailing list:

Person			Affiliation	Net Address

Thomas Gruber		Univ. of Mass.	gruber.UMass-CS@csnet-relay
Kent Pitman		MIT		kmp@mc
Dave Matthews		HP		matthews.hplabs@csnet-relay (I hope)
Walter VanRoggen	DEC		wvanroggen@dec-marlboro
Jim Large		PERQ		Jim.Large@cmu-cs-spice
Mary Fontana		TI		fontana.ti-csl@csnet-relay
Carl Hewitt		MIT		hewitt-common-error@mc
Jerry Barber		Gold Hill	jerryb@mc
Bob Kerns		Symbolics	rwk@mc
Alice Hartley		BBN		hartley@bbn
David Moon		Symbolics	moon@scrc-stonybrook
Eric Benson		Lucid		eb@su-ai
Dan Weinreb		Symbolics	DLW@scrc-stonybrook

The first order of business is for each of us to ask people we know who may
be interested in this subgroup if they would like to be added to this list.

Next, we ought to consider who might wish to be the chairman of this subgroup.
Before this happens, I think we ought to wait until the list is more nearly
complete. 

∂02-Oct-84  1312	RPG  	Chairman 
To:   cl-error-handling@SU-AI.ARPA    
Now that we've basically got most everyone who is interested on the mailing
list, let's pick a chairman. I suggest that people volunteer for chairman.

The duties are to keep the discussion going, to gather proposals and review
them, and to otherwise administer the needs of the mailing list. I will
retain the duties of maintaining the list itself and the archives, but
otherwise the chairman will be running the show. 

Any takers?
			-rpg-

∂03-Oct-84  1753	KMP@MIT-MC 	Breaking radio silence, chairing CL-ERROR-HANDLING   
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 3 Oct 84  17:53:15 PDT
Date: 3 October 1984 20:24-EDT
From: Kent M Pitman <KMP @ MIT-MC>
Subject:  Breaking radio silence, chairing CL-ERROR-HANDLING
To: RPG @ SU-AI
cc: cl-error-handling @ SU-AI
In-reply-to: Msg of 02 Oct 84  1312 PDT from Dick Gabriel <RPG at SU-AI.ARPA>

    Date: 02 Oct 84  1312 PDT
    From: Dick Gabriel <RPG at SU-AI.ARPA>

    ... I suggest that people volunteer for chairman ...

I'm willing to chair this list if people are agreeable to that.
-kmp

∂13-Oct-84  1442	RPG  	Chairman 
To:   cl-error-handling@SU-AI.ARPA    

Kent Pitman volunteered to be chairman of the Error Handling subgroup.  If
he is willing, and no one else volunteers, he will become chairman. Please
respond by October 24. At the end of this month I want to see some ideas
and proposals coming in on this mailing list.

			-rpg-

∂13-Oct-84  1521	HANDERSON@CMU-CS-C.ARPA 	Proposals and time limit 
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 13 Oct 84  15:09:25 PDT
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Sat 13 Oct 84 18:10:12-EDT
Date: Sat, 13 Oct 1984  18:10 EDT
Message-ID: <HANDERSON.12055196128.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   cl-error-handling@SU-AI.ARPA
Subject: Proposals and time limit
In-reply-to: Msg of 13 Oct 1984  17:42-EDT from Dick Gabriel <RPG at SU-AI.ARPA>


Presumably there are already some people listening.  I'd like to suggest that
before proposals are thrown around, we start discussing just what an error or
condition is, how the two interact, and what are necessary vs. gratuitous
aspects of a condition system (the last of which (especially) should be
answered by some reasonably experienced and uncommitted people).

-- Steve

∂13-Oct-84  1626	KMP@MIT-MC
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 13 Oct 84  16:24:26 PDT
Date: 13 October 1984 19:24-EDT
From: Kent M Pitman <KMP @ MIT-MC>
To: Handerson @ CMU-CS-C
cc: cl-error-handling @ SU-AI
In-reply-to: Msg of Sat 13 Oct 1984  18:10 EDT from Steven <Handerson at CMU-CS-C.ARPA>

    Date: Sat, 13 Oct 1984  18:10 EDT
    From: Steven <Handerson at CMU-CS-C.ARPA>

    ... I'd like to suggest that before proposals are thrown around, 
    we start discussing just what an error or condition is, how the 
    two interact, and what are necessary vs. gratuitous aspects of a 
    condition system ...

I'd like to start even more slowly by just defining the terms
to be used in our discussions.

The CL manual uses the terms "error", "signal", and "handle". It does
not use the term "condition", but perhaps we should introduce that
distinction (as the LispM does). My experience with using the LispM 
says that it is an important distinction to make.

In a manual put out by Symbolics entitled "Signalling and Handling
Conditions" they standardize on essentially the following terms (the
definitions of which I have mostly paraphrased here):

  The term "event" refers to "something that happens" during the 
   execution of a program.

  The term "condition" refers to a class of object which is associated
   with the occurrence of a particular kind of event in a program.

  The term "signal" refers to the action of reporting an event to other
   parts of the program which may be interested.

  The term "handle" refers to an action taken by some program as a 
   result of a signal.

  The term "error" denotes a particular type of condition which is 
   associated with an event that has been detected by a program as not 
   part of its contract. When an error condition is signalled, the 
   program may not proceed without the condition having been handled 
   somehow. This implication is not necessarily true of all conditions--
   only of error conditions.

I recommend that for our purposes the term "event" and the term
"condition" be merged and that both "something that happens" and the
object which represents that "something" be referred to as the
"condition". The rest of the terminology I recommend we adopt 
essentially as I've described it here.

As mentioned in the manual (p428), CL contains primitives to signal
errors, but no primitives for handling them. One important function of
this discussion must be to identify the primitives we need.

Also, since the manual does not treat [non-error] conditions,
it follows that CL has no primitives for signalling such conditions.
We may also want to decide if there should be some mechanism for
treating such conditions.

Does anyone disagree with any of the above and want to propose
modifications or alternatives?  First order of business should be to
standardize on as many terms as we can agree are useful so that we don't
end up talking across purposes.

-kmp

∂16-Oct-84  1331	DLW@SCRC-QUABBIN.ARPA 	Terminology of error-oloy  
Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 16 Oct 84  13:31:13 PDT
Received: from SCRC-CHICOPEE by SCRC-QUABBIN via CHAOS with CHAOS-MAIL id 91365; Mon 15-Oct-84 14:55:14-EDT
Date: Mon, 15 Oct 84 14:54 EDT
From: "Daniel L. Weinreb" <DLW@SCRC-STONY-BROOK.ARPA>
Subject: Terminology of error-oloy
To: KMP@MIT-MC.ARPA
cc: cl-error-handling@SU-AI.ARPA
In-Reply-To: The message of 13 Oct 84 19:24-EDT from Kent M Pitman <KMP at MIT-MC>
Message-ID: <841015145406.2.DLW@CHICOPEE.SCRC.Symbolics>

Your summary of the terminology is good.  Jan Walker and I established
the terminology while she was editing the document, and the word "event"
was introduced because it really turned out to be necessary to have a
word for that concept in order to be accurate and clear at the same
time.  You'll notice that the word "event" is hardly ever used after the
first few pages, which explain the fundamental concepts of the condition
mechanism.  It might turn out to be useful in this discussion; in any
case, it's likely that its meaning will be clear from context.

The exact definition of what constitutes an "error" is something that
has eluded me for a long time.  If a program has a bug such that it
computes the wrong result, but at no time actually signals anything,
then it has violated its contract and therefore is in error
nevertheless.  It can also be argued that if (/ 1 0) signals the
sys:divide-by-zero condition, then it was operating properly and
according to its contract, and therefore no error occurred.  On one
hand, I'd be happy to see a good resolution of these issues.  On the
other hand, it's probably a philosophical can of worms that need not be
opened in order for us to proceed.  I just thought I should mention that
there doesn't seem to be a completely good definition of "error".

One thing that we should all agree to is that an error is a synchronous
event; that is, it happens as a direct result of the execution of a
program, and it happens at a particular point in that program.  The
occurrance of an asynchronous event, like an interval timer going off,
or a network connection being broken due to a timeout, or any kind of
asynchronous "interrupt", is not an "error" in the sense we mean here.

∂16-Oct-84  1419	jml@cmu-cs-spice.arpa 	Re: Terminology of error-oloy   
Received: from CMU-CS-SPICE.ARPA by SU-AI.ARPA with TCP; 16 Oct 84  14:19:15 PDT
Date: Tuesday, 16 October 1984 17:12:18 EDT
From: Jim.Large@cmu-cs-spice.arpa
To: "Daniel L. Weinreb" <DLW@scrc-stony-brook.arpa>
cc: cl-error-handling@su-ai.arpa
Subject: Re: Terminology of error-oloy
Message-ID: <1984.10.16.20.50.30.Jim.Large@cmu-cs-spice.arpa>
In-Reply-To: <841015145406.2.DLW@CHICOPEE.SCRC.Symbolics>

   It might be easier to distinguish an "error" from the broader class of 
"conditions" by looking only at the point where the error is signalled.

   Perhaps an "error" is a condition signalled by some routine when
that routine has been given inconsistent inputs (its contract has been
violated by its caller) and it does not know what else to do.

   By this definition, division-by-zero is an error because it is the 
condition raised by the divide instruction when divide is given illegal
operands.
					-- Jim Large

∂16-Oct-84  1547	KMP@MIT-MC 	Terminology of error-oloy   
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 16 Oct 84  15:47:17 PDT
Date: 16 October 1984 18:49-EDT
From: Kent M Pitman <KMP @ MIT-MC>
Subject:  Terminology of error-oloy
To: Jim.Large @ CMU-CS-SPICE
cc: cl-error-handling @ SU-AI, DLW @ SCRC-STONY-BROOK
In-reply-to: Msg of 16 Oct 1984 17:12:18 EDT from Jim.Large at cmu-cs-spice.arpa

    Date: Tuesday, 16 October 1984 17:12:18 EDT
    From: Jim.Large at cmu-cs-spice.arpa

       It might be easier to distinguish an "error" from the broader class of 
    "conditions" by looking only at the point where the error is signalled.

       Perhaps an "error" is a condition signalled by some routine when
    that routine has been given inconsistent inputs (its contract has been
    violated by its caller) and it does not know what else to do.

       By this definition, division-by-zero is an error because it is the 
    condition raised by the divide instruction when divide is given illegal
    operands.

I believe the point Dan was trying to raise was the more subtle one that
functions may signal an error when they get inconsistent inputs is fine,
but to say they must signal an error when they get inconsistent inputs is
in fact contradictory. It is the same as saying that the program is defined
to work in a certain way when it is not defined to work. It's a messy
point. My intuition is that we should avoid any definition of error which
refers to the program's contract.

I spoke with Albert Meyer about this problem and he said the theory of
computation people don't have any agreement on the issue either. His advice
was just to muddle through it as best we could.

How about if we modified the definition to simply say that if a given 
lexical contour signals an "error" (as contrasted with a "condition") 
then it cannot be proceeded without externally provided advice about how to
proceed (ie, handling of some sort). People will typically use such a 
facility to deal in ways that relate to contract violation, but that will 
just be a point of style, not a point of definition.
-kmp

∂16-Oct-84  1630	HANDERSON@CMU-CS-C.ARPA  
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 16 Oct 84  16:29:57 PDT
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Tue 16 Oct 84 19:28:22-EDT
Date: Tue, 16 Oct 1984  19:28 EDT
Message-ID: <HANDERSON.12055996789.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   Kent M Pitman <KMP@MIT-MC.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
In-reply-to: Msg of 13 Oct 1984  19:24-EDT from Kent M Pitman <KMP at MIT-MC>


Actually, I disagree with the terminology.  "Event" is fine.  However, you're
presuming that there will be a "condition object" associated with a particular
event, and I think there may be some other issues we need to get through first.
I think condition should be reserved to mean "an event deemed interesting by
CL".  That way, we can talk about whether an event is a condition or not.  I
also think less-common word should be used for the things that may eventually
be created - perhaps the phrase "condition object" or somesuch (we don't need
to agree what this is yet).  One would then signal conditions, not events.

A letter I will try to write later this evening will talk about error and some
other related issues.  It will probably also lead the discussion further, so
messages realting to terminology should probably try to reach a conclusion.
Moon has flamed at me for reserving nice words for flavor stuff - I think nice
words should only refer to non-implementation things.

-- Steve

∂16-Oct-84  1712	KMP@MIT-MC 	more on terminology    
Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 16 Oct 84  17:12:37 PDT
Date: 16 October 1984 20:15-EDT
From: Kent M Pitman <KMP @ MIT-MC>
Subject:  more on terminology
To: Handerson @ CMU-CS-C
cc: cl-error-handling @ SU-AI
In-reply-to: Msg of Tue 16 Oct 1984  19:28 EDT from Steven <Handerson at CMU-CS-C.ARPA>

    Date: Tue, 16 Oct 1984  19:28 EDT
    From: Steven <Handerson at CMU-CS-C.ARPA>

    Actually, I disagree with the terminology.  "Event" is fine.
    However, you're presuming that there will be a "condition object"
    associated with a particular event, and I think there may be some
    other issues we need to get through first.  I think condition should
    be reserved to mean "an event deemed interesting by CL".  That way,
    we can talk about whether an event is a condition or not.  I also
    think less-common word should be used for the things that may
    eventually be created - perhaps the phrase "condition object" or
    somesuch (we don't need to agree what this is yet).  One would then
    signal conditions, not events...

Actually, I don't think we disagree on this. This is certainly a
restatement of what I intended to say. If it makes it clearer to
rephrase it this way, I'm happy.

The reason I had proposed eliminating the word "event" was that I
thought it presupposed the existence of objects representing conditions
and I wanted to avoid terminology that forced an object-oriented view of
error handling. Indeed, I think that "condition" is a fine name for what
the LispM documentation calls "events" and I agree that if we ever adopt
an object-oriented view, we should call the objects which represent
conditions "condition objects".

The word "event" is too generic to lock down for any use even so specific
as condition raising, which is another reason I wanted to free it. I don't
think it is fair to assign it technical meaning.
-kmp

∂16-Oct-84  1814	HANDERSON@CMU-CS-C.ARPA 	more on terminology 
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 16 Oct 84  18:14:39 PDT
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Tue 16 Oct 84 21:12:53-EDT
Date: Tue, 16 Oct 1984  21:12 EDT
Message-ID: <HANDERSON.12056015810.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   Kent M Pitman <KMP@MIT-MC.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
Subject: more on terminology
In-reply-to: Msg of 16 Oct 1984  20:15-EDT from Kent M Pitman <KMP at MIT-MC>


No, I don't see event being used for much else.  We do need something to
replace it if we do, because otherwise condition would have two meanings.  
Why don't we just capitalize everything and be done with it?

-- Steve

∂16-Oct-84  1958	HANDERSON@CMU-CS-C.ARPA 	Error-ology    
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 16 Oct 84  19:58:02 PDT
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Tue 16 Oct 84 22:56:10-EDT
Date: Tue, 16 Oct 1984  22:56 EDT
Message-ID: <HANDERSON.12056034618.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   "Daniel L. Weinreb" <DLW@SCRC-STONY-BROOK.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA, KMP@MIT-MC.ARPA
Subject: Error-ology


Your letter seems to suggest this: Whether a condition (event) is @i(errorful)
depends upon the particular code being executed, as well as the lexical and
dynamic environment.  I think this is all we really need to say.  A program
being @i(in error) is a different thing entirely, although it is likely that
one grossly in error will eventually come to an errorful event.

Actually, I guess there is more.  One way a program can be in error is not to
handle a given condition.  If conditions are globally named and dynamically
scoped, a handler for a condition in one program segment may inadvertantly
handle the same condition in another segment.  The solution to this - some
means of explicitly manipulating the conditions associated with a function -
would probably lead to a better condition system, but it might also lead to
some language other than CL.  I still think it would be a mistake to not think
about this.

The set of conditions an implementation (or CL) has is chosen on the basis of
what events will cause unpredictable or inconsistent (in the sense of math, the
CL manual, etc) results.  The condition handling mechanism provides a way that
programs can recover from such events by providing their own interpretation of
what to do next.  For instance, short-floats do not overflow into long floats
because of the change in precision; some application may decide to remember the
precision itself, ignore the precision, etc.  I doubt many handlers will be
comlpicated, but if so, it would be nice if handlers could be filed away (for
instance, were normal functions).

Also, the distinction between an error's occurrence and detection is an
important one.  In general, you can't detect an error itself (except through
varying degrees of code analysis), only some errorful consequence.  This may
actually be important if we have to talk about (asynchronous?) errors in "jobs"
given to slave processes - the "error" might be in the master.

-- Steve

∂17-Oct-84  1127	FONTANA%ti-csl.csnet@csnet-relay.arpa 	Terminology of error-ology
Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 17 Oct 84  11:27:22 PDT
Received: from ti-csl by csnet-relay.csnet id a000485; 17 Oct 84 12:55 EDT
Date: 17 Oct 1984 1144-CDT
From: Mary <Fontana@TI-CSL>
Subject: Terminology of error-ology
To: cl-error-handling@SU-AI
Received: from csl60 by ti-csl; Wed, 17 Oct 84 11:50 CST



I think a condition should be an event or some exceptional situation
detected in your program.  An error is a condition which when
signalled will be handled by an interactive debugger (error handler)
if no other handler handles it first.  A program can signal a
condition or an error and define its own handlers.  An error always
has at least one handler - the error handler, which invokes an
interactive debugger. 


-- Mary Fontana

  Fontana@ti-csl
-------

∂17-Oct-84  1529	HANDERSON@CMU-CS-C.ARPA 	Terminology of error-ology    
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 17 Oct 84  15:29:37 PDT
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Wed 17 Oct 84 18:25:59-EDT
Date: Wed, 17 Oct 1984  18:25 EDT
Message-ID: <HANDERSON.12056247570.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   Mary <Fontana.Ti-Csl@CSNET-RELAY.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
Subject: Terminology of error-ology
In-reply-to: Msg of 17 Oct 1984  12:44-EDT from Mary <Fontana at TI-CSL>


Yeah, that's what I was thinking, but I don't think it's particularly valuable
to define an error that way.  Error can and should be thought of in many
contexts, and I don't think "condition with a debugger handler" needs a new
name - I think "errorful condition" is enough.  Condition can too, but I think
it's only other major meaning is Event.

Just to be argumentative, I don't think you need every condition to have a
handler - for some applications, the debugger may be inappropriate.  Perhaps as
a matter of style you do, and obviously you don't want the "no handler"
condition to have no handler.

-- Steve

∂17-Oct-84  2222	Moon@SCRC-QUABBIN.ARPA 	Proposed agenda 
Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 17 Oct 84  22:21:52 PDT
Received: from SCRC-EUPHRATES by SCRC-QUABBIN via CHAOS with CHAOS-MAIL id 92350; Thu 18-Oct-84 01:21:12-EDT
Date: Thu, 18 Oct 84 01:21 EDT
From: "David A. Moon" <Moon@SCRC-RIVERSIDE.ARPA>
Subject: Proposed agenda
To: CL-error-handling@SU-AI.ARPA
Message-ID: <841018012150.2.MOON@EUPHRATES.SCRC.Symbolics>

Here is a list I made some years ago of issues that ought to be addressed
by the Common Lisp "error-handling system".  I have updated the list
somewhat from what I wrote back then, in case anybody has seen it before.
Perhaps this will be helpful in focussing the discussion on something more
concrete than terminology.


Recognize that we want to deal in ERRORS (events that prevent the program
that detected the event from continuing to execute without intervention),
NON-ERROR CONDITIONS (events that can safely be ignored), and DEBUGGER
CONDITIONS (events that prevent the program that detected the event from
continuing to execute without intervention, but ought not to be intercepted
by "catch all errors" mechanisms).

Provide names for unusual conditions (including but not limited to errors)
and a taxonomic system for classifying those names.  A name can be defined
to include one or more other names; this inclusion relation is transitive.
For example, division-by-zero includes arithmetic-error; no-such-version
includes file-not-found, which in turn includes file-error.  All of the
above include error, a very general condition name.  If X includes Y, then
X is a more specialized version of Y.  This taxonomic system makes it
possible to handle generic classes of errors, as well as specific errors.

Add SIGNAL, which is like WARN but doesn't print anything if the condition
is not an error and not a debugger condition.

Extend ERROR, CERROR, WARN, SIGNAL, and BREAK to permit signalling conditions
by name.  (Perhaps also extend CHECK-TYPE and ASSERT the same way).  If
a symbol appears where the current syntax calls for a format-string argument,
the symbol is the name of the condition.  The interpretation of the remaining
arguments after the symbol depends on the particular condition.  A common
technique is to take the next argument after the symbol to be a format string
and the remaining arguments to be arguments to that format string.  Another
common technique is for the condition name to imply the format string and
for the remaining arguments to be &key arguments that specify various relevant
quantities.  Since any program that signals a condition must necessarily
understand the meaning of that condition, there is no need to enforce a
uniform protocol on these arguments, just as there is no need for all functions
to take exactly the same arguments.

Ways to establish condition handlers, so that programs may respond to
conditions, by throwing out, by continuing, or by correcting the reason for
the condition and retrying.  We have developed a number of special forms
that are convenient to use in this context; the most useful subset includes
CONDITION-BIND, CONDITION-CASE, IGNORE-ERRORS, and CATCH-ERROR-RESTART,
although there are several others that may or may not be worthwhile.

Ways to define the behavior and relationships of conditions.  This
presumably involves a DEFINE-CONDITION special form that defines the name
of the condition, the names of the conditions that it includes, the
arguments to be supplied when signalling the condition, documentation, and
control over how the condition prints its error message and how it can be
recovered from.

Define the protocol by which a condition handler can obtain the arguments
that were supplied when the condition was signalled, can determine what
ways of recovering from the condition are available and invoke one of them,
and can choose either to supply values needed for recovery or to let the
condition system prompt the user interactively for the values.  This
involves a three-way handshake between the program that signalled the
condition, the program that handled the condition, and the condition
definition (which acts as the interface between the other two).  We have
developed the concept of "proceeding" and "proceed types" for this purpose.

Ways to use conditions as inter-module interfaces.

Ways to use conditions to customize the behavior of the interactive
debugger.  Ways to use condition handlers to write new interactive
debuggers for specialized applications.

--- other related issues ---

Formalization of the notion of "aborting a program," and provision of
mechanisms to define where control will be thrown to when the program is
aborted, as well as a function to abort the program.  This is more
complex than it seems because of interaction with the interactive
debugger and the condition system.

Standardization of conditions signalled by the system for various "signals
an error" cases.  Standardization of conditions signalled by those
implementations that do signal errors in various "is an error" cases.
Portable floating-point exception, overflow, and rounding control, with
some provision for different levels of implementation of the standard by
different systems, depending on their hardware.

Facilities making it possible for a user to write a portable debugger.
This is a major project.

A way to define the default description string for a user-defined type,
used when CHECK-TYPE is called with only two subforms.  This can of
course be a function of the type's parameters when the type is not
simply a symbol.

∂19-Oct-84  0048	HANDERSON@CMU-CS-C.ARPA 	Proposed agenda
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 19 Oct 84  00:47:49 PDT
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Fri 19 Oct 84 03:42:45-EDT
Date: Fri, 19 Oct 1984  03:42 EDT
Message-ID: <HANDERSON.12056611081.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   "David A. Moon" <Moon@SCRC-RIVERSIDE.ARPA>
Cc:   CL-error-handling@SU-AI.ARPA
Subject: Proposed agenda
In-reply-to: Msg of 18 Oct 1984  01:21-EDT from David A. Moon <Moon at SCRC-RIVERSIDE.ARPA>


I agree that there needs to be some taxonomic error handling system.  Catching
all errors just means catching all conditions that are more specific conditions
than the ERROR condition.  However, I disagree with your statement that there
is something fundamentally different about error conditions besides their
handlers.  I think Mary Fontana agrees with me here.  Is there anyone else out
there?  Hello?

I also disagree with the idea that we have to interface to ERROR, CERROR, etc.
The whole point of signal is that the handler gets to decide whether to halt
execution, invoke the debugger, etc.  Indeed, a handler might use ERROR or
CERROR as a result of it's operation.  If you KNOW at the point of error that
you can't proceed, you use ERROR to tell the user why.  The only reason ERROR
would want to signal a condition is if the act of signalling computed some
other information, which sounds more like a case for modular programming than
error handling.  If all else fails, you can always write a function FOOME-ERROR
that performs the relevant computation and calls ERROR.

I am entirely grossed out by the thought of using conditions as inter-module
interfaces.  Obviously, it is PART of the interface, in the same way that
function names, function arguments, and specials are, but none makes up an
entire interface.

CONDITION-BIND and -CASE sound ok, I suppose.  IGNORE-ERRORS and maybe even
CATCH-ERROR-RESTART sound like they should be implemented in terms of something
else.  "Proceed types" and argument protocol are going to be the biggies.

-- Steve

∂24-Oct-84  0236	HANDERSON@CMU-CS-C.ARPA 	Start of a proposal 
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 24 Oct 84  02:36:44 PDT
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Wed 24 Oct 84 05:36:38-EDT
Date: Wed, 24 Oct 1984  05:36 EDT
Message-ID: <HANDERSON.12057942529.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   Steven <Handerson@CMU-CS-C.ARPA>
Cc:   CL-error-handling@SU-AI.ARPA
Subject: Start of a proposal
In-reply-to: Msg of 19 Oct 1984  03:42-EDT from Steven <Handerson>


Here is a collection of some of my own (recent) ideas on how things should
work.  I thought I'd see if anyone has any reactions or suggestions based on
what I can throw together.  I haven't thought at all about compatibility or the
more esoteric aspects, just simplicity.  

I haven't thought about proceeding much, but the bit about whether to prompt or
not sounds bogus.  Why not just have different proceed types, some that prompt
that the debugger uses, and some that don't for normal handlers?  The first can
call the second.  I do think that proceed types deserve some special mechanism.

----

I basically agree with the idea that signalling a condition makes an explicit
condition object of some form, and that handling a condition consists of
performing operations on this object.  Proceed types are a kind of operation.
Condition objects naturally have some internal state (if nothing else, the
arguments to signal), which I will call instance variables, not to be confused
with those found in Flavors.

I propose that we not get into the idea of "combining" operations, since that's
messy.  I propose the only rule we adopt is that operations of more specific
conditions shadow the more general ones.  I propose that an error be signalled
when there are two candidates for inheritance (as in A and B have operations
:foo, and C is a kind of A and a kind of B); usually the desired operation is a
hybrid, and having the system pick one is just one more pointless thing to
remember and abuse.  [Operations will be normal functions, in which case you
would be able to stick the same one two different places easily.]  Operations
can still interact by calling eachother.

A condition has some required and some optional arguments, some of which may be
inherited from more general conditions.  In addition, some more specific
conditions may be able to construct the more general arguments, so that
arguments previously required are now optional, or what were supplied are now
computed.  In fact, computed arguments are indistinguishable in function from
values cached in instance variables.  I propose that rather than trying to
untangle these things, we just use a disembodied property list as the
internal state.  If the arguments to signal are just paired argument name -
value, all we need to do to get the condition object is make it a list.
A cursory investigation has shoen other approaches to be either complicated or
gross. 

Of course, this does need some discipline.  I think that all that really needs
to be done is to help the user figure out what's required and what's optional.
This can be accomplished with describe and by warning at compile time about
either missing required arguments or unknown arguments.  Also, if Flavors users
can keep from tripping over other instance variables, then there shouldn't be
much problem with condition instance variable conflicts.

Something that would be nice would be a standard (automatic) way of specifying
how various optional instance variables are calculated from the supplied ones.
A simple mechanism would be to have the iv-referencing primitive send the
condition a message [the variable name] if it isn't in the plist.  A more
specific condition that no longer requires some argument simply provides an
operation that can calculate it.

∂27-Oct-84  2150	RPG  	Hello folks   
To:   cl-error-handling@SU-AI.ARPA    

We now have a chairman of the error handling subgroup:  Kent Pitman of
MIT. I think he will make an excellent chairman.  For your information I
am including the current members of the mailing list.

I will now let Kent Pitman take over responsibility for the discussion.

Dave Matthews		HP		"hpfclp!errors%hplabs"@csnet-relay
John Foderaro		Berkeley	jkf@ucbmike.arpa
Thomas Gruber		Univ. of Mass.	gruber.UMass-CS@csnet-relay
Kent Pitman		MIT		kmp@mc
Walter VanRoggen	DEC		wvanroggen@dec-marlboro
Jim Large		PERQ		Jim.Large@cmu-cs-spice
Mary Fontana		TI		fontana.ti-csl@csnet-relay
Carl Hewitt		MIT		hewitt-errors@mc
Jerry Barber		Gold Hill	jerryb@mc
Bob Kerns		Symbolics	rwk@mc
Alice Hartley		BBN		hartley@bbn
David Moon		Symbolics	moon@scrc-stonybrook
Eric Benson		Lucid		eb@su-ai
Dan Weinreb		Symbolics	DLW@scrc-stonybrook
Steve Handerson		CMU		handerson@cmuc
Jim Larus		Berkeley	larus@berkeley
Neal Feinberg		Symbolics	feinberg@scrc-stony-brook

∂30-Oct-84  1911	HANDERSON@CMU-CS-C.ARPA 	More about proposal 
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 30 Oct 84  19:11:43 PST
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Tue 30 Oct 84 22:11:32-EST
Date: Tue, 30 Oct 1984  22:11 EST
Message-ID: <HANDERSON.12059707416.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   cl-error-handling@SU-AI.ARPA
Subject: More about proposal
In-reply-to: Msg of 28 Oct 1984  00:50-EDT from Dick Gabriel <RPG at SU-AI.ARPA>


I've been reading the Symbolics documentation and thinking about proceed types.
The criteria a proceed type may use to determine whether it can proceed or not
may not be simple.  I haven't the experience to give an example, but the idea
of passing a list of the usable proceed types sounds forced.  Ideally, a
proceed type should be able to decide itself, based on the condition object and
any other environmental information it can determine.  [It can look for itself
in a supplied list of proceed types, if it wants.]

I propose a notion of an operation @i(failing), which can basically be
implemented as the operation's function returning some special value.  If an
operation fails unexpectedly, it's a bug, and the system invokes ERROR.  If the
operation was invoked using a special catching form, the handler can cause an
expression to be evaluated instead.

Does anyone have any comments whatsoever on my proposal so far?  If you think
it's too simple, we're only in the error-handling business, not programming in
general.  I agree it's slightly messy as stated, but a little attention might
smooth out the rough edges.  The slowest part in relation to a Flavors
implementation will be the assoc list of instance variables, and I don't
anticipate enough of them to make much of a difference.

-- Steve

∂17-Nov-84  1818	HANDERSON@CMU-CS-C.ARPA 	Proposal someday soon?   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 17 Nov 84  18:17:50 PST
Received: ID <HANDERSON@CMU-CS-C.ARPA>; Sat 17 Nov 84 21:17:24-EST
Date: Sat, 17 Nov 1984  21:17 EST
Message-ID: <HANDERSON.12064416171.BABYL@CMU-CS-C.ARPA>
From: Steven <Handerson@CMU-CS-C.ARPA>
To:   cl-error-handling@SU-AI.ARPA
Subject: Proposal someday soon?
In-reply-to: Msg of 30 Oct 1984  22:11-EST from Steven <Handerson>


I've had a few additional thoughts (starting with EXCEPTION HANDLING) since my
last series of posts, which seem to be leading up to a proposal.  I've had a
few important thoughts, so I'll give those to you now.  Any questions or
comments would be appreciated.

When I'm defining a term, I use italics (just like textbooks).  I quote
"cutesy" terms.  This also contains one or two humorous analogies.  

QUESTION:

Is there any reason to have an explicit condition object to pass around?
If you can hide this from the user, you need not fear reusing storage
(of course, that presupposes a uniform representation...).  

SUMMARY

I'm presuming a lot by taking these to be the current sway of the group.

The error system should probably be as powerful as we can reasonably make it.
It has been suggested that all you really need might be something like binding
a special; if so, you can easily do this yourself.  The condition system is for
hairier cases.  Various forms of language extensions (such as making objects
that masquerade as a new type) are also better dealt with using some other
mechanism, to prevent interactions with "normal" conditions.

We define our condition system to only handle synchronous events.  Presumably
an errorful condition resulting from a (more abstract) event will be signalled
dynamically inside the call that lead to it (and presumably knows how to handle
it).  If not, perhaps binding a more complicated handler earlier can deduce
from the environment which event has occurred.  It is the purpose of the
condition system to determine what abstract event has occurred and to invoke
the appropriate corrective code.

We want taxonomic error handling, as described by Moon.  This is actually where
most of the complexity comes from.  If all the conditions have arguments, then
we need some way of converting the arguments of a specific condition into those
of a more general one.  This is the crux of my proposal - I think some sort of
object-system fits in well, but it should be simple and specific enough so that
nobody feels left out, or pained to implement something huge (my proposal
will be almost entirely portable code, except for the implementation-dependent
signalling of system errors).

EXCEPTION HANDLING

The whole point of exception handling in most languages is to make the normal
cases go fast by simplifying the initial tests for exceptions.  If some simple
test as part of the calculation can prove that there is no error, you get error
checking practically for free.  Hence the idea that an errorful event is
detected via some errorful consequence.  The majority of these initial tests
are things that concern the language's integrity, and so should be dealt with
anyway; things like taking the car of 3 [I think these should be called
@i(system errors)].

ABSTRACTION

An event can often be viewed at several different levels of abstraction.  The
lowest is at the system error that caused its detection.  This can be
characterized in different ways, using the inclusion relation.  However, if one
uses implication (which depends upon the code), you're dealing with different
levels of abstraction.

Example:
"What's that?"
"It's condition SYS:DIVIDE-BY-ZERO."
"What's that?"
"An arithmetic error."
"What does that mean?"
(looks at code) "Well, here it means the user's input is inconsistent."

Revelation!  Handlers don't just handle errors; they actually determine (by
"looking at the code" whether a given (abstract) event has occurred.  This is
probably why handlers want to abstain; they figure out that the abstract
condition they handle hasn't occurred.  Defining errors inline would probably
be pretty clumsy; such things can be as complicated as the code.  Instead, I
think that we should investigate what it means to have a handler signal another
(more abstract) condition, which can be done in existing systems (and probably
is, occasionally).

Looked at this way, the purpose of the condition system is to determine the
appropriate abstraction of the event and @b(then) the action to be taken.
Hence it's reasonable to do things like (ERROR 'my-condition), because the
sequence of handlers can determine things about the error that might be useful
to the user.  Still, I think we need to be careful with exactly what these
forms do.

For example, I think it's quite possible that you'd want to signal a condition
IN CASE it's handled (at some level of abstraction).  System errors of course
can't be @i(continued) in the CL manual sense, but this could be what ERROR is
for.  Hence, @i(errors) (conditions signalled with ERROR) are proceedable, but
not continuable.  Errors signalled with CERROR are continuable and proceedable.

THE DEBUGGER

The debugger is a special beast, because the user is a special beast.  It
should be able to access all abstractions of the signal chain.  I think how
this is to be done is pretty (error-system-) implementation dependent, but the
basic idea is that you can go down into the stack and say "what are the proceed
options for this level?"  The portable code could have some hook for this.

The debugger complicates the notion of proceed types slightly.  Ideally, it
should know which proceed types it can invoke (and ask the user rather than
insisting it be in the arguments).  This changes with whether the handler was
invoked with ERROR, whether the proceed type returns from the signal form or
not, the signalled arguments, etc.  These aren't really general problems, and
my proposal will suggest one way of dealing with them.

I've also considered something that might be analogous to Symbolic's @i(special
commands).  These are like proceed types, but they're just designed to give the
debugger user more information about the error.  The more of this that gets
standardized, the better, but some implementation might want to expand on them.
The worst that can happen is that they not be used in portable code.  Again,
somebody might have better ideas of how to provide this kind of thing.

HANDLERS

The next paragraph assumes you know about the Symbolics implementation of
handler binding.  Basically there are several binding lists, which store pairs
of a handler function and the condition it's bound to.  When an error is
signalled, the lists are cdr'ed down in order until a handler binding of the
signalled condition or a condition that includes it is encountered.  Normal
bindings are consulted first, then default bindings (implementing "bind unless
condition already handled"), then "restart handlers" (self-descriptive), and
some fourth thing I forgot about.

I think there should be two kinds of handlers: the kind that handle and the
kind that deduce a more abstract event.  Restart handlers and such would be
normal handlers of some abstract and serious condition, like
EDITOR:USER-INPUT-GARBAGED.  This works fine if you change levels of
abstraction only after all handlers [all handlers that should, anyway] have a
crack at the current level .  Thus, in addition to the normal and default
bindings, there should be an "abstraction handler" binding list which gets
looked at after the other two.  Realize that "abstraction handlers" may be on
the normal binding list, for instance if a code segment doesn't want the
original error to escape to surrounding code.  Basically, if a piece of code
expects an error, it should bind a handler as close to the source as possible
that, if nothing else, signals a condition that better describes the event.

I suggest that people not worry too much about reaching inside other people's
code; designing good interfaces and clean code is generally more of a win.  If
you can make wine out of water, fine, but hacks only lead to more hacks (don't
give ME a bottle of water to get drunk on).  No, I don't think handlers should
be examining the stack (except the debugger, but that's special).

The whole process of selecting a handler is marginally complex.  A handler
selected for the originally signalled condition may be an "abstraction
handler", in which case it signals another condition.  If this returns nil,
then it hasn't been handled, and the handler probably returns nil itself,
allowing some other abstraction a chance.  Otherwise, it's up to the handler to
arrange that proceeding the new handler does the appropriate thing with the
previous condition object.

ALMOST EXAMPLE

If you were implementing an interpreter for some other (lispy) language in
Common Lisp, you'd want to map events in Common Lisp into those in the new
language.  Handlers for system errors would push the interpretation level, and
signal some new-language condition, depending upon what was being interpreted
and the lisp system error signalled.  If the interpreter functions were
quantized, there would be no reason to proceed a lisp error; the handlers could
just restart the current new-language primitive (perhaps by throwing to a catch
around all the primitives functions).  In fact, the proceed types of the
new-language condition objects could do this directly, and the lisp handler
would just notice the abstraction.  Unexpected errors would not get abstracted
(presuming you bound the abstraction handler close enough to the source), and
would cause the interpreter to bomb out.

Other examples?

∂07-Feb-85  1612	FONTANA%ti-csl.csnet@csnet-relay.arpa 	New year error handling   
Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 7 Feb 85  16:12:07 PST
Received: from ti-csl by csnet-relay.csnet id aa01387; 7 Feb 85 18:59 EST
Date:  7 Feb 1985 1634-CST
From: Mary <Fontana%ti-csl.csnet@csnet-relay.arpa>
Subject: New year error handling
To: cl-error-handling@su-ai.ARPA
Received: from csl60 by ti-csl; Thu, 7 Feb 85 17:00 CST

I haven't seen anything from this committee since last year in October.
Have we resolved any of the following?

Definition of a condition and an error:
 - A CONDITION refers to "something that happens" during the
execution of a program.
 - An ERROR is a particular type of condition which is
associated with an event that has been detected by a program
as not part of its contract. When an error condition is
signalled, the program may not proceed without the condition
having been handled somehow. This implication is not
necessarily true of all conditions-- only of error conditions.
 - A CONDITION OBJECT represents a condition.  Holds
information about the particular condition, such as the message
describing the error, ways to proceed, data used by the
condition handler, ...

Creating a condition
  Like, MAKE-CONDITION or DEFSIGNAL

Signalling a condition.
  SIGNAL, ERROR, CERROR, .... (allow an argument for a condition name).

Establishing a handler.
   IGNORE-ERRORS, CATCH-ERROR, CONDITION-BIND, CONDITION-CASE,
CONDITION-CALL.  

What about resume handlers?  
Establish resume handlers with ERROR-RESTART, ERROR-RESTART-LOOP, 
CATCH-ERROR-RESTART, or CATCH-ERROR-RESTART-EXPLICIT-IF.

Proceeding & Proceed Types?
  Defined when create the condition object.  Also, CERROR and SIGNAL
provide ways to specify proceed types.  Rusume Handlers define proceed
types. (I didn't follow what Steve was proposing here last year).
  
What is the signalling mechanism?
  I'm assuming that functions, such as ERROR and SIGNAL, will "signal
a given condition" which means the system  first searches a list of
condition handlers for a previously established handler associated
with this condition.  If one is found invoke it,  otherwise (possibly)
invoke the Debugger. And finally look down a list of resume handlers.

-------

∂07-Feb-85  1646	KMP@SCRC-QUABBIN.ARPA 	New year error handling    
Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 7 Feb 85  16:45:52 PST
Received: from CHAGRIN by SCRC-QUABBIN via CHAOS with CHAOS-MAIL id 131429; Thu 7-Feb-85 19:45:56-EST
Date: Thu, 7 Feb 85 19:47 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: New year error handling
To: Fontana%ti-csl.csnet@CSNET-RELAY.ARPA
cc: cl-error-handling@SU-AI.ARPA
In-Reply-To: The message of 7 Feb 85 17:34-EST from Mary <Fontana%ti-csl.csnet@csnet-relay.arpa>
Message-ID: <850207194706.3.KMP@CHAGRIN.SCRC.Symbolics.COM>

    Date: 7 Feb 1985 1634-CST
    From: Mary <Fontana%ti-csl.csnet@csnet-relay.arpa>

    I haven't seen anything from this committee since last year in October.
    Have we resolved any of the following? ...

Yes, nothing has been sent recently. As you will recall, the discussion was
not going anywhere because we were
      (a) going in circles on terminology 
 and  (b) speaking at too detailed a level. Handerson's "proposals" were the
          sort of thing that really belonged on CL-OBJECT-ORIENTED-PROGRAMMING,
          where he finally diverted his interest.
In fact, I also wanted to wait a little and see what the object people came 
up with, but that discussion is not moving very quickly either.

So, trying to figure out how to salvage this design effort, I went back to
the drawing board and worked out a complete proposal (and implemented it 
in Maclisp to see how it feels -- which was pretty good). I think it will
serve as a reasonable basis of discussion. I've been changing jobs over the
last two weeks, so have been slow in getting it out to the list, but I'll
up its priority and try to get it on the record for you all to look at sometime
within the next day or so.
-kmp

∂08-Feb-85  0032	KMP@SCRC-STONY-BROOK.ARPA 	Stripped down version of LispM error system
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 8 Feb 85  00:32:25 PST
Received: from CHAGRIN by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 174758; Fri 8-Feb-85 03:36:57-EST
Date: Fri, 8 Feb 85 03:33 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Stripped down version of LispM error system
To: CL-ERROR-HANDLING@SU-AI.ARPA
In-Reply-To: <850207194706.3.KMP@CHAGRIN.SCRC.Symbolics.COM>,
             The message of 7 Feb 85 17:34-EST from Mary <Fontana%ti-csl.csnet@csnet-relay.arpa>
Message-ID: <850208033355.8.KMP@CHAGRIN.SCRC.Symbolics.COM>

The following proposal amounts to a stripped down version of what the
LispM provides. Most of the stripping down has to do with hiding
the fact that the LispM had flavors to play with and I didn't want
to depend on that.

I have an implementation of this for Maclisp. I'll see about working
out a CL implementation from that. I don't think it will be hard.

If any parts of this seem vague, let me know and I can elaborate. 
This message covers really only technical details. I have given a lot
of thought on how to describe this conceptually and will do so under
separate cover at a later date.

Anyway, maybe this will give everyone something concrete to center the
discussion around.
-kmp

!

(SIGNAL condition-type key1 val1 key2 val2 ...)		Function

  Signals a condition of the given CONDITION-TYPE with attributes
  given in keyed format. (Note: the keys are not keywords, but 
  packaged symbols.)

  If the signal is not handled, then some default action will be
  taken. The default for ERROR and conditions built on ERROR is 
  to enter the debugger. The default for other conditions is to 
  return NIL.

  Example:

	(SIGNAL 'BAD-FOOD-COLOR
		'FOOD  'MILK
		'COLOR 'GREENISH-BLUE)

	This signals a BAD-FOOD-COLOR condition, providing information
	to the condition that the FOOD was MILK and the COLOR was
	GREENISH-BLUE.

!

(SIGNAL-CASE (condition-type
	      key1 key-value1
	      key2 key-value2
	      ...)
  ((proceed-type-1 . bvl1) . body1)
  ((proceed-type-2 . bvl2) . body2)
  ...)							Special Form

  Signals a condition of the given CONDITION-TYPE with attributes
  as given by the KEYs and KEY-VALUEs. The CONDITION-TYPE and KEYs
  are not evaluated, but the KEY-VALUEs are.

  If the condition is not handled, the default action is according to 
  the rules for the simple case of SIGNAL.

  If the condition is handled, it may be proceeded by calling a proceed
  function which has the name of a PROCEED-TYPE given in the body of the
  SIGNAL-CASE. (The only valid names for PROCEED-TYPEs are those 
  that have been defined using DEFINE-PROCEED-TYPE.) If a proceed function
  is called, the BODY of its corresponding in the SIGNAL-CASE is executed
  with the variables in its BVL bound to the arguments given the proceed
  function, and the return value of that BODY becomes the return value of
  the SIGNAL-CASE.

  Example:

	(LET ((MY-FOOD       'MILK)
	      (MY-FOOD-COLOR 'GREENISH-BLUE))
	  (DO ()
	      ((REASONABLE-COLOR-FOR-FOODP FOOD COLOR))
	    (SIGNAL-CASE (BAD-FOOD-COLOR
			  FOOD  MY-FOOD
			  COLOR MY-FOOD-COLOR)
	      ((USE-COLOR NEW-COLOR) (SETQ MY-FOOD-COLOR NEW-COLOR))
	      ((USE-FOOD  NEW-FOOD)  (SETQ MY-FOOD       NEW-FOOD))))
	  (LIST MY-FOOD MY-FOOD-COLOR))

	This signals a BAD-FOOD-COLOR condition, specifying that FOOD 
	was MY-FOOD and COLOR was MY-FOOD-COLOR. If the caller wants 
	to proceed the condition, he may do something like:

		(USE-COLOR condition 'WHITE)
	     or (USE-FOOD  condition 'CHEESE)

	In this case, the return value of the SIGNAL-CASE is 
	ignored because both handlers work by side-effect.

!

(CONDITION-BIND ((condition-name1 handler1)
		 (condition-name2 handler2)
		 ...)
  . body)						Special Form

  When a condition is signalled, handlers are searched for in the dynamic
  environment of the signal. Handlers can be established by use of
  CONDITION-BIND.

  Handlers are functions of one argument (an object representing the
  data associated with the condition). They may wish to first inspect 
  the object using one of the following primitives:

	(CONDITION-SLOT condition slot-name)

	  Reads a named slot in the given condition.

	(CONDITION-PROCEED-TYPES condition)

	  Returns a list of the valid proceed types for the 
	  given condition.

  After inspecting the condition, the handler must take one of 
  the following kinds of actions:

  It may decline to handle the condition, by executing: 
	(DECLINE condition)
    The effect of this will be as if the handler had been invisible to the
    mechanism seeking to find a handler. The next handler in line will be
    tried, or if no such handler, the default action for the given 
    condition will be taken.

  It may perform some non-local transfer of control. For example,
     . It can throw to a tag.
     . It may signal an error (which will force implicit transfer
       of control).
     . It may call the function (ABORT) to unwind back to toplevel
       or the innermost (CATCH-ABORT ...) form.

  It may proceed the condition, using
	(proceed-type condition . values)
     For example, if the signal was done via
	(SIGNAL-CASE (FOO-ERROR)
          ((USE-VALUE X) (* X X)))
     and the handler does
	(USE-VALUE condition 7)
     then the SIGNAL expression will return 49.

     There is also a function (INTERACTIVE-PROCEED condition) which will
     prompt the user for a selection of how to proceed by inspecting
     the condition to see what proceed options are available. This is
     primarily useful in implementing the debugger, but may have other
     applications from time to time.

  The debugger may be entered, by invoking:
     (INTERACTIVE-DEBUGGER condition)

!

(DEFINE-SIMPLE-CONDITION name slots parents
  . report-method)					Special Form

  NAME is the name of the new condition to be defined.

  PARENTS is a (possibly null) list of condition types that the
  new condition types is to inherit from.

  SLOTS is described by:	
	  slot-name ! (slot-name) ! (slot-name slot-default-value)
     If the SLOT-DEFAULT-VALUE is not given (as in the first two cases), 
     a value must be given for the slot at SIGNAL time. If a default is
     given, an initialization for the slot is optional at SIGNAL time.

  The REPORT-METHOD is a body of forms will be run in an environment 
  where variables are bound which have the names of the slot names for
  the condition being defined and its parents. The REPORT-METHOD should
  do typeout to the default output stream. It should have NO side-effects
  other than this typeout. Its return value will be discarded. If no
  REPORT-METHOD is specified, then the first condition in the parents
  list which (explicitly or implicitly) has a report method will be the
  error reporter for this condition.

  Example:

	(DEFINE-SIMPLE-CONDITION MACHINE-ERROR (MACHINE-NAME) (ERROR)
	  (FORMAT T "There is a problem with ~A." MACHINE-NAME))

	This defines a MACHINE-ERROR condition which inherits from ERROR.
	Initialization of MACHINE-NAME is required at SIGNAL time.

	(DEFINE-SIMPLE-CONDITION MACHINE-NOT-AVAILABLE () (MACHINE-ERROR)
	  (FORMAT T "The machine ~A is not available." MACHINE-NAME))

	This defines a new, more specific, condition for use when machines 
	are not available. Like MACHINE-ERROR, a value for the the 
	MACHINE-ERROR slot must be specified when the error is signaled.

	(DEFINE-SIMPLE-CONDITION MY-FAVORITE-MACHINE-NOT-AVAILABLE
				 ((MACHINE-NAME "MIT-MC.ARPA"))
	  (MACHINE-NOT-AVAILABLE))

	The required nature of the MACHINE-NAME slot is over-ridden here
	because the new condition type makes it optional (and gives it a
	default value). Since no REPORT-METHOD was given, however, the
	report method for MACHINE-NOT-AVAILABLE will be used if the
	condition is asked to report.

!

(DEFINE-PROCEED-TYPE name pretty-name
  (var1 exp1)
  (var2 exp2)
  ...)							Special Form

  Defines a proceed type, which may appear in a handler clause of a 
  SIGNAL-CASE. The PRETTY-NAME is for use in the debugger. eg, if 
  the debuggers sees this proceed type is a proceed option for a given
  condition, it will show its PRETTY-NAME. It should be a complete
  sentence but not uppercased (unless it starts with a word that is 
  always seen upcased) and not followed by a period. The VARs name 
  values that are needed by this proceed type. The EXPs should compute 
  or prompt for any relevant values (they will be used only 
  interactively). The debugger (or other tool) will upcase the first 
  letter and add a period if contextually appropriate.

  Example:

        (DEFINE-PROCEED-TYPE USE-FOOD  "use some other kind of food"
	  (FOOD  (PROMPT-AND-READ :STRING "What kind of food? ")))

        (DEFINE-PROCEED-TYPE USE-COLOR "use some other color"
	  (FOOD  (PROMPT-AND-READ :STRING "What color? ")))
	
  Using these definitions, a session with the debugger (from the
  food example above) might look like:

	...
	>>Error: The food MILK was found to have color GREENISH-BLUE.
	The following commands may be used to proceed:
	 meta-A:	Use some other kind of food.
	 meta-B:	Use some other color.
	 control-G:	Return to toplevel.
	DBG>meta-A
	What color? white
	...

  or perhaps, depending on the implementation, like:

	...
	The milk was greenish-blue. 
	  Use some other kind of food? (Y or N) No.
	  Use some other color? (Y or N) Yes.
	  What color? white
	...

!

(ABORT)							Function

  Returns control to "toplevel", which is defined as the innermost
  (CATCH-ABORT ...) expression. The outermost expression in any process
  will always have a (CATCH-ABORT ...) around it, return from which will
  either terminate or restart the process as appropriate to the
   application.
  
(CATCH-ABORT . forms)					Special Form

  Executes the forms in its body. If no (ABORT) is done, the value returned
  by the last of the forms will be the value returned by the CATCH-ABORT 
  form. If an (ABORT) is done, then NIL will be returned instead.

!

Notes:

 Which condition types will be initially defined. At the very least ERROR 
 should be.

 Which proceed types will be initially defined. I would argue that 
 something like 
	(DEFINE-PROCEED-TYPE USE-VALUE "use some other value"
	  (VALUE (PROMPT-AND-READ :EXPRESSION "Value to use: ")))
 is quite handy and might want to come pre-defined.

 What condition types are signaled by the already-defined error functions,
 such as ERROR and CERROR.

 This intentionally does not need flavors or any kind of fancy object
 system, though it could snap smoothly into such if
 CL-OBJECT-ORIENTED-PROGRAMMING finally comes up with one. I've implemented
 this for Maclisp, so I know it works.  eg, I've intentionally left aspects
 of the REPORT-METHOD for a condition vague enough that it does not require
 "instance variables" in any magic sense, by not defining what happens if
 you assign the variables.  Internally, just a LET that binds a bunch of
 variables to data structure accesses will work just fine.

 DEFINE-SIMPLE-CONDITION is not called DEFINE-CONDITION in case we 
 later want to make a hairier version that offers more than just a 
 REPORT-METHOD. Giving it this less-generic name will avoid possible
 naming confusion later.

 There may want to be some analogs of the LispM's CONDITION-CASE and other
 more "abstract" operations, but those are easily implementable once we get
 this much mechanism agreed upon, so I've left them out of this proposal.


∂07-Jul-85  1611	FAHLMAN@CMU-CS-C.ARPA 	KMP's proposal   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 7 Jul 85  16:11:33 PDT
Received: ID <FAHLMAN@CMU-CS-C.ARPA>; Sun 7 Jul 85 19:12:01-EDT
Date: Sun, 7 Jul 1985  19:11 EDT
Message-ID: <FAHLMAN.12125199827.BABYL@CMU-CS-C.ARPA>
Sender: FAHLMAN@CMU-CS-C.ARPA
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
To:   cl-error-handling@SU-AI.ARPA
Cc:   fahlman@CMU-CS-C.ARPA
Subject: KMP's proposal


Several months ago Kent M. Pitman sent out a proposal for a Common Lisp
error system that is more or less the Lisp Machine error system
converted so that it doesn't require flavors.  (KMP's system, or a
superset of it, could easily be implemented using flavors, but flavors
are not required.)  I was too busy at the time to pay much attention to
this proposal, but lately have come back to it, since we have begun to
feel the inadequacy of Spice Lisp's very primitive error system.  I
think that KMP's proposal, with perhaps a bit of minor polishing, is
just about what we need as the standard error system for Common Lisp.  I
would really like to decouple this issue from the object-oriented stuff,
while retaining enough of the object-oriented style that the people
already using a flavor-based error system will not have trouble adapting
to this standard.

If people want to look at this proposal, I have a copy of it on CMU-CS-C
as <fahlman>kmp-error.txt.  It should be possible to FTP this
anonymously from arpanet sites.

Since it is hard to evaluate and debug an error system just by reading
about it, let me suggest the following process:

1. We discuss this specific proposal to see if it is generally
acceptable and whether anyone can find major or minor problems with it.

2. If people generally agree that this is the way to go, we tentatively
adopt this as a standard.  This system should then be implemented in a
few Common Lisp systems and should be exposed to real users.

3. We do any necessary tuning of the specification based on this
experience, and then adopt a final version as a legitimate part of
Common Lisp.

I have some reservations or questions about three things in KMP's
proposal:

1. It disturbs me that the "keywords" used in the SIGNAL form are not
really keywords.  Maybe these should be real keywords (though the
variables bound in the handlers would be packaged symbols with the same
print name).  There is precedent for this in some other parts of Common
Lisp.

2. I'm not sure that having only Condition-Bind and no Condition-Setq is
right.  I agree that programmers should be encouraged to use
Condition-Bind most of the time, but there may be occasions when it is
much more convenient to be able to establish certain condition-handlers
globally.

3. KMP does not spell out the rules of inheritance for handlers.  I
suspect that the right thing to do is to first find any matching
handlers in the dynamically-innermost condition-bind and then to try
them in most-specific-first order.  Upon exhausting those options, we
would go to the next condition-bind out and try any matching handlers
there, and so on.  The point is that one condition-bind might establish
a lot of handlers for specific errors, and then inside that extent there
might be a condition-bind that binds only ERROR.  I think that a signal
coming from within that environment wants to first try the ERROR handler
rather than any of the more specific handlers from the outer context,
since the user was obviously trying to do something like an errset.

-- Scott

∂15-Jul-85  2050	FONTANA%ti-csl.csnet@csnet-relay.arpa 	Re: KMP's proposal   
Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 15 Jul 85  20:50:17 PDT
Received: from ti-csl by csnet-relay.csnet id af26388; 15 Jul 85 23:44 EDT
Date: 15 Jul 1985 1035-CDT
From: Mary <Fontana%CSL60%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: KMP's proposal
To: Fahlman@cmu-cs-c.ARPA, cl-error-handling@su-ai.ARPA
cc: fontana%CSL60%ti-csl.csnet@csnet-relay.arpa
In-Reply-To: Your message of 7-Jul-85 1949-CDT
Received: from csl60 by ti-csl; Mon, 15 Jul 85 21:31 CST

Last week, I tried to get a copy of the file <FAHLMAN>KMP-ERROR.TXT to
see if it was the same as the message Kent sent out last February
titled "stripped down version of lispm error system".  Using FTP from
UT Austin always resulted in "file unknown".  Is the file still
around?
Here's my suggestions:

1. I think condition handlers should be searched from the inside out.
This works best when you evaluate something while in a read-eval-print
loop.  The read-eval-print loop could have a condition-bind on a
particular set of errors (like too-few-arguments, function-undefined).
A function evaluated in this loop might have a condition-bind for
these same errors.  The function's handlers should be tried first.

Kent talked about default handlers in his memo, "Exceptional
Situations in Lisp".  Whether or not the order should be reversed for
default handlers is unclear to me.

2. I think we need restart handlers to set up proceed options which do
a non-local transfer of control.  On a lisp machine, when the debugger
prints the proceed options for an error, it includes the restart
proceed options (one of which is usally assigned to ABORT).  Any
condition handler or debugger could suggest to proceed by restarting
at a certain point in the program.  We need a CONDITION-RESTART
special form.

3. Class hierarchy of conditions as well as proceed options should be
available.  This was discussed in Kent's memo on exception handling.

4. The common lisp functions ERROR and CERROR should include a
signal-name (condition-type) argument.

5. I recommend including the lisp machine's CONDITION-CASE,
CONDITION-CALL, CATCH-ERROR and IGNORE-ERRORS.  All of these could be
implemented with CONDITION-BIND.
-------

∂15-Jul-85  2118	FAHLMAN@CMU-CS-C.ARPA 	KMP's proposal   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 15 Jul 85  21:17:59 PDT
Received: ID <FAHLMAN@CMU-CS-C.ARPA>; Tue 16 Jul 85 00:18:43-EDT
Date: Tue, 16 Jul 1985  00:18 EDT
Message-ID: <FAHLMAN.12127352811.BABYL@CMU-CS-C.ARPA>
Sender: FAHLMAN@CMU-CS-C.ARPA
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
To:   cl-error-handling@SU-AI.ARPA
Subject: KMP's proposal
In-reply-to: Msg of 15 Jul 1985  11:35-EDT from Mary <Fontana%CSL60%ti-csl.csnet at csnet-relay.arpa>


Looks like everyone is having trouble with FTP'ing KMP's proposal from
CMU-CS-C, for reasons I don't understand.  I didn't want to do this for
fear of choking various mailers, but I guess the right move is for me
just to mail it out to this list.  Here goes...

---------------------------------------------------------------------------
The following proposal amounts to a stripped down version of what the
LispM provides. Most of the stripping down has to do with hiding
the fact that the LispM had flavors to play with and I didn't want
to depend on that.

I have an implementation of this for Maclisp. I'll see about working
out a CL implementation from that. I don't think it will be hard.

If any parts of this seem vague, let me know and I can elaborate. 
This message covers really only technical details. I have given a lot
of thought on how to describe this conceptually and will do so under
separate cover at a later date.

Anyway, maybe this will give everyone something concrete to center the
discussion around.
-kmp

!

(SIGNAL condition-type key1 val1 key2 val2 ...)		Function

  Signals a condition of the given CONDITION-TYPE with attributes
  given in keyed format. (Note: the keys are not keywords, but 
  packaged symbols.)

  If the signal is not handled, then some default action will be
  taken. The default for ERROR and conditions built on ERROR is 
  to enter the debugger. The default for other conditions is to 
  return NIL.

  Example:

	(SIGNAL 'BAD-FOOD-COLOR
		'FOOD  'MILK
		'COLOR 'GREENISH-BLUE)

	This signals a BAD-FOOD-COLOR condition, providing information
	to the condition that the FOOD was MILK and the COLOR was
	GREENISH-BLUE.

!

(SIGNAL-CASE (condition-type
	      key1 key-value1
	      key2 key-value2
	      ...)
  ((proceed-type-1 . bvl1) . body1)
  ((proceed-type-2 . bvl2) . body2)
  ...)							Special Form

  Signals a condition of the given CONDITION-TYPE with attributes
  as given by the KEYs and KEY-VALUEs. The CONDITION-TYPE and KEYs
  are not evaluated, but the KEY-VALUEs are.

  If the condition is not handled, the default action is according to 
  the rules for the simple case of SIGNAL.

  If the condition is handled, it may be proceeded by calling a proceed
  function which has the name of a PROCEED-TYPE given in the body of the
  SIGNAL-CASE. (The only valid names for PROCEED-TYPEs are those 
  that have been defined using DEFINE-PROCEED-TYPE.) If a proceed function
  is called, the BODY of its corresponding in the SIGNAL-CASE is executed
  with the variables in its BVL bound to the arguments given the proceed
  function, and the return value of that BODY becomes the return value of
  the SIGNAL-CASE.

  Example:

	(LET ((MY-FOOD       'MILK)
	      (MY-FOOD-COLOR 'GREENISH-BLUE))
	  (DO ()
	      ((REASONABLE-COLOR-FOR-FOODP FOOD COLOR))
	    (SIGNAL-CASE (BAD-FOOD-COLOR
			  FOOD  MY-FOOD
			  COLOR MY-FOOD-COLOR)
	      ((USE-COLOR NEW-COLOR) (SETQ MY-FOOD-COLOR NEW-COLOR))
	      ((USE-FOOD  NEW-FOOD)  (SETQ MY-FOOD       NEW-FOOD))))
	  (LIST MY-FOOD MY-FOOD-COLOR))

	This signals a BAD-FOOD-COLOR condition, specifying that FOOD 
	was MY-FOOD and COLOR was MY-FOOD-COLOR. If the caller wants 
	to proceed the condition, he may do something like:

		(USE-COLOR condition 'WHITE)
	     or (USE-FOOD  condition 'CHEESE)

	In this case, the return value of the SIGNAL-CASE is 
	ignored because both handlers work by side-effect.

!

(CONDITION-BIND ((condition-name1 handler1)
		 (condition-name2 handler2)
		 ...)
  . body)						Special Form

  When a condition is signalled, handlers are searched for in the dynamic
  environment of the signal. Handlers can be established by use of
  CONDITION-BIND.

  Handlers are functions of one argument (an object representing the
  data associated with the condition). They may wish to first inspect 
  the object using one of the following primitives:

	(CONDITION-SLOT condition slot-name)

	  Reads a named slot in the given condition.

	(CONDITION-PROCEED-TYPES condition)

	  Returns a list of the valid proceed types for the 
	  given condition.

  After inspecting the condition, the handler must take one of 
  the following kinds of actions:

  It may decline to handle the condition, by executing: 
	(DECLINE condition)
    The effect of this will be as if the handler had been invisible to the
    mechanism seeking to find a handler. The next handler in line will be
    tried, or if no such handler, the default action for the given 
    condition will be taken.

  It may perform some non-local transfer of control. For example,
     . It can throw to a tag.
     . It may signal an error (which will force implicit transfer
       of control).
     . It may call the function (ABORT) to unwind back to toplevel
       or the innermost (CATCH-ABORT ...) form.

  It may proceed the condition, using
	(proceed-type condition . values)
     For example, if the signal was done via
	(SIGNAL-CASE (FOO-ERROR)
          ((USE-VALUE X) (* X X)))
     and the handler does
	(USE-VALUE condition 7)
     then the SIGNAL expression will return 49.

     There is also a function (INTERACTIVE-PROCEED condition) which will
     prompt the user for a selection of how to proceed by inspecting
     the condition to see what proceed options are available. This is
     primarily useful in implementing the debugger, but may have other
     applications from time to time.

  The debugger may be entered, by invoking:
     (INTERACTIVE-DEBUGGER condition)

!

(DEFINE-SIMPLE-CONDITION name slots parents
  . report-method)					Special Form

  NAME is the name of the new condition to be defined.

  PARENTS is a (possibly null) list of condition types that the
  new condition types is to inherit from.

  SLOTS is described by:	
	  slot-name ! (slot-name) ! (slot-name slot-default-value)
     If the SLOT-DEFAULT-VALUE is not given (as in the first two cases), 
     a value must be given for the slot at SIGNAL time. If a default is
     given, an initialization for the slot is optional at SIGNAL time.

  The REPORT-METHOD is a body of forms will be run in an environment 
  where variables are bound which have the names of the slot names for
  the condition being defined and its parents. The REPORT-METHOD should
  do typeout to the default output stream. It should have NO side-effects
  other than this typeout. Its return value will be discarded. If no
  REPORT-METHOD is specified, then the first condition in the parents
  list which (explicitly or implicitly) has a report method will be the
  error reporter for this condition.

  Example:

	(DEFINE-SIMPLE-CONDITION MACHINE-ERROR (MACHINE-NAME) (ERROR)
	  (FORMAT T "There is a problem with ~A." MACHINE-NAME))

	This defines a MACHINE-ERROR condition which inherits from ERROR.
	Initialization of MACHINE-NAME is required at SIGNAL time.

	(DEFINE-SIMPLE-CONDITION MACHINE-NOT-AVAILABLE () (MACHINE-ERROR)
	  (FORMAT T "The machine ~A is not available." MACHINE-NAME))

	This defines a new, more specific, condition for use when machines 
	are not available. Like MACHINE-ERROR, a value for the the 
	MACHINE-ERROR slot must be specified when the error is signaled.

	(DEFINE-SIMPLE-CONDITION MY-FAVORITE-MACHINE-NOT-AVAILABLE
				 ((MACHINE-NAME "MIT-MC.ARPA"))
	  (MACHINE-NOT-AVAILABLE))

	The required nature of the MACHINE-NAME slot is over-ridden here
	because the new condition type makes it optional (and gives it a
	default value). Since no REPORT-METHOD was given, however, the
	report method for MACHINE-NOT-AVAILABLE will be used if the
	condition is asked to report.

!

(DEFINE-PROCEED-TYPE name pretty-name
  (var1 exp1)
  (var2 exp2)
  ...)							Special Form

  Defines a proceed type, which may appear in a handler clause of a 
  SIGNAL-CASE. The PRETTY-NAME is for use in the debugger. eg, if 
  the debuggers sees this proceed type is a proceed option for a given
  condition, it will show its PRETTY-NAME. It should be a complete
  sentence but not uppercased (unless it starts with a word that is 
  always seen upcased) and not followed by a period. The VARs name 
  values that are needed by this proceed type. The EXPs should compute 
  or prompt for any relevant values (they will be used only 
  interactively). The debugger (or other tool) will upcase the first 
  letter and add a period if contextually appropriate.

  Example:

        (DEFINE-PROCEED-TYPE USE-FOOD  "use some other kind of food"
	  (FOOD  (PROMPT-AND-READ :STRING "What kind of food? ")))

        (DEFINE-PROCEED-TYPE USE-COLOR "use some other color"
	  (FOOD  (PROMPT-AND-READ :STRING "What color? ")))
	
  Using these definitions, a session with the debugger (from the
  food example above) might look like:

	...
	>>Error: The food MILK was found to have color GREENISH-BLUE.
	The following commands may be used to proceed:
	 meta-A:	Use some other kind of food.
	 meta-B:	Use some other color.
	 control-G:	Return to toplevel.
	DBG>meta-A
	What color? white
	...

  or perhaps, depending on the implementation, like:

	...
	The milk was greenish-blue. 
	  Use some other kind of food? (Y or N) No.
	  Use some other color? (Y or N) Yes.
	  What color? white
	...

!

(ABORT)							Function

  Returns control to "toplevel", which is defined as the innermost
  (CATCH-ABORT ...) expression. The outermost expression in any process
  will always have a (CATCH-ABORT ...) around it, return from which will
  either terminate or restart the process as appropriate to the
   application.
  
(CATCH-ABORT . forms)					Special Form

  Executes the forms in its body. If no (ABORT) is done, the value returned
  by the last of the forms will be the value returned by the CATCH-ABORT 
  form. If an (ABORT) is done, then NIL will be returned instead.

!

Notes:

 Which condition types will be initially defined. At the very least ERROR 
 should be.

 Which proceed types will be initially defined. I would argue that 
 something like 
	(DEFINE-PROCEED-TYPE USE-VALUE "use some other value"
	  (VALUE (PROMPT-AND-READ :EXPRESSION "Value to use: ")))
 is quite handy and might want to come pre-defined.

 What condition types are signaled by the already-defined error functions,
 such as ERROR and CERROR.

 This intentionally does not need flavors or any kind of fancy object
 system, though it could snap smoothly into such if
 CL-OBJECT-ORIENTED-PROGRAMMING finally comes up with one. I've implemented
 this for Maclisp, so I know it works.  eg, I've intentionally left aspects
 of the REPORT-METHOD for a condition vague enough that it does not require
 "instance variables" in any magic sense, by not defining what happens if
 you assign the variables.  Internally, just a LET that binds a bunch of
 variables to data structure accesses will work just fine.

 DEFINE-SIMPLE-CONDITION is not called DEFINE-CONDITION in case we 
 later want to make a hairier version that offers more than just a 
 REPORT-METHOD. Giving it this less-generic name will avoid possible
 naming confusion later.

 There may want to be some analogs of the LispM's CONDITION-CASE and other
 more "abstract" operations, but those are easily implementable once we get
 this much mechanism agreed upon, so I've left them out of this proposal.

∂15-Jul-85  2149	FAHLMAN@CMU-CS-C.ARPA 	KMP's proposal   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 15 Jul 85  21:49:15 PDT
Received: ID <FAHLMAN@CMU-CS-C.ARPA>; Tue 16 Jul 85 00:49:25-EDT
Date: Tue, 16 Jul 1985  00:49 EDT
Message-ID: <FAHLMAN.12127358403.BABYL@CMU-CS-C.ARPA>
Sender: FAHLMAN@CMU-CS-C.ARPA
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
To:   Mary <Fontana%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
Subject: KMP's proposal
In-reply-to: Msg of 15 Jul 1985  11:35-EDT from Mary <Fontana%CSL60%ti-csl.csnet at csnet-relay.arpa>


Now, in response to Mary Fontana's comments:

    1. I think condition handlers should be searched from the inside out...

I doubt that anyone would disagree about searching condition-binds in
inside-out order.  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.

    Kent talked about default handlers in his memo, "Exceptional
    Situations in Lisp".  Whether or not the order should be reversed for
    default handlers is unclear to me.

I think if we get into the issue of "default handlers" and their proper
hierarchical behavior, all is lost.  I would suggest that we just try to
agree on something like what KMP proposed, and not try to standardize
what happens if you escape from the known universe.

    2. I think we need restart handlers to set up proceed options which do
    a non-local transfer of control.  On a lisp machine, when the debugger
    prints the proceed options for an error, it includes the restart
    proceed options (one of which is usally assigned to ABORT).  Any
    condition handler or debugger could suggest to proceed by restarting
    at a certain point in the program.  We need a CONDITION-RESTART
    special form.

Is a special piece of machinery really needed for this?  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?

    3. Class hierarchy of conditions as well as proceed options should be
    available.  This was discussed in Kent's memo on exception handling.

Can you supply an example where this is needed?  The simpler we keep
this, the easier it is going to be to come up with something usable.

    4. 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.

    5. I recommend including the lisp machine's CONDITION-CASE,
    CONDITION-CALL, CATCH-ERROR and IGNORE-ERRORS.  All of these could be
    implemented with CONDITION-BIND.

I'm not sure everyone on the list has access to the Lisp Machine
documentation.  Could you spell out in more detail what you are
proposing here?

-- Scott

∂16-Jul-85  1719	Moon@SCRC-STONY-BROOK.ARPA 	KMP's proposal   
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 16 Jul 85  17:18:56 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 276785; Tue 16-Jul-85 20:17:00-EDT
Date: Tue, 16 Jul 85 20:18 EDT
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: KMP's proposal
To: Scott E. Fahlman <Fahlman@CMU-CS-C.ARPA>
cc: Mary <Fontana%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>,
    cl-error-handling@SU-AI.ARPA
In-Reply-To: <FAHLMAN.12127358403.BABYL@CMU-CS-C.ARPA>
Message-ID: <850716201855.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Tue, 16 Jul 1985  00:49 EDT
    From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>

    Now, in response to Mary Fontana's comments:

	2. I think we need restart handlers to set up proceed options which do
	a non-local transfer of control.

    Is a special piece of machinery really needed for this?  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?

It's not the same as condition-case; it's more like a variant of signal-case.
The point is to provide ways of recovering from the condition that are
implemented not by the place in the program that detected the condition, but
instead by some outer part of the program -- some dynamic caller of the place
that detected the condition.  This is pragmatically useful and also is
important from a software engineering point of view, since it lets you hide
from the outside world the modularity of a program it's calling; you can hide
the fact that the detection of a condition and the means of recovering from
that condition may be in separate sub-modules.  I think this could fit in
fairly smoothly, it just involves separating the two underlying parts of
signal-case: the actual signalling and the set of proceed-types.

	3. Class hierarchy of conditions as well as proceed options should be
	available.  This was discussed in Kent's memo on exception handling.

    Can you supply an example where this is needed?  The simpler we keep
    this, the easier it is going to be to come up with something usable.

Classification of conditions is already in KMP's proposal (see
DEFINE-SIMPLE-CONDITION).  Some examples can be found in Reference Guide to
Symbolics-Lisp, pp.482-484,533.  I'm not sure about classification of proceed
options; KMP didn't propose that in his recent stripped-down proposal.

	4. 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.

The place to insert the argument has been provided and the way has been made
straight.  Remember a couple of years ago when I argued for a change to the
arguments of CERROR, and said that I would tell you the reason later?  If the
first argument to ERROR, CERROR, or WARN (but not BREAK) is a symbol, instead
of the string that would normally be expected, then it is a condition name.

∂17-Jul-85  0859	FONTANA%ti-csl.csnet@csnet-relay.arpa 	Re: KMP's proposal   
Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 17 Jul 85  08:59:41 PDT
Received: from ti-csl by csnet-relay.csnet id ah01410; 17 Jul 85 11:58 EDT
Date: 16 Jul 1985 1724-CDT
From: Mary <Fontana%CSL60%ti-csl.csnet@csnet-relay.arpa>
Subject: Re: KMP's proposal
To: Fahlman@cmu-cs-c.ARPA
cc: cl-error-handling@su-ai.ARPA
In-Reply-To: Your message of 16-Jul-85 0158-CDT
Received: from csl60 by ti-csl; Wed, 17 Jul 85 03:27 CST

> ....  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
condition-name.

 (CATCH-CONDITION-RESTART
       (CONDITION-NAMES  FORMAT-STRING FORMAT-ARGS...)
      BODY)

 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
  (CONDITION-NAMES FORMAT-STRING FORMAT-ARGS...)
    BODY)

 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
CONDITION-RESTART.

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,

(DEFINE-SIMPLE-CONDIITON  FILE-NOT-FOUND (file-name) (FILE-ERROR ERROR)
   (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)
 This replaces CERROR's CONTINUE-FORMAT-STRING with PROCEED-TYPE.
A DEFINE-PROCEED-TYPE for proceed-type whould contain the
CONTINUE-FORMAT-STRING.


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 ....)
  body
    (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 ...)
   body
    (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.

(IGNORE-ERRORS 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.

-------

∂18-Jul-85  1229	Moon@SCRC-RIVERSIDE.ARPA 	KMP's proposal
Received: from SCRC-RIVERSIDE.ARPA by SU-AI.ARPA with TCP; 18 Jul 85  12:29:41 PDT
Received: from WAIKATO.SCRC.Symbolics.COM by SCRC-RIVERSIDE.ARPA via CHAOS with CHAOS-MAIL id 42925; Thu 18-Jul-85 15:26:45-EDT
Received: from EUPHRATES.SCRC.Symbolics.COM by WAIKATO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110654; Thu 18-Jul-85 15:32:32-EDT
Date: Thu, 18 Jul 85 15:29 EDT
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: KMP's proposal
To: Scott E. Fahlman <Fahlman@CMU-CS-C.ARPA>
cc: cl-error-handling@SU-AI.ARPA
In-Reply-To: <FAHLMAN.12125199827.BABYL@CMU-CS-C.ARPA>
Message-ID: <850718152957.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Sun, 7 Jul 1985  19:11 EDT
    From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>

There seems to have been a disappointingly small amount of discussion of KMP's
proposal, unless some of the mail isn't getting to me.  I think I got two messages
from Scott Fahlman, two from Mary Fontana, and one that I sent myself.

    ....I have some reservations or questions about three things in KMP's
    proposal:

    1. It disturbs me that the "keywords" used in the SIGNAL form are not
    really keywords.  Maybe these should be real keywords (though the
    variables bound in the handlers would be packaged symbols with the same
    print name).  There is precedent for this in some other parts of Common
    Lisp.

I wouldn't take that SIGNAL form too seriously; I think it mostly reflects
Kent's dislike of keywords.  While he may well be right, at this point I think
consistency with the rest of Common Lisp is more important.

Incidentally, in my proposal analogous to KMP's (from long long ago) I think
that the arglist to SIGNAL (and SIGNAL-CASE, ERROR, CERROR, and WARN) was
allowed to be an arbitrary arglist, defined by DEFINE-SIMPLE-CONDITION, rather
than being forced to be &KEY; the advantage to this is increased brevity for
conditions that have a small number of parameters, or whose parameters consist
entirely of a format-string and arguments formatted by that string.

    2. I'm not sure that having only Condition-Bind and no Condition-Setq is
    right.  I agree that programmers should be encouraged to use
    Condition-Bind most of the time, but there may be occasions when it is
    much more convenient to be able to establish certain condition-handlers
    globally.

You need both DEFINE-GLOBAL-HANDLER and UNDEFINE-GLOBAL-HANDLER (I think
CONDITION-SETQ is an unclear name).  We have these but don't have enough
experience with them yet to consider proposing them to go into a simple
stripped-down thing like KMP's.

    3. KMP does not spell out the rules of inheritance for handlers.  I
    suspect that the right thing to do is to first find any matching
    handlers in the dynamically-innermost condition-bind and then to try
    them in most-specific-first order.  Upon exhausting those options, we
    would go to the next condition-bind out and try any matching handlers
    there, and so on.  The point is that one condition-bind might establish
    a lot of handlers for specific errors, and then inside that extent there
    might be a condition-bind that binds only ERROR.  I think that a signal
    coming from within that environment wants to first try the ERROR handler
    rather than any of the more specific handlers from the outer context,
    since the user was obviously trying to do something like an errset.

I agree, except that the handlers established by any one condition-bind should
be tried in the order that they were written.


∂18-Jul-85  1246	FAHLMAN@CMU-CS-C.ARPA 	KMP's proposal   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 18 Jul 85  12:46:39 PDT
Received: ID <FAHLMAN@CMU-CS-C.ARPA>; Thu 18 Jul 85 15:47:01-EDT
Date: Thu, 18 Jul 1985  15:46 EDT
Message-ID: <FAHLMAN.12128046090.BABYL@CMU-CS-C.ARPA>
Sender: FAHLMAN@CMU-CS-C.ARPA
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
To:   "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
Subject: KMP's proposal
In-reply-to: Msg of 18 Jul 1985  15:29-EDT from David A. Moon <Moon at SCRC-STONY-BROOK.ARPA>


    There seems to have been a disappointingly small amount of discussion of KMP's
    proposal, unless some of the mail isn't getting to me.  I think I got two messages
    from Scott Fahlman, two from Mary Fontana, and one that I sent myself.

That's all the mail I've seen as well.  Perhaps the problem with FTP-ing
the proposal from CMUC deterred people from commenting, but that should
be fixed now.  If anyone has any strong reservations about this kind of
approach (as opposed to the small details), you'd better speak up now,
or else the three or four of us who are interested in this issue will
wind up settling it among ourselves.  (Maybe that wouldn't be so bad.)
Once we've got a proposl that those of us on this list like, we should
send it to the full Common Lisp list, and if nobody objects then, we can
take it as a probationary standard, I think.

    Incidentally, in my proposal analogous to KMP's (from long long ago) I think
    that the arglist to SIGNAL (and SIGNAL-CASE, ERROR, CERROR, and WARN) was
    allowed to be an arbitrary arglist, defined by DEFINE-SIMPLE-CONDITION, rather
    than being forced to be &KEY; the advantage to this is increased brevity for
    conditions that have a small number of parameters, or whose parameters consist
    entirely of a format-string and arguments formatted by that string.

I'd prefer to go with all-keywords for uniformity, but since the user
would have to know what a given condition expects in any event, I could
live with Moon's proposal.

    You need both DEFINE-GLOBAL-HANDLER and UNDEFINE-GLOBAL-HANDLER (I think
    CONDITION-SETQ is an unclear name).  We have these but don't have enough
    experience with them yet to consider proposing them to go into a simple
    stripped-down thing like KMP's.

That name change is fine with me.  I think we'd better put these in
right from the start, since it looks to me like certain applications
will have to go through confusing gyrations if we leave them out.

    I agree, except that the handlers established by any one condition-bind should
    be tried in the order that they were written.

Sounds OK to me.  We might want to warn users that unless they are doing
something odd, they will want to put the more specific handlers before the
more general ones when they write a condition-bind.

Has anyone got time to write up a revised proposl including the changes
suggested by Fonatana and Moon, suitable for incorporation into the
manual?  I will do this if nobody else wants to, but I'll be off the net
starting next Saturday until August 4, so I can't work on it before then.

-- Scott

∂18-Jul-85  1305	FAHLMAN@CMU-CS-C.ARPA 	KMP's proposal   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 18 Jul 85  13:05:35 PDT
Received: ID <FAHLMAN@CMU-CS-C.ARPA>; Thu 18 Jul 85 16:05:39-EDT
Date: Thu, 18 Jul 1985  16:05 EDT
Message-ID: <FAHLMAN.12128049471.BABYL@CMU-CS-C.ARPA>
Sender: FAHLMAN@CMU-CS-C.ARPA
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
To:   "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
Subject: KMP's proposal
In-reply-to: Msg of 16 Jul 1985  20:18-EDT from David A. Moon <Moon at SCRC-STONY-BROOK.ARPA>


    	2. I think we need restart handlers to set up proceed options which do
    	a non-local transfer of control.

        Is a special piece of machinery really needed for this?  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?

    It's not the same as condition-case; it's more like a variant of signal-case.
    The point is to provide ways of recovering from the condition that are
    implemented not by the place in the program that detected the condition, but
    instead by some outer part of the program -- some dynamic caller of the place
    that detected the condition.  This is pragmatically useful and also is
    important from a software engineering point of view, since it lets you hide
    from the outside world the modularity of a program it's calling; you can hide
    the fact that the detection of a condition and the means of recovering from
    that condition may be in separate sub-modules.  I think this could fit in
    fairly smoothly, it just involves separating the two underlying parts of
    signal-case: the actual signalling and the set of proceed-types.

Yeah, that was a thinko on my part.  I meant SIGNAL-CASE and not
CONDITION-CASE.  If something else is really useful, I'd like to see a
specific proposal for what that would look like.  It sounds to me like
the hair-to-value ratio is pretty high here, but maybe I'm imagining a
less elegant mechanism than Moon has in mind.

    	3. Class hierarchy of conditions as well as proceed options should be
    	available.  This was discussed in Kent's memo on exception handling.

        Can you supply an example where this is needed?  The simpler we keep
        this, the easier it is going to be to come up with something usable.

    Classification of conditions is already in KMP's proposal (see
    DEFINE-SIMPLE-CONDITION).  Some examples can be found in Reference Guide to
    Symbolics-Lisp, pp.482-484,533.  I'm not sure about classification of proceed
    options; KMP didn't propose that in his recent stripped-down proposal.

OK, if the machinery in KMP's DEFINE-SIMPLE-CONDITION is all that is
being proposed, that seems reasonable enough.

    	4. 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.

    The place to insert the argument has been provided and the way has been made
    straight.  Remember a couple of years ago when I argued for a change to the
    arguments of CERROR, and said that I would tell you the reason later?  If the
    first argument to ERROR, CERROR, or WARN (but not BREAK) is a symbol, instead
    of the string that would normally be expected, then it is a condition name.

Is the signal-name arument meant to replace the error string, or just
push all the arguments back one place?  If the former, then the text to
be printed comes from the condition definition and not from the ERROR
form itself?  Seems reasonable.  My first reaction was that it would be
confusing not to see the message text there where the error is being
signalled, but I guess that is inevitable if you want to be able to
redefine handlers for the various important error classes.

Do we require (and enforce) that the condition signalled by an ERROR or
CERROR call is in fact a subtype of ERROR?  (I can see the text now: "An
Error-Condition-Not-Subtype-Of-Error error is signalled if the condition
signalled by a call to Error is not an Error.")

-- Scott

∂18-Jul-85  1331	FAHLMAN@CMU-CS-C.ARPA 	KMP's proposal   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 18 Jul 85  13:31:38 PDT
Received: ID <FAHLMAN@CMU-CS-C.ARPA>; Thu 18 Jul 85 16:31:26-EDT
Date: Thu, 18 Jul 1985  16:31 EDT
Message-ID: <FAHLMAN.12128054168.BABYL@CMU-CS-C.ARPA>
Sender: FAHLMAN@CMU-CS-C.ARPA
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
To:   Mary <Fontana%CSL60%ti-csl.csnet@CSNET-RELAY.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
Subject: KMP's proposal
In-reply-to: Msg of 16 Jul 1985  18:24-EDT from Mary <Fontana%CSL60%ti-csl.csnet at csnet-relay.arpa>


OK, the extensions you propose all look simple and fiarly useful to me.
I wouldn't mind having them around as part of the standard.  The only
one that looks dubious to me is CATCH-ERROR.  If CATCH-ERROR returns
whatever multiple values the body does, then I don't think it is useful
to return the error-p indication as the second value when an error
occurs.  You could never be sure if you were seeing an error or just
some return values that happened to come up NIL non-NIL.  That seems
dangerous.  And if you avoid cases where this confusion might occur, you
may as well use IGNORE-ERRORS.  Or have I misunderstood what CATCH-ERROR
is about?

-- Scott

∂19-Jul-85  0927	DLW@SCRC-STONY-BROOK.ARPA 	KMP's proposal    
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 19 Jul 85  09:23:36 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 278842; Fri 19-Jul-85 12:21:37-EDT
Date: Fri, 19 Jul 85 12:25 EDT
From: Daniel L. Weinreb <DLW@SCRC-QUABBIN.ARPA>
Subject: KMP's proposal
To: Fahlman@CMU-CS-C.ARPA, Moon@SCRC-STONY-BROOK.ARPA
cc: cl-error-handling@SU-AI.ARPA
In-Reply-To: <FAHLMAN.12128046090.BABYL@CMU-CS-C.ARPA>
Message-ID: <850719122556.3.DLW@CHICOPEE.SCRC.Symbolics.COM>
Fonts: CPTFONT, CPTFONTB, CPTFONTI

    Date: Thu, 18 Jul 1985  15:46 EDT
    From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>

    Once we've got a proposl that those of us on this list like, we should
    send it to the full Common Lisp list, and if nobody objects then, we can
    take it as a probationary standard, I think.

Remember the mail I sent a while ago, asking what the procedure was for
adding new things to the Common Lisp definition?  This isn't anything
like what I thought the procedure is.  Do you want to call up, say, RPG,
and tell him that he may have THOUGHT that he finished Common Lisp on
schedule, but we just moving the finish line another twenty yards back,
and he'll just have to slip all his schedules, because we just expanded
the definition of what it means to have correctly implemented Common Lisp?
What ever happened to all that talk about the current definition remaining
stable, and a Common Lisp '87 being defined in a few years, and all that
stuff?

∂19-Jul-85  1405	FAHLMAN@CMU-CS-C.ARPA 	KMP's proposal   
Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 19 Jul 85  14:05:12 PDT
Received: ID <FAHLMAN@CMU-CS-C.ARPA>; Fri 19 Jul 85 17:05:36-EDT
Date: Fri, 19 Jul 1985  17:05 EDT
Message-ID: <FAHLMAN.12128322538.BABYL@CMU-CS-C.ARPA>
Sender: FAHLMAN@CMU-CS-C.ARPA
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
To:   "Daniel L. Weinreb" <DLW@SCRC-QUABBIN.ARPA>
Cc:   cl-error-handling@SU-AI.ARPA
Subject: KMP's proposal
In-reply-to: Msg of 19 Jul 1985  12:25-EDT from Daniel L. Weinreb <DLW at SCRC-QUABBIN.ARPA>


The key word in my note was "PROBATIONARY standard".  By that I meant
that we would proceed more or less as I had outlined earlier: all of the
people interested in such things agree that this is the error system we
PROBABLY want, so a few of us take the trouble to implement it and see.
Then we do whatever has to be done to make the new standard official.
Obviously, it doesn't become an official part of the language until
there is a way to make official changes to the language, but that
doesn't mean we can't agree informally that certain things ought to be
done in certain ways.

I don't think it is so bad to have to call up the various Common Lisp
vendors and tell them that we've got a solid error system defined.  Most
of them would be delighted, especially if we can hand them the code that
implements the whole thing (modulo a couple of minor hooks).  Obviously,
we don't tell them that they are suddenly out of spec and that they
can't call their product Common Lisp until they have fixed this.
Requiring a new feature in every Common Lisp has to lag a certain amount
of time behind agreeing on it.  The error system may be special,
however, since there can't really be a complete validation suite until
there is a better standard for error handling than the one we have now
-- there's no portable way to have a program deliberately cause an error
and then recover.

As for setting up the formal charter process, or organization, or
whatever it is going to be, I'm afraid that the chairman of the charter
committee hasn't been giving this very much attention of late, mostly
because he despairs of making any progress there without finding someone
who wants to put in a couple of years of full-time work to get an
organization off the ground.  Maybe we should fire that chairman and get
one with more energy and better ideas.  The current chairman would like
that.

-- Scott

∂05-Jan-86  1741	marick@gswd-vms 	What happens when no handler is found?
Received: from GSWD-VMS.ARPA by SU-AI.ARPA with TCP; 4 Jan 86  16:30:29 PST
Received: by gswd-vms.ARPA (5.9/5.6)
	id AA00437; Sat, 4 Jan 86 18:31:03 CST
Date: Sat, 4 Jan 86 18:31:03 CST
From: marick@gswd-vms (Brian Marick)
Message-Id: <8601050031.AA00437@gswd-vms.ARPA>
To: cl-error-handling@su-ai.arpa
Subject: What happens when no handler is found?
Comment: Remailed at SU-AI after delay caused by distribution list error.

A comment on Kent Pitman's error-handling proposal:   (Reposting)

Having SIGNAL return NIL if no handler is found makes me nervous; it seems
to assume that people will explicitly plan for the case where no handler is
found, whereas I expect many people will create bugs because they implicitly
assume that their condition will be handled.  And even if detecting the case
of a missing handler by checking whether SIGNAL returns is OK, that doesn't
work with SIGNAL-CASE, which is expected to return and may return any value.

There's a distinction between code that's sending a signal to ask for help
and code that's sending a signal because there's nothing left for it to do,
no matter what.  How that distinction meshes with the definitions of SIGNAL,
SIGNAL-CASE, ERROR, and ERROR-CASE is not clear enough.

How if their definitions are modified/clarified to say

SIGNAL -- control never resumes in the signalling function.  It is an error
(with type NO-SUCH-HANDLER or whatever) for no handler to be found.

SIGNAL-CASE -- by default, it is an error (as above) for no handler to be
found. If one of the clauses of the SIGNAL-CASE is headed by :NO-HANDLER (or
a list containing :NO-HANDLER), that the body of that clause is invoked.

ERROR -- control never resumes in the signalling function.  If no handler is
found, the signalled condition is passed to the debugger.  (The distinction
between this and SIGNAL is that the error reported to the user is what was
discovered by the program, not by the error system.)

ERROR-CASE -- just like now.  A :NO-HANDLER clause makes no sense here.


Brian Marick

∂06-Jan-86  1436	KMP@SCRC-YUKON.ARPA 	What happens when no handler is found? 
Received: from SCRC-YUKON.ARPA by SU-AI.ARPA with TCP; 6 Jan 86  14:36:09 PST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-YUKON.ARPA via CHAOS with CHAOS-MAIL id 185081; Mon 6-Jan-86 17:31:14-EST
Date: Mon, 6 Jan 86 17:36 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: What happens when no handler is found?
To: cl-error-handling@SU-AI.ARPA
cc: kmp@SCRC-STONY-BROOK.ARPA, Moon@SCRC-STONY-BROOK.ARPA
In-Reply-To: <8601050031.AA00437@gswd-vms.ARPA>
Message-ID: <860106173607.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

I might as well take this opportunity to mention that Moon has been
studying the proposal that I presented at the meeting and is in the
process of negotiating a variation of that with me. Richard Mlynarik
(MLY@MIT-MC) has also passed along some comments which are being
considered in that revision. We'll be sending out a revised proposal and
accompanying sample implementation as soon as we're satisfied internally
here. It shouldn't be too much longer. Sorry for the delay; this is a
high priority item for us (as I'm sure it is for others on this list).

The rest of this message is a reply to marick@gswd-vms about 
SIGNAL/ERROR[-CASE]...

    Date: Sat, 4 Jan 86 18:31:03 CST
    From: marick@gswd-vms (Brian Marick)
    Message-Id: <8601050031.AA00437@gswd-vms.ARPA>
    To: cl-error-handling@su-ai.arpa
    Subject: What happens when no handler is found?
    Comment: Remailed at SU-AI after delay caused by distribution list error.

    A comment on Kent Pitman's error-handling proposal:   (Reposting)

    Having SIGNAL return NIL if no handler is found makes me nervous;
    it seems to assume that people will explicitly plan for the case where 
    no handler is found, whereas I expect many people will create bugs 
    because they implicitly assume that their condition will be handled.  
    And even if detecting the case of a missing handler by checking whether 
    SIGNAL returns is OK, that doesn't work with SIGNAL-CASE, which is
    expected to return and may return any value.

I think you're just confusing an "error" with a "condition". Not all
conditions are errors. You can think of a condition as being anything
exceptional. For example, if you're working on a clerical task and you
note something "unusual", you might remark it aloud to your boss and
s/he might or might not care. If s/he did not, you wouldn't dwell on it,
you'd just go on. An error, on the other hand, is something that stops
your work and that you can't proceed on without external intervention.
There are plenty more things that you might "remark about" than there
are that you might "stall over". For example, if you worked at Walt
Disney World and the 1,000,000th person walked through the turnstyles,
you might want to make a fuss over him but it wouldn't be an error not
to. This kind of planned ignorability of nevertheless interesting
information is not in error and is still quite useful. It is
underexploited today only because the right tools for playing with it
have not existed until recently.

    There's a distinction between code that's sending a signal to ask 
    for help and code that's sending a signal because there's nothing
    left for it to do, no matter what.  How that distinction meshes with 
    the definitions of SIGNAL, SIGNAL-CASE, ERROR, and ERROR-CASE is 
    not clear enough.

SIGNAL and SIGNAL-CASE do not ask for help. They allow an opportunity
for it.  In a way, ERROR and ERROR-CASE do ask for help. More properly,
though, they simply announce that without help there is nothing more
that will get done in the current computation.

    How if their definitions are modified/clarified to say

    SIGNAL -- control never resumes in the signalling function.  It is an 
    error (with type NO-SUCH-HANDLER or whatever) for no handler to be found.

Signal is not only for errors. It is for any unusual event. Not all
unusual events need to be handled. If you don't subscribe to that idea,
then you should never use SIGNAL and always use ERROR and you'll be all
set.

Examples of things that are not errors but which might want to be
signalled are

 * QUERY -- You might want a query routine which always did a 
   (non-fatal) signal saying that a query was about to happen. One 
   way to proceed from such a query (after inspecting any relevant 
   data) might be by saying what the query should be without entering a
   mode requiring actual I/O. This could be useful in various batch 
   applications. It is not necessarily an error to not handle such a 
   condition. You'd just fall through to other code which would interact 
   at the terminal.

 * DEGENERATE CASES -- Consider a function PPRINT* which took a list of 
   things and pretty printed them to a given stream. Interactively at 
   the console, in home-grown environment-saving programs, or whatever, 
   it might be fine for (PPRINT* L) to quietly print nothing when L was 
   bound to (). Yet for someapplications, it might be useful to notice 
   that nothing had been printed. One way to do this would be for PPRINT*
   to signal a non-fatal exception when it saw an empty list and to assume
   that if no one handled that exception and took control of things that 
   it was OK to proceed.

 * HOOKS -- For example, the Mode hooks which are so popular in MIT's 
   Emacs are an example of something that could be implemented as a 
   non-fatal condition. The program says "I'm selecting Text Mode now" 
   and the handler says "Wait, I'm glad you mentioned that because I 
   have code to run." Had there been no handler, it is still reasonable
   to proceed and select Text Mode.

 * WARNINGS -- The break-on-warnings feature is something which is an 
   example of something which could neatly be handled by non-fatal 
   conditions. Normally, if WARN is called, you can set a variable saying 
   that a breakpoint should be created. However, another way this (or similar
   mechanisms) could be implemented would be for WARN to signal a non-fatal
   condition and to allow people arbitrary control at the time of the WARN. 
   This would allow hooks so that one didn't have to have variables like
   *abort-on-warnings*, *beep-on-warnings*, etc. to allow every possible 
   kind of customization. Instead, one would just write:
    (condition-bind ((compiler:warning 
		       #'(lambda (cond) (ignore cond) (abort))))
      ...)
   or whatever was needed to handle a specific situation in a very general 
   way. If no such condition-bind had been done, the default would be to
   simply continue with the normal I/O done by the WARN routine.

It's fairly easy to conjure examples of places where things like this
can be used.  People who have never used the Lisp Machine condition
system probably don't have the experience to realize the importance of
this sort of thing. Most Lisp Machine users don't even realize the
flexibility at their disposal in this regard, though that is changing. I
and a few other people I know have used this feature to great advantage.

    SIGNAL-CASE -- by default, it is an error (as above) for no handler 
    to be found. If one of the clauses of the SIGNAL-CASE is headed by 
    :NO-HANDLER (or a list containing :NO-HANDLER), that the body of 
    that clause is invoked.

This is an interesting idea but I'm a little worried because it blurs
two notions that I am not sure should be blurred. The first is "how to
proceed a certain way" which is what the kind of clauses I'm proposing
do. The second, which you're proposing, is essentially a shorthand for
condition-bind, which doesn't describe how to proceed but rather
describes how to select how to proceed. For example, under your proposal
you could logically imagine writing a :NO-HANDLER clause which wanted to
proceed using one of the proceed cases in another of the clauses. I'm
not sure if it's wise to invite that sort of confusion.

    ERROR -- control never resumes in the signalling function.  If no 
    handler is found, the signalled condition is passed to the debugger.
    (The distinction between this and SIGNAL is that the error reported 
    to the user is what was discovered by the program, not by the 
    error system.)

I'm not sure what this distinction means. There are no "error systems"
that are not programs. Also, the issue of "reporting" is a kind of
"handling" and is completely logically distinct from the issue of
signalling.

    ERROR-CASE -- just like now.  A :NO-HANDLER clause makes no sense here.

    Brian Marick

∂06-Jan-86  1514	Moon@SCRC-YUKON.ARPA 	What happens when no handler is found?
Received: from SCRC-YUKON.ARPA by SU-AI.ARPA with TCP; 6 Jan 86  15:14:07 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-YUKON.ARPA via CHAOS with CHAOS-MAIL id 185102; Mon 6-Jan-86 18:09:15-EST
Date: Mon, 6 Jan 86 18:14 EST
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: What happens when no handler is found?
To: Brian Marick <marick@GSWD-VMS.ARPA>
cc: cl-error-handling@SU-AI.ARPA
In-Reply-To: <8601050031.AA00437@gswd-vms.ARPA>
Message-ID: <860106181429.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Sat, 4 Jan 86 18:31:03 CST
    From: marick@gswd-vms (Brian Marick)

    A comment on Kent Pitman's error-handling proposal:   (Reposting)

    Having SIGNAL return NIL if no handler is found makes me nervous; it seems
    to assume that people will explicitly plan for the case where no handler is
    found, whereas I expect many people will create bugs because they implicitly
    assume that their condition will be handled.  And even if detecting the case
    of a missing handler by checking whether SIGNAL returns is OK, that doesn't
    work with SIGNAL-CASE, which is expected to return and may return any value.

This is all based on the idea that there are two kinds of conditions:
errors and simple events.  SIGNAL cannot return NIL when signalling an
error because the system guarantees that there is a default handler for
errors, which typically enters a debugger.  Whether a condition is an error
or not is defined by inheritance from its parent.

I suppose SIGNAL-CASE of a simple event with no handler simply returns NIL
without executing any of the clauses, but the proposal doesn't say anything
about that.

    There's a distinction between code that's sending a signal to ask for help
    and code that's sending a signal because there's nothing left for it to do,
    no matter what.  How that distinction meshes with the definitions of SIGNAL,
    SIGNAL-CASE, ERROR, and ERROR-CASE is not clear enough.

I consider it a good idea to use the ERROR function when there's nothing left to
do, thus making it clear that you don't expect a return.

    ....
    SIGNAL-CASE -- by default, it is an error (as above) for no handler to be
    found. If one of the clauses of the SIGNAL-CASE is headed by :NO-HANDLER (or
    a list containing :NO-HANDLER), that the body of that clause is invoked.

This would be a reasonable alternative to what I supposed in my second paragraph.

∂06-Jan-86  2037	marick%ccvaxa@gswd-vms 	Re:  What happens when no handler is found?   
Received: from GSWD-VMS.ARPA by SU-AI.ARPA with TCP; 6 Jan 86  20:37:23 PST
Received: from ccvaxa.GSD (ccvaxa.ARPA) by gswd-vms.ARPA (5.9/5.6)
	id AA02369; Mon, 6 Jan 86 22:34:57 CST
Date: 6 Jan 1986 21:55-CST
From: marick@gswd-vms.arpa
Subject: Re:  What happens when no handler is found?
To: moon@scrc-stony-brook.arpa, kmp@scrc-stony-brook.arpa,
        cl-error-handling@su-ai.arpa, marick@gswd-vms.arpa
Message-Id: <505454154/marick@ccvaxa>

Okay, you've convinced me that programs might very often signal
conditions without handlers; often enough that it ought to be 
simple to do.  Nevertheless, I still think there is a class of
conditions (perhaps exemplified by EOF) where

1.  It is a programmer error if there is no handler.
2.  It's inelegant to consider the condition a subtype of ERROR.
3.  A missing handler is better reported as MISSING-HANDLER
    than ERROR:  EOF.

Of course, it's simple enough to make a subtype of CONDITION
called MUST-BE-HANDLED-CONDITION and a global handler for it
that signals the programmer error.  Should that condition and
its handler be part of the standard?

Brian Marick

∂06-Jan-86  2056	Moon@SCRC-STONY-BROOK.ARPA 	Re:  What happens when no handler is found?    
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 6 Jan 86  20:56:30 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 387247; Mon 6-Jan-86 23:53:51-EST
Date: Mon, 6 Jan 86 23:53 EST
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: Re:  What happens when no handler is found?
To: marick@GSWD-VMS.ARPA
cc: kmp@SCRC-STONY-BROOK.ARPA, cl-error-handling@SU-AI.ARPA
In-Reply-To: <505454154/marick@ccvaxa>
Message-ID: <860106235317.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 6 Jan 1986 21:55-CST
    From: marick@gswd-vms.arpa

    Okay, you've convinced me that programs might very often signal
    conditions without handlers; often enough that it ought to be 
    simple to do.  Nevertheless, I still think there is a class of
    conditions (perhaps exemplified by EOF) where

    1.  It is a programmer error if there is no handler.
    2.  It's inelegant to consider the condition a subtype of ERROR.
    3.  A missing handler is better reported as MISSING-HANDLER
	than ERROR:  EOF.

    Of course, it's simple enough to make a subtype of CONDITION
    called MUST-BE-HANDLED-CONDITION and a global handler for it
    that signals the programmer error.  Should that condition and
    its handler be part of the standard?

I don't buy your EOF example, but it's true that in Symbolics'
condition system there is a condition named DEBUGGER-CONDITION,
which is the root from which the behavior of going into the debugger
if there is no handler is inherited, and ERROR is actually a
specialization of DEBUGGER-CONDITION.  There are 12 other specializations
of DEBUGGER-CONDITION, which fall into two categories: conditions that
are part of the intestines of the debugger, and conditions (like stack
overflow) that need to be handled but are not actually errors, at
least not errors at the specific place where they happen to be detected.

The key point here is that "the type of condition that goes into the
debugger when not handled" and "the type of condition that is caught
by IGNORE-ERRORS" are very similar, but not identical.

I suppose this condition probably does need to be part of the standard.
There might be a better name than DEBUGGER-CONDITION.  Maybe KMP can
demonstrate a reason why this condition isn't really needed in the
portable language.

∂07-Jan-86  0951	KMP@SCRC-STONY-BROOK.ARPA 	Re:  What happens when no handler is found?
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 7 Jan 86  09:49:41 PST
Received: from WAIKATO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 387564; Tue 7-Jan-86 12:50:17-EST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by WAIKATO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 145781; Tue 7-Jan-86 12:51:05-EST
Date: Tue, 7 Jan 86 12:50 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Re:  What happens when no handler is found?
To: marick@GSWD-VMS.ARPA, moon@SCRC-STONY-BROOK.ARPA,
    kmp@SCRC-STONY-BROOK.ARPA, cl-error-handling@SU-AI.ARPA
In-Reply-To: <505454154/marick@ccvaxa>
Message-ID: <860107125025.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

    Date: 6 Jan 1986 21:55-CST
    From: marick@gswd-vms.arpa

    Okay, you've convinced me that programs might very often signal
    conditions without handlers; often enough that it ought to be 
    simple to do.  Nevertheless, I still think there is a class of
    conditions (perhaps exemplified by EOF) where

    1.  It is a programmer error if there is no handler.
    2.  It's inelegant to consider the condition a subtype of ERROR.
    3.  A missing handler is better reported as MISSING-HANDLER
	than ERROR:  EOF.

    Of course, it's simple enough to make a subtype of CONDITION
    called MUST-BE-HANDLED-CONDITION and a global handler for it
    that signals the programmer error.  Should that condition and
    its handler be part of the standard?

It is a part of the standard and it is called ERROR.

My proposal allowed for a default handler for any condition type. By default, 
errors have a default handler which enters the debugger non-continuably.
In practice, this forces any condition of type ERROR to be handled, even 
when signalled with SIGNAL. However, the reason this happens is not an explicit
property of SIGNAL, it is a property of the default condition handler.

I think we're not in disagreement, so let me recap the behavior and the
rationales...

You can create types of conditions which enter the debugger non-continuably.
We'll call such conditions "error conditions". Typically, they behave this way
because they inherit from ERROR, though in fact you could create conditions 
which don't inherit from ERROR but still behave this way. Moon calls 
conditions which aren't errors "simple conditions". I'll use that terminology.

If an error condition is signalled with SIGNAL but not handled, its default 
handler will cause it to enter the debugger non-continuably. If a non-error
condition is signalled with SIGNAL but not handled, SIGNAL will return NIL
because their is no default handler.

If an error condition is signalled with ERROR but not handled, its default
handler will cause it to enter the debugger non-continuably. If a non-error
condition is signalled with ERROR but not handled, the internal call to SIGNAL
made by ERROR will return but ERROR itself will force things into the debugger
non-continuably.

Here's another way of looking at it...

				ERROR			SIGNAL
	
	Error Condition		Enter Debugger		Enter Debugger
	
	Simple Condition	Enter Debugger		Return NIL

Typically you use ERROR when you don't want to proceed and SIGNAL when you
don't mind proceeding. The ability to create conditions which cannot be 
proceeded even if the signaller didn't think it was an error is a concession
to exactly the sort of concern you seem to have, which is that there might
be no reasonable way to proceed from some kinds of conditions.

By the way, you might be interested to know that I personally disagree with
you even though my proposal does not disagree with you. I don't personally 
like the idea that it's a property of the condition and not of the signaller 
that you enter the debugger. It has always seemed to me that 
(SIGNAL 'UNBOUND-VARIABLE ...) should be treated differently than
(ERROR 'UNBOUND-VARIABLE ...). There are interesting situations where I think
this difference could be usefully and interestingly exploited. My point is
that this proposal is really not based so much on my personal feelings about
how things should be done. It is based on my experience with actually using
the Lisp Machine error system as implemented since its introduction a few
years ago. It essentially tries to lift the important features of that system 
as directly as possible while staying within the CL framework just so that 
people can have the confidence of knowing they are getting something that has
in some sense been field-tested.

-kmp

∂07-Jan-86  1907	marick%fang@gswd-vms 	Re:  What happens when no handler is found?
Received: from GSWD-VMS.ARPA by SU-AI.ARPA with TCP; 7 Jan 86  19:06:50 PST
Received: from fang.GSD (fang.ARPA) by gswd-vms.ARPA (5.9/5.6)
	id AA03192; Tue, 7 Jan 86 21:07:09 CST
Date: 7 Jan 1986 20:39-CST
From: marick@gswd-vms.arpa (Brian &)
Subject: Re:  What happens when no handler is found?
To: kmp@SCRC-STONY-BROOK.ARPA.cl-error-handling@SU-AI.ARPA.marick@gswd-vms.arpa
Message-Id: <505535978/marick@fang>

Actually, when you state my position that way, *I* disagree with me.  I do
think that what happens when there's no handler should be determined by the
signaller.  The MUST-BE-HANDLED-CONDITION was just a way to include the kind
of default semantics I want for SIGNAL into your proposal as a simple
addition of text.

Now, what I want matters not a whit, but I think others might want the same
thing.  If you look at the exception handling schemes of CLU or Ada or Mesa,
you'll find that an uncaught signal "signals an error".  (In Ada, "the task
is terminated".  In Mesa, "drastic action must be taken ... all signals will
ultimately be caught and reported by the Debugger".  In CLU, an uncaught
exception signals the special FAILURE exception -- which is pretty much what
I want.)  I don't think the experience that went into (and came out of) these
languages is irrelevant.

So I propose that ERROR be used to signal conditions the signalling code
thinks are errors.  Unhandled errors go to the debugger.  SIGNAL is used to
signal "shouts into the wilderness".  There's no expectation that anyone
will necessarily be listening, so NIL is returned if there's no handler.
ESIGNAL (named by loose analogy to ETYPECASE) is used when the signalling
code expects there to be a handler.  If there's no handler, ESIGNAL signals
an error.  Signals sent for different reasons should be sent by different 
functions.

(Actually, I'd even go so far as to propose that SIGNAL be used for
signalling-with-handler-expected, since that's the name used in other
languages for that behavior.  New names for new ideas.  Part of what
confused me initially may have been my automatic association of "signal"
with traditional exception handling, and I don't think I'm all that much
stupider than the average person.)

Brian Marick

∂09-Jan-86  1434	DLW@SCRC-STONY-BROOK.ARPA 	Re:  What happens when no handler is found?
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 9 Jan 86  14:34:28 PST
Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 389575; Thu 9-Jan-86 17:34:50-EST
Date: Thu, 9 Jan 86 17:34 EST
From: Daniel L. Weinreb <DLW@SCRC-QUABBIN.ARPA>
Subject: Re:  What happens when no handler is found?
To: marick@GSWD-VMS.ARPA
cc: moon@SCRC-STONY-BROOK.ARPA, kmp@SCRC-STONY-BROOK.ARPA,
    cl-error-handling@SU-AI.ARPA
In-Reply-To: <505454154/marick@ccvaxa>
Message-ID: <860109173414.3.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: 6 Jan 1986 21:55-CST
    From: marick@gswd-vms.arpa

		   Nevertheless, I still think there is a class of
    conditions (perhaps exemplified by EOF) where

    1.  It is a programmer error if there is no handler.
    2.  It's inelegant to consider the condition a subtype of ERROR.
    3.  A missing handler is better reported as MISSING-HANDLER
	than ERROR:  EOF.

While everything Moon said about debugger-conditions is correct, it is
nevertheless the case in our error system that END-OF-FILE is a subtype
of ERROR.  Why is this inelegant?  Can you explain to me a relatively
formal criterion by which any given kind of event can be classified,
such that END-OF-FILE is not an error but DIVIDE-BY-ZERO is?  I don't
think there is any real difference.  Just because one is more likely to
write a program that intentionally signals END-OF-FILE than a program
that intentionally signals DIVIDE-BY-ZERO does not change the fact that
the two are essentially simiar: they are exceptional cases that the
programmer usually wants to not worry about.  That is, when you do a /,
you normally just assume that the answer is a number and keep on going,
and when you do a read, you normally just assume that the answer is a
Lisp expression and keep on going.  If you want to deal with the
possibility that the answer is not a number, or that end-of-file was
reached, you use the condition mechanism.  (In the case of READ you
can also use the extra args, but that's not relevant.)  If the exception
comes up and the programmer didn't prepare for it explicitly, in both
cases it is equally correct to enter the debugger, because the program's
assumptions have been made untrue and the program cannot proceed.

∂13-Jan-86  0138	marick%fang@gswd-vms 	Re:  What happens when no handler is found?
Received: from GSWD-VMS.ARPA by SU-AI.ARPA with TCP; 13 Jan 86  01:37:54 PST
Received: from fang.GSD (fang.ARPA) by gswd-vms.ARPA (5.9/5.6)
	id AA01709; Mon, 13 Jan 86 03:37:43 CST
Date: 12 Jan 1986 17:02-CST
From: marick%fang@gswd-vms (Brian &)
Subject: Re:  What happens when no handler is found?
To: moon@SCRC-STONY-BROOK.ARPA.kmp@SCRC-STONY-BROOK.ARPA.cl-error-handling@SU-AI.ARPA.DLW@scrc-stony-brook.
Message-Id: <505954978/marick@fang>

I concede that what we've been discussing is a matter of style.  Since
the error proposal can easily accomodate different styles, including
mine, I'm happy.

As far as EOF goes, I agree with what (I believe) Kent Pitman has been
saying:  a condition is a condition is a condition; the signalling code
determines whether it is an "error".  For example, an infinite stream
that generates primes might use ERROR to signal EOF.  If I had a 
stream open to an ordinary file, I'd like the function I use to signal
EOF to detect the lack of a handler and signal MISSING-HANDLER (with
ERROR).  If I had a stream like a UNIX-style TTY stream, where
EOF doesn't necessarily mean that the next read won't find data,
I might signal EOF, not caring if anything handled the condition.
The distinction between the three is style and what you see if you
enter the debugger.

Brian Marick

∂30-Jan-86  0945	jeff%aiva.edinburgh.ac.uk@Cs.Ucl.AC.UK 	Error proposal questions 
Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 30 Jan 86  09:44:54 PST
Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK   via Janet with NIFTP
           id a000382; 30 Jan 86 12:04 GMT
From: Jeff Dalton <jeff%aiva.edinburgh.ac.uk@cs.ucl.ac.uk>
Date: Wed, 29 Jan 86 22:45:31 GMT
Message-Id: <Wed Jan 29 22:45:31 1986 @ aiva.edinburgh.ac.uk>
To: kmp@scrc-stony-brook.arpa
Subject: Error proposal questions
Cc: cl-error-handling@su-ai.arpa

I have some questions about the proposal distributed in Boston.  They're
all pretty trivial, and I hope I haven't just missed some mail that answers
everything, but here they are:

(1)  DECLINE is defined only implicitly, but by analogy with PROCEED
     I assume it's a function rather than a macro.

(2)  What happens if DECLINE or PROCEED is called with some condition
     other than the one that was signalled?  Ditto for proceed functions.

(3)  How do the proceed-cases get into a condition?  Does SIGNAL-CASE
     SETF this field?  If so, what happens if this condition is later
     reused in a situation where the proceed-cases are invalid?

(4)  It seems that types like CONDITION and ERROR will have condition-
     reporters, but the proposal doesn't define any.  Nor does it say
     what their default handlers, if any, will do.

(5)  Are default-handlers meant to be inherited, a la report functions?

(6)  What does CONDITION-DEFAULT-HANDLE do if there's no default handler?

(7)  Is the 'type' argument to CATCH-CONDITION meant to be evaluated?
     The answer appears to be "no", but if the call to IGNORE-CONDITION
     in the description of IGNORE-ERRORS is meant to be CATCH-CONDITION
     then the answer would be "yes".

(8)  Is the ABORT condition type a subtype of ERROR?

(9)  Is the reference to DEFINE-PROCEED-TYPE in the description of
     PROCEED meant to be a reference to DEFINE-PROCEED-FUNCTION?

-- Jeff