perm filename CLERHA.MSG[COM,LSP]9 blob sn#817836 filedate 1986-05-27 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

∂17-Mar-86  2119	KMP@SCRC-STONY-BROOK.ARPA 	Error Proposal #5 is available   
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 17 Mar 86  21:19:01 PST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 440376; Tue 18-Mar-86 00:17:56-EST
Date: Tue, 18 Mar 86 00:18 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5 is available
To: CL-ERROR-HANDLING@SU-AI.ARPA
Message-ID: <860318001824.1.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

My error proposal has been bouncing back and forth between myself, Dave
Moon, and Richard Mlynarik for the last couple of months. I think it has
changed somewhat from what was proposed in December, for the better we
think. The three of us are not in complete agreement, but are probably
as close as we're going to get. I'd now like it if other people got
copies of the proposal and looked it over. Keep in mind as you do that
compromises are going to be necessary if we're going to ever get
anything put into place.

Since the proposal is long, I've put it temporarily in the following
file on MIT-MC:

  COMMON; CL-ERR PROP5

Dick Gabriel has promised to put a copy in a more permanent home on
SU-AI, and will follow this message with the name of that file when he
has moved that copy. If anyone is unable to FTP files from MIT-MC or
SU-AI, they should send mail to me (KMP@Symbolics) or Gabriel
(RPG@SU-AI) and we'll try to push a copy through the mail.

There were several intermediate proposals that you shouldn't expect to
have seen, which is why this is called proposal #5.

For now I think it's ok to proceed with a relatively open discussion on
the proposal to see what issues people feel are important to discuss.
However, I anticipate that the discussion to follow may need some
direction to keep it from getting out of hand, so if I end up having to
step in and take things a few issues at a time, please bear with me.

A sample, portable, public domain implementation of the majority of the
functions needed will follow under separate cover in a week or two.
Jonathan Rees has volunteered to try to put it together.

Thanks to all for their patience. I know this took a bit longer to
distribute than I'd said it would. I think the changes made in the
interim have been worth the extra time; I hope you'll agree.

∂19-Mar-86  1301	KMP@ALLEGHENY.SCRC.Symbolics.COM 	Error Proposal #5 is also available on MIT-XX 
Received: from [192.10.41.45] by SU-AI.ARPA with TCP; 19 Mar 86  12:59:02 PST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by ALLEGHENY.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 6699; Wed 19-Mar-86 15:58:49-EST
Date: Wed, 19 Mar 86 15:58 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5 is also available on MIT-XX
To: CL-ERROR-HANDLING@SU-AI.ARPA
Message-ID: <860319155816.7.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

I moved a copy to MIT-XX since people were having trouble with
the filename syntax on SU-AI and MIT-MC. Here's a list of the 
places it can be obtained from:

 Host		Local Filename

 MIT-XX		<KMP>CL-ERR.PROP.5

 MIT-MC		COMMON; CL-ERR PROP5

 SU-AI		CLERR.PRP[COM,LSP]

The file is about 10K words, 50K chars, 100 lines, or
24 printed pages.

∂25-Mar-86  0340	Daniels.PA@Xerox.COM 	Handler binding environment 
Received: from XEROX.COM by SU-AI.ARPA with TCP; 25 Mar 86  03:38:50 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 24 MAR 86 18:16:32 PST
Date: 24 Mar 86 18:16:26 PST (Monday)
From: Daniels.PA@Xerox.COM
Subject: Handler binding environment
To: CL-Error-Handling@SU-AI.ARPA
cc: , Daniels.PA@Xerox.COM
Message-ID: <860324-181632-1736@Xerox>

What handler bindings are in effect while a handler is running?

There is an important invariant in the Symbolics and similar error
systems: when a handler is running the "handler binding stack" is popped
back to just after the binding that caused that handler to be called.
Nothing like this is mentioned in the proposal. I think it should be.

		-- Andy. --

∂25-Mar-86  0340	Daniels.pa@Xerox.COM 	Error Proposal #5 questions 
Received: from XEROX.COM by SU-AI.ARPA with TCP; 25 Mar 86  03:38:37 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 24 MAR 86 18:07:58 PST
Date: 24 Mar 86 18:07 PST
From: Daniels.pa@Xerox.COM
Subject: Error Proposal #5 questions
To: CL-Error-Handling@SU-AI.ARPA
cc: Daniels.pa@Xerox.COM
Message-ID: <860324-180758-1724@Xerox>

1. I'm not sure what the second form of :report is supposed to look
like. Could I have an example of a use of it? (This is the case where
the report function goes to *standard-output*)

2. In previous versions, condition objects were immutable, i.e., all
slots were read-only. Is this still true?

3. If the condition signalled is of type SERIOUS-CONDITION, do you
always end up in the debugger if it isn't handled? The description of
SIGNAL implied that this may not be true.

4. In WARN, what is the "text of the warning" if a condition was passed
instead of a format string? (I assume that the way warnings are printed
is something like (FORMAT *ERROR-OUTPUT* "Warning: ~A." condition))

5. The definition of PROCEED-CASE states that a non-NIL name must
correspond to a defined proceed-function. This does not seem to be the
case, since INVOKE-PROCEED-CASE gives a way to get to that case. Which
is it?

6. The variable is DEFINE-PROCEED-FUNCTION differ from normal &OPTIONAL
parameters in that they to not allow a supplied-p parameter. Whay not go
ahead and make them the same as &OPTIONAL?

7. "If a named proceed function is invoked in a context in which there
is no active proceed case by that name, the proceed function simply
returns NIL." Does it still go ahead and collect parameters, or does the
test happen before any initial-value forms are evaluated?

8. If you hand INVOKE-PROCEED-CASE a name, does it simply unwind back to
the appropriate PROCEED-CASE, or does it call the proceed function? (The
answer is obvious if PROCEED-CASE names don't have to correspond to
proceed functions).

9. Since you've already define ILLEGAL-THROW and ILLEGAL-GO, it seems
like you should also have ILLEGAL-RETURN.

10. The list of standard condition types is incomplete. For example,
PARSE-NAMESTRING "signals an error if the hosts don't match." I couldn't
find an apporpriate condition to signal. It certainly isn't a
STREAM-ERROR, while simply using ERROR is distasteful -- it defeats the
purpose of having the type hierarchy.

This may be beyond the scope of the Error Proposal per se, but I believe
that there should be a well-defined condition for every place in CLtL
that indicates that an error is signalled. Of course, I don't mean that
we define a different condition type for each of these.

		-- Andy. --

∂31-Mar-86  1437	Daniels.pa@Xerox.COM 	Daniels.pa: Error Proposal #5 questions    
Received: from XEROX.COM by SU-AI.ARPA with TCP; 31 Mar 86  14:34:22 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 31 MAR 86 14:35:11 PST
Date: 31 Mar 86 14:34 PST
From: Daniels.pa@Xerox.COM
Subject: Daniels.pa: Error Proposal #5 questions
To: CL-Error-Handling@SU-AI.ARPA
Message-ID: <860331-143511-5236@Xerox>

Sorry if you've seen this already, but the first time I sent these out,
they got bounced back because Symbolics was off the air, so I'm
reposting the messages.

		-- Andy. --

     ----- Begin Forwarded Messages -----

Date: 24 Mar 86 18:07 PST
From: Daniels.pa
Subject: Error Proposal #5 questions
To: CL-Error-Handling@SU-AI.ARPA
cc: Daniels.pa

1. I'm not sure what the second form of :report is supposed to look
like. Could I have an example of a use of it? (This is the case where
the report function goes to *standard-output*)

2. In previous versions, condition objects were immutable, i.e., all
slots were read-only. Is this still true?

3. If the condition signalled is of type SERIOUS-CONDITION, do you
always end up in the debugger if it isn't handled? The description of
SIGNAL implied that this may not be true.

4. In WARN, what is the "text of the warning" if a condition was passed
instead of a format string? (I assume that the way warnings are printed
is something like (FORMAT *ERROR-OUTPUT* "Warning: ~A." condition))

5. The definition of PROCEED-CASE states that a non-NIL name must
correspond to a defined proceed-function. This does not seem to be the
case, since INVOKE-PROCEED-CASE gives a way to get to that case. Which
is it?

6. The variable is DEFINE-PROCEED-FUNCTION differ from normal &OPTIONAL
parameters in that they to not allow a supplied-p parameter. Whay not go
ahead and make them the same as &OPTIONAL?

7. "If a named proceed function is invoked in a context in which there
is no active proceed case by that name, the proceed function simply
returns NIL." Does it still go ahead and collect parameters, or does the
test happen before any initial-value forms are evaluated?

8. If you hand INVOKE-PROCEED-CASE a name, does it simply unwind back to
the appropriate PROCEED-CASE, or does it call the proceed function? (The
answer is obvious if PROCEED-CASE names don't have to correspond to
proceed functions).

9. Since you've already define ILLEGAL-THROW and ILLEGAL-GO, it seems
like you should also have ILLEGAL-RETURN.

10. The list of standard condition types is incomplete. For example,
PARSE-NAMESTRING "signals an error if the hosts don't match." I couldn't
find an apporpriate condition to signal. It certainly isn't a
STREAM-ERROR, while simply using ERROR is distasteful -- it defeats the
purpose of having the type hierarchy.

This may be beyond the scope of the Error Proposal per se, but I believe
that there should be a well-defined condition for every place in CLtL
that indicates that an error is signalled. Of course, I don't mean that
we define a different condition type for each of these.

		-- Andy. --


     ----- Next Message -----

Date: 24 Mar 86 18:16:26 PST (Monday)
From: Daniels.PA
Subject: Handler binding environment
To: CL-Error-Handling@SU-AI.ARPA
cc: , Daniels

What handler bindings are in effect while a handler is running?

There is an important invariant in the Symbolics and similar error
systems: when a handler is running the "handler binding stack" is popped
back to just after the binding that caused that handler to be called.
Nothing like this is mentioned in the proposal. I think it should be.

		-- Andy. --


     ----- End Forwarded Messages -----

∂31-Mar-86  2328	KMP@SCRC-STONY-BROOK.ARPA 	Handler binding environment 
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 31 Mar 86  23:27:54 PST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 451613; Tue 1-Apr-86 02:24:50-EST
Date: Tue, 1 Apr 86 02:27 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Handler binding environment
To: Daniels.PA@Xerox.COM, CL-Error-Handling@SU-AI.ARPA
In-Reply-To: <860324-181632-1736@Xerox>
Message-ID: <860401022715.8.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

    Date: 24 Mar 86 18:16:26 PST (Monday)
    From: Daniels.PA at Xerox.COM

    What handler bindings are in effect while a handler is running?

    There is an important invariant in the Symbolics and similar error
    systems: when a handler is running the "handler binding stack" is popped
    back to just after the binding that caused that handler to be called.
    Nothing like this is mentioned in the proposal. I think it should be.

Yes, this was intended and is just not made explicit in the proposal. I'll make
sure it gets into the next draft.
-kmp

ps Sorry for the delay in responding. Symbolics was off the network for a week
   and mail from the outside got all backed up.

∂01-Apr-86  0003	KMP@SCRC-STONY-BROOK.ARPA 	Error Proposal #5 questions 
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 1 Apr 86  00:00:38 PST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 451619; Tue 1-Apr-86 02:57:10-EST
Date: Tue, 1 Apr 86 02:59 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5 questions
To: Daniels.pa@Xerox.COM, CL-Error-Handling@SU-AI.ARPA
In-Reply-To: <860324-180758-1724@Xerox>
Message-ID: <860401025935.9.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

    Date: 24 Mar 86 18:07 PST
    From: Daniels.pa at Xerox.COM

    1. I'm not sure what the second form of :report is supposed to look
    like. Could I have an example of a use of it? (This is the case where
    the report function goes to *standard-output*)

I'll add some examples. This is supposed to use CONDITION as a "free" variable
and do output to *STANDARD-OUTPUT*. Eg,

 :REPORT (FORMAT T "~A" (FROB-AROUND-WITH CONDITION))

    2. In previous versions, condition objects were immutable, i.e., all
    slots were read-only. Is this still true?

I've never seen any good reason to assign one's slots in any code I've written
in Zetalisp. I think we might want to add wording saying that it's an error to
assign their slots. Obviously(?), for debugging it may be necessary to sometimes do
that and implementations should be permitted to support such. But I'm content to
have such be not portable.

    3. If the condition signalled is of type SERIOUS-CONDITION, do you
    always end up in the debugger if it isn't handled? The description of
    SIGNAL implied that this may not be true.

Well, the SIGNAL description says that the signal facility is invoked. I meant it
to be the case that SERIOUS-CONDITION had a default handler that non-proceeably
entered the debugger, so no, it couldn't happen. That would be most like Zetalisp.
Personally, I don't like what Zetalisp does. I think you should have to use ERROR
if you don't want to proceed and SIGNAL if you don't mind and the default handlers
shouldn't exist at all. This would clean up some things. But it might be very
incompatible with Zetalisp. Also, it's not something that I have any active 
experience with. I just have experience with the way Zetalisp does things, which is
very adequate and usable if slightly inelegant. I'm torn between personal desires
for purity and a desire to make sure we lean toward "field tested" techniques where
possible. But I'm willing to listen to arguments on the subject.

    4. In WARN, what is the "text of the warning" if a condition was passed
    instead of a format string? (I assume that the way warnings are printed
    is something like (FORMAT *ERROR-OUTPUT* "Warning: ~A." condition))

Yes, that's right. If a condition is passed, its report function is used. In 
principle, you can WARN things that are not based on WARNING, by the way. I
dunno if anyone would do that, but it's legal in my proposal. I saw no reason
to forbid it, so I didn't.)

    5. The definition of PROCEED-CASE states that a non-NIL name must
    correspond to a defined proceed-function. This does not seem to be the
    case, since INVOKE-PROCEED-CASE gives a way to get to that case. Which
    is it?

I don't think these are really contradictory, though I'm content to clean up the
wording. The real intent is that every proceed function looks for proceed cases
by the same name. As such, you could provide a named proceed case and not have
yet written the corresponding proceed function. I guess I think that the thing 
to avoid is making proceed cases named things like CAR or STRING-SEARCH where the
name is obviously not the name of a proceed case. Do you have any strong feeling
about whether it would be best to disallow cases that don't correspond to actual
proceed functions? Certainly this is something that compilers might try to warn
about in any case.

    6. The variable is DEFINE-PROCEED-FUNCTION differ from normal &OPTIONAL
    parameters in that they to not allow a supplied-p parameter. Whay not go
    ahead and make them the same as &OPTIONAL?

I'm not sure what to make of this ungrammatical mess, but I'll give a shot at 
answering the question I think you're asking. DEFINE-PROCEED-FUNCTION is intended
to be actually implemented as the cdr of an &OPTIONAL var list, so I guess it would
be hard to keep supplied-p from working. And as you say, it would be handy in some
cases, so let's write it in.

    7. "If a named proceed function is invoked in a context in which there
    is no active proceed case by that name, the proceed function simply
    returns NIL." Does it still go ahead and collect parameters, or does the
    test happen before any initial-value forms are evaluated?

Yes. The obvious reason is that proceed functions are functions. Functions
get their arguments evaluated, optionals filled in, etc. To go a bit deeper,
though, let me add that basically a named proceed function just does:

 (DEFUN myfun (CONDITION &OPTIONAL ...variables as in define-proceed-function...)
   (LET ((CASE (FIND-PROCEED-CASE 'myfun CONDITION)))
     (IF CASE (INVOKE-PROCEED-CASE CASE CONDITION ...varnames given in define-proceed-function...))))

The only difference is that it also sets up information about the default values of
:REPORT, etc. for that proceed case. So obviously, it doesn't find out the case
is missing until after the optionals are processed, etc.

    8. If you hand INVOKE-PROCEED-CASE a name, does it simply unwind back to
    the appropriate PROCEED-CASE, or does it call the proceed function? (The
    answer is obvious if PROCEED-CASE names don't have to correspond to
    proceed functions).

As should be obvious from my answer to 7 above, proceed functions call 
INVOKE-PROCEED-CASE and not vice versa.

    9. Since you've already define ILLEGAL-THROW and ILLEGAL-GO, it seems
    like you should also have ILLEGAL-RETURN.

Fine idea. I hoped that if I put down a random set of things that it would 
sufficiently offend someone enough that they'd start telling me how to fix the
list. When I mentioned that we just needed a set of condition types, no one 
came racing up with a nice set. If you think of other obvious ones, let me know.

    10. The list of standard condition types is incomplete. For example,
    PARSE-NAMESTRING "signals an error if the hosts don't match." I couldn't
    find an apporpriate condition to signal. It certainly isn't a
    STREAM-ERROR, while simply using ERROR is distasteful -- it defeats the
    purpose of having the type hierarchy.

Well, the intent is that you should suggest a type and we should include it. 
However, we are going to get to a level of detail where people no longer agree.
At that point, I expect implementations to continue to make more-specific 
condition types where they feel it appropriate and then signal them. ie, if
we added nothing for PARSE-NAMESTRING, implementors should know that they should
at least define a FILE-ERROR (or some such) on their own and signal that instead.
Some will signal FILE-PARSE-ERROR, some will signal FILE-NAMESTRING-PARSE-ERROR,
etc. It may be the case, of course, that ERROR will be the best thing a portable
program can look for. Anyway, let's assume there's a FILE-ERROR. (It got left out
because I had originally mis-named STREAM-ERROR by that name but then forgot 
FILE-ERROR would still be valid/useful when I renamed what I had been calling
FILE-ERROR to STREAM-ERROR.)

    This may be beyond the scope of the Error Proposal per se, but I believe
    that there should be a well-defined condition for every place in CLtL
    that indicates that an error is signalled. Of course, I don't mean that
    we define a different condition type for each of these.

I believe this is a very good idea. It's certainly something I'd intended to do
sometime. We should do it if possible, but we should not let the failure to do
it keep us from agreeing on this error proposal in short order since any sort
of standard in this area would be better than what we have now.

I think these were all excellent questions, by the way -- just the right level of
detail that I think we should now be addressing. I hope I've answered them coherently;
it's a bit past my bedtime. Let me know if something got garbled or if I've raised
new questions with my answers.

∂04-Apr-86  1024	KMP@SCRC-STONY-BROOK.ARPA 	Error Proposal #5 questions 
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 4 Apr 86  10:20:27 PST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 455474; Fri 4-Apr-86 13:17:33-EST
Date: Fri, 4 Apr 86 13:17 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5 questions
To: RWK@SCRC-YUKON.ARPA, CL-ERROR-HANDLING@SU-AI.ARPA
cc: KMP@SCRC-STONY-BROOK.ARPA
In-Reply-To: <860403011422.4.RWK@WHITE-BIRD.SCRC.Symbolics.COM>
References: <860401025935.9.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Message-ID: <860404131744.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Fonts: CPTFONT, CPTFONTCB

    Date: Thu, 3 Apr 86 01:14 EST
    From: Robert W. Kerns <RWK@SCRC-YUKON.ARPA>
    Subject: Error Proposal #5 questions
    To: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>

	Date: Tue, 1 Apr 86 02:59 EST
	From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>

	    4. In WARN, what is the "text of the warning" if a condition was passed
	    instead of a format string? (I assume that the way warnings are printed
	    is something like (FORMAT *ERROR-OUTPUT* "Warning: ~A." condition))

	Yes, that's right. If a condition is passed, its report function is used. In 
	principle, you can WARN things that are not based on WARNING, by the way. I
	dunno if anyone would do that, but it's legal in my proposal. I saw no reason
	to forbid it, so I didn't.)

    Some implementations may define additional protocols on warnings, relating
    to saving them in a database, delaying certain warnings so they can be
    checked later (i.e. undefined-function, etc). WARNING may provide the
    basis for this protocol. I haven't had a chance to read the proposal; how does 
    WARN differ from SIGNAL?

I had some ideas about this but they're not made clear in the proposal. My general
intuition is that it's good to allow such extensions but bad to arrange for them
by building them into the WARNING condition, especially in systems which don't allow
non-hierarchical inheritance, which this proposal doesn't try to presuppose. I believe
we should try to lock down a little more detail on this. Here are a couple of possible 
ways to refine the proposal ...

 * We could say that WARNING has a default handler which does the typeout 
   and that the WARN function is basically like SIGNAL except that the 
   default type of condition signalled is SIMPLE-WARNING instead of
   SIMPLE-CONDITION. This has the bad problem that if you do something
   like (WARN 'STREAM-ERROR) you enter the debugger instead of getting a
   warning typed out since the default handler for STREAM-ERROR goes into
   the debugger.

 * We could say that WARNING doesn't have any special default handler 
   (just gets used for type inclusion so that people can handle it). In that
   case, the implementation of WARN might look like:
     (PROCEED-CASE (PROGN (SIGNAL ...)
			  (FORMAT *ERROR-OUTPUT* "Warning: ~A." condition))
       (SKIP-WARNING ()))
   would be best. That way, WARN will SIGNAL and upon return (if there is
   a return) will always do a warning even for non-WARNING-based conditions.
   unless some handler specifically specifies that the warning should be skipped.
   This has the same problem that you enter the debugger on 
   (WARN 'UNBOUND-VARIABLE ...) but at least you have the knowledge that if
   that entry to the debugger had returned (which it can't unless you use 
   special debugger commands that would be beyond the scope of this proposal)
   it -would have- typed a warning.

Of course, it could just avoid the problem of non-WARNING-based conditions by
erring if the given condition type was not a subtype of WARNING.

Another, completely different, way we could go at it would be to say that WARN
does roughly:

 (PROCEED-CASE (LET ((C (MAKE-CONDITION ...hair based on arg types...)))
	         (SIGNAL 'WARNING :ENCAPSULATED-CONDITION C)
		 (FORMAT *ERROR-OUTPUT* "Warning: ~A." C))
   (SKIP-WARNING ()))

so that the given condition is not actually signalled but a known type is. 
In that case, we could flush SIMPLE-WARNING since the encapsulated condition
could just be type SIMPLE-CONDITION if no condition type was specified.

I think the important things to achieve with WARN are:

 * In general, it should type a warning on the console.

 * It should not be easy to trick it into -not- typing a warning (eg, by giving
   it a non-warning condition type).

 * It should be possible to "notice" a warning. eg,
    (CONDITION-BIND ((WARNING #'(LAMBDA (CONDITION)
				  (PUSH CONDITION *LIST-OF-WARNINGS*))))
      ...)

 * It should be possible to muffle a warning. eg,
    (CONDITION-BIND ((WARNING #'(LAMBDA (CONDITION)
				  (IF (... some test ...) (SKIP-WARNING CONDITION)))))
      ...)
   Note that SKIP-WARNING was just made up for the purpose of this message. 
   A better name would be a good idea.

 * It should be possible to reword a warning. eg,
    (CONDITION-BIND ((WARNING #'(LAMBDA (CONDITION)
			          (WHEN (... some test ...)
				    (... alternate I/O or call to WARN ...)
				    (SKIP-WARNING CONDITION)))))
      ...)

Does anyone else have thoughts on how we should pin this down?

∂16-Apr-86  1416	Daniels.pa@Xerox.COM 	Re: Error Proposal #5 questions  
Received: from XEROX.COM by SU-AI.ARPA with TCP; 16 Apr 86  14:16:29 PST
Received: from Salvador.ms by ArpaGateway.ms ; 16 APR 86 14:17:21 PST
Date: 16 Apr 86 13:54 PST
From: Daniels.pa@Xerox.COM
Subject: Re: Error Proposal #5 questions
In-reply-to: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>'s message of Tue,
 1 Apr 86 02:59 EST
To: KMP@SCRC-STONY-BROOK.ARPA
cc: Daniels.pa@Xerox.COM, CL-Error-Handling@SU-AI.ARPA
Message-ID: <860416-141721-1548@Xerox>

I've thought about adding supplied-p parameters to proceed functions.
They're not a whole lot of use since the only place you'd be able to
reference them is in later parameters of the proceed-function. There's
no good way to pass them on to the proceed case itself. However, since
the var list of a proceed function is essentially an &optional arglist
we should go ahead and let people put them in.

		-- Andy. --

∂16-Apr-86  1813	Daniels.pa@Xerox.COM 	Error Proposal #5: difficulties and suggestions 
Received: from XEROX.COM by SU-AI.ARPA with TCP; 16 Apr 86  18:02:31 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 APR 86 14:02:10 PST
Date: 16 Apr 86 13:15 PST
From: Daniels.pa@Xerox.COM
Subject: Error Proposal #5: difficulties and suggestions
To: CL-Error-Handling@SU-AI.ARPA
cc: Daniels.pa@Xerox.COM
Format: TEdit
Message-ID: <860416-140210-153@Xerox>

I've just finished an implementation of the error system and would like
to share some of the things I ran across that pose a problem.

First, I believe there should be a way to set default handlers, report
methods and default tests for proceed cases other than redefining the
object in question. This isn't a big deal, but it does provide the user
some flexibility. This can cause problems if you're depending on default
handlers to ensure that SERIOUS-CONDITION ends up in the debugger if it
isn't handled, but I'd rather handle that directly in the code. That is,
ERROR always calls debug after signalling the condition and SIGNAL calls
debug after signalling if the condition is of type SERIOUS-CONDITION. 

The rest of the questions have to do with proceed cases. First of all,
for a given PROCEED-CASE form must the selectors be unique? I propose
that they not be. I can imagine writing a PROCEED-CASE in which
different arms with the same selector were enabled at different times by
their :TEST methods. Allowing this only adds a small complication to the
implementation of PROCEED-CASE: instead of using the proceed case name
as the selector, you need to generate a value that is carried along with
the PROCEED-CASE object that represents that arm. An integer suffices
for this.

Proceed functions appear to serve two purposes: they are a repository
for default information for that proceed type (test, report,
parameter-gathering), and they provide a simple way to find and invoke
proceed cases. These two functions are somewhat at odds with one another
when you are invoking a proceed case from an interactive debugger. In
this situation, the user has picked a particular proceed case that
should be invoked, so the obvious thing to do is call
INVOKE-PROCEED-CASE. Unfortunately, this will not use the
parameter-gathering mechanism specified in the proceed function. If
instead you see if there is a proceed function defined for that proceed
case and invoke it to get the parameter-gathering done, the proceed
function can end up invoking the wrong proceed case if there are others
with the same name that are more recently bound.

To illustrate, consider the following (somewhat contrived) code:

(define-proceed-function use-value
  (v (eval (prompt-and-read "Enter expression to be EVALed: ")
)))

(block outer
  (condition-bind
    ((foo-error
     #'(lambda (condition)
         (proceed-case (error 'foo-error)
           (use-value (ignore x) :test true
             :report "Return to inner proceed-case"
             (return-from outer (values x 'inner)))))))
    (proceed-case (error 'foo-error) 
      (use-value (ignore x) :test true
        :report "Return to outer proceed-case"
        (values x 'outer)))
  )
)

Evaluating this will land you in the debugger with FOO-ERROR. You might
see something like:

	Error FOO-ERROR.
	1 - Return to inner proceed case
	2 - Return to outer proceed case
	Selection: 

Now, the user picks selection 2. If the debugger implements proceeding
by simply invoking the given proceed case, the final values are NIL
OUTER. If the debugger instead invokes the proceed function, the user
will be prompted for a new value, say 7, and the final values will be 7
INNER. Not quite what the user asked for.

To fix this problem I propose giving proceed functions another implicit
parameter, PROCEED-CASE. If this is NIL then the proceed function
behaves as it does now: it finds the most recently bound proceed case
with that name and invokes it. If a proceed-case is supplied, it will
invoke that one specifically if it is currently enabled. It is an error
to provide a proceed case whose name differs from the proceed function.
If the proceed case is not enabled, the proceed function simply returns
NIL.

		-- Andy. --

∂18-Apr-86  2012	KMP@SCRC-STONY-BROOK.ARPA 	Error Proposal #5: difficulties and suggestions 
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 18 Apr 86  20:11:58 PST
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 466467; Fri 18-Apr-86 01:27:26-EST
Date: Fri, 18 Apr 86 01:27 EST
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5: difficulties and suggestions
To: Daniels.pa@Xerox.COM
cc: CL-Error-Handling@SU-AI.ARPA
In-Reply-To: <860416-140210-153@Xerox>
Message-ID: <860418012754.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

    Date: 16 Apr 86 13:15 PST
    From: Daniels.pa@Xerox.COM

    I've just finished an implementation of the error system and would like
    to share some of the things I ran across that pose a problem.

    First, I believe there should be a way to set default handlers, report
    methods and default tests for proceed cases other than redefining the
    object in question. This isn't a big deal, but it does provide the user
    some flexibility. This can cause problems if you're depending on default
    handlers to ensure that SERIOUS-CONDITION ends up in the debugger if it
    isn't handled, but I'd rather handle that directly in the code. That is,
    ERROR always calls debug after signalling the condition and SIGNAL calls
    debug after signalling if the condition is of type SERIOUS-CONDITION. 

Well, it should already invoke the debugger (Moon doesn't like me to say
"calls DEBUG" because he wants to leave leeway for implementations to use
stylized entry points into the debugger other than the user's entry point)
on all conditions that are returned by the signaling process, regardless of
whether they are SERIOUS-CONDITIONs or not. Are you suggesting that we
should flush the idea of the default handler for SERIOUS-CONDITION entering
the debugger (and hence allow (SIGNAL 'a-serious-condition) to not enter
the debugger)?

    The rest of the questions have to do with proceed cases. First of all,
    for a given PROCEED-CASE form must the selectors be unique? I propose
    that they not be. I can imagine writing a PROCEED-CASE in which
    different arms with the same selector were enabled at different times by
    their :TEST methods. Allowing this only adds a small complication to the
    implementation of PROCEED-CASE: instead of using the proceed case name
    as the selector, you need to generate a value that is carried along with
    the PROCEED-CASE object that represents that arm. An integer suffices
    for this.

All this would be done at a level that is invisible to the user-side of things.
I hadn't really explicitly thought about this, but don't think the proposal
was meant to have wording that precluded it. Certainly sounds like a reasonable
thing to do. In any case, it should probably go out of its way to mention that
it's ok since as you say, some obvious implementations might lead to trouble.
I'll make a note to add that.

    Proceed functions appear to serve two purposes: they are a repository
    for default information for that proceed type (test, report,
    parameter-gathering), and they provide a simple way to find and invoke
    proceed cases. These two functions are somewhat at odds with one another
    when you are invoking a proceed case from an interactive debugger. In
    this situation, the user has picked a particular proceed case that
    should be invoked, so the obvious thing to do is call
    INVOKE-PROCEED-CASE. Unfortunately, this will not use the
    parameter-gathering mechanism specified in the proceed function. If
    instead you see if there is a proceed function defined for that proceed
    case and invoke it to get the parameter-gathering done, the proceed
    function can end up invoking the wrong proceed case if there are others
    with the same name that are more recently bound.

    To illustrate, consider the following (somewhat contrived) code:

    (define-proceed-function use-value
      (v (eval (prompt-and-read "Enter expression to be EVALed: ")
    )))

    (block outer
      (condition-bind
	((foo-error
	 #'(lambda (condition)
	     (proceed-case (error 'foo-error)
	       (use-value (ignore x) :test true
		 :report "Return to inner proceed-case"
		 (return-from outer (values x 'inner)))))))
	(proceed-case (error 'foo-error) 
	  (use-value (ignore x) :test true
	    :report "Return to outer proceed-case"
	    (values x 'outer)))
      )
    )

    Evaluating this will land you in the debugger with FOO-ERROR. You might
    see something like:

	    Error FOO-ERROR.
	    1 - Return to inner proceed case
	    2 - Return to outer proceed case
	    Selection: 

    Now, the user picks selection 2. If the debugger implements proceeding
    by simply invoking the given proceed case, the final values are NIL
    OUTER. If the debugger instead invokes the proceed function, the user
    will be prompted for a new value, say 7, and the final values will be 7
    INNER. Not quite what the user asked for.

    To fix this problem I propose giving proceed functions another implicit
    parameter, PROCEED-CASE. If this is NIL then the proceed function
    behaves as it does now: it finds the most recently bound proceed case
    with that name and invokes it. If a proceed-case is supplied, it will
    invoke that one specifically if it is currently enabled. It is an error
    to provide a proceed case whose name differs from the proceed function.
    If the proceed case is not enabled, the proceed function simply returns
    NIL.

Ugh. I understand the problem. I'll have to study the syntax of 
this implicit parameter idea and get back to you. I'll note just 
for fun that you could do something like the following, though I
certainly wouldn't mean to imply that I intended that you do this
or that I'm not embarrassed that this is the only way out or
anything like that...

 (DEFUN INVOKE-DEFAULTED-PROCEED-CASE (CASE CONDITION &REST ARGUMENTS)
   (APPLY #'INVOKE-PROCEED-CASE
	  CASE CONDITION
	  (COND ((NOT (PROCEED-CASE-NAME CASE))		;The easy case
		 ARGUMENTS)
		(T 
		 (LET ((FN #'(LAMBDA ()
			       (APPLY (PROCEED-CASE-NAME CASE)
				      CONDITION ARGUMENTS))))
		   (EVAL `(PROCEED-CASE (FUNCALL ',FN)
			  (,(PROCEED-CASE-NAME CASE)
			   (IGNORE &REST RESOLVED-ARGUMENTS)
			   RESOLVED-ARGUMENTS))))))))

If you agree that this would technically (if not aesthetically) solve 
your problem, then we're at least talking on the same wavelength. I'll 
get back to you with my thoughts on a more reasonable way around the 
problem later.

∂21-Apr-86  1515	Daniels.pa@Xerox.COM 	Re: Error Proposal #5: difficulties and suggestions  
Received: from XEROX.COM by SU-AI.ARPA with TCP; 21 Apr 86  15:13:33 PST
Received: from Semillon.ms by ArpaGateway.ms ; 21 APR 86 15:07:46 PST
Date: 21 Apr 86 14:57 PST
From: Daniels.pa@Xerox.COM
Subject: Re: Error Proposal #5: difficulties and suggestions
In-reply-to: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>'s message of Fri,
 18 Apr 86 01:27 EST
To: KMP@SCRC-STONY-BROOK.ARPA
cc: Daniels.pa@Xerox.COM, CL-Error-Handling@SU-AI.ARPA
Message-ID: <860421-150746-1975@Xerox>

	"(EVAL `(PROCEED-CASE ..."

Ugh, indeed. Yes, this will certainly get around the problem, though not
very elegantly. I'm not too happy about having this spurious proceed
case sitting around if you break while in INVOKE-DEFAULTED-PROCEED-CASE,
but it will do until we come up with the "right" way to fix it. I still
think the right fix is to have a proceed function take an optional
proceed-case argument. I just haven't been able to find any good place
to put it. The obvious place is after the implicit condition argument.
The problem I have with that is that almost all callers of proceed
functions will be condition handlers, and it seems like a nuisance to
have to always put in an extra NIL, like in (USE-VALUE CONDITION NIL
NEW-VALUE).

	"...and hence allow (SIGNAL 'a-serious-condition) to not enter
	the debugger"

I think you misread what I wrote. I was suggesting that SIGNAL check the
type of the condition it signalled and go to the debugger if it was a
SERIOUS-CONDITION instead of depending on a default handler to do it.
Then there wouldn't be any fundamental problem with allowing a user to
change a default handler on the fly. Anyway, yes, I'm suggesting that we
not depend on system-defined default handlers to implement the semantics
of SERIOUS-CONDITION.

	"In any case, it should probably go out of its way to mention that
	it's [using the same proceed-case name] ok"

Clarifications like that are always good. Another fine point that might
be useful to mention is the difference between :TEST TRUE and :CONDITION
CONDITION. The first is more general than the second because the proceed
case will be visible even if a NIL is passed to the proceed function
instead of a condition. This becomes important for things like ABORT,
which will usually not be given any arguments.

In PROCEED-CASE, under the description of :REPORT, you have CONDITION
being bound by default. Shouldn't the variable be something like
PROCEED-CASE, since that's what's being bound rather than a condition?

		-- Andy. --
 

∂05-May-86  1959	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Error Proposal #5: difficulties and suggestions   
Received: from [192.10.41.223] by SU-AI.ARPA with TCP; 5 May 86  19:59:30 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 15416; Mon 5-May-86 22:57:39 EDT
Date: Mon, 5 May 86 22:57 EDT
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5: difficulties and suggestions
To: CL-Error-Handling@SU-AI.ARPA
In-Reply-To: <860416-140210-153@Xerox>,
             <860418012754.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>,
             <860421-150746-1975@Xerox>
Message-ID: <860505225717.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

I'm surprised there has been so little mail on this topic, which last
year was said to be something that was vital to standardize right
away.  I'd like to comment on two points in the conversation.  I hope
you'll forgive me for butchering the original text in order to gather
related conversations together and edit out irrelevant material.

    Date: Fri, 18 Apr 86 01:27 EST
    From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>

	Date: 16 Apr 86 13:15 PST
	From: Daniels.pa@Xerox.COM

	Proceed functions appear to serve two purposes: they are a repository
	for default information for that proceed type (test, report,
	parameter-gathering), and they provide a simple way to find and invoke
	proceed cases. These two functions are somewhat at odds with one another
	when you are invoking a proceed case from an interactive debugger. In
	this situation, the user has picked a particular proceed case that
	should be invoked, so the obvious thing to do is call
	INVOKE-PROCEED-CASE. Unfortunately, this will not use the
	parameter-gathering mechanism specified in the proceed function. If
	instead you see if there is a proceed function defined for that proceed
	case and invoke it to get the parameter-gathering done, the proceed
	function can end up invoking the wrong proceed case if there are others
	with the same name that are more recently bound.

	To fix this problem I propose giving proceed functions another implicit
	parameter, PROCEED-CASE. If this is NIL then the proceed function
	behaves as it does now: it finds the most recently bound proceed case
	with that name and invokes it. If a proceed-case is supplied, it will
	invoke that one specifically if it is currently enabled.

	I just haven't been able to find any good place
	to put it. The obvious place is after the implicit condition argument.
	The problem I have with that is that almost all callers of proceed
	functions will be condition handlers, and it seems like a nuisance to
	have to always put in an extra NIL, like in (USE-VALUE CONDITION NIL
	NEW-VALUE).

    Ugh. I understand the problem. I'll have to study the syntax of 
    this implicit parameter idea and get back to you. I'll note just
    for fun that you could do something like the following....

I think you're both standing on your head to find some indirect way to
do this.  Why not just tell the computer directly what you want?
(PROMPT-AND-INVOKE-PROCEED-CASE proceed-case condition) would be a
reasonable syntax to say "prompt the user for the arguments to this
proceed case and then invoke it."  But let's look a little more
carefully at what you're asking for.

The exact division of labor between language (standardized) and
environment (not standardized) could be improved here.  There are three
basic mechanisms: selecting a proceed case, gathering arguments to it,
and invoking it.  Only two of these three operations were provided as
separate primitives in Kent's proposal.  To make the set complete, you
need something like (READ-PROCEED-ARGUMENTS proceed-function-name
condition).  Perhaps the first argument should be proceed-case.

In addition to the primitives, for convenience facilities that package
together several primitives should be provided.  Calling a proceed
function packages all three together.  PROMPT-AND-INVOKE-PROCEED-CASE
would package two of them, but leave selecting the proceed case to its
caller.  Other packaged facilities, such as the debugger itself, aren't
explicitly part of the language.

    Date: 16 Apr 86 13:15 PST
    From: Daniels.pa@Xerox.COM

    I believe there should be a way to set default handlers, report
    methods and default tests for proceed cases other than redefining the
    object in question. This isn't a big deal, but it does provide the user
    some flexibility. This can cause problems if you're depending on default
    handlers to ensure that SERIOUS-CONDITION ends up in the debugger if it
    isn't handled, but I'd rather handle that directly in the code. That is,
    ERROR always calls debug after signalling the condition and SIGNAL calls
    debug after signalling if the condition is of type SERIOUS-CONDITION. 

    I was suggesting that SIGNAL check the
    type of the condition it signalled and go to the debugger if it was a
    SERIOUS-CONDITION instead of depending on a default handler to do it.
    Then there wouldn't be any fundamental problem with allowing a user to
    change a default handler on the fly.

There is a significant confusion about default handlers here and in Kent's
proposal.  The problem is the idea there is only one default handler for
a given condition, and defining a new default handler replaces any old one.
This is contrary to the idea of conditions, which is that when an exceptional
event happens the condition system searches the environment and gives all
interested parties a chance to try to do something about it.

I think the :HANDLE option to DEFINE-CONDITION should be removed.  Instead
default handlers should be defined by

(DEFINE-DEFAULT-CONDITION-HANDLER name-of-handler
				  condition-type-or-list-of-types
				  argument-list
   body)

Executing this form replaces any previous default-condition-handler
named name-of-handler, regardless of what condition it was for, just
like executing a DEFUN with the same name as a previously-defined
function.  When a condition is signalled and all bound handlers decline,
all default handlers whose condition-type-or-list-of-types matches
the condition get a chance.  Unless someone has a better idea, it is
an error to depend on the order of invocation of default handlers.

This way the user can define all the default handlers he wants without
unintentionally damaging the built-in ones on which the system's correct
functioning depends, just as the user can define all the functions she
wants without unintentionally damaging the built-in ones.

I don't think defining the :TEST or :REPORT for DEFINE-PROCEED-FUNCTION
separately from doing the DEFINE-PROCEED-FUNCTION makes as much sense.
Do you have examples of how this would be used?

∂05-May-86  2008	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Error Proposal #5: Warnings   
Received: from [192.10.41.223] by SU-AI.ARPA with TCP; 5 May 86  20:06:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 15419; Mon 5-May-86 23:04:34 EDT
Date: Mon, 5 May 86 23:04 EDT
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5: Warnings
To: CL-ERROR-HANDLING@SU-AI.ARPA
In-Reply-To: <860404131744.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Message-ID: <860505230413.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Fri, 4 Apr 86 13:17 EST
    From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
    Here are a couple of possible ways to refine the proposal ...

     * We could say that WARNING has a default handler which does the typeout 
       and that the WARN function is basically like SIGNAL except that the 
       default type of condition signalled is SIMPLE-WARNING instead of
       SIMPLE-CONDITION. This has the bad problem that if you do something
       like (WARN 'STREAM-ERROR) you enter the debugger instead of getting a
       warning typed out since the default handler for STREAM-ERROR goes into
       the debugger.

     * We could say that WARNING doesn't have any special default handler 
       (just gets used for type inclusion so that people can handle it). In that
       case, the implementation of WARN might look like:
	 (PROCEED-CASE (PROGN (SIGNAL ...)
			      (FORMAT *ERROR-OUTPUT* "Warning: ~A." condition))
	   (SKIP-WARNING ()))
       would be best. That way, WARN will SIGNAL and upon return (if there is
       a return) will always do a warning even for non-WARNING-based conditions.
       unless some handler specifically specifies that the warning should be skipped.
       This has the same problem that you enter the debugger on 
       (WARN 'UNBOUND-VARIABLE ...) but at least you have the knowledge that if
       that entry to the debugger had returned (which it can't unless you use 
       special debugger commands that would be beyond the scope of this proposal)
       it -would have- typed a warning.

     * Another, completely different, way we could go at it would be to say that WARN
       does roughly:
   
	(PROCEED-CASE (LET ((C (MAKE-CONDITION ...hair based on arg types...)))
			(SIGNAL 'WARNING :ENCAPSULATED-CONDITION C)
			(FORMAT *ERROR-OUTPUT* "Warning: ~A." C))
	  (SKIP-WARNING ()))
   
       so that the given condition is not actually signalled but a known type is. 
       In that case, we could flush SIMPLE-WARNING since the encapsulated condition
       could just be type SIMPLE-CONDITION if no condition type was specified.

    Of course, it could just avoid the problem of non-WARNING-based conditions by
    erring if the given condition type was not a subtype of WARNING.

I think this last suggestion is by far the most sensible.  Why should we cater to
people who want to pass bogus arguments to the WARN function?  Just say that it is
an error to pass a condition or a condition-type that is not a subtype of WARNING.

    I think the important things to achieve with WARN are:

     * In general, it should type a warning on the console.

     * It should not be easy to trick it into -not- typing a warning (eg, by giving
       it a non-warning condition type).

     * It should be possible to "notice" a warning. eg,
	(CONDITION-BIND ((WARNING #'(LAMBDA (CONDITION)
				      (PUSH CONDITION *LIST-OF-WARNINGS*))))
	  ...)

     * It should be possible to muffle a warning. eg,
	(CONDITION-BIND ((WARNING #'(LAMBDA (CONDITION)
				      (IF (... some test ...) (SKIP-WARNING CONDITION)))))
	  ...)
       Note that SKIP-WARNING was just made up for the purpose of this message. 
       A better name would be a good idea.

     * It should be possible to reword a warning. eg,
	(CONDITION-BIND ((WARNING #'(LAMBDA (CONDITION)
				      (WHEN (... some test ...)
					(... alternate I/O or call to WARN ...)
					(SKIP-WARNING CONDITION)))))
	  ...)

All of these seem to work straightforwardly with your last suggestion,
but each of your three asterisked suggestions breaks one or more of
these goals.


∂06-May-86  1302	JAR@MC.LCS.MIT.EDU 	Error Proposal #5: difficulties and suggestions   
Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 6 May 86  13:00:27 PDT
Date: Tue,  6 May 86 16:02:02 EDT
From: Jonathan A Rees <JAR@MC.LCS.MIT.EDU>
Subject:  Error Proposal #5: difficulties and suggestions
To: Moon@SCRC-STONY-BROOK.ARPA
cc: CL-Error-Handling@SU-AI.ARPA
In-reply-to: Msg of Mon 5 May 86 22:57 EDT from David A. Moon <Moon at SCRC-STONY-BROOK.ARPA>
Message-ID: <[MC.LCS.MIT.EDU].905360.860506.JAR>

    Date: Mon, 5 May 86 22:57 EDT
    From: David A. Moon <Moon at SCRC-STONY-BROOK.ARPA>

    I'm surprised there has been so little mail on this topic, which last
    year was said to be something that was vital to standardize right
    away....

I conjecture that the reason there has been so little discussion is that
the proposal is so good no one can find much in it to criticize.

∂06-May-86  1312	FAHLMAN@C.CS.CMU.EDU 	Error Proposal #5: difficulties and suggestions 
Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 6 May 86  13:11:28 PDT
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Tue 6 May 86 16:12:05-EDT
Date: Tue, 6 May 1986  16:12 EDT
Message-ID: <FAHLMAN.12204596708.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To:   CL-Error-Handling@SU-AI.ARPA
Subject: Error Proposal #5: difficulties and suggestions
In-reply-to: Msg of 6 May 1986  16:02-EDT from Jonathan A Rees <JAR at MC.LCS.MIT.EDU>


I believe that KMP was going to produce a nearly-portable implementaiton
matching his proposal?  Is that still the plan?  For something like an
error system, it's hard to know what is awkward and what is nice until
you've used it for real.  I'd like to have some experience outside the
Lisp Machine environment on this stuff BEFORE we make it an official
part of Common Lisp.

-- Scott

∂07-May-86  1739	KMP@SCRC-STONY-BROOK.ARPA 	Error Proposal #5: difficulties and suggestions 
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 7 May 86  17:39:39 PDT
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 482287; Wed 7-May-86 14:15:22-EDT
Date: Wed, 7 May 86 14:16 EDT
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5: difficulties and suggestions
To: Fahlman@C.CS.CMU.EDU, CL-Error-Handling@SU-AI.ARPA
In-Reply-To: <FAHLMAN.12204596708.BABYL@C.CS.CMU.EDU>
Message-ID: <860507141605.8.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

    Date: Tue, 6 May 1986  16:12 EDT
    From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>

    I believe that KMP was going to produce a nearly-portable implementaiton
    matching his proposal?  Is that still the plan?  For something like an
    error system, it's hard to know what is awkward and what is nice until
    you've used it for real.  I'd like to have some experience outside the
    Lisp Machine environment on this stuff BEFORE we make it an official
    part of Common Lisp.

Jonathan Rees had volunteered do the implementation. I'd been psyched about
that because I was hoping to get some feedback from someone who hadn't used
the LispM about how intelligible the English of the proposal was based on their
having tried to implement it without seeing any code from me. I'd like the
implementation not to be the proposal since that could lead to complications.

Jonathan got bogged down with other commitments, though, and so asked to be
let off the hook. I'm pretty sure it's only about a day's work to bring up,
but I've been very busy and I haven't had a day free in the past two or so months. 
I have free time coming up later this month and hope to get to it then...
Anyone who's in a hurry is of course free to pick up the spec and do a
portable implementation sooner if their schedule is more open than mine.
				     
I'm very pleased that Daniels@Xerox has been able to work from the spec 
and derive a running version to play with, though, because that will give us
the kind of feedback I was originally hoping to get from Jonathan. I have
the impression that his implementation is either not portable or is proprietary,
but hopefully after he's played with it a bit he'll at least give us the feedback
about whether there are big holes in the spec (we've already heared some 
comments about that) and whether the features provided are interesting, 
easy-to-learn, useful, etc.

∂07-May-86  1818	Daniels.pa@Xerox.COM 	Re: Error Proposal #5: difficulties and suggestions  
Received: from XEROX.COM by SU-AI.ARPA with TCP; 7 May 86  18:18:53 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 07 MAY 86 18:13:26 PDT
Date: 7 May 86 18:07 PDT
From: Daniels.pa@Xerox.COM
Subject: Re: Error Proposal #5: difficulties and suggestions
In-reply-to: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>'s message of Wed,
 7 May 86 14:16 EDT
To: KMP@SCRC-STONY-BROOK.ARPA
cc: Fahlman@C.CS.CMU.EDU, CL-Error-Handling@SU-AI.ARPA
Message-ID: <860507-181326-2172@Xerox>

My implementation isn't portable, but certainly could be made so - I've
stuck to straight Common Lisp for the most part. If I get a short break
in my schedule I could try to produce one.

		-- Andy. --

∂07-May-86  1826	FAHLMAN@C.CS.CMU.EDU 	Error Proposal #5: difficulties and suggestions 
Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 7 May 86  18:26:22 PDT
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Wed 7 May 86 21:26:22-EDT
Date: Wed, 7 May 1986  21:26 EDT
Message-ID: <FAHLMAN.12204916036.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To:   Daniels.pa@XEROX.COM
Cc:   CL-Error-Handling@SU-AI.ARPA, KMP@SCRC-STONY-BROOK.ARPA
Subject: Error Proposal #5: difficulties and suggestions
In-reply-to: Msg of 7 May 1986  21:07-EDT from Daniels.pa at Xerox.COM


Ever get the feeling that we're all so busy we can't get anything done?
I certainly do.  I've got some people working for me this summer who
could probably do this job, but it would be quicker for someone who has
already begun work on this stuff.  I'll wait awhile for one of you to
get around to this, and if you're all too tied up I'll see if we can do
the job here at CMU.

-- Scott

∂08-May-86  1653	jeff%aiva.edinburgh.ac.uk@Cs.Ucl.AC.UK 	Re:  Error Proposal #5: difficulties and suggestions   
Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 8 May 86  16:53:14 PDT
Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK   via Janet with NIFTP
           id a000144; 8 May 86 18:17 BST
From: Jeff Dalton <jeff%aiva.edinburgh.ac.uk@Cs.Ucl.AC.UK>
Date: Thu, 8 May 86 18:15:48 -0100
Message-Id: <25292.8605081715@aiva.ed.ac.uk>
To: CL-Error-Handling@su-ai.arpa, Fahlman@c.cs.cmu.edu, 
    KMP@scrc-stony-brook.arpa
Subject: Re:  Error Proposal #5: difficulties and suggestions

   Date: Wed, 7 May 86 14:16 EDT
   From: Kent M Pitman <KMP@arpa.scrc-stony-brook>

   Jonathan Rees had volunteered do the implementation. I'd been psyched about
   that because I was hoping to get some feedback from someone who hadn't used
   the LispM about how intelligible the English of the proposal was based on
   their having tried to implement it without seeing any code from me.

   Anyone who's in a hurry is of course free to pick up the spec and do a
   portable implementation sooner if their schedule is more open than mine.
                    
For what it's worth, I implemented the #4 version of the proposal a while ago,
and found the specification fairly, but not entirely, clear.  Most of my
questions were answered by proposal #5, but I haven't yet had time to write
another implementation.  (Besides, I thought the portable one would appear any
day.)  I do think it's an excellent way to test the proposal, though, and I
may find time to try again.

The main reason for doing an implementation was that I'd never used a LispM
and couldn't really understand how it was all supposed to fit together.  It
was only after I'd written the code that I could see more or less how it was
supposed to work.
   
My guess is that other people may have had similar problems and were waiting
for something to play with before trying to discuss the proposal.

-- Jeff

∂09-May-86  1432	KMP@SCRC-STONY-BROOK.ARPA 	Error Proposal #5: difficulties and suggestions 
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 9 May 86  14:32:20 PDT
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 484606; Fri 9-May-86 16:01:14-EDT
Date: Fri, 9 May 86 16:02 EDT
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Error Proposal #5: difficulties and suggestions
To: jeff%aiva.edinburgh.ac.uk@UCL-CS.ARPA
cc: CL-Error-Handling@SU-AI.ARPA, KMP@SCRC-STONY-BROOK.ARPA
In-Reply-To: <25292.8605081715@aiva.ed.ac.uk>
Message-ID: <860509160212.6.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

    Date: Thu, 8 May 86 18:15:48 -0100
    From: Jeff Dalton <jeff%aiva.edinburgh.ac.uk@Cs.Ucl.AC.UK>

    ... The main reason for doing an implementation was that I'd never used a LispM
    and couldn't really understand how it was all supposed to fit together.  It
    was only after I'd written the code that I could see more or less how it was
    supposed to work. ...
   
I'm glad you've also taken the time to do an implementation, even if it involved
a previous proposal. I'm very concerned that people's feelings not all derive from
the 3600 unless we're going to define that the 3600 implementation is going to -be- 
the standard -- which would be silly.

My work with Macsyma and converting it to Common Lisp have caused me to realize
just how many places the Common Lisp spec is weak and how hard it is to write a
portable program. The problem isn't that Common Lisp isn't trying, but that often
things I think are specified are really not fully specified and not as easy to 
depend on as I might have guessed. 

My feeling is that the fuzziness of the spec often resulted from people taking 
things for granted -- not realizing there were important things they should write
down clearly. The result is that someone who has never talked to us and who just
sits down with the manual and writes an implementation based only on what we wrote
down may end up with a very different thing than we might expect. The only thing
truly portable programs can rely on are the things which are common between the
implementations we're familiar with and the implementations that were written
by strangers. That's often not as much as we might guess.

If we want to really make this error system usable in portable code, we may have 
to tighten up quite a lot of details or risk misinterpretation. The more people
find out about the LispM, the more they may take for granted, hence my concern 
that people try to understand the spec in the abstract or even try to do their 
own personal implementations -- not necessarily for production -- just as a 
learning exercise, as you have done.

I hope that if you or Daniels@Xerox or others have done some of the work to figure 
out what this error system is all about without `cheating' and looking at the 3600
implementation, that you'll provide us with some good feedback about questions,
concerns, etc.

I'm heartened to hear that proposal 5 seemed more specific than proposal 4. 
Hopefully with the comments we've gotten back from Daniels, it'll get more 
specific yet. 

Everyone should please keep those cards and letters coming.

∂27-May-86  1910	KMP@SCRC-STONY-BROOK.ARPA 	Sample error system implementation coming soon  
Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 27 May 86  19:09:56 PDT
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 8610; Tue 27-May-86 22:10:51 EDT
Date: Tue, 27 May 86 22:07 EDT
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Sample error system implementation coming soon
To: CL-ERROR-HANDLING@SU-AI.ARPA
Message-ID: <860527220739.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>

Since I'm still pretty busy and don't have whole days to alot, I've managed
to find a few hours here and there to put together a sample implementation.
The total time required was only about 7 hours, including coding, debugging, 
and writing some example code, so if people end up liking the idea but not 
the implementation, it shouldn't be a big deal for them to code up an alternative. 

Snapping it natively into a system instead of structuring it as an add-on might
involve a little more work, of course, since there are infinite possibilities
for adding features once the basic mechanism is in place.

I made notes about the difficulties I had along the way. Many of them are the
same problems that Daniels had, and now that I've done the implementation I
think I can make some better suggestions about what we should do about them.
Further discussion of these issues will follow in a couple of days.

I'm having a couple people play with it locally for a day or two to make 
sure the thing feels respectable before I bother sending it out to everyone.
This preliminary message is just to the alert people who are in a hurry that
we've made progress and that they should have something in their hands soon.

Stay tuned.
 -kmp