[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Issue: CLOS-CONDITIONS (Version 3)
- To: cl-cleanup@sail.stanford.edu
- Subject: Issue: CLOS-CONDITIONS (Version 3)
- From: masinter.pa@Xerox.COM
- Date: 3 Feb 89 22:30 PST
- Line-fold: NO
I believe I agreed that the cleanup committee would take over this issue. It was discussed in the Error Committee report at a previous meeting in 1988, but not voted on at the time.
As you can see, there are comments...
----- Begin Forwarded Messages -----
Return-Path: <X3J13-mailer@SAIL.Stanford.EDU>
Received: from SAIL.Stanford.EDU ([36.86.0.194]) by Xerox.COM ; 09 OCT 88 02:50:46 PDT
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Oct 88 02:30:05 PDT
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 473546; Sun 9-Oct-88 05:28:47 EDT
Date: Sun, 9 Oct 88 05:28 EDT
From: CL-ERROR-HANDLING@SAIL.Stanford.EDU
Sender: KMP@STONY-BROOK.SCRC.Symbolics.COM
Subject: Draft Issue: CLOS-CONDITIONS (Version 3)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <881009052832.8.KMP@BOBOLINK.SCRC.Symbolics.COM>
There's been some disagreement about a couple of details, so this may
change yet again before we ask you to vote on it, but this is the
version that is likely to be presented for comment at the meeting.
The conflict is represented in the writeup by the presence of two
variant proposals, YES-OPTION-A and YES-OPTION-B.
-----
Issue: CLOS-CONDITIONS
References: Condition System (Revision 18)
Category: ADDITION
Edit history: 26-Sep-88, Version 1 by Pitman
06-Oct-88, Version 2 by Pitman
09-Oct-88, Version 3 by Pitman
Status: For Internal Discussion
Problem Description:
The description of the Common Lisp condition system presupposes
only DEFSTRUCT and not DEFCLASS because it was written when
CLOS had not been adopted. It is stylistically out of step with
CLOS in a few places and places some restrictions which are not
necessary if CLOS can be presupposed.
Subproposal (CLOS-CONDITIONS:YES):
[These options are very similar. They agree except as otherwise noted.]
Define that condition types are CLOS classes.
Define that condition objects are CLOS instances.
Permit multiple parent-types to be named in the list of
parent types. Define that these parent types are treated the
same as the superior class list in a CLOS DEFCLASS expression.
Define that slots in condition objects are normal CLOS slots.
Note that WITH-SLOTS can be used to provide more convenient
access to the slots where slot accessors are undesirable.
Functions such as SIGNAL, which take arguments of class names,
are permitted to take class objects. Such class objects must
still be subclasses of CONDITION.
Eliminate the :CONC-NAME option to DEFINE-CONDITION.
Define that condition reporting is mediated through the
PRINT-OBJECT method for the condition type (class) in question,
with *PRINT-ESCAPE* always being NIL. Specifying
(:REPORT fn) in the definition of a condition type C is
equivalent to doing
(DEFMETHOD PRINT-OBJECT ((X c) STREAM)
(IF *PRINT-ESCAPE* (CALL-NEXT-METHOD) (fn X STREAM)))
Proposal (CLOS-CONDITIONS:YES-OPTION-A):
All of subproposal YES, plus the following...
Extend the syntax for a slot in a DEFINE-CONDITION as follows...
- If a symbol is used, DEFINE-CONDITION will by special case
treat this as if (symbol :INITARG keyword :READER reader-name)
were specified instead, where KEYWORD is generated by
(INTERN (SYMBOL-NAME symbol) (FIND-PACKAGE "KEYWORD"))
and reader-name is generated by
(INTERN (FORMAT NIL "~A-~A" condition-type symbol))
for CONDITION-TYPE being the condition type being defined.
- A length 1 list, (symbol), is treated the same as providing
the symbol itself.
- If a length 2 list, (symbol value) is provided, it is treated
as (symbol :INITARG keyword :READER reader-name :INITFORM value),
with KEYWORD and READER-NAME being computed as above.
- If a list of length greater than 2 is used, it is treated
the same as a CLOS slot-specifier. In that case, the :INITARG
and :READER options must be explicitly specified if desired.
This syntax is compatible with the existing semantics of
DEFINE-CONDITION.
Rationale:
This provides maximal compatibilty with the old semantics
for DEFINE-CONDITION, which numerous vendors now distribute.
Further, and perhaps more importantly, the uses of slots in
DEFINE-CONDITION are highly constrained. They are not assigned
so an INITARG is nearly always needed. There are almost
universally accessed externally, so a :READER is usually
needed. This syntax makes what is by far the most convenient
use very syntactically simple.
Proposal (CLOS-CONDITIONS:YES-OPTION-B):
Incompatibly change the syntax of a slot in DEFINE-CONDITION
to be compatible with a DEFCLASS slot specification.
An implication of this change is that forms like
(DEFINE-CONDITION FOO (BAR) ((A 1) (B 2)))
would have to be written
(DEFINE-CONDITION FOO (BAR) ((A :INITARG :A :READER FOO-A :INITFORM 1)
(B :INITARG :B :READER FOO-B :INITFORM 2)))
Rationale: This is most compatible with CLOS.
Examples:
Slot specifiers...
Under YES-OPTION-A ...
A slot specifier of X in condition type FOO is still valid
and means the same as (X :INITARG :X :READER FOO-X).
A slot specifier of (X) in condition type FOO is still valid
and means the same as (X :INITARG :X :READER FOO-X).
A slot specifier of (X V) in condition type FOO is still
valid and means the same as
(X :INITARG :X :READER FOO-X :INITFORM V).
In addition, other slot specifiers such as
(X :INITARG :EX :TYPE FIXNUM)
are permitted as in DEFCLASS.
Under YES-OPTION-B ...
A slot specifier of X is still valid but is incompatibly
changed to mean what CLOS has it mean; no :INITARG or
:READER would be supplied.
A slot specifier of (X) is still valid but is incompatibly
changed to mean what CLOS has it mean; no :INITARG or
:READER would be supplied.
A slot specifier of (X V) would no longer be valid.
In addition, other slot specifiers such as
(X :INITARG :EX :TYPE FIXNUM)
are permitted as in DEFCLASS.
Conc names ...
(DEFINE-CONDITION FOOBAR (FOO BAR) (X Y) (:CONC-NAME FUBAR))
would be rewritten
(DEFINE-CONDITION FOOBAR (FOO BAR)
((X :INITARG :X :READER FUBAR-X)
(Y :INITARG :Y :READER FUBAR-Y)))
Report methods ...
(DEFINE-CONDITION OOPS (ERROR) ())
(DEFMETHOD PRINT-OBJECT ((X OOPS) STREAM)
(IF *PRINT-ESCAPE*
(CALL-NEXT-METHOD)
(FORMAT STREAM "Oops! Something went wrong.")))
(ERROR 'OOPS)
>>Error: Oops! Something went wrong.
Rationale:
These changes are consistent with the intent of the recent
X3J13 endorsement of CLOS and the Common Lisp Condition System.
The shorthand notations for DEFINE-CONDITION's slots spec
are justified since the the way in which condition slots are
used is much more highly constrained than for arbitrary classes.
This means we can predict what will be the common case and make
it far more syntactically convenient than it might otherwise be.
Although flushing :CONC-NAME is an incompatible change, nothing
forbids an implementation from supporting it as an extension
during a transition period.
Current Practice:
Some implementations supporting CLOS probably already do this,
or something very similar.
Cost to Implementors:
If you really have CLOS, this is very straightforward.
Cost to Users:
Small, but tractable.
The main potential problems are:
- :CONC-NAME. There is nothing that keeps an implementation from
continuing to support :CONC-NAME for a short while until old code
has been upgraded.
- The incompatible change to slot syntax. Again, it is possible to
unambiguously recognize a 2-list as old-style syntax and an
implementation can provide interim compatibility support during
a transition period.
Even if implementations did not provide the recommended compatibility
support, users could trivially shadow DEFINE-CONDITION and provide the
support themselves, expanding into the native DEFINE-CONDITION in the
proper syntax.
Cost of Non-Adoption:
Conditions will seem harder to manipulate than other user-defined types.
People will wonder if CLOS is really something we're committed to.
Benefits:
A more regular language.
Aesthetics:
Anything that makes the language more regular improves the aesthetics.
Discussion:
People seem to disagree about the status that CLOS might occupy
in the upcoming standard. In spite of a vote of support, they seem
to think it might be optional in some way. Passing this proposal
establishes a clear precedent for the full integration of CLOS into
the emerging language.
Moon suggests that we might want to add condition types for the errors
CLOS might signal. It isn't obvious (to Pitman, at least) that this
change is as straightforward as it looks, though, so it will have to
come up under separate cover.
Richard Mlynarik suggests adding a generic function, REPORT-CONDITION,
which is used for reporting conditions. It is possible to discuss such
a generic function as a separate issue layered atop the substrate which
this proposal provides, so that issue has been deferred.
Pitman supports this change, with mild preference for YES-OPTION-A.
Gregor supports this change, with strong preference for YES-OPTION-B.
----- Next Message -----
Return-Path: <Mly%AI.AI.MIT.EDU@XX.LCS.MIT.EDU>
Received: from XX.LCS.MIT.EDU ([10.0.0.44]) by Xerox.COM ; 30 OCT 88 11:34:02 PST
Received: from NICKB.AI.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 30 Oct 88 14:32-EST
Date: Sun, 30 Oct 88 14:34 EST
From: Richard Mlynarik <Mly@AI.AI.MIT.EDU>
Subject: Re: Draft Issue: CLOS-CONDITIONS (Version 3)
To: masinter.pa
cc: gregor.pa
In-Reply-To: <881026-153859-14085@Xerox>
Included-msgs: <19881007052142.8.MLY@JACKIE.AI.MIT.EDU>
Message-ID: <19881030193406.7.MLY@NICKB.AI.MIT.EDU>
Character-Type-Mappings: (1 0 (NIL 0) (NIL :ITALIC NIL) "CPTFONTI")
Fonts: CPTFONT, CPTFONTI
Date: 26 Oct 88 15:38 PDT
From: masinter.pa@Xerox.COM
I thought there might be a way to word this proposal in a way that would
make the error/signal system *compatible* with CLOS but not to actually
make it require the low-level implementation to *use* CLOS if it didn't
want to. Many vendors are only now working on integrating CLOS into their
environment. A lot of the concern is for "staging" the introduction of CLOS
and the condition system. This is also a concern for those with existing
implementations where they might want to load in the CLOS support late in
the system-building process, and yet use the condition system early in that
process. While this is an implementation detail, the implementation
ramifications of your proposal need to be spelled out.
[...]
I sent the following comments to Pitman.
I guess I don't really care that much about this anymore, since I think
that the error Standard is pretty broken. The phrase ``swimming up
waterfalls'' comes to mind.
Date: Fri, 7 Oct 88 01:21 EDT
From: Richard Mlynarik <MLY@AI.AI.MIT.EDU>
Subject: Issue: CLOS-CONDITIONS (Version 2)
To: KMP@STONY-BROOK.SCRC.SYMBOLICS.COM
cc: Moon@STONY-BROOK.SCRC.SYMBOLICS.COM
In-Reply-To: <881006162757.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <19881007052142.8.MLY@JACKIE.AI.MIT.EDU>
[Mailing list removed]
I had promised myself that I would have no more to do with this
Error Standard but nevertheless...
Date: Thu, 6 Oct 88 16:27 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
The description of the Common Lisp condition system presupposes
only DEFSTRUCT and not DEFCLASS because it was written when
CLOS had not been adopted. It is stylistically out of step with
CLOS in a few places and places some restrictions which are not
necessary if CLOS can be presupposed.
Proposal (CLOS-CONDITIONS:YES):
Define that condition types are CLOS classes.
Define that condition objects are CLOS instances.
This is certainly desirable. However, it ignores a pragmatic problem:
* Even though CLOS has been adopted, it is not widely supported.
(Support means `supplied by vendors' rather than `you can use PCL')
* The error system is much simpler to implement than CLOS.
The error system is perceived to be more critical than CLOS.
(For example, I believe that Lucid supply an implementation of
something like KMP's error system in their 3.0 Lisp release. They do
not supply any CLOS or CLOS-precursor support as far as I know.)
Therefore...
It would be nice if the standard were worded in such a way that it
allowed a non-CLOS implementation. Given that the only
`object-oriented' features that the error standard requires are
* TYPEP
* slot inheritance
* report-function inheritance (with no method-combination)
and since it is very easy to write a toy class system which implements
just those features, let me suggest that the DEFINE-CONDITION macro not
implicitly define :READERs. Readers presuppose CLOS generic functions a
little too much. I feel that a better (interim -- all discussion here
is interim) solution would be to define the function SLOT-VALUE in the
spec. KMP-CONDITION-SYSTEM:SLOT-VALUE will be EQ CLOS:SLOT-VALUE in
Lisp implementations which include a CLOS implementation.
Please note that I am in no way trying to deprecate acceptance or usage
of CLOS -- I want to see it as an integral part of Common Lisp
(especially if define-method-combination worked properly by using
closures instead of manipulating list structure... :-)
Permit multiple parent-types to be named in the list of
parent types. Define that these parent types are treated the
same as the superior class list in a CLOS DEFCLASS expression.
You should explicitly state that the class precedence list is computed
in the way CLOS specifies.
Extend the syntax for a slot in a DEFINE-CONDITION as follows...
- If a symbol is used, DEFINE-CONDITION will by special case
treat this as if (symbol :INITARG keyword :READER reader-name)
were specified instead, where KEYWORD is generated by
(INTERN (SYMBOL-NAME symbol) (FIND-PACKAGE "KEYWORD"))
and reader-name is generated by
(INTERN (FORMAT NIL "~A-~A" condition-type symbol))
for CONDITION-TYPE being the condition type being defined.
- A length 1 list, (symbol), is treated the same as providing
the symbol itself.
- If a length 2 list, (symbol value) is provided, it is treated
as (symbol :INITARG keyword :READER reader-name :INITFORM value),
with KEYWORD and READER-NAME being computed as above.
- If a list of length greater than 2 is used, it is treated
the same as a CLOS slot-specifier. In that case, the :INITARG
and :READER options must be explicitly specified if desired.
I think that this is highly undesirable wording to place in the
specification (but then, it wouldn't be the first time I've thought
that.)
I really don't think that your Standard is entrenched far enough
that backwards compatibility is an issue in its definition. Note that
whether individual ε1implementationsε0 wish to offer such a
backward-compatibility feature is a different matter.
DEFINE-CONDITION (like statice:define-entity-type...) should require the
use of the standard :INITFORM option. I'm of two minds about whether
DEFINE-CONDITION should default the :INITARG. I lean towards having it
do so, with the prosiso that the initarg be exactly the symbol, *NOT* a
keyword. My reasons for this are as follows:
* I can't think of a single case in which it is undesirable for the
caller of MAKE-CONDITION to be able to specify the value of a slot.
* Given that there exists a DEFINE-CONDITION macro (distinct from
DEFCLASS) we might as well make it do things that are useful for
conditions. (While we're at it, we should make it support
:required-initargs -- only 1/4 joking.)
I think this argues for defaulting the :INITARG option.
* (intern ... (find-package "KEYWORD")) is just asking for disaster.
Major disaster. The sort of disaster which non-keyword initargs were
invented to avoid in the first place. Just Say No!
(BTW, this doesn't pose much of a compatibility problem. A
backwards-compatible DEFINE-CONDITION can recognise
slot-specifications of the obsolete forms <name> and (<name> <initform>)
and default the :INITARG in these cases to the losing keyword.
There remains the problem of (<name>)...)
Functions such as SIGNAL, which take arguments of class names,
are permitted to take class objects.
Presumably it is an error to pass something which is not a subclass of
CONDITION.
Eliminate the :CONC-NAME option to DEFINE-CONDITION.
Strongly agreed.
Define that condition reporting is mediated through the
PRINT-OBJECT method for the condition type (class) in question,
with *PRINT-ESCAPE* always being NIL. Specifying
(:REPORT fn) in the definition of a condition type C is
equivalent to doing
(DEFMETHOD PRINT-OBJECT ((X c) STREAM)
(IF *PRINT-ESCAPE* (CALL-NEXT-METHOD) (fn X STREAM)))
I think that this is a very bad move.
A much better idea is the define something like DBG:REPORT, which is
only called in the PRINC case. Otherwise every time a user wants to
write a method to affect the way a condition reports itself she must go
through the (if *print-escape* (call-next-method) ...) crap.
I suggest
(defgeneric report-condition (condition stream &key verbosely))
[BTW the reason for the :VERBOSELY keyword is in case you have ever seem
the error messages from ILA-NFS -- there is no way to control whether
they print a dozen lines explaining every possible conceivable cause of
the problem (which is appropriate when the debugger is entered, for
example) or whether they should just summarise the problem (which is
appropriate when the ":Copy File" command reports that it was unable to
copy one particular file.)]
Having the :VERBOSELY keyword can't hurt anything, and it provides a way
to avoid horrible inappropriate verbosity.
Another reason for defining a new generic function and not reusing
PRINT-OBJECT is that that ε1doesε0 provide a way to add extra options like
:VERBOSELY.
Examples:
[...]
Report methods ...
(DEFMETHOD PRINT-OBJECT ((X OOPS) STREAM)
(IF *PRINT-ESCAPE*
(CALL-NEXT-METHOD)
(FORMAT STREAM "Oops! Something went wrong.")))
I think this is a good example of the lossage I described above.
[...]
Discussion:
People seem to disagree about the status that CLOS might occupy
in the upcoming standard. In spite of a vote of support, they seem
to think it might be optional in some way. Passing this proposal
establishes a clear precedent for the full integration of CLOS into
the emerging language.
As I said above, I completely agree with this. However, the pragmatics
of the next year or so -- in which users will likely be offered
vendor-supported Error Standard implementations but not vendor-supported
CLOS -- argue for the sort of minor change I suggested above.
Finally, in <881006184006.0.KMP@BOBOLINK.SCRC.Symbolics.COM> you reply
to Gregor:
Also, it's no different than what DEFSTRUCT does, so it's not like this
is the only place in the language following those rules. Have you
submitted a proposal to deprecate DEFSTRUCT?
I think this is a highly spurious argument. There is no reason to prepetuate
the bad design of DEFSTRUCT. (I have never heard anybody argue that the
mandatory default-value in defstruct slot syntax is anything but a
mistake.)
----- End Forwarded Messages -----