1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Issues/iss049_w.htm
2024-04-01 10:24:07 +02:00

261 lines
16 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Issue CLOS-CONDITIONS Writeup</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="../Issues/iss048_w.htm">
<LINK REL=UP HREF="../Issues/iss049.htm">
<LINK REL=NEXT HREF="../Issues/iss050_w.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="../Issues/iss048_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss049.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss050_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue CLOS-CONDITIONS Writeup</H2>
<PRE><B>Status:</B> DRAFT<P>
<B>Issue:</B> <A HREF="iss049.htm">CLOS-CONDITIONS</A><P>
<B>References:</B> Condition System (Revision 18)<P>
<B>Category:</B> ADDITION<P>
<B>Edit history:</B> 26-Sep-88, Version 1 by Pitman<P>
06-Oct-88, Version 2 by Pitman<P>
09-Oct-88, Version 3 by Pitman<P>
10-Mar-89, Version 4 by Pitman (remove unsupported options)<P>
<P>
<B>Problem Description:<P>
</B><P>
The description of the Common Lisp condition system presupposes<P>
only <A REL=DEFINITION HREF="../Body/m_defstr.htm#defstruct"><B>DEFSTRUCT</B></A> and not <A REL=DEFINITION HREF="../Body/m_defcla.htm#defclass"><B>DEFCLASS</B></A> because it was written when<P>
CLOS had not been adopted. It is stylistically out of step with<P>
CLOS in a few places and places some restrictions which are not<P>
necessary if CLOS can be presupposed.<P>
<P>
<B>Proposal (CLOS-CONDITIONS:INTEGRATE):<P>
</B><P>
1. Define that condition types are CLOS classes.<P>
<P>
2. Define that condition objects are CLOS instances.<P>
<P>
3. Functions such as <A REL=DEFINITION HREF="../Body/f_signal.htm#signal"><B>SIGNAL</B></A>, which take arguments of <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> names, are<P>
permitted to take <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> objects. Such <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> objects must still be<P>
subclasses of <A REL=DEFINITION HREF="../Body/e_cnd.htm#condition"><B>CONDITION</B></A>.<P>
<P>
4. Define that slots in condition objects are normal CLOS slots. Note<P>
that <A REL=DEFINITION HREF="../Body/m_w_slts.htm#with-slots"><B>WITH-SLOTS</B></A> can be used to <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> more convenient access to the<P>
slots where slot accessors are undesirable.<P>
<P>
5. Incompatibly change the syntax of a slot in <A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A><P>
to be compatible with a <A REL=DEFINITION HREF="../Body/m_defcla.htm#defclass"><B>DEFCLASS</B></A> slot specification.<P>
<P>
An implication of this change is that forms like<P>
(<A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> FOO (BAR) ((A 1) (B 2)))<P>
would have to be written<P>
(<A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> FOO (BAR)<P>
((A :INITARG :A :READER FOO-A :INITFORM 1)<P>
(B :INITARG :B :READER FOO-B :INITFORM 2)))<P>
<P>
6. Permit multiple parent-types to be named in the list of parent types.<P>
Define that these parent types are treated the same as the superior<P>
<A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> list in a CLOS <A REL=DEFINITION HREF="../Body/m_defcla.htm#defclass"><B>DEFCLASS</B></A> expression.<P>
<P>
7. Eliminate the :CONC-NAME option to <A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A>.<P>
<P>
8. Define that condition reporting is mediated through the <A REL=DEFINITION HREF="../Body/f_pr_obj.htm#print-object"><B>PRINT-OBJECT</B></A><P>
<A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A> for the condition type (<A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A>) in question, with <A REL=DEFINITION HREF="../Body/v_pr_esc.htm#STprint-escapeST"><B>*PRINT-ESCAPE*</B></A><P>
always being <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>. Specifying (:REPORT fn) in the definition of a<P>
condition type C is equivalent to doing <P>
(<A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A> <A REL=DEFINITION HREF="../Body/f_pr_obj.htm#print-object"><B>PRINT-OBJECT</B></A> ((X c) <A REL=DEFINITION HREF="../Body/t_stream.htm#stream"><B>STREAM</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>IF</B></A> <A REL=DEFINITION HREF="../Body/v_pr_esc.htm#STprint-escapeST"><B>*PRINT-ESCAPE*</B></A> (<A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A>) (fn X <A REL=DEFINITION HREF="../Body/t_stream.htm#stream"><B>STREAM</B></A>)))<P>
<P>
<B>Rationale:<P>
</B><P>
These changes are consistent with the intent of the X3J13 endorsement<P>
of CLOS and the Common Lisp Condition System.<P>
<P>
Although items 5 and 7 are incompatible with the interim condition<P>
handling which we've been working with, the overall proposal significantly<P>
improves compatibility with CLOS.<P>
<P>
This compatibility will make the language seem less fragmented, and<P>
probably more learnable because there will be fewer paradigms to learn.<P>
<P>
Also, items 5 and 7 in particular are an improvement for reasons<P>
unrelated to CLOS if only because they get rid of the need for symbol<P>
concatenation, a process which has been seen to cause problems because<P>
of the transient nature of the binding of <A REL=DEFINITION HREF="../Body/v_pkg.htm#STpackageST"><B>*PACKAGE*</B></A>.<P>
<P>
<B>Examples:<P>
</B><P>
Slot specifiers...<P>
<P>
A slot specifier of X is still valid but is incompatibly<P>
changed to mean what CLOS has it mean; no :INITARG or <P>
:READER would be supplied.<P>
<P>
A slot specifier of (X) is still valid but is incompatibly<P>
changed to mean what CLOS has it mean; no :INITARG or <P>
:READER would be supplied.<P>
<P>
A slot specifier of (X V) would no longer be valid.<P>
<P>
In addition, other slot specifiers such as<P>
(X :INITARG :EX :TYPE <A REL=DEFINITION HREF="../Body/t_fixnum.htm#fixnum"><B>FIXNUM</B></A>)<P>
are permitted as in <A REL=DEFINITION HREF="../Body/m_defcla.htm#defclass"><B>DEFCLASS</B></A>.<P>
<P>
Conc names ...<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> FOOBAR (FOO BAR) (X Y) (:CONC-NAME FUBAR))<P>
would be rewritten<P>
(<A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> FOOBAR (FOO BAR)<P>
((X :INITARG :X :READER FUBAR-X)<P>
(Y :INITARG :Y :READER FUBAR-Y)))<P>
<P>
Report methods ...<P>
<P>
(<A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> OOPS (<A REL=DEFINITION HREF="../Body/a_error.htm#error"><B>ERROR</B></A>) ())<P>
(<A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A> <A REL=DEFINITION HREF="../Body/f_pr_obj.htm#print-object"><B>PRINT-OBJECT</B></A> ((X OOPS) <A REL=DEFINITION HREF="../Body/t_stream.htm#stream"><B>STREAM</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>IF</B></A> <A REL=DEFINITION HREF="../Body/v_pr_esc.htm#STprint-escapeST"><B>*PRINT-ESCAPE*</B></A> <P>
(<A REL=DEFINITION HREF="../Body/f_call_n.htm#call-next-method"><B>CALL-NEXT-METHOD</B></A>)<P>
(<A REL=DEFINITION HREF="../Body/f_format.htm#format"><B>FORMAT</B></A> <A REL=DEFINITION HREF="../Body/t_stream.htm#stream"><B>STREAM</B></A> &quot;Oops! Something went wrong.&quot;)))<P>
(<A REL=DEFINITION HREF="../Body/a_error.htm#error"><B>ERROR</B></A> 'OOPS)<P>
&gt;&gt;Error: Oops! Something went wrong.<P>
<P>
<P>
<B>Current Practice:<P>
</B><P>
Some implementations supporting CLOS probably already do this,<P>
or something very similar.<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
If you really have CLOS, this is very straightforward.<P>
<P>
<B>Cost to Users:<P>
</B><P>
Small, but tractable.<P>
<P>
The main potential problems are:<P>
<P>
- :CONC-NAME. There is nothing that keeps an implementation from<P>
continuing to support :CONC-NAME for a short while until old code<P>
has been upgraded.<P>
<P>
- The incompatible change to slot syntax. Again, it is possible to<P>
unambiguously recognize a 2-list as old-style syntax and an<P>
implementation can <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> interim compatibility support during<P>
a transition period.<P>
<P>
Even if implementations did not <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> the recommended compatibility<P>
support, users could trivially shadow <A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> and <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> the<P>
support themselves, expanding into the native <A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> in the<P>
proper syntax.<P>
<P>
In any case, the total number of uses of <A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> at this <P>
point is probably quite small. Searching for them and repairing<P>
each by hand is probably not an expensive operation.<P>
<P>
<B>Cost of Non-Adoption:<P>
</B><P>
Conditions will seem harder to manipulate than other user-defined types.<P>
<P>
People will wonder if CLOS is really something we're committed to.<P>
<P>
<B>Benefits:<P>
</B><P>
A more regular, more learnable language.<P>
<P>
<B>Aesthetics:<P>
</B><P>
Improved.<P>
<P>
<B>Discussion:<P>
</B><P>
Gregor, Pierson, Moon, and Pitman support this proposal.<P>
<P>
People seem to disagree about the status that CLOS might occupy<P>
in the upcoming <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A>. In spite of a vote of support, they seem<P>
to think it might be optional in some way. Passing this proposal<P>
establishes a clear precedent for the full integration of CLOS into<P>
the emerging language.<P>
<P>
The sense of the cleanup committee was that it was acceptable for<P>
a vendor to identify a CLOS-free subset of Common Lisp, but that since<P>
the position of X3J13 seems to be that no resources should be devoted<P>
to work on subsets, it was inappropriate for us to work out the details<P>
of that subset ourselves. Since nothing about this proposal would<P>
impede such a subset, we took that to be adequate basis for presenting<P>
this single proposal.<P>
<P>
Moon thinks we might want to add condition types for the errors<P>
CLOS might signal. Richard Mlynarik thinks we should add a generic<P>
function, REPORT-CONDITION, which is used for reporting conditions.<P>
Both of these issues should probably be pursued under separate cover.<P>
<P>
<P>
!<P>
&quot;One comment is that you should explicitly mention bootstrapping<P>
concerns under cost to implementors. If you just leave it out,<P>
someone may think it is a difficult problem. &quot;<P>
<P>
&quot;This isn't any sort of clarification. The actual clarification required<P>
-- which has been requested several times, and not just by myself -- is<P>
what the *METACLASS* of condition types is.<P>
<P>
Condition types may be &quot;CLOS classes&quot; without being STANDARD-CLASSes<P>
Condition objects may be &quot;CLOS instances&quot; without being STANDARD-OBJECTs.<P>
Just what are &quot;normal CLOS slots&quot;? As I see it, the &quot;normalcy&quot; or<P>
otherwise of slots is determined by the metaclass.<P>
<P>
<P>
My opinion for some time has been that condition types should not be<P>
STANDARD-CLASSes but instead something like READ-ONLY-CLASS.<P>
Conceptually, It Is An Error to modify the slots of condition objects,<P>
which are supposed to be immutable descriptions of part of the state of<P>
a computation. Implementationally,<P>
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_slt_va.htm#slot-value"><B>slot-value</B></A> &lt;condition-object&gt; &lt;slot-name&gt;) &lt;new-value&gt;) should<P>
signal an error.<P>
<P>
(I also think that conditions in particular have a strong need for<P>
something like :REQUIRED-INIT-KEYWORDS, but that's another story.)<P>
<P>
Even if you decide to make condition classes' metaclass <A REL=DEFINITION HREF="../Body/t_std_cl.htm#standard-class"><B>STANDARD-CLASS</B></A>,<P>
the point is that you need to state this, so that users may define<P>
condition classes and mixins using <A REL=DEFINITION HREF="../Body/m_defcla.htm#defclass"><B>DEFCLASS</B></A>.&quot;<P>
<P>
&quot;I do not agree that it is a -necessary- thing to specify the Meta-Class<P>
of conditions because all intended uses of conditions can be done<P>
without this information.<P>
<P>
I agree that it is a -possibly useful- thing to do, but there is a down<P>
side to it -- it would unnecessarily tie the hands of people who want<P>
implementation flexibility for one reason or another.&quot;<P>
<P>
&quot;... If we don't specify the metaclass, then users<P>
won't know what other classes they can mix in when defining condition<P>
classes. It may seem weird, but I can imagine someone wanting to mix<P>
in an arbitrary <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> into a condition <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A>.<P>
<P>
I think we should just say that the <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> <A REL=DEFINITION HREF="../Body/e_cnd.htm#condition"><B>CONDITION</B></A> is an instance of<P>
<A REL=DEFINITION HREF="../Body/t_std_cl.htm#standard-class"><B>STANDARD-CLASS</B></A>, and that by default <A REL=DEFINITION HREF="../Body/m_defi_5.htm#define-condition"><B>DEFINE-CONDITION</B></A> defines <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A><P>
classes. Sure it might be nice to do the read only <A REL=DEFINITION HREF="../Body/t_class.htm#class"><B>class</B></A> thing but I<P>
don't think this is a good time to design a special purpose metaclass<P>
for this. &quot;<P>
<P>
<P>
<P>
</PRE>
<HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>