Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Mar 87 04:04:28 EST Date: 05 Mar 87 0058 PST From: Dick Gabriel Subject: Agenda To: common-lisp-object-system@SAIL.STANFORD.EDU I don't think there's any agenda. The meta-object protocol is as good as anything else. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Mar 87 22:38:21 EST Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Mar 87 19:27:44 PST Received: from hplabsc by hplabs.HP.COM with TCP ; Wed, 4 Mar 87 15:30:52 pst Received: by hplabsc ; Wed, 4 Mar 87 15:29:30 pst Date: Wed, 4 Mar 87 15:29:30 pst From: Jim Kempf Message-Id: <8703042329.AA09807@hplabsc> To: Bobrow.pa@Xerox.COM, Common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Chapter 3 At the risk of repeating myself, here is a note on Chapter 3 that I posted last week. We have been having some problems with mail delivery, and Danny's note has led me to believe this may not have gotten delivered. -------------------------------------------------------------------- I feel the major lack in this document is a clear statement of how one goes about defining and implementing a new metaclass. What protocol does a class need to support in order to be promotable to a metaclass via DEFINE-METACLASS? Does DEFINE-METACLASS even care, i.e. does it check before promoting a class? What types of slots? The answer to this question seems to be scattered about the document, so this is more a criticism of organization than content. An example defining a new metaclass would be helpful, but perhaps this document is not the place for it, but rather a "User's Manual" type document might be more appropriate. As in the programmer interface document, a major technical problem is lack of specification of compile time semantics. While the :COMPILE-TIME-HASH-TABLE keyword argument to CLASS-NAMED-FROM-METACLASS on pg. 3-14 provides a hook for maintaining information about partially defined classes at compile time, no such hook exists for methods. To give an example of how this can make implementation of a new metaclass difficult, consider my experience with implementing inheritence of methods in CommonObjects on CommonLoops (COOL). In COOL, CommonObjects inheritence is maintained orthogonally to CommonLoops inheritence, due to the nature of the encapsulation semantics specified by CommonObjects. But COOL depends on the PCL kernel to obtain information about what methods are defined on which classes (via CLASS-DIRECT-METHODS). Where the interaction between these two factors becomes a problem is in inheritence of methods. COOL determines at compile time what methods a subclass inherits from its supers since it needs to generate special code for inherited methods. However, the code generated by PCL for methods doesn't fully define the method until load time, as should be the case, since otherwise the compile time environment could be detrimentally side effected. This means that a CommonObjects super class and methods on the super class cannot be defined in the same file as a subclass, since the superclass methods won't be fully defined until load time and therefore won't be found during compilation for the subclass to inherit. To be fair, it would probably be possible to work around this problem through more extensive redefinition of the method handling portion of the PCL metaclass kernel, but it seems as if some means of maintaining partially defined method information, as with classes, could be designed to simplify implementing novel kinds of method inheritence. Additional examples of where compile time semantics may cause problems appear throughout the document. Consider the following description of class precedence list calculation on pg. 3-4: It is computed (just) before the first instance of this class is created, or when any method is defined on this class or any subclass. What effect (if any) does compilation have on the class precedence list? I can imagine cases where optimization of method lookup may require knowing the class precedence list at compile time, and where compilation of something may correspondingly cause the class precedence list to change. This could even be true for the default CLOS language; however, I think it is even more important that compile time semantics get pinned down in the metaobject protocol because the metaclass kernel is, in a certain sense, a means of modifying the compiler/evaluator. As a final point about the importance of nailing down compile time semantics, consider the possibility of portability problems developing. This is, in fact, currently the case with DEFSTRUCTs in Kyoto Common Lisp. Unless *compile time too* mode is turned on within KCL (the default), the SETF functions for DEFSTRUCT accessors don't get generated at compile time, and hence SETF's of DEFSTRUCT accessors don't expand properly. Turning on *compile time too* mode causes an implicit (EVAL-WHEN (COMPILE) ...) to be wrapped around the processing of top level forms, which can cause serious problems with embedded languages (like PCL) that require certain things (like full method definition) not get done at compile time but rather only at load time. One solution to this problem is simply to interpret the file before compiling, but that is pushing the portability problem back into the system building process. Minor points of fuzziness within the document: 1) pg. 3-3. A figure of the inheritence/instance relationship between the metaclass kernel classes would be most useful here. 2) pg 3-6. The description of INITFORM. Is INITFORM run in the context of a method? Is WITH-SLOTS valid within it? Again, as with the CLOS language, this should probably be pinned down along with the entire initialization protocol. 3) pg. 3-14. Description of SETF of class name. Does this go both ways, i.e. if I (SETF CLASS-NAME) then will CLASS-NAMED recognize the class under the new name? The last time I looked in PCL, this was not the case (though it may have changed). 4) pg. 3-18. Description of FUNCTION slot in METHOD class. Is this a fundef object (function pointer) or a symbol whose function cell is bound? 5) Section 2.2. The description of the relationship between the generic function classes and the method classes leaves me somehow uneasy. While I can't make a case for having one inherit from the other, it seems as if the relationship should be more intimate than the generic function classes simply having a slot for methods. Perhaps this can be handled by using inheritence from one of the generic function classes and having the SETF method distinguish which methods get put onto the slot. I am particularly concerned about having two co-existing metaclasses and users trying to define methods on the same symbol from both metaclasses. We currently handle this in COOL by convention, i.e. telling users to use PCL and COOL in the same package at their own risk. 6) pg. 3-21, and throughout the discussion of the generic function classes. I somehow have the feeling that having the generic function classes inherit from a standard type class FUNCTION would more elegently tie together the CLOS with Common Lisp, provided, of course, the questions raised by the discussion on having a class for FUCTION and the other types which were originally not on the list to have classes can be answered.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Mar 87 21:13:03 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Mar 87 18:03:25 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 MAR 87 17:09:09 PST Date: 4 Mar 87 17:08 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Meeting Monday In-reply-to: Dick Gabriel 's message of 04 Mar 87 16:31 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870304-170909-2070@Xerox> I would like to spend a significant part of it discussing the meta-object protocol. What else is on the agenda. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Mar 87 20:14:21 EST Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Mar 87 17:01:34 PST Received: from hplabsc by hplabs.HP.COM ; Mon, 23 Feb 87 11:36:39 pst Received: by hplabsc ; Mon, 23 Feb 87 11:35:56 pst Date: Mon, 23 Feb 87 11:35:56 pst From: Jim Kempf Message-Id: <8702231935.AA19678@hplabsc> To: common-lisp-object-system@sail.stanford.edu Subject: Comments on 87-002, Chapter 1 Comments are listed in order of how important I think the problems with the document are. A) REDEFINING CLASSES I have serious problems with this section. Coming at it from an implementor's viewpoint, there are some potential portability holes (port holes? :-) ) in the document that would be well to catch before they become cast in concrete. Additionally, this section, in my opinion, slants the entire CLOS in the direction of a prototyping vehicle rather than a vehicle for implementing production code. I have nothing against prototyping, but the degree of difficulty involved in engineering production code from the prototype will ultimately determine whether anyone will use CLOS, since the objective of most potential users is to deliver software products (unless the CLOS is meant to be restricted to academic and research ends). Keep in mind that I'm coming at this from a conventional architecture viewpoint. To be specific, there are three points with which I take issue: 1) Paragraph 2, pg 1-11: "Updating an instance does not change its identity as defined by the EQ function" Practically, this constrains instance implementations to use double indirect referencing for slot access. Since most CL implementations will use pointer equality for EQ, the requirement that instances must be updatable means that some kind of base level storage block must be used to maintain EQ-ness, and the slot values themselves must be stored in another, which can potentially grow or shrink. In fact, this requirement violates the whole concept of EQ-ness in Common Lisp. From CLtL, pg. 78: "Thus EQL tells whether two objects are *conceptually* the same, whereas EQ tells whether two objects are *implementationally* identical" Changing the number of slots in a class, in fact, is changing the instance implementation, since the size of the storage block will change. Conceptually, the two classes are the same, since they have the same name (one could argue even with this, I guess), but clearly their instances are implemented differently, since they have different numbers of slots. 2) The fact that instance updating can be done at all means serious trouble for garbage collection. Since the CLOS needs somehow to be able to find all instances of a class when the class is incompatibly redefined, either pointers to the instances must be kept around by the system or the entire heap must be searched for instances when an update occurs. Presuming the latter is a time-consuming operation (it need not be, if classes are kept in different segments of the heap, sort of a modified BIBOP scheme, but that has its own problems) the most efficient way would probably be to keep track of pointers. However, if the system is holding on to instances, they won't be forgotten when the user's code forgets about them. This means that, without special modifications to the garbage collector, forgotten instances will start clogging the heap. One solution is "weak links", garbage collectable links which the system forgets about when the user does, but these may be difficult to implement on certain machines, or may involve much overhead. Another is to treat user level access and update of variables involving instances specially, so that the CLOS is notified when the user forgets about something, but that would be putting overhead into a process which should be fast. Finally, the user could be required to notify the system when an instance is to be forgotten, but that somehow doesn't fit well into the Common Lisp scheme of things. 3) What happens to methods written on the old class? Do they stop working? What if the methods contain a WITH-SLOTS and some of the slots accessed within the scope of the WITH-SLOTS disappear? Automatic instance updating would limit the amount of optimization that could be done during a WITH-SLOTS expansion, since changing the number of slots could invalidate any attempts to directly access the slot values (like, for example, trying to get rid of the double indirect referencing mentioned above). What about accessor functions? Are they undefined? Redefined to give an error? 4) Automatic instance updating, in and of itself, could have potentially serious side effects in every day use. Consider the following scenario. I am developing an application within a programming environment written in CLOS. The environment contains a class called TEXT-BUFFER, with a slot called CONTENTS. While developing, I define a new TEXT-BUFFER class, but either accidently or intentionally forget to include the CONTENTS slot. As soon as I redefine the class, my environment is trashed, since all the TEXT-BUFFER instances are redefined without CONTENTS. Counter arguments to this are either "use the package system" or "use another name for the class". But anyone who has developed a large Common Lisp application can testify that packages and naming are enough of a problem without adding this degree of complexity. The potential for unpleasent suprises should cause one to seriously reconsider automatic redefiniton, I think. 5) What, precisely, are the compile time semantics for class changing (in fact, the entire document is vague on this subject but more later)? If a class is being recompiled, is the class redefined in the compile time environment? This could potentially cause the compiler to break, if instances needed for the compilation are updated automatically. I would be particularly interested in hearing Garbial's comments on this, since some of the problems I've outlined may be peculiar to conventional architectures. B) COMPILATION SEMANTICS As mentioned above, there is no discussion of compilation semantics in the document. There is a hook mentioned in 87-003 about a compile time hash table for storing name-class associations during compilation, but it is not clear in 87-002 what, if any, effect this hook has on the default CLOS programmer interface. A whole host of questions arise. Is it possible to define a class and subclasses which inherit from it in a file and have things work correctly? Are classes fully defined at compile time, and, if so, will that cause the compilation environment to change in a significant way? Can methods on a class be defined in the same file as the class definition? Can methods on a superclass be defined in the same file as methods on a subclass and have optimizations for CALL-NEXT-METHOD work correctly? I should note that in several other object systems, making inheritence work gracefully across seperate compilation has been one of the hardest things to do. Objective-C, for example, uses two text files to record inheritence information, and this makes system building more complex. C++ deliberately restricts how methods can be inherited in order to avoid problems with seperate compilation. In general, my feeling on this is that the CLOS should try to stick to the Common Lisp goal of having the semantics of compiled and interpreted code be identical. Additionally, many complications can be avoided by side effecting the compile time environment only when necessary. For example, macros need to be defined in the compile time environment so they get properly expanded into code being compiled, so macro definition would seem to be a necessary side effect. If users really want to have the compilation environment side effected, they can always use (EVAL-WHEN (COMPILE) ...) around the code to establish *compile time too* mode. C) INTERACTION BETWEEN CLOS AND CL `DECLARE' AND `THE' There is no mention in the document of how the CLOS will interact with CL DECLARE and THE. The requirement that parameter specifiers be type specifiers (pg. 1-19, paragraph 6) means that TYPEP must do the right thing when given an instance object and a valid class name (and presumably TYPEOF must return the class name as well?) but does that mean I can say: (DECLARE (TYPE TEXT-BUFFER X)) and: (THE TEXT-BUFFER X) CLtL is vague on what happens if I try to bind X to something not of TYPE TEXT-BUFFER and I have it so DECLAREd (see pg. 158) but more explicit for THE (pg. 161). And what happens if I have two TEXT-BUFFER classes, one whose metaclass is the default and one with metaclass COMMON-OBJECTS-CLASS? Seems to me an additional set of declarations are needed, one, perhaps, restricting the metaclass and one for specifying that a variable name can be bound to an object of a particular class *or a subclass*, since the restriction to a single class is covered by TYPE. This would allow implementations to optimize method lookup away at compile time to varying degrees, potentially completely for a TYPE declaration, and partially for subclass and metaclass declarations. D) PARTICULAR QUIBBLES 1) Pg. 1-5, paragraph 1. A reference to 87-003 (the metaobject chapter) would probably be good here. 2) Pg. 1-6, paragraph 6. There is no statement anywhere in this section or the next that a class cannot be defined with two slots having the same name. Is this valid and, if so, how is access to be distinguished? By different accessor function names? If so, which is used in WITH-SLOTS? 3) pg 1-7 through 1-9. The description of slot options, as Moon has stated, seems needlessly complex. During the following, keep in mind that I am coming at inheritence from the global viewpoint that subclasses specialize behavior of superclasses. If that is kept in mind, I think there are a number of ways to reduce the complexity. On to particulars: a) pg. 1-7 paragraph 8: "characteristics of that slot involve some combination of the several slot descriptions" I don't understand why it is necessary to have do this. Why not simply use the class precedence list to determine which class has highest priority and simply have the slot options for that one dominate. Presumably, the user wants the highest precedence class behavior to dominate, since it is the most specialized. If that is not the case, then the slot option would, in my opinion, be better off left as a method. The user can then redefine it using CALL-NEXT-METHOD to get more general behavior. b) The description of valid values on the top of the page has some notational ambiguity. The first paragraph uses C(j) to indicate classes, but halfway through the description on valid values, the notation uses the syntax: (:CLASS j) to indicate that a class shares a shared slot. Did you really mean that the user had to put a number indicating the location of the class in the class precedence list? I think not. c) At the bottom of the page, do you really want the default to be UNSUPPLIED? If so, in what package is this symbol? d) pg. 1-8. Middle bullet. Why use (AND T(1) .. T(n) )? Again, coming at this from the point of view that subclasses specialize behavior of supers, shouldn't the more specialized type prevail? e) same page, last bullet. If there is no :INITFORM, then what happens when the user tries to access the slot and it is not initialized? In general, I think this particular bit needs to be worked out in tandem with initialization in general, which has yet to be specified. 4) pg 1-13 paragraph 2 "However, it is not allowed..." I think the usual CLtL way of saying this is "an error is signalled." Also, in paragraph 3, it sounds to me as if STRUCTURE-CLASS is actually a metaclass is this so? Here would be a good place to have a figure illustrating the top level metaclass/class structure which shadows the type system. Details can be left to 87-002.2, but a figure would help conceptualization. 5) pg. 1-14-1-16. The inheritence algorithm. I actually thought this was one of the best parts of the document (sorry Dick). It precisely specifies how to calculate inheritence, and avoids some of the pitfalls and nasty side effects that other multiple inheritence schemes seem to generate (though I can't say I've examined it in lots of detail). However, it IS poorly explained. In particular, some heuristic explanation of the role R and S play in the algorithm would be useful. Also, on pg. 1-14, there is a forward reference in paragraph 3, immediately after the definition of R, to consistency, which leave the reader wondering what that is. Also, I think the reference to topological sorting should be toned down some, and the algorithm should rather be outlined stepwise instead of as a paragraph. Finally, the example is OK, but there should be examples of inconsistency as well. The single example given is trivial. For my taste (no pun intended), the pie examples could very well be be replaced by something more abstract, but not all readers may feel this way. 6) pg. 1-19 after bullets: "Let N be a parameter specializer name and P be the corresponding parameter specializer; if N is a class name, then P is the class with that name; otherwise N equals P." This is unnecessarily confusing. Try: "The method lookup process distingushes between parameter specializer names and parameter specializers. If N is a parameter specializer name and also the name of a class, then the corresponding parameter specializer P will be the class named N." The rest of this section has similar problems. 7) General comment on method combination. It is certainly clearer now than in the original documents, but I wish the preciseness with which the inheritence algorithm was specified could also be true of method combination. 8) pg. 1-26. paragraph 1. Protocol point. In the list of other object languages, why not include CommonObjects? As far as I know, it is the ONLY language which has actually been implemented on top of the metaobject protocol.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Mar 87 19:39:04 EST Date: 04 Mar 87 1631 PST From: Dick Gabriel Subject: Meeting Monday To: common-lisp-object-system@SAIL.STANFORD.EDU I have started the wheels churning for getting a meeting room at the hotel for monday for the CLOS confab. I will reserve it for all day, but we might only need part of it. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Mar 87 19:31:35 EST Date: 04 Mar 87 1622 PST From: Dick Gabriel Subject: Errata etc. To: common-lisp-object-system@SAIL.STANFORD.EDU Seems as though Moon and I begin to converge (!). LGD worked up some macros to TEX of the errata in a pretty format. If Moon were to send his errata to us, we will TEX and reproduce it for the meeting. We'll need 2 - 3 days to do this to be safe. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Mar 87 19:16:29 EST Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Mar 87 16:08:19 PST Received: from hplabsc by hplabs.HP.COM with TCP ; Fri, 27 Feb 87 09:28:03 pst Received: by hplabsc ; Fri, 27 Feb 87 09:27:21 pst Date: Fri, 27 Feb 87 09:27:21 pst From: Jim Kempf Message-Id: <8702271727.AA19940@hplabsc> To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET, RPG@SAIL.STANFORD.EDU Subject: Re: Meeting Cc: common-lisp-object-system@SAIL.STANFORD.EDU > Date: 20 Feb 87 2242 PST > From: Dick Gabriel > > I can make a meeting on monday, but I'd like to be within hailing > distance of the main meeting in case a fight breaks out. > >Sounds good. > >Patrick. > Ok by me also. Jim Kempf  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Mar 87 18:11:12 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Mar 87 15:02:21 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 MAR 87 13:31:07 PST Date: 4 Mar 87 08:46 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Chapter 3 To: Common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870304-133107-1251@Xerox> I am preparing the presentation for X3J13 of the metaobject material. I would appreciate feedback on the chapter, even of the form of "this part is good, but I don't see what that part is for" with specifics for this and that. Of course, specific criticisms and/or suggestions for improvements are even more welcome. thanks danny  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 3 Mar 87 18:25:27 EST Received: from Cabernet.ms by ArpaGateway.ms ; 03 MAR 87 14:38:46 PST Date: 3 Mar 87 14:37 PST From: Gregor.pa@Xerox.COM Subject: new package name in PCL To: CommonLoops.pa@Xerox.COM cc: Gregor.pa@Xerox.COM Reply-to: Gregor.pa@Xerox.COM Message-ID: <870303-143846-7947@Xerox> Is anyone out there using PCL also using a package with one of the following names? PCLI PCL-DEFSYS If you aren't, don't bother responding, just let me know if you are. Thanks Gregor  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Mar 87 03:11:57 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Mar 87 00:05:53 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 82921; Tue 3-Mar-87 03:06:30 EST Date: Tue, 3 Mar 87 03:04 EST From: David A. Moon Subject: Moon's Comments on RPG's Comments on Moon's Errata To: Common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 28 Feb 87 03:12 EST from Dick Gabriel Message-ID: <870303030444.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 28 Feb 87 0012 PST From: Dick Gabriel [comments where I had nothing more to add omitted for brevity] Moon writes: ``I didn't think the phrase "where {\it parameter-specializer-name\/} is a parameter specializer name" added anything to understandability.'' If a reader has gotten used to meta-syntactic items being linked to English phrases in a precise way, then failing to do that reduces understandability. How about this: Each method has a {\bit specialized lambda-list}, which determines when that method can be selected. A specialized lambda-list is like an ordinary lambda-list except that a {\bit specialized parameter} may occur instead of the name of a parameter. A specialized parameter is a list, {\tt ({\it variable-name parameter-specializer-name\/})}, where {\it parameter-specializer-name} is a parameter specializer name. Every parameter specializer name is a Common Lisp type specifier, but the only Common Lisp type specifiers that are valid as parameter specializer names are the following: This is Moon's rewrite with my pissant addition. OK, I put that into the draft errata file I am maintaining. Moon correctly comments and asks: ``If this means that typep is to be extended to accept class objects, that is a reasonable extension to propose, however since it is mentioned nowhere else in the document and is not stated explicitly here, and was never discussed on the mailing list, I assumed that that was not the intention, and instead the problem was that the conversion from "parameter specializer" to "parameter specializer name" had not been carried out uniformly. So which is it? If typep is to accept class objects, we need an errata entry that makes that very explicit.'' The class redefinition prose that Moon inserted into the document at some point in time requires either that the prose talking about TYPEP at this point in the document be removed or amended as I tried. I presumed that deleting content was incorrect, so I tried to fix up this prose to be consistent. The offending statement is ``the function TYPEP can be used to determine whether an argument satisfies a parameter specializer.'' This statement is meant to reinforce the fact that the class system extends the CL type system. If this statement is to stand, TYPEP has to deal with class objects in addition to class names, because of the functional interface. More specifically, the issue is that MAKE-METHOD specifies class objects and possibly TYPEP should be used during generic function invocation to determine which methods are applicable. The class redefinition protocol requires that we be able to write methods that apply to classes that have been rendered obsolete (or nameless). Of course there are other reasons as well to want anonymous classes. Here are the alternatives: 1. MAKE-METHOD takes class names; TYPEP operates on names and type specifiers as usual (extended to classes); redefining a class creates a stupid but predictable name for the ``old'' class (or we invent some funny notation to refer to obsolete classes of various vintages). 2. MAKE-METHOD takes class objects; TYPEP is extended to class objects; class redefinition renders the ``old'' class nameless. 3. We simplify the class redefinition protocol to eliminate CLASS-CHANGED (this is the generic function that causes the problem. 4. We can talk about how TYPEP can be used by the user to predict which methods are applicable. 5. We can eliminate any statements about TYPEP. I think 3. is not easily acceptable, because Moon's class redefinition protocol is quite powerful (and suggestive to people trying to understand the system). Option 2. probably will piss off the Common Lisp crowd. Option 3. will piss me off. Option 4. is dumb. Option 5. requires some further changes to the document to provide the function that really decides satisfaction. Moon's further remarks on this point correctly indicate other problems that can be easily solved once we decide whether we really intend that TYPEP work on class objects. After thinking this over, I think #2 is the only alternative that will fly. Perhaps this will give bozos something to yell about at the X3J13 meeting. The only real problem I have with this is the anomaly that in parameter specializers classes are represented by the objects themselves but "individuals" are represented by funny little lists with QUOTE in the CAR. This doesn't seem to generalize very well to other type-specifiers, should we want to add them in the future. Would it be better to introduce pseudo-class objects (obeying a subset of the protocol of classes; in particular, you cannot instantiate them) for these parameter specializers? Or is it better to draw a sharp boundary between real classes, which are full-scale objects, from pseudo-class types, which are type-specifier lists? Leaving that issue aside, I'd make the following amendments to the errata to implement this suggestion. This is a first draft and might need some cleaning up before letting the general public see it. 1-13 First paragraph: Delete the last sentence. Add a new paragraph at the end of the page: "Every class that has a name has a corresponding type with the same name as the class. In addition, every class object is a valid type specifier. Thus (typep ) is true if the class of the given is itself or a subclass of and (subtypep ) returns t t if is a subclass of or they are the same class, and returns nil t otherwise." 1-19 seventh paragraph: Change to "This proposal requires that both parameter specializers and parameter specializer names be Common Lisp type specifiers." [no substantive change here, this is just to avoid the possibility of misinterpretation] [no change any more to 1-19 eighth paragraph] 1-19 tenth paragraph: Change "parameter specializers are t" to "parameter specializers are the class named t". 2-15 third paragraph: Add "A class object can be used directly as a type-specifier. Thus (typep ) is true if the class of the given is itself or a subclass of ." 2-54: Add pages for SUBTYPEP, TYPE-OF, and TYPEP, explaining that SUBTYPEP and TYPEP are to be extended to accept class objects as type specifiers, and explaining that TYPE-OF never returns a class object [is this right?], with a cross-reference to CLASS-OF. I think I agreed with all of Moon's other errata. Moon: at some point (when we all agree on the list) you should mail your current errata list to me. Will do. Are you going to print up copies for the meeting or would you like me to take care of that?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Mar 87 01:40:46 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 2 Mar 87 22:34:17 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 82864; Tue 3-Mar-87 01:34:47 EST Date: Tue, 3 Mar 87 01:33 EST From: David A. Moon Subject: Moon's comments on RPG's comments on Moon's Errata for Chapter 2 To: Common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 28 Feb 87 04:18 EST from Dick Gabriel Message-ID: <870303013303.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 28 Feb 87 0118 PST From: Dick Gabriel [comments where I had nothing to add omitted for brevity] Moon writes: ``2-11 second Arguments paragraph: Delete the second sentence. It lost its intended meaning as a result of previous editing.'' I'm not sure of this. I would agree to an argument that the paragraph is hard to understand, but I think it stands on its own: ``When change-class is invoked on an instance, a copy [definition of the `copy'] of that instance is made; change-class then destructively alters the original instance [not the copy]. The first argument to class-changed, previous, is that copy [reference to the `copy'], and the second argument, current, is the altered original instance.'' Is this wrong? If it's unclear we can re-do it somehow. That's the first Arguments paragraph. I have no problems with it. I was referring to the second Arguments paragraph, and suggesting removal of "Any function, generic or not, can receive the value passed as -previous- as an argument." Moon writes: ``2-11 first Remarks paragraph: Delete this. It contradicts an example on page 2-8 and it isn't true.'' While he is literally correct, I think we need to reinforce somewhere in this section that the functional interface must be used when classes are redefined. This paragraph is the result of a hurry. I think we could leave that to the discussion of class redefinition in chapter 1. I see it more as a property of the "obsolete" class than a property of the class-changed generic function. Moon writes a specific comment that requires a general policy answer: ``2-34 second paragraph...[This paragraph duplicates information found elsewhere so perhaps it should be shortened.]'' In general I repeated information that I thought would puzzle readers. Should we establish a convention of putting information on some topic mostly in one place? Either way is okay with me. I suggested shortening it because I thought that would be easier than making the same corrections in more than one place. Moon writes: ``2-48 second Purpose paragraph: Delete "to the top level".'' Or change it to ``Whether ... or returns via THROW'' I don't like the terminology ``or throws.'' That's better. I changed my draft errata file to read: 2-41 second Purpose paragraph: Replace it with "Whether {\bf invalid-method-error} returns to its caller or exits via {\bf throw} is implementation dependent." 2-48 second Purpose paragraph: Replace it with "Whether {\bf method-combination-error} returns to its caller or exits via {\bf throw} is implementation dependent." Moon writes: ``2-46 second Purpose paragraph first sentence: It was not intended to guarantee that the returned value is a list with certain objects in its car and cdr. Add the phrase "or a form with equivalent effect" at the end of the sentence.'' Or maybe: ``The function {\bf make-method-call} returns a form whose effect is the same as a form whose first element is the operator specified by the {\bf :operator} keyword argument (the default is {\bf progn}) and the rest of which is a list of forms that call the methods in the given method list....'' Yes, that's better. I put it into my draft errata file. Moon writes: ``2-53 last Arguments paragraph: Change "second" to "errorp". Change (twice) "If there is no such method" to "If {\it generic-function} does not know {\it method}".'' How about one of these: ``If {\it generic-function} does not perceive directly {\it method}.'' ``If {\it generic-function} does not perceive or apprehend as true {\it method}.'' ``If {\it generic-function} does not have immediate experience of {\it method}.'' ``If {\it generic-function} has not been apprised of {\it method}.'' Abstract objects in a computer are not people, so we cannot use verbs that apply to people to talk about them. Leave it as it is. (I had to have fun somewhere in this message.) I guess we can't fix this nicely without terminology that comes from the meta-object chapter. We should all have more fun. Should we make an end run around the problem and simply remove the errorp argument and say that remove-method never signals an error? Sort of like REMPROP, REMOVE, and REMHASH.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Feb 87 04:35:33 EST Date: 28 Feb 87 0127 PST From: Dick Gabriel Subject: All is Not Lost (?) To: common-lisp-object-system@SAIL.STANFORD.EDU I showed Chapter 1 to two people at Lucid who thought it was very clear and well-written: 1. A mathematician with several theorems named after him. 2. A mathematician who got his PhD at age 19. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Feb 87 04:27:24 EST Date: 28 Feb 87 0118 PST From: Dick Gabriel Subject: Moon's Errata for Chapter 2 To: Common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: ``2-5 Values paragraph: Replace the whole sentence with "The value is {\it generic-function}." to clarify that the value is EQ to the argument.'' We should agree on and adopt a means of stating that some function destructively alters an argument, returning the altered thing as its value. I'm not sure this suggestion accomplishes that best, but maybe it does. Moon writes: ``2-11 second Arguments paragraph: Delete the second sentence. It lost its intended meaning as a result of previous editing.'' I'm not sure of this. I would agree to an argument that the paragraph is hard to understand, but I think it stands on its own: ``When change-class is invoked on an instance, a copy [definition of the `copy'] of that instance is made; change-class then destructively alters the original instance [not the copy]. The first argument to class-changed, previous, is that copy [reference to the `copy'], and the second argument, current, is the altered original instance.'' Is this wrong? If it's unclear we can re-do it somehow. Moon writes: ``2-11 first Remarks paragraph: Delete this. It contradicts an example on page 2-8 and it isn't true.'' While he is literally correct, I think we need to reinforce somewhere in this section that the functional interface must be used when classes are redefined. This paragraph is the result of a hurry. Moon writes: ``2-18 first bullet (:type). There is no discussion of the meaning and enforcement of :type. Add the following (stolen from CLtL p.310):...'' This overlaps with the discussion about chapter 1. The language in chapter 1 has been variously vague on this also, but the version mailed to X3J13 also copied terminology from CLtL. We minimally changed the DEFINE-METHOD-COMBINATION description due to lack of time. It needs a major rewrite in addition to the comments Moon has about it. Moon writes a specific comment that requires a general policy answer: ``2-34 second paragraph...[This paragraph duplicates information found elsewhere so perhaps it should be shortened.]'' In general I repeated information that I thought would puzzle readers. Should we establish a convention of putting information on some topic mostly in one place? Moon writes: ``2-48 second Purpose paragraph: Delete "to the top level".'' Or change it to ``Whether ... or returns via THROW'' I don't like the terminology ``or throws.'' Moon writes: ``2-46 second Purpose paragraph first sentence: It was not intended to guarantee that the returned value is a list with certain objects in its car and cdr. Add the phrase "or a form with equivalent effect" at the end of the sentence.'' Or maybe: ``The function {\bf make-method-call} returns a form whose effect is the same as a form whose first element is the operator specified by the {\bf :operator} keyword argument (the default is {\bf progn}) and the rest of which is a list of forms that call the methods in the given method list....'' Moon writes: ``2-47 Values paragraph: same as the preceding. ``2-48 second Purpose paragraph: Delete "to the top level".'' My earlier comments apply here, too. Moon writes: ``2-53 last Arguments paragraph: Change "second" to "errorp". Change (twice) "If there is no such method" to "If {\it generic-function} does not know {\it method}".'' How about one of these: ``If {\it generic-function} does not perceive directly {\it method}.'' ``If {\it generic-function} does not perceive or apprehend as true {\it method}.'' ``If {\it generic-function} does not have immediate experience of {\it method}.'' ``If {\it generic-function} has not been apprised of {\it method}.'' Abstract objects in a computer are not people, so we cannot use verbs that apply to people to talk about them. Leave it as it is. (I had to have fun somewhere in this message.) -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Feb 87 03:22:54 EST Date: 28 Feb 87 0012 PST From: Dick Gabriel Subject: Moon's Comments on RPG's Comments on Moon's Errata To: Common-lisp-object-system@SAIL.STANFORD.EDU Moon comments: ``For example, in an earlier proposal from Xerox C-sub-o was given the name (intern (concatenate 'string "obsolete-" (symbol-name (class-name class)))), or something similar. This had a problem if the class was redefined twice, but that could easily be fixed.'' Thank God this proposal went by the boards, though it is an excellent example of why it's the case that the fewer things are named the better off we are. Moon continues: ``I put the following into my errata file, is this okay with everybody? ``1-11 fourth paragraph: Delete the entire paragraph, it isn't true. Replace it with this paragraph: Because the class C-sub-O does not have a name, writing a method for class-changed that is specialized to a particular C-sub-O must be done through the functional interface, using add-method rather than using defmethod. See the section ``Introduction to Methods.'' '' This seems fine. Moon writes: ``I didn't think the phrase "where {\it parameter-specializer-name\/} is a parameter specializer name" added anything to understandability.'' If a reader has gotten used to meta-syntactic items being linked to English phrases in a precise way, then failing to do that reduces understandability. How about this: Each method has a {\bit specialized lambda-list}, which determines when that method can be selected. A specialized lambda-list is like an ordinary lambda-list except that a {\bit specialized parameter} may occur instead of the name of a parameter. A specialized parameter is a list, {\tt ({\it variable-name parameter-specializer-name\/})}, where {\it parameter-specializer-name} is a parameter specializer name. Every parameter specializer name is a Common Lisp type specifier, but the only Common Lisp type specifiers that are valid as parameter specializer names are the following: This is Moon's rewrite with my pissant addition. Moon writes: ``This is better than what I suggested, but self-contradictory. First it says that each required parameter must be a specializer parameter, which was earlier defined as a list, then it says that a required parameter can be a symbol.'' Well, it actually said that the notation enabled a programmer to write a symbol that would be taken as a specialized parameter, but Moon's rewriting is better than what I had: Only required parameters can be specialized, and there must be a parameter specializer for each required parameter. For notational simplicity, if some required parameter in a specialized lambda-list is simply a variable name, its parameter specializer defaults to the class named {\bf t}. Moon correctly comments and asks: ``If this means that typep is to be extended to accept class objects, that is a reasonable extension to propose, however since it is mentioned nowhere else in the document and is not stated explicitly here, and was never discussed on the mailing list, I assumed that that was not the intention, and instead the problem was that the conversion from "parameter specializer" to "parameter specializer name" had not been carried out uniformly. So which is it? If typep is to accept class objects, we need an errata entry that makes that very explicit.'' The class redefinition prose that Moon inserted into the document at some point in time requires either that the prose talking about TYPEP at this point in the document be removed or amended as I tried. I presumed that deleting content was incorrect, so I tried to fix up this prose to be consistent. The offending statement is ``the function TYPEP can be used to determine whether an argument satisfies a parameter specializer.'' This statement is meant to reinforce the fact that the class system extends the CL type system. If this statement is to stand, TYPEP has to deal with class objects in addition to class names, because of the functional interface. More specifically, the issue is that MAKE-METHOD specifies class objects and possibly TYPEP should be used during generic function invocation to determine which methods are applicable. The class redefinition protocol requires that we be able to write methods that apply to classes that have been rendered obsolete (or nameless). Here are the alternatives: 1. MAKE-METHOD takes class names; TYPEP operates on names and type specifiers as usual (extended to classes); redefining a class creates a stupid but predictable name for the ``old'' class (or we invent some funny notation to refer to obsolete classes of various vintages). 2. MAKE-METHOD takes class objects; TYPEP is extended to class objects; class redefinition renders the ``old'' class nameless. 3. We simplify the class redefinition protocol to eliminate CLASS-CHANGED (this is the generic function that causes the problem. 4. We can talk about how TYPEP can be used by the user to predict which methods are applicable. 5. We can eliminate any statements about TYPEP. I think 3. is not easily acceptable, because Moon's class redefinition protocol is quite powerful (and suggestive to people trying to understand the system). Option 2. probably will piss off the Common Lisp crowd. Option 3. will piss me off. Option 4. is dumb. Option 5. requires some further changes to the document to provide the function that really decides satisfaction. Moon's further remarks on this point correctly indicate other problems that can be easily solved once we decide whether we really intend that TYPEP work on class objects. I think I agreed with all of Moon's other errata. Moon: at some point (when we all agree on the list) you should mail your current errata list to me. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Feb 87 02:04:51 EST Date: 27 Feb 87 2258 PST From: Dick Gabriel Subject: Inheritance of Slots and Slot Options To: Common-Lisp-object-system@SAIL.STANFORD.EDU Moon's rewrite has some features of interest. Recall I don't claim that what ended up in the draft is the last word, but it was meant to be clear (at least) though not written as best it could be. I have a few minor questions and comments about it: Moon writes: ``We say that a slot is accessible in an instance of a class if the slot is defined by the class of the instance or is inherited from a superclass of that class. A detailed explanation of the inheritance of slots is given in the section ``Inheritance of Slots and Slot Options.'' '' He removed the sentence: ``At most, one slot of a given name can be accessible in an instance.'' Although he inserts it later, I think it doesn't hurt to leave it where it is (as well). Moon writes: ``- The type of a slot is (and T1 T2 T3...), where T1, T2, T3, and so on are the :type slot options contained in all of the slot specifiers. If no slot specifier contains :type, the type is t.'' Here I think the language is unclear. Does this mean that the :type option for the most specific class is taken to be (and ...)? Is the slot constrained to hold values that satisfy (and ...) in the sense that an error is signaled if someone tries to store something there that does not satisfy the type? The language we had originally stated that the :type option defaulted to T, and the contents of the slot would always be of type (and ...). This mimicked the language in CLtL for defstruct and represents a statement more in line with types as optional information to the compiler. Later Moon writes: ``A consequence of the type rule is that the value of a slot must satisfy the type constraint in -every- slot specifier that contributes to that slot.'' The convention in CLtL is that the phrase ``x must do y'' means that otherwise it is an error, so we can deduce that he means that the slot is not constrained in the sense of signaling an error. We should probably include at the beginning of these chapters a warning to read page 6 of CLtL to understand the conventions of the language we use. Moon writes in the next paragraph: ``An argument to a method can be an instance of a subclass of the class declared by a parameter specializer, so the compiler cannot know the exact class.'' This should be expanded because many will not easily see the connection between random methods and optimizing based on the types of slots. The strong type constraint rule Moon proposes has some effects that might be difficult for a reader to understand unless explained properly. Suppose we have: (defclass c1 () ((foo :type t1))) (defclass c2 (c1) ((foo :type t2))) (defclass c3 (c1) ((foo :type t3))) The FOO slot in C1 must be of type (and T1 T2) when regarded from the point of view of C2, and it must be of the type (and T1 T3) when regarded from the point of view of C3. Therefore, it actually must be of type (and T1 T2 T3). The compiler compiling methods on C2 or C3 alone won't care much, and when it compiles a method on C2 and C3 it might discover the happy fact. A reader of this specification might be confused into thinking that there is some intractable problem at hand and that the type of a slot cannot actually be deduced because it depends on classes very far away. Moon writes near the end: ``The :reader and :accessor slot options were not mentioned above because they create methods rather than defining characteristics of a slot. Reader and accessor methods are inherited in the sense described in the section ``Inheritance of Methods.'' '' This needs to be made clear at the outset: two-pass reading is bad news. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Feb 87 21:40:02 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Feb 87 18:33:41 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 FEB 87 18:31:58 PST Date: 27 Feb 87 18:31 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: CPL In-reply-to: Dick Gabriel 's message of 20 Feb 87 22:55 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870227-183158-4758@Xerox> My worry is that most people, even after a lot of thought, will think of it like this: 1. the CPL respects the superclass relationships 2. the CPL respects the order of direct superclasses 3. otherwise, it is a black box, and if the programmer doesn't like it, he can supply his own. I would hope that people would think more like (and we would present it as): 1. the CPL respects the superclass relationships 2. the CPL respects the order of direct superclasses 3. the CPL keeps supers of superclasses together 4. classes appear only once in the CPL, as late as possible For simple hierarchies, independent superclasses, and even simple joins (last element of a superclass list is the only class that occurs more than once), the CPL is simple to understand, i.e. left to right depth first keeping the last occurrence of a class. For complicated uses (not encouraged), where common supers occur in non-last position, it is harder to satisfy these constraints (maybe impossible). So there is a complicated algorithm. I won't worry about it since I will never do these bad things (or will only think about the constraints) rather than the list. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Feb 87 21:30:57 EST Date: 27 Feb 87 1824 PST From: Dick Gabriel Subject: CPL To: common-lisp-object-system@SAIL.STANFORD.EDU Why not wait until X3J13 comments before we think about it further. We should think in terms of people doing their own thing and extending DEFCLASS accordingly. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Feb 87 19:34:20 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Feb 87 16:25:59 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 FEB 87 16:20:43 PST Date: 27 Feb 87 16:20 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Proposed revision of "Inheritance of Slots and Slot Options" section In-reply-to: David A. Moon 's message of NIL To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870227-162043-4596@Xerox> I am now back from my trip so I will try to comment on some of the relevant messages in my absence. SLOT IHERITANCE In general I agree with Moon that slot inheritance is simple and like his rewording. A few minor glitches: If the :allocation slot option is omitted or specifies a local slot, then each instance of C stores its own value for the slot. This needs to be specific about local being either :instance or :dynamic (or perhaps it should have that earlier). Secondly, the type constraint is presented very strongly. The intent of having it (I pushed it in) was to allow compatibility with current defstruct. Current defstruct does not specify that a slot MUST meet its type constraint. Consequently, I would suggest that the rule specify: "The :type of a slot need not be specified. If it is, the interpretation is that the value of the slot should be of type (and T1 T2 T3...), where T1 , ... Tn are all the type specifiers provided in any slot specifcation. Implementations need not check for values, but those that do should use the interpretation, and hence may optimize for those values." And then one could add the following from Moon's suggestion. A consequence of the type rule is that the value of a slot must satisfy the type constraint in -every- slot specifier that contributes to that slot. This maximally restrictive rule allows a compiler to optimize on the basis of the :type slot option. An argument to a method can be an instance of a subclass of the class declared by a parameter specializer, so the compiler cannot know the exact class. danny  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 27 Feb 87 15:45:25 EST Received: from Cabernet.ms by ArpaGateway.ms ; 27 FEB 87 11:08:50 PST Date: 27 Feb 87 11:07 PST From: Gregor.pa@Xerox.COM Subject: New version of PCL To: CommonLoops.pa@Xerox.COM Message-ID: <870227-110850-4071@Xerox> There is a new version of PCL on parcvax.xerox.com. To the best of my knowledge, this version runs in: Xerox Common Lisp (Lyric beta release) Symbolics 7.0 Lucid ExCL Vaxlisp 2.0 KCL (September 16, 1986) I have not been able to test it in any other Common Lisps yet. Changes in this version include: - introduction of defmethod-setf as the right way to define setf methods, where you used to say: (defmeth (speed (:setf (nv))) ((p plane)) .. code to set plane's speed ..) You should now say: (defmethod-setf speed ((p plane)) (nv) .. code to set plane's speed ..) - Slot access optimization has been turned back on inside of with-slots forms. - defmethod and defmethod setf (and defmeth) no longer support macros which expand into declarations at the beginning of their bodies. Use of a macro here may cause that declaration to be put somewhere it doesn't belong. People should use this release to convert their code to use defmethod, defmethod-setf, defclass and with-slots. The old versions of these (defmeth ndefstruct with and with*) are becoming less and less supported. The next release will be different in a number of ways. Most importantly, discriminator objects are being replaced by generic-function objects. People which have code that hacks around with method and discriminator objects will probably have to edit it. Some parts of the meta-object protocol will be changed. Method lookup should be faster, although much of this may not happen until the following release. PCL will no longer be able to run without any implementation dependent customizations.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 27 Feb 87 12:27:25 EST Received: from Cabernet.ms by ArpaGateway.ms ; 27 FEB 87 07:58:31 PST Return-Path: <@CONGER.bbn.com,@WIMSEY.bbn.com:kanderson@VAX.bbn.com> Received: from CONGER.bbn.com by Xerox.COM ; 27 FEB 87 07:56:52 PST Received: from WIMSEY.bbn.com by CONGER.bbn.com via INTERNET with SMTP id 12820; 27 Feb 87 10:55:08-EST Date: Fri, 27 Feb 87 10:55 EST From: Kenneth R. Anderson Subject: Bug in change-class To: commonloops.pa@Xerox.COM Message-ID: <870227105542.4.KANDERSON@WIMSEY.bbn.com> I got into an infinite loop printing an obsolete-class which seems to be due to the cycle: get-slot-using-class -> change-class -> change-class-internal -> all-slots -> all-slots-using-class -> get-slot-using-class ... The following seems to fix the problem: (defmeth all-slots-using-class ((class obsolete-class) object) (append (iterate ((slotd in (class-instance-slots class))) (collect (slotd-name slotd)) (collect (get-slot--class object (slotd-name slotd)))) (iwmc-class-dynamic-slots object)))  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 26 Feb 87 22:56:18 EST Received: from Cabernet.ms by ArpaGateway.ms ; 26 FEB 87 19:08:52 PST Date: 26 Feb 87 19:07 PST From: Gregor.pa@Xerox.COM Subject: Draft Specification/PCL documentation withdrawn To: CommonLoops.pa@Xerox.COM Message-ID: <870226-190852-3420@Xerox> The documentation I announced earlier has been, for the time being, withdrawn. I will let you know as soon as it is available again.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 26 Feb 87 18:42:56 EST Received: from Cabernet.ms by ArpaGateway.ms ; 26 FEB 87 14:47:42 PST Date: 26 Feb 87 14:45 PST From: Gregor.pa@Xerox.COM Subject: Draft Specification/PCL documentation To: CommonLoops.pa@Xerox.COM cc: Gregor.pa@Xerox.COM Message-ID: <870226-144742-3106@Xerox> The directory /pub/pcl/doc/ contains TEX source files for the first two chapters of the current draft of the Common Lisp Object System Proposal. In the next few weeks, I will be changing PCL to make it conform to this specification. In this way, this draft specification will become the documentation for PCL. Please FTP these documents and enjoy. In a few weeks, we may look into some way of getting copies of these documents to people who can't FTP them or run TEX on them; for now, try to get them by FTP.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Feb 87 22:51:04 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 25 Feb 87 19:43:54 PST Received: from relay2.cs.net by RELAY.CS.NET id aa25849; 25 Feb 87 19:38 EST Received: from ti-csl by csnet-relay.csnet id cb13175; 25 Feb 87 19:30 EST Received: from dsg (juliett.ARPA) by tilde id AA16731; Tue, 24 Feb 87 08:18:23 cst Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 24 Feb 87 08:18:39 CST Message-Id: <2750163506-3742966@Jenner.ti-7> Date: Tue, 24 Feb 87 08:18:26 CST Sender: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET From: Patrick H Dussud To: Dick Gabriel Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Meeting In-Reply-To: Msg of 20 Feb 87 2242 PST from Dick Gabriel Date: 20 Feb 87 2242 PST From: Dick Gabriel I can make a meeting on monday, but I'd like to be within hailing distance of the main meeting in case a fight breaks out. Sounds good. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Feb 87 18:08:14 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 25 Feb 87 14:58:34 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79019; Wed 25-Feb-87 17:59:06 EST Date: Wed, 25 Feb 87 17:57 EST From: David A. Moon Subject: Comments On Moon's Errata (Chapter 1 only) To: Common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 19 Feb 87 17:22 EST from Dick Gabriel Message-ID: <870225175739.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 19 Feb 87 1422 PST From: Dick Gabriel Sorry about the slow response to these, I've been tied up with other things the past few days. Moon writes: ``1-11 fourth paragraph: Delete the entire paragraph, it isn't true.... I think the original statement is true, and it is because of that fact that Moon's re-statement would be true. Possibly both statements should be made, suitably phrased: Because redefining a class does not change its name, the class $C\sub o$ does not have a name. Thus, writing a method for {\bf class-changed} that is specialized to a particular $C\sub o$ must be done through the functional interface, using {\bf add-method} rather than using {\bf defmethod}. See the section ``Introduction to Methods.'' I think this might make the situation clearer to the reader. I agree that this is better, except for one thing. The reason that C-sub-o does not have a name is -not- because redefining a class does not change its name. For example, in an earlier proposal from Xerox C-sub-o was given the name (intern (concatenate 'string "obsolete-" (symbol-name (class-name class)))), or something similar. This had a problem if the class was redefined twice, but that could easily be fixed. I put the following into my errata file, is this okay with everybody? 1-11 fourth paragraph: Delete the entire paragraph, it isn't true. Replace it with this paragraph: Because the class C-sub-O does not have a name, writing a method for class-changed that is specialized to a particular C-sub-O must be done through the functional interface, using add-method rather than using defmethod. See the section ``Introduction to Methods.'' Moon writes: ``1-18 first paragraph under "Introduction to setf Generic Functions": Change "(setf (generic-function-name arguments) new-value)" to "(setf (function-name arguments) new-value)" because the base function does not have to be generic, in fact it does not even have to be defined.'' If this is correct, then it should be: ``(setf (symbol arguments) new-value)'' Good point, I made that change in my file. Moon writes: ``1-18 last paragraph: The term "parameter specifier" is used in a way that is inconsistent with its use by CLtL and there are a couple of typographical problems. Replace the entire paragraph with: Each method has a {\bit specialized lambda-list}, which determines when that method can be selected. A specialized lambda-list is like an ordinary lambda-list except that a {\bit specialized parameter} may occur instead of the name of a parameter. A specialized parameter is a list, {\tt ({\it variable-name parameter-specializer-name\/})}. Every parameter specializer name is a Common Lisp type specifier, but the only Common Lisp type specifiers that are valid as parameter specializer names are the following:'' The comment about bad use of ``parameter specifier'' is correct; I only wish he had brought it up sooner. I would have brought it up sooner if I had seen this edition of the document sooner. The previous edition used "parameter specifier" in a way that was consistent with CLtL. I think the re-wording is not as good as the original, though. We need to connect the linguistic item {\it parameter-specializer-name} (typeset in italics) with an English phrase that can be explained. The original had more information about the relationship between parameter specializer names and Common Lisp type specifiers, and the implicitness of that information in Moon's re-wording (and in earlier versions) rendered the whole section incomprehensible. I didn't think the phrase "where {\it parameter-specializer-name\/} is a parameter specializer name" added anything to understandability. If you strongly disagree we can put it back, but to me it seems unnecessary. Aside from that, the only changes I made to the paragraph were to change "parameter specifier" to "specialized parameter", removing a typo ("specializers" for "specializer"), and removing the portions of the last two sentences that were redundant with the table at the top of 1-19. The explanation that quote and member are the same also appears in the eighth paragraph on 1-19. Here is a possible re-wording: Each method has a {\bit specialized lambda-list}, which determines when that method can be selected. A specialized lambda-list is like an ordinary lambda-list except that a {\bit specialized parameter} may occur instead of the name of a parameter. A specialized parameter is a list, {\tt ({\it variable-name parameter-specializer-name\/})}, where {\it parameter-specializer-name\/} is a parameter specializer name. Every parameter specializer name is a Common Lisp type specifier, but the only Common Lisp type specifiers that are parameter specializers names are type specifier symbols with corresponding classes and type specifier lists of the form {\tt ({\bf quote} {\it object})}. The form {\tt ({\bf quote} {\it object})} is equivalent to the type specifier {\tt ({\bf member} {\it object\/})}. This undoes the changes I made, other than "parameter specifier" to "specialized parameter". I really think that this would make it harder to understand. Think about it again, and if you still disagree we can keep discussing it, or strike this correction from the errata and do it later. Moon writes: ``1-19 fourth paragraph, beginning "Only required parameters can be specialized": The term "parameter specifier" is misused again. Replace the paragraph with: Only required parameters can be specialized, and each required parameter must have an associated parameter specializer. For notational simplicity, ordinary lambda-list syntax can be used, that is, a parameter name can be used instead of a specialized parameter. In this case the parameter specializer defaults to the class named {\bf t}, the class of all objects.'' Again, the substantive point is well-taken, but the re-wording is bad. The style has become flabby and imprecise. If you need to say ``that is,'' then you said the wrong thing in the first place. The paragraph is talking about the required parameters, and the comment linking the syntax of them to lambda-list syntax doesn't restrict the lambda-list syntax of interest to the lambda-list syntax of required parameters. It is usually good to link new concepts with old ones, but this wording simply confuses the issue. Try this instead: Only required parameters can be specialized, and each required parameter must be a specialized parameter. For notational simplicity, if some required parameter in a specialized lambda-list is simply a variable name, the corresponding parameter specifier is taken to be {\tt ({\it variable-name} {\bf t})}. This is better than what I suggested, but self-contradictory. First it says that each required parameter must be a specializer parameter, which was earlier defined as a list, then it says that a required parameter can be a symbol. Also I have trouble figuring what is corresponding to what when you say "corresponding". How about this wording? Only required parameters can be specialized, and there must be a parameter specializer for each required parameter. For notational simplicity, if some required parameter in a specialized lambda-list is simply a variable name, its parameter specializer defaults to the class named {\bf t}. Moon writes: ``1-19, seventh, eighth, and tenth paragraphs, discussing the relationship of parameter specializers to type specifiers: Change "parameter specializer" to "parameter specializer name" throughout these paragraphs, to be consistent with the terminology used in earlier paragraphs.'' Nope. Moon missed the point, which, I guess, needs to be clarified even more. The second paragraph on page 19 defines parameter specializers (PS) in terms of parameter specializer names (PSN). The PSN's correspond to names of classes while the PS's are the classes. ``Satisfaction'' operates on the classes. This is so that the functional interface (ADD-METHOD et al) can take PS's and DEFMETHOD can take PSN's. Otherwise we cannot explain the change-class protocol. I did not miss this point. Indeed, I thought that clarifying this distinction substantially improved the document. Since I was only making an errata sheet and since I didn't think you needed me to stroke your ego I left out comments on the things that I thought were improved, and only commented on the things that I thought were not good enough yet. Read the offending paragraphs again. Paragraph 7 says This proposal requires that parameter specializers also be Common Lisp type specifiers. and paragraph 8 says typep accepts parameter specializers. If this means that typep is to be extended to accept class objects, that is a reasonable extension to propose, however since it is mentioned nowhere else in the document and is not stated explicitly here, and was never discussed on the mailing list, I assumed that that was not the intention, and instead the problem was that the conversion from "parameter specializer" to "parameter specializer name" had not been carried out uniformly. So which is it? If typep is to accept class objects, we need an errata entry that makes that very explicit. Later in paragraph 8 it says Note that in general a parameter specializer cannot be a type specifier list, such as {\tt ({\bf vector single-float})}. which is true, but would make more sense to say of parameter specializer names since that's what users write. Paragraph 10 says A method all of whose parameter specializers are {\bf t}... but a parameter specializer cannot be t, only a parameter specializer name can be t. This was the point that convinced me that all of these occurrences of "parameter specializer" were typos for "parameter specializer name". I'll think about the Chapter 2 comments later. I look forward to your comments.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Feb 87 15:13:29 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 25 Feb 87 12:05:15 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 78684; Wed 25-Feb-87 13:38:11 EST Date: Wed, 25 Feb 87 13:36 EST From: David A. Moon Subject: Proposed revision of "Inheritance of Slots and Slot Options" section To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870225133647.9.MOON@EUPHRATES.SCRC.Symbolics.COM> The description of "Inheritance of Slots and Slot Options" is too complex and too long. So far we have not been able to come up with a description of this that is both precise and understandable. Because I don't believe there is anything inherently complicated in the idea, I'm making another attempt to write a description. To keep the terminology consistent, I find I also have to change the section "Slots" on page 1-5. For readability I have removed all formatting controls; once we have agreed on the wording the formatting controls can be restored. \beginsubSection{Slots} [first two paragraphs unchanged] We say that a slot is defined by a class if the defclass form for that class contains a slot specifier with the given slot's name. [Metaclasses extend this idea, because they allow classes that aren't defined by defclass, but I don't think we need to go into that here. We could separate the ideas of "slot specifier" (source language syntax found in defclass forms) and "slot description" (object found in data structure, computed from a slot specifier), but that didn't seem to add to understandability when I tried it, so I prefer not to introduce slot descriptions until the meta-object chapter.] We say that a slot is accessible in an instance of a class if the slot is defined by the class of the instance or is inherited from a superclass of that class. A detailed explanation of the inheritance of slots is given in the section ``Inheritance of Slots and Slot Options.'' \beginsubSection{Inheritance of Slots and Slot Options} The set of the names of all slots accessible in an instance of a class, C, is the union of the sets of names of slots defined by C and its superclasses. At most one slot of a given name can be accessible in an instance. In the simplest case, only one class in the class precedence list of C defines a slot with a given slot name. If the class that defines the slot is not C, we say that the slot is inherited. The characteristics of the slot are determined by that class's slot specifier. If the :allocation slot option is omitted or specifies a local slot, then each instance of C stores its own value for the slot. If :allocation specifies a shared slot, the class that defined the slot stores the value and all instances of C access that single slot. In general, more than one class in the class precedence list can define a slot with a given name. In such cases, at most one slot with a given name is accessible in an instance of C, and the characteristics of that slot are a combination of the several slot specifiers, computed as follows. - All the slot specifiers for a given slot name are ordered from most specific to least specific, according to the order of the classes that define them in the class precedence list. - The allocation of a slot is controlled by the most specific slot specifier. If the most specific slot specifier does not contain an :allocation slot option, :instance is used. Less specific slot specifiers never affect the allocation. - The initform of a slot is controlled by the most specific slot specifier that contains an :initform slot option. If no slot specifier contains an :initform, the slot has no default initial value form. - The type of a slot is (and T1 T2 T3...), where T1, T2, T3, and so on are the :type slot options contained in all of the slot specifiers. If no slot specifier contains :type, the type is t. A consequence of the allocation rule is that shared slots can be shadowed. If a class C-sub-1 defines a shared slot named S, normally that single slot is accessible in instances of C-sub-1 and all of its subclasses. However, if C-sub-2 is a subclass of C-sub-1 and also defines a slot named S, C-sub-1's slot is not shared by instances of C-sub-2 and its subclasses. See S2 in the section ``Examples of Inheritance.'' A consequence of the type rule is that the value of a slot must satisfy the type constraint in -every- slot specifier that contributes to that slot. This maximally restrictive rule allows a compiler to optimize on the basis of the :type slot option. An argument to a method can be an instance of a subclass of the class declared by a parameter specializer, so the compiler cannot know the exact class. Methods that access slots know only the name of the slot and the type of the slot's value. Suppose a superclass provides a method that expects to access a shared slot of a given name and a subclass defines a local slot with the same name. If the method provided by the superclass is used on an instance of the subclass, the method accesses the local slot. The :reader and :accessor slot options were not mentioned above because they create methods rather than defining characteristics of a slot. Reader and accessor methods are inherited in the sense described in the section ``Inheritance of Methods.'' [I also tried writing the above in notational form, in the spirit of Dick's notation used in 87-002. However, with the new simplified description the notation doesn't appear to add any understandability, so I won't bother mailing it out. It's available on request.]  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Feb 87 01:13:44 EST Received: from NAVAJO.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 23 Feb 87 22:06:45 PST Received: by navajo.stanford.edu; Mon, 23 Feb 87 22:05:30 PST Received: from bhopal.edsel.com by edsel.uucp (2.2/SMI-2.0) id AA01335; Mon, 23 Feb 87 17:46:32 pst Received: by bhopal.edsel.com (3.2/SMI-3.2) id AA12677; Mon, 23 Feb 87 17:43:59 PST Date: Mon, 23 Feb 87 17:43:59 PST From: edsel!bhopal!jonl@navajo.stanford.edu (Jon L White) Message-Id: <8702240143.AA12677@bhopal.edsel.com> To: navajo!common-lisp-object-system%sail@navajo.stanford.edu Subject: Relations to window standardization Two messages recently appearing on the cl-windows mailing list: Date: Fri, 20 Feb 87 23:43:36 PST From: navajo!edsel!bhopal!jonl@navajo.stanford.edu (Jon L White) To: navajo!Fahlman%C.CS.CMU.EDU@navajo.stanford.edu Cc: navajo!cl-windows%SAIL@navajo.stanford.edu In-Reply-To: "Scott E. Fahlman"'s message of Fri, 20 Feb 1987 22:45 EST Subject: CW Standard Status One possibility for standardization in the Common Lisp world is merely on a user-interface to a window system. Having seen the sentiment on this list, and others, it seems that folks clearly want (1) some sort of object-oriented interface (2) and one which doesn't require research-project-level effort to understand and use. I guess that is why the disussions often tie together a potential window system candidate with an o-o candidate. Let us very-hypothetically suppose that some o-o standard emerges within the next year; then what do you think? can a reasonable subset of window capability be described in o-o terms? This would not be the kind of standard where everybody had to implement the features described in the interface, or were restricted to it; but rather it would say "if you provide capability Z, then the user interface to it should look like ....". I'd expect that over time, there would come to be a certain minimum set of required capabilities that everyone agreed would have to be implemented in order for a candidate to call itself a window system. I think we can rule out the ASR/35 and friends as being any part of a "window" system. -- JonL -- Date: Sun, 22 Feb 1987 20:42 EST Sender: navajo!FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: edsel!bhopal!jonl@navajo.stanford.edu (Jon L White) Cc: cl-windows@SAIL.STANFORD.EDU Subject: CW Standard Status In-Reply-To: Msg of 21 Feb 1987 02:43-EST from edsel!bhopal!jonl at navajo.stanford.edu (Jon L White) Sure, given an object-oriented standard, it's just a matter of figuring out what higher-level abstractions are most appropriate and convenient for a graphics/windows interface. If a consensus emerges about that, then it's just a small matter of turning that consensus into a formal standard. In order for this consensus to develop, we need some experience, some good ideas, someone to work out a coherent proposal, and someone to implement that proposal in reasonably portable public-domain code. I think that this may eventually happen. I don't know how long it will take. Most of the groups I know about are just starting to experiment with this stuff. Maybe there are segments of the Lisp community that already have enough experience with objects and graphics to understand what a really good set of abstractions would look like. If that same set of people have the time and motivation to produce a proposal and supporting code, then we could make very fast progress; if not, then we're in for a couple of years of experimentation. If most of us can work on a shared low-level substrate such as X, then the experimentation will go more quickly because we can share what we develop. -- Scott  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 23 Feb 87 23:40:42 EST Received: from Salvador.ms by ArpaGateway.ms ; 23 FEB 87 19:49:47 PST Return-Path: Received: from H.CS.CMU.EDU ([128.2.254.156]) by Xerox.COM ; 23 FEB 87 19:47:59 PST Date: 23 Feb 87 22:37 EST From: Rick.Busdiecker@h.cs.cmu.edu To: CommonLoops.PA@Xerox.COM Subject: method declarations Message-Id: <541136278/rfb@h.cs.cmu.edu> It appears that declarations at the start of the body of a method (using either DefMeth or DefMethod) are not passed through the function at compile time. For example, with CMU CommonLisp and PCL of "1/26/87", compiling: (defmeth ((self foo) bar) (declare (ignore self bar))) generates a warning that foo and bar are bound but not referenced although compiling: (lambda (self bar) (declare (ignore self bar))) does not. Rick  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Feb 87 22:48:47 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Feb 87 19:41:35 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 77255; Mon 23-Feb-87 22:41:37 EST Date: Mon, 23 Feb 87 22:40 EST From: David A. Moon Subject: errata sheet To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 21 Feb 87 01:42 EST from Dick Gabriel Message-ID: <870223224014.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 20 Feb 87 2242 PST From: Dick Gabriel I don't especially mind an errata sheet as long as it doesn't contain un-agreed-to proposed re-wordings. The factual errors are ok to put there, but I'd rather not see listed as errata an inferior re-wording of a clearly worded paragraph. I don't mind re-wording things if the re-wording is better, but good wording is the result of long, careful thought. I have a separate list of problems noticed in the document that I expect to be controversial, which I do not plan to distribute publically. I hope to mail it to this group in a few days for our own discussion. I would be happy to move individual items that you disagree with on the errata sheet into that other list instead, if you'll tell me which ones they are, and if one round of discussion doesn't remove the controversy. (I haven't finished studying Dick's earlier message commenting on my draft errata sheet, and I haven't seen any comments from anyone else yet.)  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Feb 87 22:47:54 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Feb 87 19:37:55 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 77253; Mon 23-Feb-87 22:38:24 EST Date: Mon, 23 Feb 87 22:36 EST From: David A. Moon Subject: CPL To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 21 Feb 87 01:55 EST from Dick Gabriel Message-ID: <870223223657.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 20 Feb 87 2255 PST From: Dick Gabriel You might wonder why I continue to harp on the CPL.... Moon argued that the New Flavors CPL algorithm did the right thing and was intuitive. He argued that some huge number of users depended on it and liked it. So we tried to figure out an alternative formulation that was easier to understand. The result was that we found an example that showed that the algorithm that did the right thing and that programmers loved did the wrong thing. This is not quite accurate. The CPL algorithm in New Flavors and the one in 87-002 are very close in their effects. The example we found where they differ is one in which the algorithm used in New Flavors fails to produce the intuitive result. The programmers never loved the algorithm, nor even knew in such detail what it did that they could distinguish between the New Flavors algorithm and the 87-002 algorithm. What they liked was the result, not the way it was computed. What I argued against was other proposed algorithms that produced very different results. What you argued against was algorithms whose description was not very algorithmic. We both got what we wanted. Why aren't we trying to think of a simple way for the user to have control of the CPL without making him write his own algorithm? Does this mean that you want me to convert the following, extracted directly from the Flavors documentation, to 87-002 terminology and distribute it for comments, either in this working group or at the X3J13 meeting? If so, I'll be happy to do so. @Topic[:component-order Option for defflavor] Enables you to state explicitly the ordering constraints for the flavor components whose order is important. You can use it to relax ordering constraints on component flavors for which order is not important. You can also use it to add ordering constraints on flavors that are not components; this means that if this flavor is later mixed with another flavor, the ordering of components takes into account the constraints given by this option. If :component-order is given, the order of flavor components at the top of the defflavor form is no longer significant. The arguments to :component-order are lists. The members of each list are constrained to appear in the order they appear in the list. Any component that does not appear in these lists has no ordering constraints placed on it. For example, the following form imposes many constraints on the ordering of the seven flavor components: (defflavor foo (var1 var2) (a b c d e f g)) However, your program might not depend on a specific ordering of components, because the components have no effect on each other. For example, your program might depend only these ordering constraints: - Flavor c must precede d. - Flavor b must precede g. - If flavor x is present (it could be a component of one of the components, or it could be mixed into flavor foo to create a new flavor), it must follow b and precede g. You can specify those restrictions by giving the following option to defflavor: (defflavor foo (var1 var2) (a b c d e f g) (:component-order (c d) (b x g))) Note that this does not constrain flavors c and d to precede flavors b, x, and g. Also, it is not an error to specify an ordering constraint for a flavor that is not a component of this flavor. For example, it is valid to constrain the order of x, although x might not be a direct or indirect component of this flavor.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Feb 87 13:48:05 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Feb 87 10:41:03 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 76668; Mon 23-Feb-87 13:41:22 EST Date: Mon, 23 Feb 87 13:39 EST From: David A. Moon Subject: Errata To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870223133957.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Here's one I missed: 1-6 first paragraph: Change ":instance" to ":instance or :dynamic".  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Feb 87 13:15:43 EST Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 23 Feb 87 10:07:41 PST Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 53681; Mon 23-Feb-87 13:06:32 EST Date: Mon, 23 Feb 87 13:06 EST From: Daniel L. Weinreb Subject: CPL To: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 21 Feb 87 01:55 EST from Dick Gabriel Message-ID: <870223130627.8.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: 20 Feb 87 2255 PST From: Dick Gabriel Moon thought this algorithm was the right thing for about a year (?). Why is what we now have the right thing? Why aren't we trying to think of a simple way for the user to have control of the CPL without making him write his own algorithm? We can provide some default, but I think that making someone write their own topological sort as the only alternative is a loser. The answer to this problem in New Flavors is a per-flavor option that lets you explicitly add partial-order constraints. I think this would be a good way to address the problems you raise. It means that for relatively small or simple application, in which the first two rules fully specify the order, the right thing happens automatically. For larger or more complex applications, it let you explicitly control any ambiguity that might be a problem, but does not force you to completely enumerate every CPL (which would be a real pain in the neck and make subsequent modifications awkward).  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 23 Feb 87 12:34:50 EST Received: from Cabernet.ms by ArpaGateway.ms ; 23 FEB 87 08:29:27 PST Return-Path: Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 23 FEB 87 08:27:32 PST Received: from hplabsc by hplabs.HP.COM ; Mon, 23 Feb 87 08:25:58 pst Received: by hplabsc ; Mon, 23 Feb 87 08:25:37 pst Date: Mon, 23 Feb 87 08:25:37 pst From: Jim Kempf Message-Id: <8702231625.AA17194@hplabsc> To: CommonLoops.PA@Xerox.COM, Rick.Busdiecker@h.cs.cmu.edu Subject: Re: function names and warnings If you look in methods.l, the code generated for the method functions in EXPAND-DEFMETH-INTERNAL inserts a DECLARE after the LAMBDA which declares the name of the method to be a method function name, as: (DECLARE (METHOD-FUNCTION-NAME ,)) METHOD-FUNCTION-NAME is not a standard declaration from CLtL. I would assume, however, most Common Lisp implementations have a way of naming LAMBDA's, which they use for named function definition. In HP Lisp, the extension is: (DECLARE (EXTN:NAME ,)) I modified my methods.l so it looks something like this: (defvar *method-name-declaration* #-HP 'method-function-name #+HP 'extn:name ) (declare (,*method-name-declaration* ,)) As to why not just use a DEFUN instead of a LAMBDA, I'm only guessing, but there are a number of possible reasons. One is to decrease method definition time by open coding function definition, another is so that only one block can be established around the method function with the method name. A DEFUN would establish an additional block with the generated function name as well. Depending on the implementation, this could result in code which was less efficient, and, in any event, semantically incorrect, since the user could jump out of the method by using the generated function name. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Feb 87 14:09:02 EST Date: 22 Feb 87 1054 PST From: Dick Gabriel Subject: Away To: common-lisp-object-system@SAIL.STANFORD.EDU I'm away until Wednesday night. Please do not immolate each other until I return. -rpg-  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Feb 87 12:25:01 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 FEB 87 09:09:02 PST Return-Path: Received: from H.CS.CMU.EDU ([128.2.254.156]) by Xerox.COM ; 22 FEB 87 08:28:01 PST Date: 22 Feb 87 11:18 EST From: Rick.Busdiecker@h.cs.cmu.edu To: CommonLoops.PA@Xerox.COM Subject: function names and warnings Message-Id: <541009137/rfb@h.cs.cmu.edu> In CMU CommonLisp using PCL of 1/28/87, I find that I when I'm compiling PCL code, I get a lot of warnings of the form: Warning in #:Gxxx PCL::METHOD-FUNCTION-NAME unknown declaration type. What is the method-function-name declaration? Why are the symbols for method functions made this way (as presumeably gensym'ed symbols?) I much preferred the names which preserved information from the defmeth form in the function symbol name. Rick  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Feb 87 12:24:53 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 FEB 87 09:07:36 PST Return-Path: Received: from H.CS.CMU.EDU ([128.2.254.156]) by Xerox.COM ; 22 FEB 87 08:18:30 PST Date: 22 Feb 87 11:06 EST From: Rick.Busdiecker@h.cs.cmu.edu To: CommonLoops.PA@Xerox.COM Subject: defclass Message-Id: <541008361/rfb@h.cs.cmu.edu> > From: Gregor.pa@Xerox.COM > Subject: IMPORTANT changes to PCL on the horizon > > construct new instances. No accessor, reader, or constructor functions > are defined by default: their generation must be explicitly requested. It looks like the constructors are generated by default. I use CMU CommonLisp and PCL of 1/26/87: * (defclass dip () (zim bob way)) DIP * (make-dip) #S(DIP ZIM NIL BOB NIL WAY NIL)  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Feb 87 12:24:42 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 FEB 87 08:05:43 PST Return-Path: Received: from H.CS.CMU.EDU ([128.2.254.156]) by Xerox.COM ; 22 FEB 87 08:02:10 PST Date: 22 Feb 87 10:52 EST From: Rick.Busdiecker@h.cs.cmu.edu To: CommonLoops.PA@Xerox.COM Subject: setf in defmethod? Message-Id: <541007536/rfb@h.cs.cmu.edu> I was under the impression that DefMeth and DefMethod were supposed to have the same syntax for defining SetF methods, and that syntax was: (DEFMETHOD (accessor-name (:SETF new-value)) defmethod-lambda-list body-of-setf-method) While that syntax works fine for DefMeth, it fails under CMU CommonLisp using the PCL of 1/26/87 with an error of the form: Error in function STRING. (accessor-name (:SETF (new-value))) cannot be coerced to a string. What is the correct syntax for defining SetF methods using Defmethod?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Feb 87 02:03:16 EST Date: 20 Feb 87 2255 PST From: Dick Gabriel Subject: CPL To: common-lisp-object-system@SAIL.STANFORD.EDU You might wonder why I continue to harp on the CPL. Moon argues that the CPL computation should do a clear, unambiguous thing. If it's intuitive, all the better. Maybe so. My worry is that most people, even after a lot of thought, will think of it like this: 1. the CPL respects the superclass relationships 2. the CPL respects the order of direct superclasses 3. otherwise, it is a black box, and if the programmer doesn't like it, he can supply his own. The CPL is used all over the place, and it's not comforting to think that the correctness of your program depends on a black box. Moon argued that the New Flavors CPL algorithm did the right thing and was intuitive. He argued that some huge number of users depended on it and liked it. So we tried to figure out an alternative formulation that was easier to understand. The result was that we found an example that showed that the algorithm that did the right thing and that programmers loved did the wrong thing. Moon thought this algorithm was the right thing for about a year (?). Why is what we now have the right thing? Why aren't we trying to think of a simple way for the user to have control of the CPL without making him write his own algorithm? We can provide some default, but I think that making someone write their own topological sort as the only alternative is a loser. Well, let's have the committee look over the proposal and make its comments. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Feb 87 01:48:25 EST Date: 20 Feb 87 2242 PST From: Dick Gabriel Subject: Meeting To: common-lisp-object-system@SAIL.STANFORD.EDU I can make a meeting on monday, but I'd like to be within hailing distance of the main meeting in case a fight breaks out. I don't especially mind an errata sheet as long as it doesn't contain un-agreed-to proposed re-wordings. The factual errors are ok to put there, but I'd rather not see listed as errata an inferior re-wording of a clearly worded paragraph. I don't mind re-wording things if the re-wording is better, but good wording is the result of long, careful thought. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Feb 87 12:35:02 EST Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 20 Feb 87 09:28:39 PST Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 52917; Fri 20-Feb-87 12:27:39 EST Date: Fri, 20 Feb 87 12:27 EST From: Daniel L. Weinreb Subject: Consistency To: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 19 Feb 87 20:52 EST from Dick Gabriel Message-ID: <870220122725.1.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: 19 Feb 87 1752 PST From: Dick Gabriel At this point I'm worried about a couple of new things: first, that the Common-Lisp-skeptics will accuse us of doing to object-oriented programming what we did to Lisp: obfuscate and ruin it; second, that the proposal might be in jeopardy because it is too complex. I share your worries about this. However, it's not too surprising, since all we're giving the community is a reference manual. Reference manuals are good for DEFINING a standard, but they aren't so good for SELLING a standard. (For example, I am absolutely convinced that Scott Fahlman's snarling antipathy to Flavors is due entirely to the fact that the Flavors documentation that Moon and I wrote doesn't separate the easy, everyday features from the sophisticated, only-for-experts features, thus giving a false impression that you must master great complexity in order to do even the simplest thing.) Based on all my experience with technical writing, I don't think it's practical or desirable to try to come up with a single document that serves both as a precise reference for CLOS, and also as a friendly introduction to CLOS. I still believe that we are writing a specification, and it would be wrong to put fluffy, imprecise language into the document... When I decide to write things using mathematical notation, for example, it is because I cannot think of how to unambiguously express the concepts in English.... Exactly. The problem is that what you call "fluffy, imprecise English" is often the best way to TEACH someone about something. You use conversational English to establish the basic idea, the motivation, the paradigm; then you use precise, rigorous, and maybe even mathematical language to explain it in such a way that the user can be sure of understanding all the cases, including complicated interations, and so on. Papers like the ones mailed out as X3J13/86-018, or something even gentler, are more like what you'd want for teaching the basic concepts. I don't know whether something like this could be produced in time for distribution at the next X3J13 meeting. At least, though, when we present the material, we can take that kind of gentle approach, and remind people several times that what they're holding is a reference manual, not a tutorial, and not to think that everybody would learn CLOS by reading the reference manual.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Feb 87 20:58:13 EST Date: 19 Feb 87 1752 PST From: Dick Gabriel Subject: Consistency To: common-lisp-object-system@SAIL.STANFORD.EDU At this point I'm worried about a couple of new things: first, that the Common-Lisp-skeptics will accuse us of doing to object-oriented programming what we did to Lisp: obfuscate and ruin it; second, that the proposal might be in jeopardy because it is too complex. The people at Tektronix had no trouble understanding what I said, nor did they fail to understand CLOS. They were appalled at the complexity and questioned whether that complexity was necessary. I'm suggesting, also, that maybe the organization of the system should be made to reflect the proposed organization of the document. The point would be to make CLOS less intimidating to the new user. I still believe that we are writing a specification, and it would be wrong to put fluffy, imprecise language into the document. I think from my comments about Moon's errata you can still see this attitude. And if you compared the draft material as of 2 weeks ago with the current draft you will see a major movement towards consistency and preciseness, even at the expense of pretty language - it may not be perfect, but a lot of what was there before was embarrassingly bad. When I decide to write things using mathematical notation, for example, it is because I cannot think of how to unambiguously express the concepts in English. (Also, if the concepts were simpler, they could be expressed in prose more easily.) I must admit a little bit second-thinking about CLOS and how much more time I can justify putting into it. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Feb 87 20:51:44 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Feb 87 17:43:36 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74578; Thu 19-Feb-87 20:18:19 EST Date: Thu, 19 Feb 87 19:58 EST From: David A. Moon Subject: CLOS Response To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 19 Feb 87 16:23 EST from Dick Gabriel Message-ID: <870219195839.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 19 Feb 87 1323 PST From: Dick Gabriel Monday I presented CLOS to the SmallTalk and Scheme folks at Tektronix in Beaverton, Oregon. The response was disappointing, though one would expect SmallTalk people to respond negatively. However, they made some good points. I think this feedback is valuable, but should be put into perspective. Comments below. First, they were skeptical about the class precedence list and the wary of the importance of it....They proposed that the CPL computation should explicitly pick a random but valid total ordering when nondeterminism happens. I sent mail in November with some strong arguments for why this won't work. I think it was November; I can dig up the exact message reference if you like. This radical suggestion can be made palletable by adding the following things. 1. There should be a flag that controls when the system warns about nondeterminism; We could do this if we didn't mind adding extra complexity to the standard. It would have to be a class option, not a global flag, so that classes using both styles could coexist in the same Lisp. 2. There should be a new class option which is of this form: (:relations (C1 C2) ... (Cn-1 Cn)) in DEFCLASS which give further constraints to the ordering of superclasses. Flavors has this but there didn't seem to be much interest in putting it into the standard. Should we reconsider that decision, or would that be making the standard too complex? Second, they thought that the complexity of slot description combination was complex. I agree. The description in the document is horrendously overcomplicated. The previous attempt was much simpler but still too hard to understand and imprecise. For some reason we've had great difficulty explaining this concept, even though it is actually rather simple. I've been planning on mailing out a proposed better way of explaining slot inheritance for discussion, but haven't had time to finish it yet. In any case something clearly has to be done. Third, they thought that method combination was complex. Because we all seem to agree that method combination is important, this probably indicates a different presentation methodology or a different organization to the system is desirable. One suggestion is to present CLOS so that it looks as much like CommonLoops as possible at first glance and to then bring in method combination. That is, maybe a good idea is to break up the current first chapter into two chapters where the first chapter defines only unqualified methods along with the behavior of methods under CALL-NEXT-METHOD. The second chapter could show what happens when methods are qualified using standard method combination. This is the reaction one would expect from people used to Smalltalk's send-to-super mechanism. I think you would find the analogous reaction, that the call-next-method feature is complex and should be relegated to the back of the book, if you presented it to people who were used to method combination. I think the order of presentation should be left the way it is and we should concentrate on the remaining substantial issues that need to be resolved. At least a conceptual simplicity in presentation must be maintained. LGD and I only cleaned up the description of method combination enough that it was not grossly inconsistent, and I think it needs a major amount of thought to present it well. I thought we were trying to be precise with this document, rather than trying to be easy to understand.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Feb 87 18:33:08 EST Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 19 Feb 87 15:24:47 PST Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 52619; Thu 19-Feb-87 18:23:49 EST Date: Thu, 19 Feb 87 18:23 EST From: Daniel L. Weinreb Subject: CLOS Response To: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 19 Feb 87 16:23 EST from Dick Gabriel Message-ID: <870219182341.9.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: 19 Feb 87 1323 PST From: Dick Gabriel Third, they thought that method combination was complex. Because we all seem to agree that method combination is important, this probably indicates a different presentation methodology or a different organization to the system is desirable. One suggestion is to present CLOS so that it looks as much like CommonLoops as possible at first glance and to then bring in method combination. That is, maybe a good idea is to break up the current first chapter into two chapters where the first chapter defines only unqualified methods along with the behavior of methods under CALL-NEXT-METHOD. The second chapter could show what happens when methods are qualified using standard method combination. This suggestion doesn't seem very consistent with your earlier (months ago) statements about the philosophy of this document. Earlier, you pointed out that we are writing a specification, mainly intended for implementors and language experts, with the goal of making sure that each implementation of CLOS will be compatible with each other, to assure portability. You even criticised some of the early draft text because it was too pedagogical. I think you convinced all of us that you were right, that our priorities should be on specificity and exactness, rather than on providing a friendly, teaching approach, for purposes of this document. I'm sure we all agree that at least one friendly, pedagogical explanation of CLOS can and will appear in the future (probably many), after CLOS is defined and accepted, but the present document isn't it.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Feb 87 17:28:36 EST Date: 19 Feb 87 1422 PST From: Dick Gabriel Subject: Comments On Moon's Errata (Chapter 1 only) To: Common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: ``1-11 fourth paragraph: Delete the entire paragraph, it isn't true. Replace it with this paragraph: Because the class C-sub-O does not have a name, writing a method for class-changed that is specialized to a particular C-sub-O must be done through the functional interface, using add-method rather than defmethod.'' I think the original statement is true, and it is because of that fact that Moon's re-statement would be true. Possibly both statements should be made, suitably phrased: Because redefining a class does not change its name, the class $C\sub o$ does not have a name. Thus, writing a method for {\bf class-changed} that is specialized to a particular $C\sub o$ must be done through the functional interface, using {\bf add-method} rather than using {\bf defmethod}. See the section ``Introduction to Methods.'' I think this might make the situation clearer to the reader. Moon writes: ``1-18 first paragraph under "Introduction to setf Generic Functions": Change "(setf (generic-function-name arguments) new-value)" to "(setf (function-name arguments) new-value)" because the base function does not have to be generic, in fact it does not even have to be defined.'' If this is correct, then it should be: ``(setf (symbol arguments) new-value)'' Moon writes: ``1-18 last paragraph: The term "parameter specifier" is used in a way that is inconsistent with its use by CLtL and there are a couple of typographical problems. Replace the entire paragraph with: Each method has a {\bit specialized lambda-list}, which determines when that method can be selected. A specialized lambda-list is like an ordinary lambda-list except that a {\bit specialized parameter} may occur instead of the name of a parameter. A specialized parameter is a list, {\tt ({\it variable-name parameter-specializer-name\/})}. Every parameter specializer name is a Common Lisp type specifier, but the only Common Lisp type specifiers that are valid as parameter specializer names are the following:'' The comment about bad use of ``parameter specifier'' is correct; I only wish he had brought it up sooner. I think the re-wording is not as good as the original, though. We need to connect the linguistic item {\it parameter-specializer-name} (typeset in italics) with an English phrase that can be explained. The original had more information about the relationship between parameter specializer names and Common Lisp type specifiers, and the implicitness of that information in Moon's re-wording (and in earlier versions) rendered the whole section incomprehensible. Here is a possible re-wording: Each method has a {\bit specialized lambda-list}, which determines when that method can be selected. A specialized lambda-list is like an ordinary lambda-list except that a {\bit specialized parameter} may occur instead of the name of a parameter. A specialized parameter is a list, {\tt ({\it variable-name parameter-specializer-name\/})}, where {\it parameter-specializer-name\/} is a parameter specializer name. Every parameter specializer name is a Common Lisp type specifier, but the only Common Lisp type specifiers that are parameter specializers names are type specifier symbols with corresponding classes and type specifier lists of the form {\tt ({\bf quote} {\it object})}. The form {\tt ({\bf quote} {\it object})} is equivalent to the type specifier {\tt ({\bf member} {\it object\/})}. Moon writes: ``1-19 fourth paragraph, beginning "Only required parameters can be specialized": The term "parameter specifier" is misused again. Replace the paragraph with: Only required parameters can be specialized, and each required parameter must have an associated parameter specializer. For notational simplicity, ordinary lambda-list syntax can be used, that is, a parameter name can be used instead of a specialized parameter. In this case the parameter specializer defaults to the class named {\bf t}, the class of all objects.'' Again, the substantive point is well-taken, but the re-wording is bad. The style has become flabby and imprecise. If you need to say ``that is,'' then you said the wrong thing in the first place. The paragraph is talking about the required parameters, and the comment linking the syntax of them to lambda-list syntax doesn't restrict the lambda-list syntax of interest to the lambda-list syntax of required parameters. It is usually good to link new concepts with old ones, but this wording simply confuses the issue. Try this instead: Only required parameters can be specialized, and each required parameter must be a specialized parameter. For notational simplicity, if some required parameter in a specialized lambda-list is simply a variable name, the corresponding parameter specifier is taken to be {\tt ({\it variable-name} {\bf t})}. Moon writes: ``1-19, seventh, eighth, and tenth paragraphs, discussing the relationship of parameter specializers to type specifiers: Change "parameter specializer" to "parameter specializer name" throughout these paragraphs, to be consistent with the terminology used in earlier paragraphs.'' Nope. Moon missed the point, which, I guess, needs to be clarified even more. The second paragraph on page 19 defines parameter specializers (PS) in terms of parameter specializer names (PSN). The PSN's correspond to names of classes while the PS's are the classes. ``Satisfaction'' operates on the classes. This is so that the functional interface (ADD-METHOD et al) can take PS's and DEFMETHOD can take PSN's. Otherwise we cannot explain the change-class protocol. I'll think about the Chapter 2 comments later. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Feb 87 16:30:02 EST Date: 19 Feb 87 1323 PST From: Dick Gabriel Subject: CLOS Response To: common-lisp-object-system@SAIL.STANFORD.EDU Monday I presented CLOS to the SmallTalk and Scheme folks at Tektronix in Beaverton, Oregon. The response was disappointing, though one would expect SmallTalk people to respond negatively. However, they made some good points. First, they were skeptical about the class precedence list and the wary of the importance of it. Their concern was that much of the behavior of the system depended on it while the user couldn't control it easily nor could a user understand it well. There was little problem with the topological sorting, and the problems were with what happened when the explicit rules (a class precedes its superclasses and the local precedence order is preserved) underconstrained the ordering. They did not understand the ``tiebreaker.'' The Scheme people had an interesting proposal: the specification should say that the CPL is a topological sort of the C and its superclasses subject to the explicit rules, but that the user could not depend on what happened when the problem was underconstrained. They proposed that the CPL computation should explicitly pick a random but valid total ordering when nondeterminism happens. This radical suggestion can be made palletable by adding the following things. 1. There should be a flag that controls when the system warns about nondeterminism; 2. There should be a new class option which is of this form: (:relations (C1 C2) ... (Cn-1 Cn)) in DEFCLASS which give further constraints to the ordering of superclasses. This way the user can specify the ordering without having to write his own CPL computation function. We could also have some means of using a default tiebreaker, which would probably be the one we have now. I imagine people would program by writing defclasses, watching or thinking about what's happening, and then adding the further constraints to get the desired behavior. The reasonable behavior of the programming environment tools is important here. Second, they thought that the complexity of slot description combination was complex. I agree. Third, they thought that method combination was complex. Because we all seem to agree that method combination is important, this probably indicates a different presentation methodology or a different organization to the system is desirable. One suggestion is to present CLOS so that it looks as much like CommonLoops as possible at first glance and to then bring in method combination. That is, maybe a good idea is to break up the current first chapter into two chapters where the first chapter defines only unqualified methods along with the behavior of methods under CALL-NEXT-METHOD. The second chapter could show what happens when methods are qualified using standard method combination. At least a conceptual simplicity in presentation must be maintained. LGD and I only cleaned up the description of method combination enough that it was not grossly inconsistent, and I think it needs a major amount of thought to present it well. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Feb 87 00:50:22 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Feb 87 21:39:19 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73697; Thu 19-Feb-87 00:38:18 EST Date: Thu, 19 Feb 87 00:38 EST From: David A. Moon Subject: Errata for 87-002 To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870219003802.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Here is my first draft of the errata sheet for the 87-002 documents. This doesn't get into things that need to be explained better in a major way, nor into things that are controversial, only things where what the document says is obviously in error. I'll send out the other things separately. Comments, corrections, and additions are of course highly welcome. I tried to find everything but no doubt overlooked some errors. 1-4 seventh paragraph: The distinguished class T is mentioned but I don't think its characteristics are ever described in the document, except by implication. Add the sentence: T has no superclasses and is a superclass of every class except itself. 1-6 last paragraph: At the end of the second sentence: change "lexically available" to "lexically available as if they were variables". 1-10: Replace the last sentence with "There is also a method for {\bf setf} of {\tt C2-S3} that writes the value of {\tt S3}." 1-11 second paragraph: The vague word "access" is used without definition. Add the sentence: "In this context, an instance is said to be accessed when a generic function is called with the instance as an argument that is used for method selection, or when {\bf slot-value} is called with the instance as its first argument." 1-11 third paragraph: Remove the sentence "The function {\bf change-class} is called when the number of instance variables changes or when the name of any instance variable changes" since there is no such concept as "instance variable" in this standard. Replace it with the sentence: "When a class is redefined in such a way that the set of local slots accessible to an instance of the class is changed, or the order of slots in storage is changed, updating an instance of the class calls the function {\bf change-class}." 1-11 fourth paragraph: Delete the entire paragraph, it isn't true. Replace it with this paragraph: Because the class C-sub-O does not have a name, writing a method for class-changed that is specialized to a particular C-sub-O must be done through the functional interface, using add-method rather than defmethod. 1-11 fifth paragraph third sentence: Change "Each slot of the new version" to "Each local slot of the new version". Last sentence: Delete "For local slots," since we are only talking about local slots anyway. 1-11 last paragraph: Change "the value of that slot will be the same in both instances" to "the value of that slot is unchanged". Since only one instance is involved, we can't say "both instances." 1-11 last paragraph: Break the paragraph after the third sentence so local slots and shared slots are discussed in separate paragraphs. Clarify that the paragraph discussing shared slots refers to what happens at the time the class is redefined, and shared slots are not affected by updating an instance nor by the values of local slots. 1-12 last paragraph: Change "Whether {\bf defclass} is allowed to change the metaclass" to "Whether {\bf defclass} is allowed to change the metaclass, and whether redefining a class updates existing instances,". 1-18 first paragraph under "Introduction to setf Generic Functions": Change "(setf (generic-function-name arguments) new-value)" to "(setf (function-name arguments) new-value)" because the base function does not have to be generic, in fact it does not even have to be defined. 1-18 last paragraph: The term "parameter specifier" is used in a way that is inconsistent with its use by CLtL and there are a couple of typographical problems. Replace the entire paragraph with: Each method has a {\bit specialized lambda-list}, which determines when that method can be selected. A specialized lambda-list is like an ordinary lambda-list except that a {\bit specialized parameter} may occur instead of the name of a parameter. A specialized parameter is a list, {\tt ({\it variable-name parameter-specializer-name\/})}. Every parameter specializer name is a Common Lisp type specifier, but the only Common Lisp type specifiers that are valid as parameter specializer names are the following: 1-19: Delete the first line "In short..." since the two bulleted items are now introduced by the preceding paragraph. 1-19 fourth paragraph, beginning "Only required parameters can be specialized": The term "parameter specifier" is misused again. Replace the paragraph with: Only required parameters can be specialized, and each required parameter must have an associated parameter specializer. For notational simplicity, ordinary lambda-list syntax can be used, that is, a parameter name can be used instead of a specialized parameter. In this case the parameter specializer defaults to the class named {\bf t}, the class of all objects. 1-19 fifth paragraph: Change "when the class of each required argument" to "when each required argument". 1-19, seventh, eighth, and tenth paragraphs, discussing the relationship of parameter specializers to type specifiers: Change "parameter specializer" to "parameter specializer name" throughout these paragraphs, to be consistent with the terminology used in earlier paragraphs. 1-19 tenth paragraph: Change "always part of the generic function" to "always applicable". 1-19 last paragraph fourth sentence: Change "cons" to "list". 1-22 second paragraph: Change "the specializers must be quoted objects (otherwise" to "the specializers must be equal (otherwise". 1-23 first line: Change "defmacro" to "defmethod". 1-25 sixth paragraph: Change "All {\bf :around} methods run before any primary methods run." to "All {\bf :around} methods run before any non-{\bf :around} methods run." 2-5 Values paragraph: Replace the whole sentence with "The value is {\it generic-function}." to clarify that the value is EQ to the argument. 2-8 Purpose paragraph: Add the sentences "The generic function {\bf change-class} is invoked automatically by the system after {\bf defclass} has been used to redefine an existing class. It can also be explicitly invoked by the user." 2-8 Values paragraph: Replace the whole sentence with "The value is {\it instance}." to clarify that the value is EQ to the argument. 2-11 Purpose paragraph: Delete the sentences "The generic function {\bf change-class} is invoked automatically by the system after {\bf defclass} has been used to redefine an existing class. It can also be explicitly invoked by the user." Add the sentence "The function {\bf class-changed} is called only by the function {\bf change-class}." 2-11 second Arguments paragraph: Delete the second sentence. It lost its intended meaning as a result of previous editing. 2-11 first Remarks paragraph: Delete this. It contradicts an example on page 2-8 and it isn't true. 2-11 second Remarks paragraph: Some occurrences of change-class should be class-changed and there are a couple of terminological problems ("copy", "part"). Replace the paragraph with: The arguments to {\bf class-changed} are computed by {\bf change-class}. The first argument is an instance of the original class created to hold the old slot values temporarily. This argument has dynamic extent within {\bf class-changed}, and therefore it is an error to reference it in any way once {\bf class-changed} returns. 2-15 last line: Delete this. Defclass has no effect on the value cells of symbols. 2-17 second paragraph: Delete ", from their superclasses, and so on". 2-17 :allocation bullet: Change "in the class instance" to "in each instance". 2-18 first bullet (:type). There is no discussion of the meaning and enforcement of :type. Add the following (stolen from CLtL p.310): This specifies that the contents of the slot will always be of the specified data type. This is entirely analogous to the declaration of a variable or function; indeed, it effectively declares the result type of the reader generic function when applied to an object of this class. An implementation may or may not choose to check the type of the new object when initializing or assigning to a slot. 2-18 :accessor-prefix, :reader-prefix bullets: Change "These ... functions are interned" to "These ... function names are interned". 2-26 short-form-option syntax: Delete the :order clause. 2-27 fourth bullet: Delete it. 2-29 first paragraph: Replace the next to last sentence with: "If {\bf :description} is not specified, a default description is generated based on the variable name and the qualifier patterns, and on whether this method-group includes the unqualified methods." 2-33 third paragraph: Change "If no generic function is currently named by the symbol {\it name\/}" to "If {\tt (fboundp {\it name\/})} is {\bf nil}" to match the terminology used on page 2-21. 2-34 first paragraph: Change "primary (in this case, unqualified) methods" to "unqualified methods". 2-34 second paragraph: Same problem with "parameter specifier" as on 1-18. Replace the first two sentences of the paragraph with: The {\it specialized-lambda-list\/} argument is like an ordinary function lambda-list except that required parameter names can be replaced by specialized parameters. A specialized parameter is a list of the form {\tt ({\it variable-name parameter-specializer-name\/})}. [This paragraph duplicates information found elsewhere so perhaps it should be shortened.] 2-35 syntax for specialized-setf-lambda-list: Change "specializer" to "parameter-specializer-name". 2-38 fourth Arguments paragraph: Change "If the first argument is a symbol" to "If the first argument is a symbol that names a class". 2-38 last Arguments paragraph: Change "If the first argument is a symbol" to "If the first argument is a symbol that has a setf generic function associated with it". 2-39 last Arguments paragraph: Change "second" to "errorp". 2-41 second Purpose paragraph: Delete "to the top level". 2-46 second Purpose paragraph first sentence: It was not intended to guarantee that the returned value is a list with certain objects in its car and cdr. Add the phrase "or a form with equivalent effect" at the end of the sentence. 2-47 Values paragraph: same as the preceding. 2-48 second Purpose paragraph: Delete "to the top level". 2-53 last Arguments paragraph: Change "second" to "errorp". Change (twice) "If there is no such method" to "If {\it generic-function} does not know {\it method}". 2-53 Values paragraph: Replace the whole sentence with "The value is {\it generic-function}." to clarify that the value is EQ to the argument. 2-55 last paragraph first sentence: Delete "or a superclass". 2-55 last paragraph fourth sentence: Change "not a subclass of the specified class" to "not the specified class or a subclass of the specified class". 2-55 last paragraph fifth sentence: Change "superclass of the instance" to "superclass of the actual class of the instance" and change "different" to "smaller". 2-56 second paragraph: Change "using the accessor function" to "calling the accessor function", "is used to access" to "is called to access", and "accesses the slots by using" to "accesses the slots by calling". 2-56 Values paragraph: Change "value" to "values" to clarify that the body can return multiple values.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Feb 87 18:09:28 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 18 Feb 87 15:02:32 PST Received: from Cabernet.ms by ArpaGateway.ms ; 18 FEB 87 14:48:48 PST Date: 18 Feb 87 14:48 PST From: Gregor.pa@Xerox.COM Subject: Re: ensure-generic-function In-reply-to: Patrick H Dussud 's message of Wed, 18 Feb 87 15:36:35 CSTTo: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET cc: Gregor.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870218-144848-2907@Xerox> If we don't want the type of the generic function to be changed, we can pass (CLASS-NAMED 'GENERIC-FUNCTION) to the keyword-arg :GENERIC-FUNCTION-CLASS. I am not sure I understand what this means. If this function is meant to be used to normalize the argument to GET-METHOD then it's not okay to create the generic function. We can work around it by checking if the symbol is FBOUNDP before calling it but a situation like this seems to be frequent enough so ensure-generic-function should handle it. It seems to me that this error case is better dealt with outside of ensure-generic-function. I guess that means I don't see this function being used to normalize the first argument to get-method very often. I expect it to be used to normalize the first argument to add-method more often. Basically, there are so many different ways I can imagine wanting to be careful about what to do with the value that is already in the function cell, that I think the best thing to do is make this function have a simple behavior and let people put checking code around calls to it when that is appropriate.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Feb 87 17:46:33 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Feb 87 14:38:19 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73453; Wed 18-Feb-87 17:37:17 EST Date: Wed, 18 Feb 87 17:37 EST From: David A. Moon Subject: Things we should do to prepare for the March meeting To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870218173711.5.MOON@EUPHRATES.SCRC.Symbolics.COM> There are quite a few errors in the document. I believe it is important to distribute an errata sheet at the meeting. I have read the document very carefully and am producing a first draft of an errata sheet, which I will send out in a separate mail message, either today or tomorrow. I assume we can produce a final draft errata sheet, acceptable to everyone, through the mail. The glossary section should be finished, checked for consistency with the rest of the document, and distributed at the meeting. This will make the document easier to understand. Make-instance should be resolved. There are several other issues (perhaps I will put together a list in a day or two) that should be resolved also if we have additional time. I have not yet read the meta-object chapter carefully enough to comment on it. Maybe next week.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Feb 87 17:44:36 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 18 Feb 87 14:36:42 PST Received: from relay2.cs.net by RELAY.CS.NET id aa07115; 18 Feb 87 17:03 EST Received: from ti-csl by csnet-relay.csnet id ad02241; 18 Feb 87 17:02 EST Received: from dsg (juliett.ARPA) by tilde id AA02284; Wed, 18 Feb 87 15:36:06 cst Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Wed, 18 Feb 87 15:37:33 CST Message-Id: <2749671395-289490@Jenner.ti-7> Date: Wed, 18 Feb 87 15:36:35 CST Sender: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET From: Patrick H Dussud To: Gregor.pa@XEROX.COM Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: ensure-generic-function In-Reply-To: Msg of 6-Feb-87 14:14:00 from Gregor.pa@xerox.com Date: 6-Feb-87 14:14:00 From: Gregor.pa@xerox.com Try this for ensure-generic-function: ensure-generic-function &key ( (class-named 'standard-generic-function)) (make-exisiting-function-default-p nil) If symbol is fboundp to a generic-function of the same class as then this function does nothing and returns the generic function object. If symbol is fboundp to a generic-function of some other class, the generic-function class changing protocol is followed, see chapter3. If we don't want the type of the generic function to be changed, we can pass (CLASS-NAMED 'GENERIC-FUNCTION) to the keyword-arg :GENERIC-FUNCTION-CLASS. If symbol not foundp a generic function of generic-function-class is created and put in symbol's function cell. If this function is meant to be used to normalize the argument to GET-METHOD then it's not okay to create the generic function. We can work around it by checking if the symbol is FBOUNDP before calling it but a situation like this seems to be frequent enough so ensure-generic-function should handle it. If symbol is boundp to a function, and make-exisiting-function-default-p is not nil, a generic-function is created, put in the function cell, a default method is added to the generic-function and the symbol's previous function cell value is used as the function for the default method. If symbol is fboundp to a function and make-exisiting-function-default-p is nil an error is signalled. If symbol names a macro or a special form, an error is signalled. OK. Patrick.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Feb 87 19:41:22 EST Received: from Cabernet.ms by ArpaGateway.ms ; 17 FEB 87 14:51:39 PST Date: 17 Feb 87 14:49 PST From: Gregor.pa@Xerox.COM Subject: Re: KCL CALL-NEXT-METHOD bug In-reply-to: Jim Kempf 's message of Tue, 17 Feb 87 14:37:24 pst To: kempf%hplabsc@hplabs.HP.COM cc: gregor.pa@Xerox.COM, commonloops.pa@Xerox.COM Message-ID: <870217-145139-1588@Xerox> I am in the process of compiling a new version of PCL in KCL. This version of PCL has the call-next-method (nee run-super) stuff completely re-worked (for the nth time). I believe that this version will manage to run in all the Common Lisps as I believe it manages to walk the tight line needed to get around all the different bugs in the way macrolet and &environment works. I will send a message when this version works in all the Lisp's I have easy access to (Franz, KCL, Lucid, Symbolics, Vaxlisp). Gregor  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Feb 87 19:41:07 EST Received: from Cabernet.ms by ArpaGateway.ms ; 17 FEB 87 14:41:50 PST Return-Path: Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 17 FEB 87 14:38:58 PST Received: from hplabsc by hplabs.HP.COM ; Tue, 17 Feb 87 14:37:38 pst Received: by hplabsc ; Tue, 17 Feb 87 14:37:24 pst Date: Tue, 17 Feb 87 14:37:24 pst From: Jim Kempf Message-Id: <8702172237.AA00508@hplabsc> To: gregor.pa@Xerox.COM Subject: KCL CALL-NEXT-METHOD bug Cc: commonloops.pa@Xerox.COM KCL currently does not handle &ENVIRONMENT parameters correctly. For example, the following test (defmacro test (&environment e) (format T "~S~%" e) ) (let ( (a 3) ) (flet ( (b (x) a) ) (test) ) ) causes NIL to be printed, even the lexical environment passed to the macro is considerably richer (e.g., both lexical variables and a lexically defined function). This also is true of MACROLET. Anyway, this causes the loading sequence for high.l to break as soon as it tries to expand CALL-NEXT-METHOD, since the expansion for CALL-NEXT-METHOD is heavily dependent on the lexically defined macro defined during method generation. While I think this is a problem with KCL (and *not* PCL), are there any quick, short term workarounds suggested? Jim Kempf kempf@hplabs.hp.com PS: The backtrace during loading of high.l is: DEFINE-BUILT-IN-CLASS NDEFSTRUCT EXPAND-DEFSTRUCT PARSE-DEFSTRUCT-OPTIONS CALL-NEXT-METHOD  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 16 Feb 87 14:07:47 EST Received: from Cabernet.ms by ArpaGateway.ms ; 16 FEB 87 10:12:52 PST Date: 16 Feb 87 10:09 PST From: Gregor.pa@Xerox.COM Subject: Re: OPTIMIZE-GET-SLOT, OPTIMIZE-SETF-OF-GET-SLOT no-ops? In-reply-to: Jim Kempf 's message of Sat, 14 Feb 87 16:13:29 pst To: kempf%hplabsc@hplabs.HP.COM cc: gregor.pa@Xerox.COM, commonloops.pa@Xerox.COM Message-ID: <870216-101252-1954@Xerox> Right now, the optimize-get-slot methods are not called. These will be turned back on in the next release.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 15 Feb 87 18:26:10 EST Received: from Cabernet.ms by ArpaGateway.ms ; 15 FEB 87 14:22:04 PST Return-Path: Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 15 FEB 87 14:20:35 PST Received: from hplabsc by hplabs.HP.COM ; Sat, 14 Feb 87 16:13:54 pst Received: by hplabsc ; Sat, 14 Feb 87 16:13:29 pst Date: Sat, 14 Feb 87 16:13:29 pst From: Jim Kempf Message-Id: <8702150013.AA28497@hplabsc> To: gregor.pa@Xerox.COM Subject: OPTIMIZE-GET-SLOT, OPTIMIZE-SETF-OF-GET-SLOT no-ops? Cc: commonloops.pa@Xerox.COM In the 1/26/87 version of PCL, these methods no longer seem no longer seem to be called. Have they now become no-ops? Jim Kempf kempf@hplabs.hp.com  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 15 Feb 87 18:25:59 EST Received: from Cabernet.ms by ArpaGateway.ms ; 15 FEB 87 14:13:09 PST Return-Path: Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 15 FEB 87 14:11:07 PST Received: from hplabsc by hplabs.HP.COM ; Sun, 15 Feb 87 12:14:38 pst Received: by hplabsc ; Sun, 15 Feb 87 12:14:28 pst Date: Sun, 15 Feb 87 12:14:28 pst From: Jim Kempf Message-Id: <8702152014.AA05946@hplabsc> To: gregor.pa@Xerox.COM Subject: Naming Method Functions Cc: commonloops.pa@Xerox.COM Since the naming of LAMBDA's is likely to be implementation dependent, I wonder if the code in EXPAND-DEFMETH-INTERNAL in class-prot.l could be modified to take an implementation dependent DECLARE specification. I've modified mine to look like this: (defvar *method-name-declaration* #-HP 'method-function-name #+HP 'extn:name ) (defmeth expand-defmeth-internal ..... internals, down to where a LAMBDA is generated ... #'(lambda ,merged-args ,@documentation (declare (,*method-name-declaration* ,method-name) ) ..... ) This would allow each CL implementation to add their way of naming methods. Jim Kempf kempf@hplabs.hp.com  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 13 Feb 87 23:11:45 EST Received: from Cabernet.ms by ArpaGateway.ms ; 13 FEB 87 16:50:36 PST Return-Path: Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 13 FEB 87 16:49:09 PST Received: from hplabsc by hplabs.HP.COM ; Fri, 13 Feb 87 16:47:31 pst Received: by hplabsc ; Fri, 13 Feb 87 16:46:59 pst Date: Fri, 13 Feb 87 16:46:59 pst From: Jim Kempf Message-Id: <8702140046.AA20251@hplabsc> To: commonloops.PA@Xerox.COM Subject: CALL-NEXT-METHOD not exported In the latest version of PCL, CALL-NEXT-METHOD is not exported from the PCL package.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Feb 87 21:44:17 EST Date: 12 Feb 87 1838 PST From: Linda DeMichiel Subject: Documents To: common-lisp-object-system@SAIL.STANFORD.EDU The draft of the spec that is being sent out to the X3J13 committee is now available on Sail. New files on [CLS,LSP] are concep.tex, concep.dvi, functi.tex, functi.dvi. (Symfun.dvi and symcon.dvi have stripped-down fonts to accommodate the Symbolics printers.) Macros.tex has also been updated--anyone who prefers to TEX files locally will need to ftp the new copy of that also. lgd  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Feb 87 21:21:21 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Feb 87 18:15:58 PST Received: from relay2.cs.net by RELAY.CS.NET id af14773; 12 Feb 87 19:33 EST Received: from ti-csl by csnet-relay.csnet id dg20055; 12 Feb 87 19:30 EST Received: from dsg (juliett.ARPA) by tilde id AA00230; Thu, 12 Feb 87 12:13:49 cst Received: FROM Jenner BY dsg Via CHAOS-NET with CHAOS-MAIL; 12-Feb-87 07:22:36 Message-Id: <2749123430-91366@Jenner> Sender: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET Date: 12-Feb-87 07:23:50 From: Patrick H Dussud To: Gregor.pa@XEROX.COM Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: ensure-generic-function In-Reply-To: In-Reply-To: Msg of 6-Feb-87 14:14:00 from Gregor.pa@xerox.comMsg of 6-Feb-87 14 Date: 6-Feb-87 14:14:00 From: Gregor.pa@xerox.com Try this for ensure-generic-function: ensure-generic-function &key ( (class-named 'standard-generic-function)) (make-exisiting-function-default-p nil) If symbol is fboundp to a generic-function of the same class as then this function does nothing and returns the generic function object. If symbol is fboundp to a generic-function of some other class, the generic-function class changing protocol is followed, see chapter3. If we don't want the type of the generic function to be changed, we can pass (CLASS-NAMED 'GENERIC-FUNCTION) to the keyword-arg :GENERIC-FUNCTION-CLASS. If symbol not foundp a generic function of generic-function-class is created and put in symbol's function cell. If this function is meant to be used to normalize the argument to GET-METHOD then it's not okay to create the generic function. We can work around it by checking if the symbol is FBOUNDP before calling it but a situation like this seems to be frequent enough so ensure-generic-function should handle it. If symbol is boundp to a function, and make-exisiting-function-default-p is not nil, a generic-function is created, put in the function cell, a default method is added to the generic-function and the symbol's previous function cell value is used as the function for the default method. If symbol is fboundp to a function and make-exisiting-function-default-p is nil an error is signalled. If symbol names a macro or a special form, an error is signalled. OK.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 12 Feb 87 17:25:58 EST Received: from Cabernet.ms by ArpaGateway.ms ; 12 FEB 87 10:31:11 PST Date: 12 Feb 87 10:29 PST From: Gregor.pa@Xerox.COM Subject: Re: :generate-accessors and print-instance In-reply-to: David McKelvie 's message of Thu, 12 Feb 87 12:53:26 -0100 To: david%ecrcvax.uucp%germany.csnet@RELAY.CS.NET cc: CommonLoops.pa@Xerox.COM Message-ID: <870212-103111-1734@Xerox> I'm using PCL on a Xerox 1108 Koto. When I specify a class with :generate-accessors = nil as in (ndefstruct (thing (:class class)(:generate-accessors nil)) a b) with the intent that I'm never going to access the slots of instances of this class using methods like (thing-a), then when I try to create an instance of this class, it fails in print-instance when it tries to print out the result with 'unspecified function NIL'. There is a bug in some older versions of PCL which causes this. The new version of PCL does not have this problem, you should get the new version. In the meantime, you could get around this problem by defining accessors for your class, or by patching the definition of all-slots-using-class to use get-slot to get the value of the slots rather than funcalling the accessor.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 12 Feb 87 12:00:23 EST Received: from Cabernet.ms by ArpaGateway.ms ; 12 FEB 87 07:18:46 PST Return-Path: Received: from RELAY.CS.NET by Xerox.COM ; 12 FEB 87 07:17:17 PST Received: from relay2.cs.net by RELAY.CS.NET id ab09881; 12 Feb 87 9:43 EST Received: from germany by csnet-relay.csnet id ag16863; 12 Feb 87 9:38 EST Received: from ecrcvax by uka.uucp id aa03004; 12 Feb 87 13:18 MET Received: by ecrcvax.ecrc (4.12/4.7) id AA23930; Thu, 12 Feb 87 12:53:26 -0100 Date: Thu, 12 Feb 87 12:53:26 -0100 From: David McKelvie Message-Id: <8702121153.AA23930@ecrcvax.ecrc> To: Germany!CommonLoops.pa%xerox.arpa%germany.csnet@RELAY.CS.NET Subject: :generate-accessors and print-instance Cc: david%ecrcvax.uucp%germany.csnet@RELAY.CS.NET I'm using PCL on a Xerox 1108 Koto. When I specify a class with :generate-accessors = nil as in (ndefstruct (thing (:class class)(:generate-accessors nil)) a b) with the intent that I'm never going to access the slots of instances of this class using methods like (thing-a), then when I try to create an instance of this class, it fails in print-instance when it tries to print out the result with 'unspecified function NIL'. Clearly, I'm doing something wrong. Does anyone know how to suppress the creation of the accessor methods properly?  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 11 Feb 87 12:40:25 EST Received: from Salvador.ms by ArpaGateway.ms ; 11 FEB 87 08:30:21 PST Return-Path: Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 11 FEB 87 08:28:04 PST Received: from hplabsc by hplabs.HP.COM ; Wed, 11 Feb 87 08:27:26 pst Received: by hplabsc ; Wed, 11 Feb 87 08:27:09 pst Date: Wed, 11 Feb 87 08:27:09 pst From: Roy D'Souza Message-Id: <8702111627.AA14392@hplabsc> To: commonloops.PA@Xerox.COM Subject: KCL Cc: kempf%hplabs@hplabs.HP.COM Is anybody out there running PCL on Kyoto Common Lisp ? Please e-mail dsouza@hplabs.HP.COM Roy D'Souza  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Feb 87 12:01:04 EST Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Feb 87 08:56:53 PST Received: from hplabsc by hplabs.HP.COM ; Wed, 11 Feb 87 07:56:11 pst Received: by hplabsc ; Wed, 11 Feb 87 07:55:49 pst Date: Wed, 11 Feb 87 07:55:49 pst From: Jim Kempf Message-Id: <8702111555.AA13823@hplabsc> To: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Meta-object protocol I have read through the meta-object protocol posting and have some comments, but would prefer to wait until the concepts and functions chapters (which I believe were called Chapters 1 & 2 in Danny's note?) are ready for distribution, so I can cross check. Some of my comments are the result of 6 months of working with the PCL meta-object protocol and trying to port the result to Kyoto Common Lisp, in the event the committee is interested in experiences with the existing PCL meta-object implementation. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Feb 87 01:48:52 EST Date: 10 Feb 87 2229 PST From: Dick Gabriel Subject: Documents To: common-lisp-object-system@SAIL.STANFORD.EDU The documents are just about ready to go onto [cls,lsp]. They will be mailed out friday afternoon, I believe. I will be out of town until next Wednesday. Until I return, the protection on [cls,lsp] will prevent any accidental overwriting of the files. This way people who wish to FTP them for early perusal will know they are getting the very thing that is being mailed. Once they have been digested by people we will decide what to do. I think it's reasonable to let the documents sit for a while for people to gather their thoughts about what's left. First, Danny and Gregor will be sending out a preliminary version of a draft for chapter 3. It will have a separate document number so that people will be able to refer to the reasonably well-thought-out chapter 1-2 draft without including the hot-out-of-the-oven chapter 3. We should think about what to do with chapter 3. Second, MAKE-INSTANCE was left unspecified, and the things it supercedes (MAKE-METHOD etc) were left in chapters 1 and 2. Third, Danny mentioned some discomfort with respect to inheritance of slot descriptions as described in chapter 1. Again, I tried to make it precise and unambiguous so that we can all see what it is we are buying into. Fourth, I think we should seriously think about the overall complexity of the specification and what it specifies. I think the complexity is a little high for something on which to standardize. The descriptions of the aspects of it are very complex in places, mostly because there is no vocabulary or a priori mental model of the concepts. LGD will be around while I'm away, but she (and I) are pretty burned out after a solid week of 8 - 10 hours a day on this document (!). Enjoy. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 18:42:29 EST Date: 10 Feb 87 1438 PST From: Dick Gabriel Subject: Inheritance of Slots To: common-lisp-object-system@SAIL.STANFORD.EDU My ``venture'' at re-describing was an attempt to do exactly one thing: To present the rules completely and unambiguously. LGD and I had a very hard time understanding them as presented by Moon, mostly because of English problems, and also because we couldn't believe that the simple prose explained something as complex as it does. Once we are all in agreement that these rules do what we want, the tremendous effort it will take to discover the best writeup can begin. As you can all see, the exercise in precision has alerted Danny to aspects of the rules that he apparently didn't realize during the earlier discussions. On the topic of accessor and readers, Moon's writeup left no ambiguity, however. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 16:40:38 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 10 Feb 87 13:30:37 PST Received: from Cabernet.ms by ArpaGateway.ms ; 10 FEB 87 13:28:59 PST Date: 10 Feb 87 13:27 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Inheritance of Slots In-reply-to: David A. Moon 's message of Tue, 10 Feb 87 15:10 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870210-132859-7240@Xerox> I read the current document last night and was appalled at the complexity of the rules that were used to explain the inheritance of the characterisics of slot-descriptions. Is this before or after Dick's venture at improving the way it's described? The hardcopy I have (from Jan 31) doesn't look extremely complicated, certainly less complicated than earlier attempts. The English does need to be cleaned up a bit to make it crystal clear, though. Yes it is different in style completely. It makes a mathematical statement of the inheritance rules. It is three times longer. I don't think it changes the intent. I think it's fundamentally complicated, because :initform, :allocation, and :type have been specified by the group to work three different ways, and changing any one of them to work the same as another breaks something. My opinion is that the only way to simplify it would be to get rid of some features. I would be happy to get rid of :type at this point, and allow :type to be added by the metaobject protocol using compute-effective-slot-description. I wouldn't mind it if one always had to (re)specify an initform if one changed the allocation, and if allocation always defaulted to :instance in any specification. This would mean that you couldn't add an accessor to :dynamic or :class slots without repeating the :allocation. For :class slots that would of course mean a slot in this class, as opposed to having another way to access the one up above. To do the latter, one could simply use defmethod. I also realized that accessors and readers MUST be inherited. A new method need not be built for every class if the implementation guarantees that the method inherited still works. But whenever there is a change of the :allocation characteristic, every accessor and reader in the inheritance chain must have a new method created for it. I don't believe this is true. Could you specify some reasons why new methods would have to be created? And do those reasons mean that the following will not work? (defclass c1 () (s)) (defclass c2 (c1) ((s :allocation :class :initform 1))) (defmethod foo ((self c1)) (with-slots (self) (print s))) (foo (make-instance 'c2)) How does this relate to the remark in the inheritance section "Methods that access slots know only the name of the slot and the type constraint ..."? I am assuming (perhaps wrongly) that the methods to access a slot would optimize the slot access and that access to an instance slot would be optimized very differently than access to a class slot or dynamic slot. If this is true, then all methods that have optimized slot access will have to be redefined. If the underlying implementation can both optimize and handle all three types of access, then I am wrong.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 16:40:04 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 10 Feb 87 13:30:29 PST Received: from Cabernet.ms by ArpaGateway.ms ; 10 FEB 87 13:03:13 PST Date: 10 Feb 87 13:02 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Meta-object protocol To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870210-130313-7181@Xerox> In a meeting with RPG yesterday, it was agreed that the metaobject protocol chapter would go out in the same package as the first two chapters, but with a separate document number, and the following disclaimer: This document is a preliminary draft of the protocol. It was not discussed extensively before being distributed, nor was it rationalized with Chapters 1 and 2. It is being provided as a basis for the presentation to be made at the X3J13 meeting in March 1987 so that members of the committee can have a feeling for the entire proposed object system. Most of the description is applicable to PCL, the model portable implementation, and as such has been used by some people in the community. The presentation in March will take into account changes suggested by the Common Lisp Objects subcommittee between this distribution and that meeting. I am happy to put either of the following on the front: 1) Minimal responsibility This document was written by Daniel G. Bobrow and Gregor Kiczales. Contributers include everybody else 2) Maximal credit This documetn was written by Daniel G. Bobrow, Linda G. DeMichiel, Richard P. Gabriel, Sonya E. Keene, Gregor Kiczales, and David A. Moon Contributers include the rest. Or any compromise in between. Since you have only had a brief chance to look at the document, please let me know which credit line you prefer. Since by the time March comes, I hope we will have had a chance to work on this document, and make 2 true, feel free to choose that alternative. Please respond to this message so I know your feelings. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 15:17:57 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Feb 87 12:11:49 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 67300; Tue 10-Feb-87 15:10:43 EST Date: Tue, 10 Feb 87 15:10 EST From: David A. Moon Subject: Re: Inheritance of Slots To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870210-104034-6948@Xerox> Message-ID: <870210151039.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 10 Feb 87 10:38 PST From: Danny Bobrow I read the current document last night and was appalled at the complexity of the rules that were used to explain the inheritance of the characterisics of slot-descriptions. Is this before or after Dick's venture at improving the way it's described? The hardcopy I have (from Jan 31) doesn't look extremely complicated, certainly less complicated than earlier attempts. The English does need to be cleaned up a bit to make it crystal clear, though. I think it's fundamentally complicated, because :initform, :allocation, and :type have been specified by the group to work three different ways, and changing any one of them to work the same as another breaks something. My opinion is that the only way to simplify it would be to get rid of some features. I also realized that accessors and readers MUST be inherited. A new method need not be built for every class if the implementation guarantees that the method inherited still works. But whenever there is a change of the :allocation characteristic, every accessor and reader in the inheritance chain must have a new method created for it. I don't believe this is true. Could you specify some reasons why new methods would have to be created? And do those reasons mean that the following will not work? (defclass c1 () (s)) (defclass c2 (c1) ((s :allocation :class :initform 1))) (defmethod foo ((self c1)) (with-slots (self) (print s))) (foo (make-instance 'c2)) How does this relate to the remark in the inheritance section "Methods that access slots know only the name of the slot and the type constraint ..."?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 14:12:33 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 10 Feb 87 11:04:19 PST Received: from Cabernet.ms by ArpaGateway.ms ; 10 FEB 87 10:40:34 PST Date: 10 Feb 87 10:38 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Inheritance of Slots In-reply-to: David A. Moon 's message of Tue, 10 Feb 87 12:32 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870210-104034-6948@Xerox> I read the current document last night and was appalled at the complexity of the rules that were used to explain the inheritance of the characterisics of slot-descriptions. I also realized that accessors and readers MUST be inherited. A new method need not be built for every class if the implementation guarantees that the method inherited still works. But whenever there is a change of the :allocation characteristic, every accessor and reader in the inheritance chain must have a new method created for it. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 12:53:30 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Feb 87 09:46:39 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 67071; Tue 10-Feb-87 12:45:10 EST Date: Tue, 10 Feb 87 12:45 EST From: David A. Moon Subject: Semantic difficulties To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 7 Feb 87 01:18 EST from Dick Gabriel Message-ID: <870210124511.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 06 Feb 87 2218 PST From: Dick Gabriel Possibly defining CALL-NEXT-METHOD to have dynamic extent within a generic function invocation along with Moon's clarification of 100 Iterations of Call-Next-Methoditude would do the trick? I don't think so. I don't see why it should have dynamic extent rather than indefinite extent like all other closures. Furthermore, changing the class in the middle of a method can make its valid extent end even before dynamic extent ends.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 12:51:27 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Feb 87 09:41:41 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 67062; Tue 10-Feb-87 12:40:11 EST Date: Tue, 10 Feb 87 12:40 EST From: David A. Moon Subject: Document To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 9 Feb 87 23:44 EST from Dick Gabriel , The message of 10 Feb 87 05:45 EST from Dick Gabriel Message-ID: <870210124014.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 09 Feb 87 2044 PST From: Dick Gabriel Sounds like Moon made a mistake in accepting my deadlines, which carefully outlined the steps leading up to the mailing. He should have requested that work stop a week earlier. All I want is an open process. I hadn't expected from your deadlines message that the final revision would be done in secret. I'm willing to blame this on the poor quality of Arpanet communications. Your second message listing what you've done is helpful; thanks. The title page now lists authors separately from contributors. Because time is short, I'll remove Moon's and Sonya's names from the authors list, but leave them as contributors. Later, when they approve or whatever, and the document is in final form we can put them back. I don't think this really helps, so why don't you not bother to change it. Date: 10 Feb 87 0245 PST From: Dick Gabriel Here is what Linda and I have been doing to the specification.... 5. Incorporating the latest, most final comments of Gregor and Moon. I'm not sure we've done this completely well, but we did all the comments through Feb 6. I'd like to see what happened here, since I thought some of the issues weren't resolved yet. Or maybe you only incorporated the ones that have been resolved.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 12:42:56 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Feb 87 09:34:29 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 67053; Tue 10-Feb-87 12:32:58 EST Date: Tue, 10 Feb 87 12:32 EST From: David A. Moon Subject: Inheritance of Slots To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 7 Feb 87 02:01 EST from Dick Gabriel Message-ID: <870210123253.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 06 Feb 87 2301 PST From: Dick Gabriel Moon writes: ``No, :allocation doesn't inherit.'' Moon wrote in CONCEPTS: ``{\bf :allocation} comes from the most specific slot description in the class precedence list---if it does not explicitly specify {\bf :allocation}, the default is {\bf :allocation} {\bf :instance}.'' What is the ``most specific slot description''? Is it the one closest to the front? Is there some intrinsic specificity of a slot description? I thought this was clear from context, in the three paragraphs before the one you quoted. Re-reading them, it would be clearer to some readers if it said explicitly "The slot descriptions are ordered according to the order of classes in the class precedence list." instead of only implying that. What is ``it''? Is ``it'' the most specific slot description? Is ``it'' the class precedence list? Is this not some sort of inheritance? "It" is the most specific slot description; slot descriptions are the only things that specify {\bf :allocation}. This would be better written as two sentences with no pronouns. Dick, the problem here is that in the piece of mail you quoted I used the word "inherit" in a different sense from the way it's used in the document. I think the 31 Jan version of the document is consistent in its use of inherit, and has it that :allocation does inherit. When I said :allocation does not inherit, I meant that only the most specific slot description for a given slot affects :allocation. When the document says that :allocation does inherit, it means that the most specific slot description controls :allocation, even if that slot description is attached to a superclass of the class whose slots are being discussed. So I don't think we are disagreeing about anything here. Moon wrote in CONCEPTS: ``{\bf :initform} comes from the most specific slot description that explicitly specifies {\bf :initform}. '' So what does this do: (defclass c1 () ((s :allocation :class :initform 99))) (defclass c2 (c1)((s :initform 22))) Is S an :instance in instances of C2 ? Of course. :allocation comes from the most specific slot description. Is it a :class in C2? No, since it's :instance. Is it shared with the one in C1? Of course not. Do we reinitialize S? I don't know what this means. My guess is you're referring to the weird thing that would happen if we had different inheritance rules for :allocation, so that C2's class definition referred to a :class slot of C1. A weirdo case you were perhaps thinking of is (defclass c1 () ((s :allocation :class :initform 99))) (defclass c2 (c1)((s))) Here the instance slot named S in a C2 is initialized to 99. I propose that this not a problem. ``{\bf :type} is constrained to satisfy all of the type constraints given by classes in the class precedence list.'' What does ``constrained'' mean? Is there enforcement? Is it the same way that slots in Defstructs have :type declarations? If so, this doesn't say it. Steele's working is much better. I don't know what it means. We just put it in the document based on what was said in the mail. Here is all the mail I was able to find on the subject. Date: 17 Nov 86 14:33 PST Sender: Bobrow.pa@Xerox.COM :type type-expression should be allowed as it is in DEFSTRUCT. No requirements on its use should be in the standard. Date: Fri, 21 Nov 86 23:08 EST From: David A. Moon I don't see what use this could be, but I don't see how it could hurt, other than by making the language larger. Let's go ahead and put it in. Date: 22 Nov 86 1048 PST From: Dick Gabriel Sometimes a compiler will be able to optimize things a little given some information like this. It might not be that the storage or its direct handling will improve or change, but, perhaps, some other operation can be slightly improved - such a being able to emit the machine addition instruction with only overflow checking - when the slot, directly, is involved in an arithmetic expression. Date: 5 Jan 87 11:07 PST Sender: Bobrow.pa@Xerox.COM :type is inherited, but we do not specify what the system does with it. An open question is whether inheritance here should be a union operation, or if the more specific type must always be a subtype of the inherited one. If "Steele's wording" refers to p.310 of CLtL, that's probably saying the same thing, although it's a little vague too. The analogy to type declaration of a variable is valuable and should be used in our document. Well, maybe Moon's right, we should leave it as it is so that the readers of the document can have fun guessing what this mess means. LGD and I sure had fun for a day doing exactly this. All we were doing with our suggestions was to propose something that someone could understand along with a description of it that was understandable. The point of a specification is to spell out the details in such a way that they are precise, unambiguous, and clearly stated. This specification does not do that. I will say only that I am glad that the process of review is resulting in an improved document.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Feb 87 05:50:47 EST Date: 10 Feb 87 0245 PST From: Dick Gabriel Subject: State of the world To: common-lisp-object-system@SAIL.STANFORD.EDU Here is what Linda and I have been doing to the specification. 1. Settling on terminology. This mostly involves selecting one out of several different terminologies inserted into the spec by different people, where the terms refer to the same thing. 2. Making the organization right. In several places material that belongs in FUNCTIONS ended up in CONCEPTS and vice versa. Sometimes material was repeated. These were rationalized and pointers back and forth were placed where appropriate. 3. Clarifying terminology. This mostly happened in places where people had inserted good terminology without definition or comment on its use. A good example is ``primary method,'' which is used intuitively in some places and precisely in others. We put in an explanation of the use of the term in CONCEPTS. The explanation says that a primary method is used to refer to a method with an intended role depending on the method combination type. In standard method combination it means a certain thing (precisely) as it does when you use the short form (though it means something slightly different). This way the reader is not jolted upon reading in standard method combination that a primary method is precisely an unqualified method while under the short form he'll read that some qualified methods are primary. (And without the explanation, a reader could spend 15 minutes going back and forth among the various apparent definitions of it). 4. Rationalizing where objects versus names of objects are to be used, particularly in parameter specializers where one thing is meant in specialized lambda-lists and another in parameter specializers of a method object (one needs names and the other needs objects). 5. Incorporating the latest, most final comments of Gregor and Moon. I'm not sure we've done this completely well, but we did all the comments through Feb 6. 6. Re-writing sections that were very hard to understand. The worst part was redefining classes and the change-class protocol, which Moon put in during the last round. After a number of sessions on the phone with Danny and Gregor and after a face-to-face with them, I think we finally have it down reasonably. This re-write impacted number 4 above. I think that Moon's change-class protocol, though a little obscure, is now understandable, which means it has some hope of gaining approval in March. 7. Correcting grammar. There were many grammatical and punctuation mistakes made here and there. Some seem to be typos and oversights. Correcting these takes sharp, fresh eyes. 8. Formatting was regularized and BNF's were scrutinized. 9. Typesetting bugs were and aesthetics improved. We are still 1/2 day away from being done with this cleanup. The magnitude of work required to achieve 1 through 7 was much greater than we thought, which is why the documents are not now on [cls,lsp]. I'm afraid that people are not going to get much of a chance, if any, to read the document before it goes out. But the document can be superceded at the March meeting, and we didn't intentionally change any content, even in the parts we don't like. I think the document is complex enough that the folks who will try to read it for March deserve as much time as possible to grind through it. Mostly because redundancies were removed, the document will be approximately 82 pages long: 26 pages for CONCEPTS and 56 for FUNCTIONS. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Feb 87 23:47:33 EST Date: 09 Feb 87 2044 PST From: Dick Gabriel Subject: Document To: common-lisp-object-system@SAIL.STANFORD.EDU Sounds like Moon made a mistake in accepting my deadlines, which carefully outlined the steps leading up to the mailing. He should have requested that work stop a week earlier. As mentioned in my previous messge on the topic, the documents are now in the maw of my grammarians who are making sure they aren't completely embarrassing. I expect the documents to pop out by friday, just in time to be mailed. Nothing regarding semantics has been changed except for those things which were so poorly written that the most reasonable re-write changed them. Inheritance of slots is as it was, though I rewrote it to be a little less confusing. As expected, the document was badly inconsistent throughout, because everyone who had their hands on it decided to introduce their own personal jargon with little thought to how it went together. The title page now lists authors separately from contributors. Because time is short, I'll remove Moon's and Sonya's names from the authors list, but leave them as contributors. Later, when they approve or whatever, and the document is in final form we can put them back. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Feb 87 22:03:19 EST Received: from AI.AI.MIT.EDU by SAIL.STANFORD.EDU with TCP; 9 Feb 87 18:41:12 PST Date: Mon, 9 Feb 87 21:41:30 EST From: "David A. Moon" Subject: X3J13 version of document To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <151649.870209.MOON@AI.AI.MIT.EDU> The concep.tex and functi.tex files on SU-AI have not changed at all since the versions I put there on 31 Jan. Since it is now after midnight on Feb 8, I assume this means that the versions that will be mailed out are identically those. If what's being mailed is stored someplace else than [cls,lsp] on su-ai, please let me know in time to read them before they are printed up. I do not want something being mailed out with my name on it that I have not seen (not that I expect any surprises). I'll try to phone Lucid Tuesday afternoon to check on the status of the files. My comments on recent discussion about inheritance and so forth will be mailed out when it stops snowing and my connection to the Arpanet comes back..  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Feb 87 13:51:56 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Feb 87 10:46:11 PST Received: from Cabernet.ms by ArpaGateway.ms ; 09 FEB 87 10:27:50 PST Date: 9 Feb 87 10:24 PST From: Gregor.pa@Xerox.COM Subject: Re: Inheritance of Slots In-reply-to: Dick Gabriel 's message of 06 Feb 87 23:01 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870209-102750-5712@Xerox> So what does this do: (defclass c1 () ((s :allocation :class :initform 99))) (defclass c2 (c1)((s :initform 22))) Is S an :instance in instances of C2 ? Is it a :class in C2? Is it shared with the one in C1? Do we reinitialize S? I can't understand why you found this so confusing. Before you started hacking what Moon wrote, I sent out a message which included a different explanation of these rules and exactly included this example. I find the inheritance mechanism Moon was describing quite simple (I agree the description could be improved) all you have to do is get the slot descriptions in class precedence list order, default them according to the appropriate rule for each option and then pick the most specific *supplied* value for each option. The only thing even remotely complex is that one of the options (:initform) defaults to *unsupplied*. I also don't like the new rules you have proposed.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Feb 87 12:23:51 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Feb 87 08:02:22 PST Received: from Cabernet.ms by ArpaGateway.ms ; 09 FEB 87 08:02:09 PST Date: 9 Feb 87 08:01 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Stan's Comments In-reply-to: Dick Gabriel 's message of 05 Feb 87 13:12 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870209-080209-5490@Xerox> rules for well-defined class structures would prevent situations like the one he mentions, but they don't. I suppose I had hoped for an upper semi-lattice, but it isn't in the cards. DAG it will probably be. Since this is so, it means that we do not need a class named NIL to close the bottom. This allows (CLASS-NAME class) ->NIL to mean no name. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Feb 87 12:22:02 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Feb 87 08:14:46 PST Received: from Cabernet.ms by ArpaGateway.ms ; 09 FEB 87 08:06:09 PST Date: 9 Feb 87 08:06 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Discussion at X3J13 In-reply-to: David A. Moon 's message of Thu, 5 Feb 87 00:43 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870209-080609-5502@Xerox> We should talk about how we're going to organize the discussion at X3J13. I believe we have a whole day allocated to us. One way of organizing it that I had in mind was for me to present the programmer interface as it currently stands, for Danny to present the meta-object protocol as it currently stands. This is OK with me. I do want the best draft we can have of what I sent out on Friday to go out with the other two chapters. I recognize that this has not been argued about and hence may change in a significant ways before it is adopted, but I think people should have some chance to see what is being referred to before I talk about it. As I said in my earlier message, most of it is the extended programmers tools for working with the the object system. danny  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 8 Feb 87 18:13:57 EST Received: from Salvador.ms by ArpaGateway.ms ; 08 FEB 87 14:28:46 PST Return-Path: Received: from cogsci.berkeley.edu ([128.32.130.5]) by Xerox.COM ; 08 FEB 87 14:26:33 PST Received: by cogsci.berkeley.edu (5.57/1.20) id AA05339; Sun, 8 Feb 87 14:27:15 PST Date: Sun, 8 Feb 87 14:27:15 PST From: ehl%cogsci.Berkeley.EDU@berkeley.edu (Edward H. Lay) Message-Id: <8702082227.AA05339@cogsci.berkeley.edu> To: commonloops.pa@Xerox.COM Subject: with* in the latest release walking macrolets inside of with* seems to be broken in the latest release running in lucid 1.2. An example follows: ;; COLLECT is straight from the book, and is documented there. (DEFMACRO WITH-COLLECTION (&BODY BODY) (LET ((VAR (GENSYM))) `(LET ((,VAR NIL)) (MACROLET ((COLLECT (ARGUMENT) `(PUSH ,ARGUMENT ,',VAR))) . ,BODY) (NREVERSE ,VAR)))) ;; and to catch unbounded COLLECTs (DEFMACRO COLLECT (ARGUMENT) (WARN "~S Used Outside of ~S" 'COLLECT 'WITH-COLLECTION) `(ERROR "~S Used Outside of ~S" `(COLLECT ,,ARGUMENT) 'WITH-COLLECTION)) (defclass foo () ((a 1))) ;; this works (defmeth test1 ((foo foo) list) (with-collection (dolist (e list) (collect (+ e (get-slot foo 'a)))))) ;; this doesn't (defmeth test2 ((foo foo) list) (with* (foo) (dolist (e list) (collect (+ e a))))) edward lay  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Feb 87 02:06:36 EST Date: 06 Feb 87 2301 PST From: Dick Gabriel Subject: Inheritance of Slots To: common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: ``No, :allocation doesn't inherit.'' Moon wrote in CONCEPTS: ``{\bf :allocation} comes from the most specific slot description in the class precedence list---if it does not explicitly specify {\bf :allocation}, the default is {\bf :allocation} {\bf :instance}.'' What is the ``most specific slot description''? Is it the one closest to the front? Is there some intrinsic specificity of a slot description? What is ``it''? Is ``it'' the most specific slot description? Is ``it'' the class precedence list? Is this not some sort of inheritance? Moon wrote in CONCEPTS: ``{\bf :initform} comes from the most specific slot description that explicitly specifies {\bf :initform}. '' So what does this do: (defclass c1 () ((s :allocation :class :initform 99))) (defclass c2 (c1)((s :initform 22))) Is S an :instance in instances of C2 ? Is it a :class in C2? Is it shared with the one in C1? Do we reinitialize S? ``{\bf :type} is constrained to satisfy all of the type constraints given by classes in the class precedence list.'' What does ``constrained'' mean? Is there enforcement? Is it the same way that slots in Defstructs have :type declarations? If so, this doesn't say it. Steele's working is much better. Well, maybe Moon's right, we should leave it as it is so that the readers of the document can have fun guessing what this mess means. LGD and I sure had fun for a day doing exactly this. All we were doing with our suggestions was to propose something that someone could understand along with a description of it that was understandable. The point of a specification is to spell out the details in such a way that they are precise, unambiguous, and clearly stated. This specification does not do that. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Feb 87 01:28:08 EST Date: 06 Feb 87 2218 PST From: Dick Gabriel Subject: Semantic difficulties To: common-lisp-object-system@SAIL.STANFORD.EDU Better read that prose quickly, because it is among the 2 or 3 sections regarded as too pathetic to make it into the final version in a shape very much resembling what's there now. It is replaced with a more terse comment. Possibly defining CALL-NEXT-METHOD to have dynamic extent within a generic function invocation along with Moon's clarification of 100 Iterations of Call-Next-Methoditude would do the trick? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Feb 87 00:44:14 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Feb 87 21:36:43 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 64749; Sat 7-Feb-87 00:34:58 EST Date: Sat, 7 Feb 87 00:35 EST From: David A. Moon Subject: Inheritance of Slots To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 5 Feb 87 02:49 EST from Dick Gabriel Message-ID: <870207003502.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 04 Feb 87 2349 PST From: Dick Gabriel Sorry about the 2-day delay in response, I've been real busy with other things this week. Moon writes: ``Third, when compiling a method you cannot assume anything about the types of the slots, since a subclass could throw away your :type slot-option.'' I guess I didn't say it clearly enough. The effective type of a slot is the AND (as in (AND T1 T2 ... Tn)) of the slots in the CPL. I thought this was exactly what this meant: ``{\bf :type} is constrained to satisfy all of the type constraints given by classes in the class precedence list. That is, if T1, T2 and so on are the type constraints given by the class and all of its superclasses, the value of the slot must satisfy {\bf (typep value '(and T1 T2 T3...)}.'' Didn't you (Moon) and Sonya write this? Yes. I was commenting on your apparent proposal to change that rule so that the effective type of a slot depended on -only- the most specific slot-description, when you said "If C's defclass has a slot description, it totally shadows any other in CPL." If you weren't really proposing to make that change, then there is no problem. Moon comments: ``No net gain.'' Before there were these categories of slot inheritance: 1. accessors and readers don't specially inherit 2. :allocation inherits some funny way No, :allocation doesn't inherit. 3. :initform inherits some other funny way No, the most specific :initform is used. 4. :type inherits by doing AND Now we have: 1. accessors and readers as above 2. :allocation, :initform, and :type are totally inherited or totally shadowed with simple defaults. 3. :type constrained to be AND. The only change is one cannot specify any slot options without clobbering the :initform. Nothing about :allocation or :type has changed. I really think it would be a bad idea to change :initform inheritance. Please leave it the way it is. ...I thought my proposal said that if you mention slot options only (:accessor, for example) normal inheritance happens. I didn't get that from reading your proposal. If I had I would have barfed, because that's a really strange rule. In the slot description list of defclass, (foo :allocation :instance) would mean something different from (foo), because one prevents inheritance of :initform and the other doesn't. I would have real difficulty agreeing that that is simple! The simplified rule is for slot descriptions only (:allocation, :type, :initform). If you had :accessor only, the slot description stuff is totally inherited - ``the right thing.'' If you mention a slot description, all slot descriptions are shadowed. To be specific, the following statement is true: ...I think that the briarpatch of inheritance rules surrounding :allocation, :type, and :initform are too complex. I don't disagree, but I think your suggestion doesn't make it simpler. At the risk of repeating myself, flushing :allocation and :type would make it a lot simpler. So would forbidding two classes in a given class precedence list from describing the same slot. Short of that, I don't see any way to make it simpler.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Feb 87 00:35:19 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Feb 87 21:23:43 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 64740; Sat 7-Feb-87 00:22:23 EST Date: Sat, 7 Feb 87 00:22 EST From: David A. Moon Subject: Gregor's comments on 2/2/87 draft of functi To: Common-Lisp-Object-System@Sail.Stanford.edu In-Reply-To: <870204-141352-1087@Xerox> Message-ID: <870207002216.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 4 Feb 87 14:13 PST From: Gregor.pa@Xerox.COM Here are a bunch of comments on the 2/2 draft of functi. The last draft I've seen is 1/31; what changed? -- add-method (and remove-method) still say that it accepts symbols or a list of (SETF ) as argument. I proposed and Moon agreed that it should only accept generic function objects as its first argument. In a separate message I will mail out a proposal for ensure-generic-function which is needed as part of this change. For the time being I suggest that ensure-generic-function be added to functi to "hold a place for it". In general I agree with that. There might be some details to settle. I think the discussion happened after we finished editing the document, which is why it didn't get reflected. There may not be quite time to finish this before Dick's stated deadline of Sunday night. -- call-next-method (2nd paragragh under purpose, end of next to last sentence) The phrase "otherwise it is the next most specific primary method" is wrong. It should be something like "otherwise it is the effective method which would have been called had there been no :around methods". Right, looks like an editing mistake since it's the same text as in the next sentence. (1rst paragraph under remarks) The last sentence would be more clear if it read: Neither argument defaulting, nor the use of setq, nor rebinding the variables with the same names as parameters affects the values call-next-method passes to the method it calls. Whatever. -- change-class (1rst para under purpose, 3rd sentence) should say the class-changed generic-function is called. I agree. I don't like the indenting of the defclass forms in the examples here. I would like to see defclass dorms indented as follows. If there are no slots and no options, it should be all on one line: (defclass foo () ()) (defclass bar (foo) ()) If there are slots or options, the name and supers should be on the first line, then the slot descriptions should be indented under the c in defclass, then the options should be indented under the e in defclass. That's okay with me. I guess it's time we spent the 5 minutes it takes to make our editor know about defclass and enforce those indentation rules. -- class-of last paragraph on the page (under remarks) shouldn't this say that class-of returns a class at "least as specific" as specified according to figure 1-2. The difference is that what is written says that class-of will always return a class the user has heard of, what I am suggesting is that class-of will always return a subclass of a class the user has heard of. In general I agree. I think your proposed wording is still confusing. I would rephrase it (assuming "meta-instance of" as a dual of "meta-class of" is defined elsewhere): If the object is a meta-instance of STANDARD-TYPE-CLASS, the class returned may be a subclass of one of the classes listed in Figure 1-2. I'm not sure the phrase "most specific class" really means anything, I would avoid it. -- defclass (2nd para under purpose) "that FUNCTIONS be automatically generated" should be "that METHODS automatically BE DEFINED ON GENERIC-FUNCTIONS to .." or something like it. This same mistake occurs later in the paragraph. It looks like someone just lifted this from some defstruct documentation somewhere. Agreed. The 3rd (and last) paragraph under purpose wouldn't be needed if we could figure out this type to class mapping better and explain it better. I disagree. This is the class to type mapping, not the type to class mapping; the description here is about as specific as could be; and I think defclass is a good place to mention it. Probably it should be mentioned in the Concepts chapter too. Under Syntax: the abbreviation for having an initform with no other slot options ( ) is missing. Agreed. Does anyone think this should not be put back? the argument to accessor-prefix and friends is described as string or symbol. Its always a symbol, its sometimes NIL. Agreed that string should go away. I think the special-casing of NIL should go away too, but Danny is still resisting. Under arguments: (2nd para) it doesn't say that the superclass-name arguments must name a class of class standard-class. This may not be the right place to say it, but I can't find this anywhere. I don't think it should be explained in terms of standard-class. I think the explanation should be that if a class and one of its superclasses are of different metaclasses, whether this is valid depends on the particular two metaclasses and is controlled by the meta-class protocol. Further discussion should be in the meta-objects chapter. The special case of a standard class and a standard type class is mentioned on the last page of the Concepts chapter. (3rd para) "there must not be any duplicate slot-names" Or else what? Perhaps "If there are any duplicate slot-names an error is signalled" would be better. Yes, although that language can get rather stilted when discussing macros, where the errors are signalled at compile time rather than run time. Under the description of class-options, the argument to :accessor-prefix and friends is also listed as a string-or-symbol. Under values: I thought we decided all these DEF forms were going to return the object they defined? This seems to have been changed back and forth several times. I'm happy with all of them returning the object if that's okay with everyone else. Under remarks: (6th para after the 4 bullets), there is a sentence missing before the last sentence. The last sentence reads "No other slot option may appear more than once.." The missing sentence would say which slots options could appear more than once. Editing error. The last sentence of that paragraph belongs two paragraphs earlier ("It is valid to specify..."). -- defgeneric-options-setf (and defmethod-setf) Let me say once again, that in order for the user to be able to add methods to a setf-generic-function with add-method, we must document the convention which defgeneric-options-setf and defmethod-setf use to pass the new-value argument to the setf generic function. I believe the convention we must use is that the new-valeu argument to setf becomes the first argument to the generic function. Wouldn't it be better to ask the generic function what its convention is? Probably a generic function on a generic function and two lambda-lists that returns one lambda-list. This seems to be just one of several things we have to solve or clarify if we expect the add-method level to be taken seriously. -- get-method The specializers argument needs to be changed to be a list of class-objects or (QUOTE ). As I've said several times, this isn't right because it doesn't extend well to discriminating on optional and keyword arguments. I agree that class objects rather than class names are wanted, now that we have clarified that redefining a class modifies the existing class object rather than creating a new one. I don't agree with the format as a simple list. get-method should not error in the case where no such method exists. get-method is the only way to see if such a method exists, it should return nil if there isn't one. Once get-method is changed this way, add-method and remove-method's error conditions are good. Give it an optional error-p argument, I think. -- invalid-method-error and method-combination-error I still don't like having these as separate functions. Could we put a note saying that if the condition system is adopted before this proposal, these functions would be replaced by descriptions of the appropriate condition to signal? I don't agree with this. I believe in abstractions for signalling conditions rather than signalling them directly. I can spend time writing a detailed explanation if the motherhood statement that abstractions are good, and a few minutes thought about proceeding, aren't enough to convince you. -- make-generic-function and make-method I thought we had decided to remove this from the spec. I believe the only thing holding that up is a decision about the initialization protocol. Since nothing is happening with the initialization protocol, I plan to write up a revised version of my Strawman, incorporating the comments I have received from Moon and as Linda to put it in the spec. Afterwards, I think we should replace make-generic-function and make-method with descriptions of the appropriate arguments to pass to make-instance to make a method a generic-function (and a class). Agreed tentatively. -- with-slots The first paragraph under arguments should probably say the instance form must evaluate to an object of class standard class. I assume you made a typo here and you meant to say that the document should -not- say this. with-slots should work for anything. Of course if the class has no slots it will be a no-op, but it shouldn't blow out. The meta-object protocol chapter will describe how to extend with-slots to work with instances with other meta-classes. That's why with-slots should work for anything.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 23:43:03 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Feb 87 20:29:09 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 64725; Fri 6-Feb-87 23:27:51 EST Date: Fri, 6 Feb 87 23:27 EST From: David A. Moon Subject: Re: call-next-method is not a function To: Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870206-133321-3786@Xerox> Message-ID: <870206232754.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 6 Feb 87 13:34 PST From: Masinter.pa@Xerox.COM Perhaps it is unavoidable, but the possible indefinite extent of the call-next-method function also exposes another issue, which is whether identity of the "next method" is closed over, or dynamic. In the same example, given (defclass wozzle (nozzle)) (defmethod test ((a wozzle)) #'call-next-method) (defmethod test ((a nozzle)) "Nozzle tester") (defvar *nozzle-tester* (test (make-wozzle))) (defclass big-nozzle (nozzle)) (defclass wozzle (big-nozzle)) ; redefines wozzle (defmethod test ((a big-nozzle)) "Big nozzle tester") ; whew... (funcall *nozzle-tester*) Does this get "Nozzle tester" or "Big nozzle tester"? The issue is "what's closed over" in the call-next-method. In my trial implementation I did back in September, it closes over everything and the answer is "Nozzle tester". But if you read the Remarks field of change-class (in the 31 Jan version), this situation is already explicitly undefined (the "first semantic difficulty") if we merely extend "the execution of a method" to include the lifetime of any call-next-method closures it creates. So let's just add a sentence there mentioning call-next-method closures. This includes not only #'call-next-method, also #'(lambda .... (call-next-method) ...), thus the problem was not introduced by changing call-next-method from a macro to a function. A related issue, which I think should be explicitly defined, is to make clear that (defmethod ... (dotimes (i 100) (call-next-method))) calls the same method 100 times. It does not call the 100 next most specific methods (erring if there are fewer than 100).  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 21:42:52 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Feb 87 18:25:48 PST Received: from Cabernet.ms by ArpaGateway.ms ; 06 FEB 87 18:16:11 PST Date: 6 Feb 87 18:15 PST From: Bobrow.pa@Xerox.COM Subject: LONG MESSAGE -- Draft of meta-object protocol To: Common-Lisp-Object-System@Sail.stanford.edu Message-ID: <870206-181611-4193@Xerox> Meta-object Protocol (DRAFT 6 Feb 87) The meta-object protocol is based upon a set of objects that are defined in the system. The following is a public view of these classes. Implementations are free to have addtional slots, or simulate slots using the accessors that are defined. For all slots specified, there is a reader with the prefix specified. For some slots setf methods are also defined as described below. The notation (setf ) is used to refer to such methods. There are four pairs of classes described: class, standard-class, slot-description, standard-slot-description, method, standard-method, generic-function and standard-generic-function. The first of each pair represents what is thought of as the minimal or most abstract functionality to be defined in CLOS. The second, with prefix standard-, are the ones described in chapters 1 and 2. All these classes are required to be instances of standard-class. All instances of standard class (these are all classes)inherit from standard-object which defines a small set of default behaviors. This class is effectively defined by: (defclass standard-object (t)()) Behaviors for standard-object include methods for describe, print-object and initialize as described in the concepts chapter. There are two major sections, one dealing with the classes and slot-descriptions, the second with methods and generic-functions. Both start with descriptions of the classes and then describe other methods specialized to the classes, organized by their use in the metaobject protocol. Methods that are described in the function chapter are mentioned but not described. 1. Classes and Slot Descriptions Classes are used for two distinct purposes: to describe the structure of a set of objects, and as a parameter specializer for the definition of methods. The description of the structure uses a set of objects that are instances of slot-descriptions. Classes specify some direct slot-descriptions, and inherit others from their super-classes. We first show the structure of class, and standard class, and then the classes for slot-descriptions. 1.1 Class and standard-class (defclass class (standard-object) (direct-supers direct-subclasses class-precedence-list) (:reader-prefix class-)) (defclass standard-class (class) (direct-slots all-slots generic-functions prototype) (:reader-prefix class-)) [[Initial values for these slots are all NIL]] direct-supers is a list of class objects. If it is changed, then the updating protocol described below is followed. There is a setf generic function for class-direct-supers. (setf class-direct-supers) on class causes the direct-supers slot to get updated, and calls supers-changed. See supers-changed. direct-subclasses is a list of classes. It is the inverse of the links from direct-supers. If x is in the direct-supers of y, then y is in the direct-subclasses of x. See add-direct-subclass, remove-direct-subclass. There is no setf generic function for class-direct-subclasses. class-precedence-list is a list of classes. It is computed from direct-supers. It is computed (just) before the first instance of this class is created, or when any method is defined on this class or any subclass. It is maintained whenever supers of this class or any super class change. See compute-class-precedence-list, compatible-super-p, supers-changed. There is no setf generic function for class-class-precedence-list. direct-slots is a list of slot-description objects. If it is changed, then the updating protocol described in section 1.4. There is a setf generic function for class-direct-slots. (setf class-direct-slots) on class signals an error. (setf class-direct-slots) on standard-class causes the class to get updated. See slots-changed and section 1.4. all-slots is a list of slot-description objects. It is computed from direct-slots of all the classes on class-precedence-list. It is computed (just) before the first instance of this class is created, or with-slots is expanded for any method on this class or subclass. It is maintained if the supers or slots of the class or any of its supers are changed. See collect-slot-descriptions, compute-effective-slot-description, supers-changed, slots-changed. There is no setf generic function for class-all-slots. generic-functions is a list of generic-function objects that have a method defined using this class as a parameter specializer. A generic function appears on this list only once no matter how many relevant methods it contains. It is kept on a class as a cache to allow access to methods that depend on the class definition. This allows updating of methods when classes change. It also provides a hook for browsers in an environment. It is maintined by add-method. There is no setf generic function for class-generic-functions. prototype contains an instance of this class. It is created the first time the accessor class-prototype is used. The prototype is not guaranteed to have any slots filled in. It is to be used as an argument to allow access to methods specialized to the class that don't use the contents of an instance of the class. This is used extensively in the paarsing of the defclass form, for example. In general, it allows a specialized method to be invoked without having to create a new instance of the class each time. There is no setf generic function for class-prototype. 1.2 Slot-description and standard-slot-description (defclass slot-description (standard-object) (name) (:reader-prefix slotd-)) (defclass standard-slot-description (slot-description) (initform allocation type) (:reader-prefix slotd-)) name is a symbol that CLtL allows to be used as a variable. An instance of any class that contains a slot-description with this name will have access to a slot of this name. See concepts document. There is no setf generic function for slotd-name. initform is a lisp form. There is a setf generic function for slotd-initform. (setf slotd-initform) sets the value of initform and calls slots-changed. allocation is one of :instance, :class, :dynamic. There is no setf generic function for slotd-allocation See the concepts chapter to see how these values are used for standard-class. type is a Common Lisp type descriptor There is no setf generic function for slotd-type class-value is the storage for a value in a class. There is a setf function for slotd-class-value (setf slotd-class-value) sets the value. 1.3 Creation of classes Classes are instances of metaclasses. Hence they can be created by the ordinary make-instance protocol. The initalization of a class allows allows two slot-names to be given: direct-slots with value a list of slot-description objects direct-supers with value a list of classes (or names of classes) These names are changed to the classes they refer to (using class-named-for-metaclass) as the first step in compute-class-precedence-list. An error is signalled if a class is not defined with that name at that time. In addition, at the start of the computation of class-precedence-list, a compatibility check is made to determine whether the class (of this metaclass) can inherit from the specifed direct-super-classes using:. compatible-super-p class possible-direct-super class is the one to get the new possible-direct-super class. If this method returns NIL an error is signalled. The default method for compatible-super-p allows use of possible-direct-super only if the metaclasses of class and possible-direct-super are the same. compute-class-precedence-list class &optional (direct-supers (class-direct-supers class)) This computes a total order extracted from the direct-supers of the class. The optional argument allows the environment to compute what the class-precedence-list would be if the direct-supers were those provided. See concepts chapter for the behavior of compute-class-precedence-list for class. Once the class-precedence list is computed, the set of all slot-descriptions for the class can be computed. collect-slot-descriptions class &key (direct-supers (class-direct-supers class)) (direct-slotds (class-direct-slots class)) This generic-function computes a list of slot-descriptions interpreted as a set. The importance of the word set is that the order of the slot-descriptions is not guaranteed to be used by the implementation to build instance structure. No two slot-descriptions in the set can have the same name. The set of slot-descriptions is computed using the method compute-effective-slot-description, called once for each name in the union of all the slot-descriptions of all the classes in the class-precedence list. An implementation is free to add additional slot-descriptions. The optional arguments possible-direct-supers and possible-direct-slots are available so that the environment can ask what the set of slots would be if those were used instead of the values in the current slots. compute-effective-slot-description class same-named-slotds The argument same-named-slotds is a list of slot-descriptions in most-specific-first order specified by the class-precedence-list. The behavior of this method for the standard-slot-description is found in the concepts chapter. 1.4 Updating classes A standard-class once defined can be updated to have different direct-slots and direct-supers update-class class &key :direct-supers :direct-slots where direct-supers is list of classes and direct-slots is a list of slot-descriptions. It allows only a single updating pass when both direct-supers and direct-slots are changing. To preserve the backlinks from supers to subclasses, the following generic functions are provided. supers-changed calls these. add-direct-subclass class subclass adds subclass to direct-subclasses if it is not present. remove-direct-subclass class subclass removes subclass from direct-subclasses of class if it is present. It signals an error if subclass was not in the list. If any changes are made to supers, the class-precedence-list of this class and its subclasses may have changed. The set of slot-descriptions of this class and subclasses might have changed. To allow updating of these slots, and any other cached information in a particular implementation, the protocol calls the recursive generic function: supers-changed class old-supers old-slots &optional top-flag &rest rest-args When this method is invoked, it is assumed that class-direct-supers and class-direct-slots will return their new values. The old values are provided to facilitate making incremental changes. The contract of the generic function is to update any cached information about supers and slots in class, and any of its subclasses. supers-changed is called recursively on all the subclasses of the class that is changed. The variable top-flag, which is T only on the initial call from updating methods, allows specialized methods to take specific actions for the class that has changed directly. The rest-args are provided so that extra information can be passed down by specializations, if desired. The supers-changed method for standard-class updates the class-precedence-list, and the list of all-slots using compute-class-precedence-list, and collect-slot-descriptions. It also makes obsolete any class that has a different shape, that is has a different number or organization for slots. See below for a further description of obsolete classes. supers-changed is called by (setf class-direct-supers) and by update-class. A similar protocol support updating if only the set of slot-descriptions provided have changed using the generic function slots-changed slots-changed class old-slots &optional top-flag &rest rest-args It is assumed any updating to direct-slots has already been done. The old-slots are provided to facilitate updating. The contract of the generic function is to update any cached information about slots in class, and any of its subclasses. The variable top-flag, which is T only on the initial call, allows specialized methods to take specific actions for the class which directly changed. The rest-args are provided so that extra information can be passed down by specializations, if desired. The method for standard-class updates the list of all-slots using collect-slot-descriptions. It also makes obsolete any class that has a different shape, that is has a different number or organization for slots. See below for a further description of obsolete classes. In order to support caching in generic functions, when a class is changed, the following protocol is supported update-method-inheritance class old-supers In standard-class this causes recomputation of effective methods for all the generic functions on this class and any subclass. 1.5 Obsolete Classes If the effect of updating the class is to change the shape of instances that would be produced by this class, then instances produced according to the former description are now "obsolete"; that is they no longer conform to the current description in the class by this name. When a class must be made obsolete, a protocol informs the class: make-class-obsolete class To determine if a class needs to be made obsolete, it is a useful optimization to know if any instances of this class have ever been made. has-instances-p class is a predicate that returns NIL if it knows no instances have ever been made. For standard-class, make-class-obsolete ensures that old instances are now instances of an obsolete-class that knows about the old structure, and about the new class description. The next time any instance of this obsolete class is used either as an argument to slot-value, or as a specialized argument for a method, (change-class instance updated-class) is called to change it to conform to the new class definition. See concepts chapter for further discussion 1.6 Expanding defclass forms This protocol is defined to allow users to extend the use of defclass in some limited ways. For this purpose, we define the abstract syntax of defclass as follows: (defclass name (super-name*) ((slot-name {slot-prop slot-prop-value}*)*) {(class-option-keyword . class-option-args)}*) That is, slots can have an arbitrary property list following the name, and all class-options are lists with a keyword. The only way to specify the metaclass used by defclass is by using the :metaclass class-option. The metaclass option is used to get a prtotype of the metaclass for use by the generic functions specified below The types of extensions we visualize are ones that would allow additional slot-properties and class options interpreted by the metaclass. expand-defclass metaclass-prototype defclass-form uses the :metaclass option to obtain a prototype of the metaclass, and expands the defclass form. check-defclass-form metaclass-prototype slot-list class-options signals an error if there are any slot-properties or class-options that are not recognized. add-named-class metaclass-prototype name super-list slot-list class-options creates the appropriate class, doing the conversion from a list of names to a list of super-classes, converting the slot-list to a list of slot-descriptions of the appropriate kind. The defclass expansion contains an (add-named-class ...) form. The other forms in the expansion of a defclass form are expressions to creating the accessor, reader and constructor methods specified in the defclass form. add-named-class checks if these is currently a class defined with the same name. If so, it checks to see if it is acceptable to update that class using the generic function: class-for-redefinition metaclass-prototype old-class-with-name &rest other-information class-for-redefinition signals an error if the class cannot be redefined, else, or returns a class that is to be updated (this might be a new class or the old one). On class, class-for-redefinition always signals an error. standard-class, it updates the class and supports obsolete instances. make-slot-description metaclass-prototype slot-description-list creates the appropriate kind of slot-description object for class, filling it in from slot-description-list This is how extensions to the slot-properties can be added without breaking defclass. compute-super-from-name metaclass-prototype name is used to obtain a class from a name. It can use class-named or in a compile-time environment may want to be shadowed to find a special class object or definition. 1.7 Class names The association of a name with a class is supported by the metaclass. Not all classes need have names. The basic lookup function is: class-named-from-metaclass metaclass-prototype name &key :no-error-flag :compile-time-hash-table This returns the class with that name, or signals an error if none. If no-error-flag=T then returns NIL if none. If compile-time-hash-table is given then it is used for looking up names, and for setting them. This allows a sompiler to interface with this metaclass specific name lookup. There is a setf generic function defined for class-named-from-metaclass. (setf class-named-from-metaclass) signals an error if name is already in use for another class. It no-error-flag is T, then this is a noop. Additional support for instances of class is provided by class-named name &optional no-error-flag class-named is defined in terms of class-named-from-metaclass. If a class has a name, then it can be found using: class-name class &optional unnamed-value Returns the name of a class, if it has one, or returns unnamed-value. There is a setf generic function defined for class-name. (setf class-name) name We do not need a class-name-using-metaclass since class-name is already specialized to the class. If new-name is NIL, then class will have no name afterwards. If new-name is the name of another class, then an error is signalled. If class has another name, then class will be first made unnamed, then then given the new name. It is noop if class already has that name. 1.7 Instance Slot Access The function slot-value is defined to use: slot-value-using-class class instance-of-that-class slot-name &optional value-if-slot-missing This method on the metaclass that knows the representation of the instance, and returns the value. It calls slot-missing if a slot by this name is not accessible from this instance. If value-if-slot-missing is provided, this value returned instead of calling slot-missing. slot-missing instance slot-name is called if no slot with slot-name is accessible in instance. The method for slot-missing on standard-class just signals an error There is a setf generic function for slot-value-using-class. (setf slot-value-using-class) sets the value of the specified slot. It calls slot-missing-for-setf if a slot by this name is not accessible from this instance. If value-if-slot-missing is provided in the slot-value form, this value is returned instead of calling slot-missing-for-setf slot-missing-for-setf instance slot-name new-value The method on class for slot-missing-for-setf signals an error. slot-exists-p instance slot-name &optional allocation is a predicate that returns true if there is a slot with name slot-name accessible from instance. If allocation is given, then returns true if it has the given allocation. Returns NIL otherwise all-slot-names instance &optional allocation returns the list of all slot-names accessible within this instance, limiting it to slots with a particular allocation if that argument is given. add-dynamic-slot instance slot-name new-value adds to instance a dynamic slot with value new-value. Signals an error if slot-name is already a slot accessible from instance, and not a dynamic slot. If it is a dynamic slot then just changes the value. remove-dynamic-slot instance slot-name removes the dynamic slot from the instance. Signals an error if such a slot does not exist on the instance. dynamic-slot-value instance slot-name &optional default-value gets the value from the dynamic slot. Signals an error if slot is not a dynamic slot, or returns default-value it is provided. (setf dynamic-slot-value) new-value sets the value of the dynamic slot. Signals an error if slot is not a dynamic slot, or returns default-value it is provided. 1.8 Optimizing Slot Access at Compilation To provide users a hook to optimize access to slots in compiled code, the protocol provides optimize-slot-value class-for-var form This returns a specialized form for compilation, or original form if it can do nothing with the form. It can check in the method about the parameter-specializer for any arguments in the form. form look like: (slot-value ') optimize-setf-slot-value class-for-var form returns a specialized form for compilation, or original form. form must be of the form (setf (slot-value '...)...) 1.9 Relationships among classes and instances The class system extends the type system. There are methods that correspond to typep and subtypep classp instance class Returns T if (class-of instance) is a subclass of class, that is, if (subclassp (class-of instance) class). subclassp class1 class2 returns T if class2 is an element of the class precedence list of class1, that is, if class2 is class1 or any of its superclasses. [[?? As an alternative, we could extend typep and subtypep directly to allow class arguments where they now have type-specifier arguments]] 2. Methods and Generic Functions 2.1 Method Structure (defclass method (object) (generic-function parameter-specializers function) (:reader-prefix method-)) (defclass standard-method (method) (qualifiers) (:reader-prefix method-)) generic-function is NIL or the generic-function of which this method is a part. There is no setf generic function for method-generic-function. parameter-specializers is a list of elements interpeted by compute-discriminator-code to determine if this method is applicable for a particular set of arguments. For standard-method, this list consists of class objects or lists of the form (QUOTE individual). See concepts chapter. There is no setf generic function for method-parameter-specializers. function is a function that generic-function will call if the discriminator-code selects this method as the appropriate effective method. This method function can be applied directly to the same argument list to the generic-function, provided the arguments match their parameter-specializers. There is a setf generic function for method-function. (setf method-function) fn signals an error if the fn can not be determined to have a lambda list congruent with that of the generic function. (setf method-function) calls generic-function-changed. qualifiers is a list of non-nil atoms. There is no setf generic function for method-qualifiers. 2.2 Generic Function Structure (defclass generic-function (object) (methods discriminator-code) (:reader-prefix gf-)) (defclass standard-generic-function (generic-function) (argument-list argument-precedence-order method-class method-combination declarations) (:reader-prefix gf-)) methods is a list of method objects. There is no setf generic function for gf-methods discriminator-code is a function that actually does the discrimination when the a generic-function is called. Implementations are free to make special classes of generic-function objects that are recognized by the interpreter, and for which the discrimination code is done in the interpreter. There is no setf generic function for gf-discriminator-code. For the following, see also the discussion in the function and concepts chapters. argument-list is an ordinary CL lambda-list with no aux variables. There is a setf generic function for gf-argument-list. If there are any methods on the generic function, it signals an error if the argument list is not congruent to those of the methods. argument-precedence-order specifies the order that is to be used in computing precedence of methods. It is a permutation of the required arguments of argument-list. It is used by compute-discriminator-code to determine the order of applicability of methods. There is a setf method for gf-argument-precedence-order. If it is used, it checks that the new value is a permutation of the required arguments of argument-list, or signals an error. If argument-precedence-order is different than it was before, compute-discriminator-code is called to update the gf-function. method-combination is a list whose first element (car) is the combination type and the rest (cdr) is a list of parameters for method-combination. There is a setf generic-function for gf-method-combination with a method defined for standard-generic-function. If it is used, then compute-discriminator-code is called to update the gf-function. method-class is a class. It will be used as the class for methods defined with defmethod on this generic-function. gf-method-class has a setf-method. declarations are those provided in def-generic-options. It is used by compute-discriminator-code. gf-declarations has a setf method. 2.3 Creating Methods and Generic Functions Instances of methods and generic functions are made using make-instance. The initialize method for method supports slot-names of parameter-specializers, argument-list and function. The initialize method for generic-function supports properties for all of its slots except discriminator-code. ensure-generic-function symbol &key class make-fn-be-default-p is documented in the concepts and function chapter. 2.4 Manipulating generic-functions and methods add-method generic-function method remove-method generic-function method get-method generic-function parameter-specializers generic-function-changed gf &optional hints this is called by add-method remove-method and (setf method-function) get-setf-generic-function symbol These are documented in the concepts and function chapter. 2.5 Building Code for Generic Functions The code used by a generic function is computed by the following method. All callers of this method know how to install that code. compute-discriminator-code generic-function This method returns a function, or some object recognizable to the implementation dependent code that installs this function in the generic-function object. The usual way for people to effect what code is generated is throguh method combination, and its define-method-combination interface. This interface defines a method on the generic-function compute-effective-method. As part of the code, if there is no applicable method for a generic-function, the generic function should call the method no-matching-method generic-function arglist The default method for this generic function signals an error. compute-effective-method generic-function combination-type applicable-methods &optional parameters This should return a form that is used for the body of an effective method composed from the set of applicable methods. It can use make-method-call. See concepts chapter. The contract between compute-discriminator-code and compute-effective-method says that it must be called for all significantly different sets of applicable methods that can arise from a set of arguments. If the user wants to build code using compute-discriminator-code, the following methods may prove useful. find-applicable-methods generic-function argument-list &optional sorted-flag returns a list of methods on generic-function that are applicable to the arguments given. If sorted-flag the list is sorted most-specific-first. method-equal method1 method2 tests whether two methods of the same generic-function have the same specializers and qualifiers. method-more-specific generic-function method1 method2 argument-list Returns T if method1 is more specific than method2 with respect to the argument list. 3.0 Defining New Storage Metaclasses In order to define new mechanisms for storing instances, there must be some system dependent code. The interface to that code is: define-metaclass name size class-of-code This function creates associated with name 1) a mechanism for allocating structures of this kind The structure should be of the size specified. If size is NIL, then the allocation routine will expect a parameter indicating the desired size. 2) a mechanism for recognizing when a structure of this type is asked for its class. For such structures, the function (or macro) specified by class-of-code will return the code. A new class must also be defined using the same name. In its make-instance method it can use: meta-allocate-instance meta-name &optional size meta-slot-value meta-name thing position meta-set-slot-value meta-name thing position new-value As a mechanism for storing slots, the user should have accessible a function (macro) make-memory-block size and accessor memory-block-ref block size In PCL these are just calls to make-vector but something better is probably needed.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 20:09:28 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Feb 87 16:58:52 PST Received: from Cabernet.ms by ArpaGateway.ms ; 06 FEB 87 16:53:46 PST Date: 6 Feb 87 16:53 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: List of generic functions To: Common-Lisp-Object-System@Sail.stanford.edu cc: Bobrow.pa@Xerox.COM Message-ID: <870206-165346-4066@Xerox> The following is a list of the generic functions (and argument names) that are in the metaobject protocol or are part of the extended programming interface. I don't know how to distinguish these two. Some of them have been been described in the first two chapters of the CLOS document. A description of what these generic functions do is coming later today. But it is much longer. The notation below uses (setf ) to indicate the setf generic function that corresponds to . The argument shown for the setf function is only the new-value argument. The names of the arguments are an attempt to give some clue as to the types of the arguments. **Class Access Generic Functions class-direct-supers class (setf class-direct-supers) list-of-classes direct-subclasses class class-precedence-list class direct-slots class (setf class-direct-slots) slot-descriptions all-slots class generic-functions class class-prototype class **Slot-Description Access Generic Functions slotd-name slot-description slotd-initform standard-slot-description (setf slotd-initform) form slotd-allocation standard-slot-description slotd-type standard-slot-description **Inherited Class Structure compute-class-precedence-list class &optional possible-supers compatible-super-p class possible-direct-super collect-slot-descriptions class &key :direct-supers :direct-slotds compute-effective-slot-description class same-named-slotds update-class class &key :direct-supers :direct-slots add-direct-subclass class subclass remove-direct-subclass class subclass supers-changed class old-supers old-slots &optional top-flag &rest rest-args slots-changed class old-slots &optional top-flag &rest rest-args update-method-inheritance class old-supers **Obsolete Classes make-class-obsolete class has-instances-p class change-class instance new-class class-changed previous current ** Parsing defclass form expand-defclass metaclass-prototype defclass-form check-defclass-form metaclass-prototype slot-list class-options add-named-class metaclass-prototype name super-list slot-list class-options class-for-redefinition metaclass-prototype old-class-with-name &rest other-information make-slot-description metaclass-prototype slot-description-list ** Class names class-named name &optional no-error-flag (setf class-named) class class-name class (setf class-name) name class-named-from-metaclass metaclass-prototype name &key :no-error-flag :compile-time-hash-table (setf class-named-from-metaclass) class ** Slot access slot-value-using-class class instance-of-that-class slot-name &optional value-if-slot-missing slot-missing instance slot-name (setf slot-value-using-class) new-value slot-missing-for-setf instance slot-name new-value slot-exists-p instance slot-name &optional allocation all-slot-names instance &optional allocation add-dynamic-slot instance slot-name new-value remove-dynamic-slot instance slot-name get-dynamic-slot-value instance slot-name &optional default-value ** Compiling Slot Access optimize-slot-value class-of-object form optimize-setf-slot-value class-of-object form ** Type Relations classp instance class subclassp class1 class2 ** Method Acess Functions method-generic-function method method-parameter-specializers method method-function method (setf method-function) function method-qualifiers method ** Generic Function Access generic functions gf-methods generic-function gf-discriminator-code gf-argument-list generic-function (setf gf-argument-list) lambda-list gf-argument-precedence-order generic-function (setf gf-argument-precedence-order) list gf-method-class generic-function (setf gf-method-class) class gf-method-combination generic-function (setf gf-method-combination) method-combination-option gf-declarations generic-function (setf gf-declarations) declaration-list ** Changing Generic Functions ensure-generic-function symbol &key :generic-function-class :make-exisiting-function-default-p add-method generic-function method remove-method generic-function method get-method generic-function parameter-specializers generic-function-changed gf &optional hints get-setf-generic-function symbol ** Changing code of generic functions compute-discriminator-code generic-function compute-effective-method generic-function combination-type applicable-methods &optional parameters find-applicable-methods generic-function argument-list &optional sorted-flag method-equal method1 method2 method-more-specific generic-function method1 method2 argument-list ** Making new storage types for metaclasses define-metaclass name size class-of-code meta-allocate-instance meta-name &optional size meta-slot-value meta-name thing position meta-set-slot-value meta-name thing position new-value make-memory-block size danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 17:00:25 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Feb 87 13:39:12 PST Received: from Cabernet.ms by ArpaGateway.ms ; 06 FEB 87 13:33:21 PST Date: 6 Feb 87 13:34 PST From: Masinter.pa@Xerox.COM Subject: Re: call-next-method is not a function In-reply-to: David A. Moon 's message of Thu, 5 Feb 87 23:30 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870206-133321-3786@Xerox> Perhaps it is unavoidable, but the possible indefinite extent of the call-next-method function also exposes another issue, which is whether identity of the "next method" is closed over, or dynamic. In the same example, given (defclass wozzle (nozzle)) (defmethod test ((a wozzle)) #'call-next-method) (defmethod test ((a nozzle)) "Nozzle tester") (defvar *nozzle-tester* (test (make-wozzle))) (defclass big-nozzle (nozzle)) (defclass wozzle (big-nozzle)) ; redefines wozzle (defmethod test ((a big-nozzle)) "Big nozzle tester") ; whew... (funcall *nozzle-tester*) Does this get "Nozzle tester" or "Big nozzle tester"? The issue is "what's closed over" in the call-next-method. Clearly it has to close over the identity of the arguments. (All of the arguments.) Its less clear whether it can somehow cache the identity of the classes of the arguments, the class of the next argument, or any other information which was used in the computation of this method. Its also fairly sticky about what happens if this method gets removed from the hierarchy. Maybe its ok to leave this unstated, but it seems bothersome.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 16:59:06 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Feb 87 13:38:48 PST Received: from Cabernet.ms by ArpaGateway.ms ; 06 FEB 87 13:00:33 PST Date: 6 Feb 87 13:01 PST From: Masinter.pa@Xerox.COM Subject: Re: Functions In-reply-to: Gregor.pa's message of 6 Feb 87 08:51 PST To: Gregor.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870206-130033-3754@Xerox> The problem, I imagine, is that the manual format used so far requires documented items to say something like [function] or [macro] in the right margin, and neither is entirely appropriate.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 15:53:20 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Feb 87 12:38:01 PST Received: from Cabernet.ms by ArpaGateway.ms ; 06 FEB 87 12:14:43 PST Date: 6 Feb 87 12:14 PST From: Gregor.pa@Xerox.COM Subject: ensure-generic-function To: Common-Lisp-Object-System@Sail.stanford.edu cc: Gregor.pa@Xerox.COM Message-ID: <870206-121443-3684@Xerox> Try this for ensure-generic-function: ensure-generic-function &key ( (class-named 'standard-generic-function)) (make-exisiting-function-default-p nil) If symbol is fboundp to a generic-function of the same class as then this function does nothing. If symbol is fboundp to a generic-function of some other class, the generic-function class changing protocol is followed, see chapter 3. If symbol not foundp a generic function of generic-function-class is created and put in symbol's function cell. If symbol is boundp to a function, and make-exisiting-function-default-p is not nil, a generic-function is created, put in the function cell, a default method is added to the generic-function and the symbol's previous function cell value is used as the function for the default method. If symbol is fboundp to a function and make-exisiting-function-default-p is nil an error is signalled. If symbol names a macro or a special form, an error is signalled. Feel free to change the names of the arguments. Note that this is a function not a generic-function.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 12:07:37 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Feb 87 09:00:29 PST Received: from Cabernet.ms by ArpaGateway.ms ; 06 FEB 87 08:51:20 PST Date: 6 Feb 87 08:51 PST From: Gregor.pa@Xerox.COM Subject: Re: Functions In-reply-to: Dick Gabriel 's message of 05 Feb 87 13:21 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870206-085120-3357@Xerox> Doesn't this mean that we can say: "within the body of a defmethod form, call-next-method is a lexically bound function which ..."  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Feb 87 00:09:38 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 5 Feb 87 20:55:35 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 63741; Thu 5-Feb-87 23:30:21 EST Date: Thu, 5 Feb 87 23:30 EST From: David A. Moon Subject: call-next-method is not a function To: Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870205-120337-2399@Xerox> Message-ID: <870205233020.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 5 Feb 87 12:05 PST From: Masinter.pa@Xerox.COM It is wrong to say that call-next-method "is a function", because that terminology is used exclusively in CLtL to mean that the symbol has a global function definition with the given interpretation. I think that careful wording is called for. Good point. What would happen in the following (defmethod test ((a wozzle)) #'call-next-method) (defmethod caller ((a wombat) fn) (funcall fn)) (caller (make-wombat) (test (make-wozzle))) would it call the next method of test, or the next method of caller? Of test.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 20:10:29 EST Date: 05 Feb 87 1321 PST From: Dick Gabriel Subject: Functions To: common-lisp-object-system@SAIL.STANFORD.EDU Larry writes: ``It is wrong to say that call-next-method "is a function", because that terminology is used exclusively in CLtL to mean that the symbol has a global function definition with the given interpretation.'' Larry's right about this, but this wording might be a little misleading. He is contrasting the phrase ``is a function'' with ``is a macro'' and ``is a special form.'' In our document, we mention that this, that, or the other thing is a function or a generic function. Of course, Common Lisp does state that there are global names and local names for functions, so one could have functions that are stored in no function cell. CALL-NEXT-METHOD is a function in the local-name sense in that it is only an accessible function within method combination defining macros. There should be some other phrase to describe this, I suppose. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 19:41:33 EST Date: 05 Feb 87 1312 PST From: Dick Gabriel Subject: Stan's Comments To: common-lisp-object-system@SAIL.STANFORD.EDU Stan has some good comments: He writes: ``"The definition of the class specifies the structure of instances of the class. The slots define the structure of the instance." This seems contradictory to me. Perhaps the point is that the class specifies the slots, and the slots define the structure instances.'' The two sentences on which he comments are not contradictory, only poorly written. The language construct that serves to define the class *specifies* the structure. The slots are the structure that is specified - that is, they *define* it. The distinction is between the words `specify' and `define,' the first being in a linguistic category the second being in an operational category. He's right it's bad wording because his quick reading did not result in comprehension. Stan mentions that the ``lattice'' isn't. I suppose we thought that the rules for well-defined class structures would prevent situations like the one he mentions, but they don't. I suppose I had hoped for an upper semi-lattice, but it isn't in the cards. DAG it will probably be. All the wording regarding orderings and their generators have long since been made consistent. Though his comments are valuable, we generally have not distributed the document of the date he mentions, but I guess a public file is a public file. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 19:19:23 EST Date: 05 Feb 87 1227 PST From: System Files Subject: call-next-method is not a function Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Feb 87 12:23:44 PST Received: from Cabernet.ms by ArpaGateway.ms ; 05 FEB 87 12:03:37 PST Date: 5 Feb 87 12:05 PST From: Masinter.pa@Xerox.COM Subject: call-next-method is not a function To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870205-120337-2399@Xerox> It is wrong to say that call-next-method "is a function", because that terminology is used exclusively in CLtL to mean that the symbol has a global function definition with the given interpretation. I think that careful wording is called for. What would happen in the following (defmethod test ((a wozzle)) #'call-next-method) (defmethod caller ((a wombat) fn) (funcall fn)) (caller (make-wombat) (test (make-wozzle))) would it call the next method of test, or the next method of caller?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 15:17:15 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Feb 87 11:47:17 PST Received: from Cabernet.ms by ArpaGateway.ms ; 05 FEB 87 11:25:13 PST Date: 5 Feb 87 11:25 PST Sender: Lanning.pa@Xerox.COM From: Stan Lanning Subject: Comments on Chapter 1 To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870205-112513-2354@Xerox> Some comments on the Jan 23 draft of Chapter 1, Programmer Interface Concepts. My apologies if there is a newer draft that has these fixed. Page 1-6, section "The Structure of Instances", paragraph one states: "The definition of the class specifies the structure of instances of the class. The slots define the structure of the instance." This seems contradictory to me. Perhaps the point is that the class specifies the slots, and the slots define the structure instances. Page 1-9, section "Inheritance of defclass Options" The options are given here for the first time. It would be nice if they had been mentioned before, perhaps with a brief description of their intended function. Page 1-15, section "Computing the Class Precedence List" Sorry, the class lattice is not a lattice (in the mathematician's sense of the word). For example, consider the following network: T / \ A B |\ /| | X | ;; X is not a class, just two lines crossing |/ \| C D \ / NIL The set {A, B} has no least upper bound, so the ordering isn't a lattice. The most you can say is that the ordering is an acyclic directed graph. Also, "we assume they are consistent and that R is a partial ordering" isn't right. You mean that the trasitive closure of R is a partial ordering. Perhaps R should be defined to be the transitive closure, if Rl and Rp are consistent? Page 1-18, section "Introduction to Methods", states: "If a defmethod form is evaluated and a method object corresponding to the given parameter specializers already exists, the new definition replaces the old." How does this relate to qualified methods? Surely a (defmethod :before ...) doesn't replace an unqualified defmethod. Page 1-24, section "Standard Method Combination" states: "An error is signalled if call-next-method is used and there is no appliciable primary method to call." Is there going to be a (remaining-method-p) function? Or are you counting on catching the error? That's all for now. ----- smL  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 15:14:22 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Feb 87 11:46:14 PST Received: from Cabernet.ms by ArpaGateway.ms ; 05 FEB 87 11:21:16 PST Date: 5 Feb 87 11:21 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Various of Danny's Comments In-reply-to: David A. Moon 's message of Thu, 5 Feb 87 00:29 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870205-112116-2346@Xerox> Danny writes: ``I vote for (:accessor-prefix) as the right way to say use the slot-names.'' To quote a famous computer scientist, ``ugh, bletch.'' I don't like this either, since it has nothing to do with prefixes. We should say what we mean. How about :writable-instance-variables? Excuse me, I mean :writeable-slots. This has everything to do with prefix. Its intention is to create from the slot-names accessors (readers) with names constructed with no prefix. Gregor tells me we argued this before and decided NIL was the way to do it. So be it. But not a different class-option. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 14:06:20 EST Date: 05 Feb 87 0938 PST From: Dick Gabriel Subject: X3J13 Discussion To: common-lisp-object-system@SAIL.STANFORD.EDU Moon's plan is reasonable, but I doubt we need to preach to the converted - these people want to know technical details. I can possibly moderate the discussion, but since I'm not running for office and since there will be no babies to kiss, I can probably skip the speech. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 13:02:45 EST Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 5 Feb 87 09:54:15 PST Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 47380; Thu 5-Feb-87 11:41:15 EST Date: Thu, 5 Feb 87 11:38 EST From: Daniel L. Weinreb Subject: Re: initializing class slots To: Bobrow.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870204-210601-1571@Xerox> Message-ID: <870205113817.8.DLW@CHICOPEE.SCRC.Symbolics.COM> Line-fold: No Date: 4 Feb 87 21:05 PST From: Danny Bobrow (defclass A () ((s :initform 1 :allocation :class))) By the way, I could not find anything specific in the document that says how initforms work for class slots. For example, exactly when is the initform evaluated? At the time of the evaluating of the containing defclass? Yes and No. It is no because it is really at the time the class is defined. Compiling a file with a defclass will expand the defclass into something else, and that will evaluate at load time. But for ordinary loading of files (or evaluating the form in a listener) the answer is yes. Actually, I'd take that as a "yes" answer. It's evaluated at the time that the defclass is evaluated. Compiling a file causes the defclass to be evaluated when the file is loaded. That is, defclass is (eval-when (load eval) ...) by default, not (eval-when (compile load eval) ...). So it's easy to explain.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 03:15:31 EST Date: 04 Feb 87 2352 PST From: Dick Gabriel Subject: CPL Varia To: common-lisp-object-system@SAIL.STANFORD.EDU Now I understand about the partial ordering in Flavors. Interesting idea. In any event, Moon and I now agree on CPL, and, as you can all see, we are engaged in strutting behavior. This might go on a little longer, but most people enjoy watching peacocks spread their tail feathers. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 03:06:42 EST Date: 04 Feb 87 2349 PST From: Dick Gabriel Subject: Inheritance of Slots To: common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: ``Third, when compiling a method you cannot assume anything about the types of the slots, since a subclass could throw away your :type slot-option.'' I guess I didn't say it clearly enough. The effective type of a slot is the AND (as in (AND T1 T2 ... Tn)) of the slots in the CPL. I thought this was exactly what this meant: ``{\bf :type} is constrained to satisfy all of the type constraints given by classes in the class precedence list. That is, if T1, T2 and so on are the type constraints given by the class and all of its superclasses, the value of the slot must satisfy {\bf (typep value '(and T1 T2 T3...)}.'' Didn't you (Moon) and Sonya write this? Moon comments: ``No net gain.'' Before there were these categories of slot inheritance: 1. accessors and readers don't specially inherit 2. :allocation inherits some funny way 3. :initform inherits some other funny way 4. :type inherits by doing AND Now we have: 1. accessors and readers as above 2. :allocation, :initform, and :type are totally inherited or totally shadowed with simple defaults. 3. :type constrained to be AND. Moon writes: ``In addition, I'm not happy about the idea that one cannot define an :accessor for an inherited slot without clobbering its :initform.'' I thought my proposal said that if you mention slot options only (:accessor, for example) normal inheritance happens. The simplified rule is for slot descriptions only (:allocation, :type, :initform). If you had :accessor only, the slot description stuff is totally inherited - ``the right thing.'' If you mention a slot description, all slot descriptions are shadowed. To be specific, the following statement is true: ``one *can* define an :accessor for an inherited slot without clobbering its :initform as long as :type and :allocation are not mentioned in the defclass form.'' I think that the briarpatch of inheritance rules surrounding :allocation, :type, and :initform are too complex. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 01:32:49 EST Date: 04 Feb 87 2218 PST From: Dick Gabriel Subject: Clarification Clarification To: common-lisp-object-system@SAIL.STANFORD.EDU No one was trying to change anyone's rules about inheritance, though in the end that happened. The problem was that LGD and I could not figure out what the text in the document meant. Good intentions do not make for good writing. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 01:29:01 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 22:22:29 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 62592; Thu 5-Feb-87 01:01:52 EST Date: Thu, 5 Feb 87 01:01 EST From: David A. Moon Subject: call-next-method: More feedback from Symbolics reviewers To: Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870204-212007-1602@Xerox> Message-ID: <870205010132.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 4 Feb 87 21:20 PST From: Danny Bobrow In the current version of the document, CALL-NEXT-METHOD is documented as a macro. That was a mistake; it should be a function. We need a proposal for the extension for call-next-method for changed arguments. What is the problem with providing call-next-method with an &rest argument, and if it is non-null, then argument checking is done on those elements of the argument-list that have been used in the discriminator-code. No problem, that's what I had in mind. The only reason it's not in is that someone wouldn't let me put it in because the proposal wasn't lean enough. Maybe it's time to put it in now? Does this argue for a macro implementation to allow alternative expansions in the case where arguments are provided. That was my idea at first, but it was firmly pointed out to me that issues of optimization should be separated from issues of semantics. Implementations can surely figure out how to make their compilers notice whether arguments are provided or not, and generate different code. One way is to declare the FLET function INLINE and constant-fold the conditional inside the function that checks whether arguments were supplied.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 01:21:49 EST Date: 04 Feb 87 2146 PST From: Dick Gabriel Subject: CALL-NEXT-METHOD To: Common-lisp-object-system@SAIL.STANFORD.EDU I think the fact that it isn't documented correctly is a slip-up. I think we all agreed to this at one point, at least implicitly - it was in your last define-method-combination proposal. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 01:05:15 EST Date: 04 Feb 87 2134 PST From: Dick Gabriel Subject: CL Types To: common-lisp-object-system@SAIL.STANFORD.EDU Not all Common Lisp programmers program in all Common Lisps. All classes good for a Common Lisp might not be good for all Common Lisps. That is, a lot of programmers program in exactly one Common Lisp, and their code might not be portable, but it can be written portably. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:55:35 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:45:21 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 62580; Thu 5-Feb-87 00:43:20 EST Date: Thu, 5 Feb 87 00:43 EST From: David A. Moon Subject: Discussion at X3J13 To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870205004300.8.MOON@EUPHRATES.SCRC.Symbolics.COM> We should talk about how we're going to organize the discussion at X3J13. I believe we have a whole day allocated to us. One way of organizing it that I had in mind was for me to present the programmer interface as it currently stands, for Danny to present the meta-object protocol as it currently stands, for Dick to present the reasons why this is the right thing for the broader Lisp community, not just for the people like Xerox and Symbolics and TI with specialized Lisp machines, and for anything left of the morning to be spent on questions and answers directly related to the presentations. Then the next half day would be spent either on more detailed Q&A if the meeting attendees seem to have trouble understanding what's in the document, or else on technical discussion of what changes they would like to propose, how to finish the parts that we haven't finished yet, and "where do we go from here" discussion. Does this sound good?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:47:23 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:34:23 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 62557; Thu 5-Feb-87 00:06:17 EST Date: Thu, 5 Feb 87 00:05 EST From: David A. Moon Subject: Inheritance of Slot Options To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 4 Feb 87 13:04 EST from Dick Gabriel Message-ID: <870205000552.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 04 Feb 87 1004 PST From: Dick Gabriel I think the current spec suffers from excessive rules for the sake of marginal functionality. I propose this slight modification: We break what was slot options into two categories, slot descriptions and slot options (in the BNF, what was ``slot options'' becomes ``slot descriptor''). Slot options are the :accessor and :reader guys. Slot descriptions are :initform, :allocation, and :type. The slot options are as before. Slot description inherit like this: Let CPL be the class precedence list for C. If C's defclass doesn't have a slot descrption for a slot it is totally inherited from the next most specific class in the CPL. If C's defclass has a slot description, it totally shadows any other in CPL. When this latter case happens, some of the aspects of the slot description might be defaulted. The defaulting is as follows: :initform is defaulted to unsupplied :allocation is :instance :type is T The effective type of a slot is the AND of all types specified for it in the CPL. There are two differences between this and the previous rule (which I now, unfortunately, understand). First, :initform acts differently - if you want to change the :type or :allocation and keep the :initform, you have to mention the :initform again. Second, it is an easier rule to understand and remember. Third, when compiling a method you cannot assume anything about the types of the slots, since a subclass could throw away your :type slot-option. As far as I can tell this would make it impossible to use :type for anything, certainly it seems to rule out the use you (Dick) mentioned for it when it was first proposed. I think it's counterproductive to have a complex set of rules to enforce some intuition that doesn't pay its own way. A simpler but slightly inaccurate model, where the inaccuracy to someone's intuition is unimportant, is preferrable to a complex model that captures someone's epicycle. These rules don't really seem any simpler to me. The concept of looking at every slot-option in the class precedence list is no different from the concept of looking at every method in the class precedence list; that concept has been simplified out, but the concept of slot options and slot descriptions being two different things has been added. No net gain. In addition, I'm not happy about the idea that one cannot define an :accessor for an inherited slot without clobbering its :initform. This seems just plain wrong. It's a symptom either of your proposal not being right or of the whole defclass syntax not being modularized properly.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:44:49 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:37:54 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 62576; Thu 5-Feb-87 00:35:56 EST Date: Thu, 5 Feb 87 00:35 EST From: David A. Moon Subject: CPL Varia To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 1 Feb 87 17:10 EST from Dick Gabriel Message-ID: <870205003536.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 01 Feb 87 1410 PST From: Dick Gabriel Moon's writes: ``Oh, right, this only happens if you add the extension that the local precedence order of a class can be a partial order rather than a total order. We have that in Flavors, and it comes in handy, but I'm not proposing to standardize on it at this time.'' I'm not sure what this means, but whether the local precedence order is partial or total the leftmost siblings must come first. No, the whole point of a partial local precedence order is that it is not a total order. Therefore the classes mentioned in the direct superclass list are not constrained to appear in the class precedence list in the same order as they appear in the direct superclass list. Instead, one specifies the local precedence order explicitly as a set of pairs (before, after). (Well, actually, there is a little syntactic sugar, but it's basically a set of ordered pairs.) The example at the start of this message shows that intuition isn't going to help much in all cases. At this point I firmly believe that for any algorithm an example can be constructed that can be plausibly argued to be unintuitive. I think the important thing is for intuition to help in the cases that people expect to be simple, not in all cases.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:44:19 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:34:41 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 21:20:07 PST Date: 4 Feb 87 21:20 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: More feedback from Symbolics reviewers In-reply-to: David A. Moon 's message of Wed, 4 Feb 87 20:16 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870204-212007-1602@Xerox> In the current version of the document, CALL-NEXT-METHOD is documented as a macro. That was a mistake; it should be a function. The document should be updated. We'll do it next time we get the lock on the document, unless someone else does it first, which would be perfectly okay with me. The Remarks field of CALL-NEXT-METHOD should say that it can only be called from the lexical scope of the body of a DEFMETHOD or DEFMETHOD-SETF. The current documentation sort of implies this but doesn't say it explicitly. In most implementations CALL-NEXT-METHOD will be defined with a FLET that DEFMETHOD wraps around its body, rather than being a global function, and maybe the Remarks field should mention this. We need a proposal for the extension for call-next-method for changed arguments. What is the problem with providing call-next-method with an &rest argument, and if it is non-null, then argument checking is done on those elements of the argument-list that have been used in the discriminator-code. Does this argue for a macro implementation to allow altrnative expansions in the case where arguments are provided. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:44:03 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:36:06 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 62569; Thu 5-Feb-87 00:30:08 EST Date: Thu, 5 Feb 87 00:29 EST From: David A. Moon Subject: Various of Danny's Comments To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 2 Feb 87 19:45 EST from Dick Gabriel Message-ID: <870205002948.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 02 Feb 87 1645 PST From: Dick Gabriel Danny writes: ``I vote for (:accessor-prefix) as the right way to say use the slot-names.'' To quote a famous computer scientist, ``ugh, bletch.'' I don't like this either, since it has nothing to do with prefixes. We should say what we mean. How about :writable-instance-variables? Excuse me, I mean :writeable-slots.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:39:58 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:32:32 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 62566; Thu 5-Feb-87 00:23:17 EST Date: Thu, 5 Feb 87 00:22 EST From: David A. Moon Subject: Re: Clarification To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870203-141235-2721@Xerox> Message-ID: <870205002252.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 3 Feb 87 14:12 PST From: Gregor.pa@Xerox.COM Your "fair text" describes completely different inheritance rules. The case in particular, as I outlined in my message on slot inheritance the other day is: (defclass foo () ((a :allocation :class))) (defclass bar (foo) ((a :initform ())) Under the rules currently in the document, and the rules I mailed out the other day: instances of the class foo share a :class variable named a instances of the class bar each have their own :instance variable a Under the rules you propose its unclear what would happen. Perhaps their would be two class variables, perhaps there would be one, its not clear what would happen with :initform. I agree with Gregor. The rules described in the document should not be changed in substance. I have only read them once, but they seem to match the rules which Danny and I came up with and which I mailed out the other day. They were intended to.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:26:29 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:17:32 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 21:12:25 PST Date: 4 Feb 87 21:12 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Addendum to ``Inheritance of Slot Options'' In-reply-to: Dick Gabriel 's message of 04 Feb 87 11:38 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870204-211225-1586@Xerox> I forgot to mention in my last message that :allocation :none should be flushed as well, because the current ``rules'' for it are not as wonderful as someone might like. If we (democratically construed) decide to keep :allocation :none, I think the rule I proposed in the last message is adequate; possibly someone should remind me why As the last holdout for :none, I give in. I want to keep :dynamic however. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:19:28 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:08:41 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 21:07:18 PST Date: 4 Feb 87 21:07 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Inheritance of Slot Options In-reply-to: Dick Gabriel 's message of 04 Feb 87 10:04 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870204-210718-1572@Xerox> After a discussion with Linda, I believe your rules (that do not make initform special) are reasonable in that they promote having all descriptions of a slot in one place. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Feb 87 00:10:40 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 21:06:46 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 21:06:01 PST Date: 4 Feb 87 21:05 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: initializing class slots In-reply-to: Daniel L. Weinreb 's message of Wed, 4 Feb 87 12:05 EST To: DLW@ALDERAAN.SCRC.Symbolics.COM cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870204-210601-1571@Xerox> (defclass A () ((s :initform 1 :allocation :class))) By the way, I could not find anything specific in the document that says how initforms work for class slots. For example, exactly when is the initform evaluated? At the time of the evaluating of the containing defclass? Yes and No. It is no because it is really at the time the class is defined. Compiling a file with a defclass will expand the defclass into something else, and that will evaluate at load time. But for ordinary loading of files (or evaluating the form in a listener) the answer is yes. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 23:17:41 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 20:11:56 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 19:37:57 PST Date: 4 Feb 87 19:37 PST From: Gregor.pa@Xerox.COM Subject: initialization protocol To: Common-Lisp-Object-System@Sail.Stanford.edu cc: Gregor.pa@Xerox.COM Message-ID: <870204-193757-1495@Xerox> Here is my proposed initialization protocol. It is based on the one I sent out before. Like that protocol, the primary goals are simplicity and flexibility. This proposal also includes some comments about the conventions for use of this protocol. There are two major changes in this protocol: 1.) there is a system-supplied initialize method which processes the &rest argument to make-instance as plist of slot names and values. This method initializes the slots of the instance from the values in this plist, any slot for which no value is specified in the plist is initialized from the default value specified in the defclass form. This change provides the user with access to the canned functionality of treating the &rest argument to make-instance as a plist of slot-names and values. It provides it in a way that Moon seems to like in which the :initforms in the defclass are only evaluated when no value for the slot is specified in the &rest argument to make-instance. 2.) initialize take the &rest argument which was passed to make-instance as a single argument rather than an &rest or &key argument. This is the part of this protocol I am the least attached to. If we want to change this so that make-instance uses apply to call initialize I am amenable to that. The reason I have done it this way is to avoid the pain of always having to add: (.. &rest options &key &allow-other-keys) to initialize methods. Here is some prototype code which implements this protocol. I am using this code here because it is simple, and it makes it exactly clear what happens when. (defmethod make-instance ((class-name symbol) &rest options) (apply #'make-instance (class-named class-name) options)) (defmethod make-instance ((class class) &rest options) (let ((instance (make-instance-internal class))) (initialize instance options) instance)) (defmethod initialize ((o object) options) (dolist (slot-name (all-slots (class-of o))) (setf (slot-value o slot-name) (let* ((getf-default (list nil)) (plist-value (getf options slot-name getf-default))) (if (eq plist-value getf-default) (evaluate-initform o slot-name) plist-value))))) The convention for the &rest argument to make-instance (which I will call the init-plist but someone else is free to invent a better term) is as follows: It should be a true plist, the keys (odd-numbered elements of the list) should be either: slot-names, in which case the default initialize method (or some user-defined initialize method will initialize the slots from those values keywords, a keyword implies that the initialize method is going to do more "work" than just set the slot value (with slot value). Things specified with keywords are often compound values or values which don't map directly onto slot values. Here are some sample initialize methods. These show some standard stuff people might want to do: (defmethod initialize ((p plane) options) (when options (error "Planes accept no init-plist"))) (defmethod initialize ((b boat) options) (call-next-method) ;first do slot values (when (cadr (memq options ':start)) ;then start if we should (start boat))) ;;; note that the flet with apply used in this example is the downside ;;; of the decision to pass the options to initialize as one argument. ;;; as I said above, I think this is worth it. (defmethod initialize ((m method) options) ;; We do hairy processing to set function specializers and ;; qualifiers in parallel. So we accept those as keywords. (flet ((internal (&key function specializers qualifiers) (setf (slot-value m 'function) function (slot-value m 'specializers) specializers (slot-value m 'qualifiers) qualifiers) .. code to process the new values in parallel ..)) (apply #'internal options))) ;;; In this case, we want to process the options if there are any, ;;; but before we do so, we want to evaluate ALL the :initforms in ;;; the defclass and install them in the instance. (defmethod initialize ((s ship) options) (if (null options) (call-next-method) (progn (initialize s ()) ;Go evaluate :initforms. .. now process options ..))) Some bugs (and answers) with my proposal: B: The convention of using flet and apply is weird. A: Its no so bad really, and its much better than having to say &rest options &key &allow-other-keys all over B: The default initialize method only signals an error if the init-plist has an even number of elements. If the user wants to implement complete error-checking of the init-plist they have to do it themselves. A: Right. Doing complete error checking of the init-plist involves checking the values too, so if the user is going to do that they will have no more code to write to check the keys. Please, speak now...  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 20:22:16 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 17:17:45 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 62496; Wed 4-Feb-87 20:16:52 EST Date: Wed, 4 Feb 87 20:16 EST From: David A. Moon Subject: More feedback from Symbolics reviewers To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870204201632.3.MOON@EUPHRATES.SCRC.Symbolics.COM> In the current version of the document, CALL-NEXT-METHOD is documented as a macro. That was a mistake; it should be a function. The document should be updated. We'll do it next time we get the lock on the document, unless someone else does it first, which would be perfectly okay with me. The Remarks field of CALL-NEXT-METHOD should say that it can only be called from the lexical scope of the body of a DEFMETHOD or DEFMETHOD-SETF. The current documentation sort of implies this but doesn't say it explicitly. In most implementations CALL-NEXT-METHOD will be defined with a FLET that DEFMETHOD wraps around its body, rather than being a global function, and maybe the Remarks field should mention this. In the Possible Extensions field of CALL-NEXT-METHOD, the sentence that discusses APPLY-NEXT-METHOD should be deleted. Regular APPLY can be used now that it is a function. Making it a function instead of a macro makes it slightly more difficult for implementations to optimize it, but not significantly more difficult. It makes the semantics simpler and more consistent with the rest of Lisp. Does anyone object to these changes?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 18:26:02 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 15:02:19 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 14:13:52 PST Date: 4 Feb 87 14:13 PST From: Gregor.pa@Xerox.COM Subject: my comments on 2/2/87 draft of functi To: Common-Lisp-Object-System@Sail.Stanford.edu cc: Gregor.pa@Xerox.COM Message-ID: <870204-141352-1087@Xerox> Here are a bunch of comments on the 2/2 draft of functi. Also scattered in here for your reading pleaser are my proposals for how to solve some other problems like: - initialization - setf generic function argument lists - indentation convention for defclass -- add-method (and remove-method) still say that it accepts symbols or a list of (SETF ) as argument. I proposed and Moon agreed that it should only accept generic function objects as its first argument. In a separate message I will mail out a proposal for ensure-generic-function which is needed as part of this change. For the time being I suggest that ensure-generic-function be added to functi to "hold a place for it". -- call-next-method (2nd paragragh under purpose, end of next to last sentence) The phrase "otherwise it is the next most specific primary method" is wrong. It should be something like "otherwise it is the effective method which would have been called had there been no :around methods". (1rst paragraph under remarks) The last sentence would be more clear if it read: Neither argument defaulting, nor the use of setq, nor rebinding the variables with the same names as parameters affects the values call-next-method passes to the method it calls. -- change-class (1rst para under purpose, 3rd sentence) should say the class-changed generic-function is called. I don't like the indenting of the defclass forms in the examples here. I would like to see defclass dorms indented as follows. If there are no slots and no options, it should be all on one line: (defclass foo () ()) (defclass bar (foo) ()) If there are slots or options, the name and supers should be on the first line, then the slot descriptions should be indented under the c in defclass, then the options should be indented under the e in defclass. This puts the slot-descriptions in a place that doesn't move when there are supers, and makes a nice "line" between them and the options. (defclass foo () ((a 1) (b 2))) (defclass bar (foo) ((c 3) (d 4)) (:accessor-prefix bar-)) (defclass baz (bar) () (:metaclass mumble)) -- class-of last paragraph on the page (under remarks) shouldn't this say that class-of returns a class at "least as specific" as specified according to figure 1-2. The difference is that what is written says that class-of will always return a class the user has heard of, what I am suggesting is that class-of will always return a subclass of a class the user has heard of. -- defclass (2nd para under purpose) "that FUNCTIONS be automatically generated" should be "that METHODS automatically BE DEFINED ON GENERIC-FUNCTIONS to .." or something like it. This same mistake occurs later in the paragraph. It looks like someone just lifted this from some defstruct documentation somewhere. The 3rd (and last) paragraph under purpose wouldn't be needed if we could figure out this type to class mapping better and explain it better. Under Syntax: the abbreviation for having an initform with no other slot options ( ) is missing. the argument to accessor-prefix and friends is described as string or symbol. Its always a symbol, its sometimes NIL. Under arguments: (2nd para) it doesn't say that the superclass-name arguments must name a class of class standard-class. This may not be the right place to say it, but I can't find this anywhere. (3rd para) "there must not be any duplicate slot-names" Or else what? Perhaps "If there are any duplicate slot-names an error is signalled" would be better. Under the description of class-options, the argument to :accessor-prefix and friends is also listed as a string-or-symbol. Under values: I thought we decided all these DEF forms were going to return the object they defined? Under remarks: (6th para after the 4 bullets), there is a sentence missing before the last sentence. The last sentence reads "No other slot option may appear more than once.." The missing sentence would say which slots options could appear more than once. -- defgeneric-options-setf (and defmethod-setf) Let me say once again, that in order for the user to be able to add methods to a setf-generic-function with add-method, we must document the convention which defgeneric-options-setf and defmethod-setf use to pass the new-value argument to the setf generic function. I believe the convention we must use is that the new-valeu argument to setf becomes the first argument to the generic function. Using this convention, the user could write the following piece of code. (defgeneric-options-setf foo (moving-obj) (new-foo)) (add-method (get-setf-generic-function 'foo) (make-method :specializers (list (class-named 't) (class-named 'plane)) :function #'(lambda (new-value plane) ..))) Unless anyone objects to this convention or to documenting it, it should be placed in the document either in concepts or under defmethod-setf or defgeneric-options-setf or some combination and cross-referenced etc. If someone needs help explaining this let me know. -- get-method The specializers argument needs to be changed to be a list of class-objects or (QUOTE ). get-method should not error in the case where no such method exists. get-method is the only way to see if such a method exists, it should return nil if there isn't one. Once get-method is changed this way, add-method and remove-method's error conditions are good. -- invalid-method-error and method-combination-error I still don't like having these as separate functions. Could we put a note saying that if the condition system is adopted before this proposal, these functions would be replaced by descriptions of the appropriate condition to signal? -- make-generic-function and make-method I thought we had decided to remove this from the spec. I believe the only thing holding that up is a decision about the initialization protocol. Since nothing is happening with the initialization protocol, I plan to write up a revised version of my Strawman, incorporating the comments I have received from Moon and as Linda to put it in the spec. Afterwards, I think we should replace make-generic-function and make-method with descriptions of the appropriate arguments to pass to make-instance to make a method a generic-function (and a class). -- with-slots The first paragraph under arguments should probably say the instance form must evaluate to an object of class standard class. The meta-object protocol chapter will describe how to extend with-slots to work with instances with other meta-classes.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 17:18:39 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 14:12:38 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 12:57:54 PST Date: 4 Feb 87 12:57 PST From: Gregor.pa@Xerox.COM Subject: class-named To: Common-Lisp-Object-System@Sail.Stanford.edu cc: Gregor.pa@Xerox.COM Message-ID: <870204-125754-114@Xerox> the function class-named is missing from the spec. It should be documented something like this: class-named &optional ( t) The first argument to class-named should be a symbol. class-named returns the class-named by that symbol if there is one. If there is no class-named by that symbol and the second argument is unsupplied or is not nil, class-named signals an error. If there is no class-named by that symbol, and the second argument is nil, class-named returns nil. I don't believe anyone objects to the existence of this function.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 14:52:03 EST Date: 04 Feb 87 1138 PST From: Dick Gabriel Subject: Addendum to ``Inheritance of Slot Options'' To: common-lisp-object-system@SAIL.STANFORD.EDU I forgot to mention in my last message that :allocation :none should be flushed as well, because the current ``rules'' for it are not as wonderful as someone might like. If we (democratically construed) decide to keep :allocation :none, I think the rule I proposed in the last message is adequate; possibly someone should remind me why WITH-SLOTS behaves as it does? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 13:12:53 EST Received: from SCRC-RIVERSIDE.ARPA by SAIL.STANFORD.EDU with TCP; 4 Feb 87 09:53:07 PST Received: from CHICOPEE.SCRC.Symbolics.COM by RIVERSIDE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 98755; Wed 4-Feb-87 12:07:53 EST Date: Wed, 4 Feb 87 12:05 EST From: Daniel L. Weinreb Subject: initializing class slots To: Bobrow.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870203-143435-2787@Xerox> Message-ID: <870204120512.0.DLW@CHICOPEE.SCRC.Symbolics.COM> Line-fold: No Date: 3 Feb 87 14:34 PST From: Danny Bobrow (defclass A () ((s :initform 1 :allocation :class))) By the way, I could not find anything specific in the document that says how initforms work for class slots. For example, exactly when is the initform evaluated? At the time of the evaluatino of the containing defclass?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 13:06:51 EST Date: 04 Feb 87 1004 PST From: Dick Gabriel Subject: Inheritance of Slot Options To: common-lisp-object-system@SAIL.STANFORD.EDU I think the current spec suffers from excessive rules for the sake of marginal functionality. I propose this slight modification: We break what was slot options into two categories, slot descriptions and slot options (in the BNF, what was ``slot options'' becomes ``slot descriptor''). Slot options are the :accessor and :reader guys. Slot descriptions are :initform, :allocation, and :type. The slot options are as before. Slot description inherit like this: Let CPL be the class precedence list for C. If C's defclass doesn't have a slot descrption for a slot it is totally inherited from the next most specific class in the CPL. If C's defclass has a slot description, it totally shadows any other in CPL. When this latter case happens, some of the aspects of the slot description might be defaulted. The defaulting is as follows: :initform is defaulted to unsupplied :allocation is :instance :type is T The effective type of a slot is the AND of all types specified for it in the CPL. There are two differences between this and the previous rule (which I now, unfortunately, understand). First, :initform acts differently - if you want to change the :type or :allocation and keep the :initform, you have to mention the :initform again. Second, it is an easier rule to understand and remember. I think it's counterproductive to have a complex set of rules to enforce some intuition that doesn't pay its own way. A simpler but slightly inaccurate model, where the inaccuracy to someone's intuition is unimportant, is preferrable to a complex model that captures someone's epicycle. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 13:01:03 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 09:56:30 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 87 09:40:11 PST Date: 4 Feb 87 09:39 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Common Lisp Types In-reply-to: Jim Kempf 's message of Wed, 4 Feb 87 08:06:25 pst To: kempf%hplabsc@hplabs.HP.COM cc: Bobrow.pa@Xerox.COM, RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870204-094011-3744@Xerox> From the application programmer's viewpoint, classes for some of the types listed as not having any would make application development using CLOS more straightforward. Consider the STREAM type. If a STREAM class exists, and is subclass-able, then developing a window system application which can run on a variety of displays becomes easier, since WINDOW can be a subclass of STREAM. In this sense, I think Gabrial's proposal is a sound one, since it increases the integration between the CL type system and CLOS. Jim Kempf kempf@hplabs.hp.com I believe having abstract classes is great. The problem becomes when the user expects a method to be applicable, but it isn't because the type (class) system doesn't preserve the appropriate subclass relationships. For example, will the type (class) system support (subclassp (class-of #'(lambda(x) x)) (class-named 'function)) If so, then function is a good class; if not, then I think there is some confusion. If all implementations of stream are such that (subclassp (class-of *stream-object*) (class-named 'stream)) then stream is a good class. Thus, I believe in most of what RPG suggested. But we should be careful not to break the users model of the class system. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Feb 87 11:16:57 EST Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Feb 87 08:07:32 PST Received: from hplabsc by hplabs.HP.COM ; Wed, 4 Feb 87 08:06:36 pst Received: by hplabsc ; Wed, 4 Feb 87 08:06:25 pst Date: Wed, 4 Feb 87 08:06:25 pst From: Jim Kempf Message-Id: <8702041606.AA20595@hplabsc> To: Bobrow.pa@Xerox.COM, RPG@SAIL.STANFORD.EDU Subject: Re: Common Lisp Types Cc: common-lisp-object-system@SAIL.STANFORD.EDU From the application programmer's viewpoint, classes for some of the types listed as not having any would make application development using CLOS more straightforward. Consider the STREAM type. If a STREAM class exists, and is subclass-able, then developing a window system application which can run on a variety of displays becomes easier, since WINDOW can be a subclass of STREAM. In this sense, I think Gabrial's proposal is a sound one, since it increases the integration between the CL type system and CLOS. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Feb 87 22:47:45 EST Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 3 Feb 87 19:41:07 PST Received: from hplabsc by hplabs.HP.COM ; Tue, 3 Feb 87 19:38:45 pst Received: by hplabsc ; Tue, 3 Feb 87 19:38:29 pst Date: Tue, 3 Feb 87 19:38:29 pst From: Jim Kempf Message-Id: <8702040338.AA08376@hplabsc> To: Common-Lisp-Object-System@Sail.stanford.edu, Gregor.pa@Xerox.COM Subject: Re: Some other open issues I agree with Gregor about the portable code walker interface not being necessary for the deadline, however, I would like to point out that it may be desirable to press the issue of a symbol macro special form for Common Lisp. The reason I mention this is because some recent profiling results I have from PCL indicate that the code walker is in the top two or three slowest functions called during method generation. Addition of a symbol macro special form (called LET-PSEUDO in our system) would allow the compiler to take care of substituting the proper form for slot access when a WITH is processed. So proper resolution of this issue may impact the efficiency of method generation in Classes, as well as the potential for extention using the metaclass protocol. Obviously, this issue need not be resolved until more important semantic issues are. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Feb 87 19:01:26 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Feb 87 15:55:49 PST Received: from Cabernet.ms by ArpaGateway.ms ; 03 FEB 87 14:34:35 PST Date: 3 Feb 87 14:34 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Clarification In-reply-to: Dick Gabriel 's message of 03 Feb 87 13:54 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870203-143435-2787@Xerox> We propose the following fair copy: ``The slot options provided by the various slot descriptions combine as follows: The {\bf :allocation} option is inherited from the most specific class in the class precedence list. If no superclass explicitly specifies the {\bf :allocation} option, the default is {\bf :allocation} {\bf :instance}.'' Note that this definition is intended to be recursive, because there might be no class that explicitly specifies the :allocation option. The only issue this skirts is the following example that has a problem: (defclass A () ((s :initform 1 :allocation :class))) (defclass B (A)((s :initform 2))) The latter MUST mean :allocation :instance (or signal an error). I think we should insist that :allocation :class be repeated if it is intended to change anything else about the class variable (this is the only sane semantic interpretation). Another alternative is to make there be a different class variable in B. For :dynamic, this kind of example makes sense (there is a different value stored in a different class). But on the principle that the unusual case (namely anything but :allocation :instance) ought to be visible locally. I would say that if a local description appears in a class, then allocation is :instance, unless overridden locally. Or stronger, if allocation inherited is anything but :instance, then an error is signalled if no :allocation is specified locally. Which of these two do you like?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Feb 87 17:34:45 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Feb 87 14:26:03 PST Received: from Cabernet.ms by ArpaGateway.ms ; 03 FEB 87 14:12:35 PST Date: 3 Feb 87 14:12 PST From: Gregor.pa@Xerox.COM Subject: Re: Clarification In-reply-to: Dick Gabriel 's message of 03 Feb 87 13:54 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870203-141235-2721@Xerox> Your "fair text" describes completely different inheritance rules. The case in particular, as I outlined in my message on slot inheritance the other day is: (defclass foo () ((a :allocation :class))) (defclass bar (foo) ((a :initform ())) Under the rules currently in the document, and the rules I mailed out the other day: instances of the class foo share a :class variable named a instances of the class bar each have their own :instance variable a Under the rules you propose its unclear what would happen. Perhaps their would be two class variables, perhaps there would be one, its not clear what would happen with :initform. The rules described in the document should not be changed in substance. I have only read them once, but they seem to match the rules which Danny and I came up with and which I mailed out the other day.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Feb 87 17:00:44 EST Date: 03 Feb 87 1354 PST From: Dick Gabriel Subject: Clarification To: common-lisp-object-system@SAIL.STANFORD.EDU LGD and I are going over the CONCEPTS file. The following sentence appears: ``The slot options provided by the various slot descriptions combine as follows: {\bf :allocation} comes from the most specific slot description in the class precedence list---if it does not explicitly specify {\bf :allocation}, the default is {\bf :allocation} {\bf :instance}.'' We propose the following fair copy: ``The slot options provided by the various slot descriptions combine as follows: The {\bf :allocation} option is inherited from the most specific class in the class precedence list. If no superclass explicitly specifies the {\bf :allocation} option, the default is {\bf :allocation} {\bf :instance}.'' Note that this definition is intended to be recursive, because there might be no class that explicitly specifies the :allocation option. Any objections? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Feb 87 15:05:51 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 3 Feb 87 12:00:03 PST Received: from ti-csl by csnet-relay.csnet id ak05669; 3 Feb 87 14:48 EST Received: from dsg (juliett.ARPA) by tilde id AA03965; Mon, 2 Feb 87 17:39:55 cst Received: FROM Jenner BY dsg Via CHAOS-NET with CHAOS-MAIL; 2-Feb-87 10:32:56 Message-Id: <2748270803-690773@Jenner> Sender: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET Date: 2-Feb-87 10:33:23 From: Patrick H Dussud To: Common-Lisp-Object-System@SU-AI.ARPA Subject: Re: Moon/Bobrow phone conversation In-Reply-To: In-Reply-To: Msg of 31-Jan-87 22:52:00 from "David A. Moon" Msg of 31-Jan-87 22 Date: 31-Jan-87 22:52:00 From: "David A. Moon" I made some changes to define-method-combination that Danny Bobrow and I discussed on the phone. The generic-function is no longer in the lambda list, instead it's a wired-in variable name. The lambda-list is still present for expansion, but is () in standard method combination. The short form is described after the long form and the expansion into the long form is shown. compute-effective-method takes 4 arguments. :operator :call-next-method replaces :around t in make-method-call. The short form takes the operator as a keyword argument instead of a positional argument. I think we all agree on this compromise now. It's OK with me. I am glad to see this issue resolved. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Feb 87 01:32:55 EST Received: from NAVAJO.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 2 Feb 87 22:19:21 PST Received: by navajo.stanford.edu; Mon, 2 Feb 87 22:18:25 PST Received: from bhopal.edsel.com by edsel.uucp (2.2/SMI-2.0) id AA07825; Mon, 2 Feb 87 21:52:17 pst Received: by bhopal.edsel.com (3.2/SMI-3.2) id AA06846; Mon, 2 Feb 87 21:55:47 PST Date: Mon, 2 Feb 87 21:55:47 PST From: edsel!bhopal!jonl@navajo.stanford.edu (Jon L White) Message-Id: <8702030555.AA06846@bhopal.edsel.com> To: navajo!Bobrow.pa%Xerox.COM@navajo.stanford.edu Cc: navajo!common-lisp-object-system%SAIL.STANFORD.EDU@navajo.stanford.edu In-Reply-To: Danny Bobrow's message of 2 Feb 87 18:34 PST Subject: CPL anxieties Re: If the currently proposed algorithm is used, you will not be able to see the difference between merging turtle and animate-thing, and/or merging gren and colored things. . . . The "anxiety" followed from merging Colored-things and Animate-things, rather than either of those with their direct inferiors. When they are merged (and they have no similar methods so it would be a disjoint merger), then the "up to join" nature of the pre-order treewalk forces a semi-breadth-first ordering. Which is what the original source of this example was trying to achieve. Re . . . The order proposed puts both turtle and animate before both green and colored, so the latter two will have no effect wrt the two methods of concern. I claim this is correct. This is simply the depth-first order. While it enforces *some* ordering on the problem, there is no reason in the topology of the inheritance graph to believe that one ordering is preferable to another. In such circumstances, either there are some methods which would be inherited from essentially *incomparable* classes, or there are no such methods. In the latter case, it is a "moot" point, but in the former, shouldn't an error of some sort be signalled? or shouldn't there be some way for the user to specify more exactly what he wants? The anxieties, then, can be summarized as 1) defining a "mix in" subclass forces the programmer to specify an order among the direct suprs; but this ordering may have no relation whatsoever to the application problem, and it will probably determine all the method inheritance choices. 2) merging/spliting a class "way up" in the inheritance graph can override what methods the new class has; but the programmer wanted to be able to say something (anything?) which would insure the selection of the correct blush and pen-up methods. Maybe there should be an "unordered" defclass, for which the CPL is built exactly like in the "ordered" case, but for which the error signalling conditions might be more stringent. -- JonL --  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 23:58:58 EST Date: 02 Feb 87 2053 PST From: Dick Gabriel Subject: Common Lisp Types To: common-lisp-object-system@SAIL.STANFORD.EDU When I feel conservative, I agree with Larry's message. When I want to stir up the CL community, I disagree. His message is well-reasoned and it probably makes sense to simply adopt his stance. However, let's consider stirring up the hornets: Larry writes: ``[we should eliminate] types where the "type" of an object can change without going through the change-class protocol, e.g., satisfies. Keyword is here because it is not an error to change a keyword's home package.'' The people writing code that distinguishes keywords from other things and that can break if objects change classes `unexpectedly' consider themselves wizards. I don't care about their bugs. Larry remarks that the range of FUNCTION could be weird. My desire to have CLOS specify some better treatment of functions is partially a desire to humiliate the CL crowd into wanting to fix functions. Larry writes: ``In RPG's proposal, without a corresponding change to CL, you could get back from (function (lambda ...)) a list (lambda ...) for which class-of would return the class LIST, which is not a sub-class of function.'' You bet, and I would think users would start to lobby against a CL that did that. Make 'em sweat! Larry writes: ``Also ommitted is the type standard-char, which is a fairly arbitrary subset of characters.'' Even though they are arbitrary, some people might want to write portable but system-dependent code that reasons about such arbitrary decisions. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 22:58:31 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 19:19:01 PST Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 87 18:34:50 PST Date: 2 Feb 87 18:34 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: CPL anxieties In-reply-to: edsel!bhopal!jonl@navajo.stanford.edu (Jon L White)'s message of Sun, 1 Feb 87 22:40:28 PST To: edsel!bhopal!jonl@navajo.stanford.edu cc:common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870202-183450-1444@Xerox> (defclass Animate-things (. . . ) ()) ;has possibly many suprs (defclass Colored-things (. . . ) ()) ;has possibly many suprs also (defclass Turtles (Animate-things) ()) (defclass Green-things (Colored-things) ()) (defclass Green-turtles (Turtles Green-things) ()) . . . . Animate-things . blush-method = turn-pink . | . | Colored-things | noseup-method = become-haughty | | \ Turtles Green-things noseup-method = pick-up-pen blush-method = turn-purple \ / \ / \ / | | Green-turtles I presume everyone can see the conflict which will arise if the two direct supers to Green-turtles don't directly follow the class itself. One way to view this situation is that Green-turtles is a contradictory class, because it would inherit, say, a blush-method from two distinct suprs -- from Green-things and from Animate-things. Another view is that the present methods of the direct suprs are "more important and shadow any "higher" up. A third view is that the user ought to be able to distinguish such situations in his program in a simple way. If you are of the first opinion, then a good question to ask yourself is "Why does the conflict go away when I merge the class Colored-things into the class Animate-things? Should it?" If the currently proposed algorithm is used, you will not be able to see the difference between merging turtle and animate-thing, and/or merging gren and colored things. The order proposed puts both turtle and animate before both green and colored, so the latter two will have no effect wrt the two methods of concern. I claim this is correct. The CPL algorithm as I now undertand it preserves: 1) subclasses go before superclasses 2) local precedence order is preserved 3) if two sublattices from two classes that have have no members in common, then all members of one sublattice occur before all the members of the other. This preserves the invariant that a program should not change if you just split the functionality of a class into any number of subclasses. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 22:43:46 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 19:17:57 PST Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 87 13:35:55 PST Date: 2 Feb 87 13:37 PST From: Masinter.pa@Xerox.COM Subject: Re: symbols are not generic functions In-reply-to: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET's message of 30 Jan 87 11:00:25 To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870202-133555-227@Xerox> that seems awfully complicated for something that is of mainly internal benefit. Also, it continues to confound the use of symbols vs functions. The :error-if kinds of keyword arguments are generally a last-resort technique -- you know if you need them that something is busted.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 22:33:56 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 19:19:47 PST Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 87 18:43:21 PST Date: 2 Feb 87 18:43 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Common Lisp Types In-reply-to: Dick Gabriel 's message of 31 Jan 87 09:23 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870202-184321-1467@Xerox> In particular, the current Design Rationale chapter says there are no classes for these things: `` - Types too specific to be useful to put methods on: bit, keyword, standard-char, string-char I think that we must consider the rationales I gave in my message of 22 Jan 87 15:10 PST. For this case the problem is: "c) The class of any instance should be quickly determinable. Thus standard-char might be a case which is outlawed since it is a char that is member of a set. Probably bit (represented by an integer that is either 1 or 0) also falls in this category." - Specification of the type is too vague: common, function, stream Here the problem is whether the user is in for a surprise. For functions, I propose that the Class Function include as instances those objects in the Lisp that are in the range of the function Function. For many implementations this will coincide with Compiled-Function, which would be a subclass of Function. This means that CLOS adopts the attitude that symbols and lists that happen to represent functions are the second-class version of functions. "a) all instances of the class (or any subclass) can be identified as being of that type. FUNCTION has a problem in that respect wrt lists. " Perhaps we want to have methods on compiled-function. With these two exceptions I agree with the points expressed by Dick in: I propose that every implementation be required to provide the classes explicitly excluded in the design rationale except for negation classes (atom) and Common, though there may be no instances of them, and I presume we can arrange for the metaclass to state that fact. Furthermore, I propose that the structure of the lattice in the vicinity of implementation-dependent types be variable, reflecting the implementation hierarchy. For example, if an implementation has single-floats only, the classes would be: (defclass short-float (single-float)) (defclass long-float (single-float)) (defclass double-float (single-float)) (defclass single-float (float)) and only single-float would have instances. The other permissible float configurations have different topology. I propose that the class named NIL be at the bottom of the lattice and that it also has no instances. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 22:33:32 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 19:18:19 PST Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 87 15:55:24 PST Date: 2 Feb 87 15:58 PST From: Masinter.pa@Xerox.COM Subject: Re: Common Lisp Types In-reply-to: Dick Gabriel 's message of 31 Jan 87 09:23 PST To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870202-155524-1154@Xerox> Strategy: We're better off leaving out classes where we have some doubts than putting them in. New classes can be added easily later, but its hard to get rid of things later. Most of the classes ommitted don't belong, but for different reasons than given: -- types where the "type" of an object can change without going through the change-class protocol, e.g., satisfies. Keyword is here because it is not an error to change a keyword's home package. -- union types (or ...) are ommitted for now because there is no natural ordering for two different union types. Included in this is the predefined union type COMMON. -- range types. These include integer, floating ranges like (integer 3 12). These are omitted for the same reason that union types are omitted. They include the predefined range types bit and fixnum. Also ommitted is the type standard-char, which is a fairly arbitrary subset of characters. -- negation types. For similar reasons, types which are merely defined as the negation of others are omitted. These include types of the form (not x), atom, which is (not cons), and bignum, which is (and integer (not fixnum)) We can include those implementation-dependent subclasses which have portable language semantics: string-char, short-float, long-float, double-float, single-float. [This is a different position than that in the current paper.] I much prefer having the CLOS description for function, stream (and pathname?) be done 'right' but conditional on a corresponding cleanup of CL than having a standard class which no implementation is required to use or generate. The issue is, what do you get when you say (class-of '(lambda --)). If you insert function in the class hierarchy with RPG's definition, you get LIST. However, this seems to violate what I think of as an invariant, namely for all objects x, for all classes y, (subtypep (class-of x) y) == (typep x y) "For functions, I propose that the Class Function include as instances those objects in the Lisp that are in the range of the function Function. For many implementations this will coincide with Compiled-Function, which would be a subclass of Function. This means that CLOS adopts the attitude that symbols and lists that happen to represent functions are the second-class version of functions." In RPG's proposal, without a corresponding change to CL, you could get back from (function (lambda ...)) a list (lambda ...) for which class-of would return the class LIST, which is not a sub-class of function.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 22:32:45 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 19:16:17 PST Received: from Chardonnay.ms by ArpaGateway.ms ; 02 FEB 87 08:29:37 PST From: masinter.PA@Xerox.COM Date: 2 Feb 87 8:29:19 PST Subject: Re: Common Lisp Types In-reply-to: RPG@SAIL.STANFORD.EDU's message of 31 Jan 87 09:23 PST To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870202-082937-171@Xerox> Didn't you get my mail on this issue? Should I resend it?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 22:27:21 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 19:19:30 PST Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 87 18:36:57 PST Date: 2 Feb 87 18:36 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: CPL Varia In-reply-to: Dick Gabriel 's message of 01 Feb 87 14:10 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870202-183657-1455@Xerox> Given that Moon has agreed that the example (defclass c1 (top) ()) (defclass c2 (top) ()) (defclass c3 (top) ()) (defclass d1 (c1 c2) ()) (defclass d2 (c1 c3) ()) (defclass e1 (d1 d2) ()) producing the CPL (E1 D1 D2 C1 C3 C2 TOP) is ok, I am willing to accept it. I will make sure the writeup is reasonable. I agree too. Thank you. I am glad to see this reach closure. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 22:25:56 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 19:18:53 PST Received: from Cabernet.ms by ArpaGateway.ms ; 02 FEB 87 17:42:21 PST Date: 2 Feb 87 17:42 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Various of Danny's Comments In-reply-to: Dick Gabriel 's message of 02 Feb 87 16:45 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870202-174221-1368@Xerox> I think this is pretty lousy. Having special hidden arguments is bad in the same way that non-local references to variables are. What does ``ONLY for parsing of extra parameters'' mean? Are we really going to put the meta-object function COMPUTE-EFFECTIVE-METHOD into CONCEPTS and FUNCTIONS? All that has to be said in the concepts or functions chapter is that "generic-function" is a well-known name. Within the body of define-method-combination, extra parameters in the def-generic-option :method-combination option are bound to the variables provided in the lambda-list in define-method-combination. ``I vote for (:accessor-prefix) as the right way to say use the slot-names.'' To quote a famous computer scientist, ``ugh, bletch.'' Vell, you got xomething better. We have two cases for names: 1) Create symbols for each of the methods (accessors) specified. Make these symbols by interning the concatenation of prefix with the slot-name. Intern the symbols in the package of the specified prefix. 2) Use the names of the slots for the accessors. For the first we use (:accessor-prefix ) For the second which special case do you like: a) (:accessor-prefix) b) (:accessor-prefix nil) c) (:accessor-prefix ||) Of these three ugly choices, I prefer the first. The second and third have symbols that are interned in some package, and hence violate the interning rule. b) (:accessor-prefix nil) c) (:accessor-prefix ||) Of these three ugly choices, I prefer the first. The second and third have symbols that are interned in some package, and hence violate the rule. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 20:24:53 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 16:18:42 PST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 17:31:15 PST Date: 30 Jan 87 16:06 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Gregor's comments on some things In-reply-to: David A. Moon 's message of Thu, 29 Jan 87 22:58 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@Sail.Stanford.edu Message-ID: <870130-173115-103@Xerox> What does the phrase "x is of class array mean"? In the first paragraph of the section Integrating Types and Classes in Concepts (draft of 1/23) it is used to mean "x is of class array or some subclass of array"? Is that official? I think so. I believe "X is of class Y" and "X is an instance of Y" mean that (class-of X) is Y or a subclass of Y, rather than (eq (class-of X) Y). This whole terminology issue would be easier if we up front indicated that classes are used to reify Common Lisp types specified by (most of) the type specifer symbols. Hence, we could use the expression "x is of type array" in its usual sense (any subtype will do), and (typep x (class-name class)) is the same as (classp x class) What do you think about extending typep to allow (typep x class). Another implication of going to this terminology is that we could say class C1 is a subtype of class C2 meaning that C1 is C2 or is some subclass of C2. Another terminological suggestion. To eliminate the two uses of the term "metaclass", I suggest that we reserve metaclass to mean a class whose instances are classes, and use the term "metatype" to refer to the relationship of an instance to the class of its class, that is "it is the metatype of an instance that determines its implementation." Well, it's pretty weird that symbols are turned into class objects but QUOTE-expressions are not. This doesn't generalize very well to the extension to supporting other Common Lisp type specifiers. This does generalize in the sense that classes correspond to type symbols, and list expressions correspond to list type specifiers. (QUOTE X) means (MEMBER (X)). Thus the language generalizes in correspondence to CLtL. A second answer is that this is the internal representation of add-method etc. and is designed to keep dependence on names Of course it makes get-method and related functions useless until we put in the supporting functions such as class-named. Is there any reason that these aren't documented already? I sent one message describing them already. The only issue I know is what class-name should do if the class has no name. Two options are: 1) Signal an error 2) class-name has a second optional argument which is the value returned if class has no name. (class-named name &optional no-error-flag) returns the class with the name given or signals an error. Do you Gregor, or anyone else, have a list of these missing functions? I'm not talking about the full meta-object protocol, just the functions needed to program at the next level of abstraction below the defxxx macros. I will get a message out about these. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 20:06:24 EST Date: 02 Feb 87 1645 PST From: Dick Gabriel Subject: Various of Danny's Comments To: common-lisp-object-system@SAIL.STANFORD.EDU Danny writes: ``However, lambda-list is an internal lambda list used ONLY for parsing of extra parameters supplied to compute-effective-method. It does not include a name for the generic-function. The well-known-name "generic-function" is available for use within the define-method-combination forms.'' I think this is pretty lousy. Having special hidden arguments is bad in the same way that non-local references to variables are. What does ``ONLY for parsing of extra parameters'' mean? Are we really going to put the meta-object function COMPUTE-EFFECTIVE-METHOD into CONCEPTS and FUNCTIONS? Danny writes: ``I vote for (:accessor-prefix) as the right way to say use the slot-names.'' To quote a famous computer scientist, ``ugh, bletch.'' -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 19:43:56 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 16:19:06 PST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 17:59:40 PST Date: 30 Jan 87 15:51 PST From: Gregor.pa@Xerox.COM Subject: Some other open issues To: Common-Lisp-Object-System@Sail.stanford.edu Message-ID: <870130-175940-103@Xerox> I believe we have to get the initialization stuff in the spec by RPG's deadline. We also need to haev time to talk about it, and fix the examples to use it, and document make-instance when the first argument is one of (STANDARD-METHOD STANDARD-GENERIC-FUNCTION STANDARD-CLASS), and to just think about it. I think this is more important than polishing method combination or class-precedence-list stuff. An issue which is less important, is a portable interface to the code walker so that people can make their own versions of with-slots. The last time we talked about this it became a big debate about how to write macros. This probably doesn't need to be done by RPG's deadline, but I wanted to remind us that it was something we said we would do.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 19:43:44 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 16:19:26 PST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 18:02:44 PST Date: 30 Jan 87 15:51 PST From: Gregor.pa@Xerox.COM Subject: Some other open issues To: Common-Lisp-Object-System@Sail.stanford.edu Message-ID: <870130-180244-104@Xerox> I believe we have to get the initialization stuff in the spec by RPG's deadline. We also need to haev time to talk about it, and fix the examples to use it, and document make-instance when the first argument is one of (STANDARD-METHOD STANDARD-GENERIC-FUNCTION STANDARD-CLASS), and to just think about it. I think this is more important than polishing method combination or class-precedence-list stuff. An issue which is less important, is a portable interface to the code walker so that people can make their own versions of with-slots. The last time we talked about this it became a big debate about how to write macros. This probably doesn't need to be done by RPG's deadline, but I wanted to remind us that it was something we said we would do.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 19:31:32 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 16:16:21 PST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 15:39:07 PST Date: 30 Jan 87 15:38 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Minor things noticed while proofreading documents In-reply-to: David A. Moon 's message of Fri, 30 Jan 87 00:50 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870130-153907-143@Xerox> slot-spec syntax: did (slot-name initform) as a convenient abbreviation for (slot-name :initform initform) go away accidentally, or did we really decide to get rid of it? I don't remember discussing this. I thought this was still supposed to be there, but I don't care. :accessor-prefix, :reader-prefix: the document says that the argument to these can be a string, a symbol, or nil. My memory is that we got rid of the string and nil cases. True or false? We certainly agreed to flush strings. We need to be able to say that the slot-names themselves are used for the accessors. If (:accessor-prefix) is used for that, we do not need NIL. I vote for (:accessor-prefix) as the right way to say use the slot-names. The documentation for get-method says that the specializers argument is a list of parameter specializers. I proposed an alist format instead, to allow extensibility to specializing on keyword arguments in the future. I thought it was accepted. Was it rejected, or did the document just not get updated yet? This applies to make-method also. I thought we said one could extend the parameter specializers list by putting in &key and using an alist for those specializers later, and this way the user does not have to specify argument names. Should make-generic-function and make-method be flushed in favor of documenting particular sets of arguments to make-instance that perform those functions? I favor this. slot-names in the standard meta-objects should be used. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 19:26:09 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 16:18:00 PST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 17:14:26 PST Date: 30 Jan 87 15:51 PST From: Gregor.pa@Xerox.COM Subject: Some other open issues To: Common-Lisp-Object-System@Sail.stanford.edu Message-ID: <870130-171426-101@Xerox> I believe we have to get the initialization stuff in the spec by RPG's deadline. We also need to haev time to talk about it, and fix the examples to use it, and document make-instance when the first argument is one of (STANDARD-METHOD STANDARD-GENERIC-FUNCTION STANDARD-CLASS), and to just think about it. I think this is more important than polishing method combination or class-precedence-list stuff. An issue which is less important, is a portable interface to the code walker so that people can make their own versions of with-slots. The last time we talked about this it became a big debate about how to write macros. This probably doesn't need to be done by RPG's deadline, but I wanted to remind us that it was something we said we would do.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 19:24:19 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Feb 87 16:16:01 PST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 15:30:22 PST Date: 30 Jan 87 15:30 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Method Combination To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-system@SAIL.STANFORD.EDU Message-ID: <870130-153022-143@Xerox> Dave and I had a telephone conversation today to discuss the outstanding issues of define-method-combination (mostly because there were things I didn't understand). My understanding of the agreement we came to follows. Dave please comment if you think I have misrepresented any part. 1) Syntax of define-method-combination: (d-m-c name lambda-list method-group-specifiers doc/decl* form*) as is specified in current document. However, lambda-list is an internal lambda list used ONLY for parsing of extra parameters supplied to compute-effective-method. It does not include a name for the generic-function. The well-known-name "generic-function" is available for use within the define-method-combination forms. The argument list of compute-effective-method is (generic-function combination-name applicable-methods &optional params) define-method-combination implicitly defines a specialized method for compute-effective-method, using lambda-list as an internal lambda-list to destructure, bind and error check the params argument for compute-effective-method. (d-m-c name lam-list ((v1 v1-pat)(v2 v2-pat ..)...) . body) expands to approximately (defmethod ((generic-function standard-generic-function) (c-type (quote name)) applicable-methods &optional params) (declare (special generic-function)) ;; is this declaration right ((lambda lam-list (let ((methods-left applicable-methods) v1 v2 ...) (multiple-value-setq v1 methods-left (select-methods methods-left 'v1-pat ...)) (multiple-value-setq v2 methods-left (select-methods methods-left 'v2-pat ...)) ... (AND methods-left (method-combination-error...)) . body) params)) 2) Support of around methods We agreed that the make-method-call form made it easy enough to support :around methods, so no further syntax was needed. We agreed that we would use :operator :call-next-method in make-method-call as the way to indicate call-next-method combination. We will eliminate the :around keyword from make-method-call. 3) We disagreed whether the standard should have only one form of define-method-combination (danny thought Yes, dave No), but Dave agreed to put the short form second in the document, and to describe it mostly in terms of its expansion to the long form. Dave said he would think about renaming the short form, for example to define-simple-combination. 4) I agreed that Moon's rule for CPL, although not as easy to understand as I might like, captured the criteria I wanted to preserve for the class precedence list. I am happy to stop worrying about this problem.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 2 Feb 87 11:24:54 EST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 14:05:19 PST Return-Path: Received: from H.CS.CMU.EDU ([128.2.254.156]) by Xerox.COM ; 30 JAN 87 14:03:55 PST Date: 30 Jan 87 16:58 EST From: Rick.Busdiecker@h.cs.cmu.edu To: Gregor.pa@Xerox.COM (Gregor Kiczales) Cc: CommonLoops.PA@Xerox.COM Subject: optional args (again) Message-Id: <539042289/rfb@h.cs.cmu.edu> I think I just sent out a message that I had just started putting together. Sorry. Anyway, I understand why the required arguments must match, but not why the optional arguments must match as well. Will it be possible to specify the class of optional arguments in the future? Is it possible now? If it won't be possible, could someone give me an example of a case where it causes problems to have differing numbers of optional arguments for the same message? Rick  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 2 Feb 87 11:24:47 EST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 14:02:52 PST Return-Path: Received: from H.CS.CMU.EDU ([128.2.254.156]) by Xerox.COM ; 30 JAN 87 14:01:31 PST Date: 30 Jan 87 16:55 EST From: Rick.Busdiecker@h.cs.cmu.edu To: Gregor.pa@Xerox.COM Cc: CommonLoops.PA@Xerox.COM Subject: optional arguments Message-Id: <539042125/rfb@h.cs.cmu.edu> Date: 30 Jan 87 11:30 PST From: Gregor.pa@Xerox.COM Subject: Re: questions from JEIDA Object Oriented Programming WG 87 10:39:55 To: shochi.ishida@NTT-20.ARPA Oops I should have answered this message sooner. At present, we have observed the followings. baz-a... invalid(symbolics, Vaxlisp,kcl) 1(symbolics),10(kcl) bar-a... 10(symbolics,Vaxlisp,kcl) 1(symbolics),10(kcl) foo-a... 10(symbolics,Vaxlisp),1(kcl) 1(symbolics,kcl) The result you observed with ndefstruct and defstruct are all correct. ndefstruct with :class class does not define new accessor methods for inherited slots. You should stop using ndefstruct and start using defclass in your code and I think you will find this less confusing. PCL does not handle multi-methods when those arities are different. Right, every method on a generic function must have the same number of required, and optional arguments. In addition, the must all agree about whether &rest is accepted, and they must all accept the same keywords.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Feb 87 02:04:01 EST Received: from NAVAJO.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 1 Feb 87 22:57:34 PST Received: by navajo.stanford.edu; Sun, 1 Feb 87 22:56:38 PST Received: from bhopal.edsel.com by edsel.uucp (2.2/SMI-2.0) id AA04633; Sun, 1 Feb 87 22:36:57 pst Received: by bhopal.edsel.com (3.2/SMI-3.2) id AA04283; Sun, 1 Feb 87 22:40:28 PST Date: Sun, 1 Feb 87 22:40:28 PST From: edsel!bhopal!jonl@navajo.stanford.edu (Jon L White) Message-Id: <8702020640.AA04283@bhopal.edsel.com> To: navajo!common-lisp-object-system%SAIL.STANFORD.EDU@navajo.stanford.edu Subject: CPL anxieties Gabriels "green, animate turtles" diagram is super-simplification of the example I showed several people at the Boston meeting in Dec 1985; Danny had actually seen it earlier that year. The oversimplification was the joining of the superclasses at the second level; because of that, the depth-first **up to join** type algorithms will in fact become breadth first on it [which is the desired behaviour!]. A closer approximation to the troubling scenario is below, which has no super-class hierarchy drawn above the third level. Then Dick's commentary and criticisms apply exactly to it. That is, any algorithm which tries to preserve the property that "inherited methods are indistinguishable from present methods" will have to place at least some of the super-super-classes before one of the direct supers, and thus the resulting order will not be breadth-first. This example may be related to the problem of "shadowing methods", which hasn't yet been addressed, but which some people feel is important. (defclass Animate-things (. . . ) ()) ;has possibly many suprs (defclass Colored-things (. . . ) ()) ;has possibly many suprs also (defclass Turtles (Animate-things) ()) (defclass Green-things (Colored-things) ()) (defclass Green-turtles (Turtles Green-things) ()) . . . . Animate-things . blush-method = turn-pink . | . | Colored-things | noseup-method = become-haughty | | / \ Turtles Green-things noseup-method = pick-up-pen blush-method = turn-purple \ / \ / \ / | | Green-turtles I presume everyone can see the conflict which will arise if the two direct supers to Green-turtles don't directly follow the class itself. One way to view this situation is that Green-turtles is a contradictory class, because it would inherit, say, a blush-method from two distinct suprs -- from Green-things and from Animate-things. Another view is that the present methods of the direct suprs are "more important and shadow any "higher" up. A third view is that the user ought to be able to distinguish such situations in his program in a simple way. If you are of the first opinion, then a good question to ask yourself is "Why does the conflict go away when I merge the class Colored-things into the class Animate-things? Should it?" The basic problem is the rigidity and complexity of the CPL algorithm. In some (unlikely) choices of supers for Animate-things and for Colored-things, it may be that the CPL will fortuitously be (Green-turtles Turtles Green-things . . .) but if so, the user will probably have no way of understanding why. He will certainly complain that there is no comprehensible way to control the CPL algorithm when it produces an ordering with some random super-super ahead of one of the two direct supers. No easily-comprehensible way to control CPL means essentially no control over inheritance, which means, again, a "black box of unpredicibility, like Flavors". -- JonL -- [Regarding the impredicability of Flavors-type inheritance -- I know KDO fairly well know, and wouldn't accuse him of shallow understanding. If he had to tweak flavors classes in an unknowing way to get the desired behaviour out of them, it was because there was no reasonably comprehensible way to program the desired behaviour.]  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 1 Feb 87 17:18:27 EST Date: 01 Feb 87 1410 PST From: Dick Gabriel Subject: CPL Varia To: common-lisp-object-system@SAIL.STANFORD.EDU Given that Moon has agreed that the example (defclass c1 (top) ()) (defclass c2 (top) ()) (defclass c3 (top) ()) (defclass d1 (c1 c2) ()) (defclass d2 (c1 c3) ()) (defclass e1 (d1 d2) ()) producing the CPL (E1 D1 D2 C1 C3 C2 TOP) is ok, I am willing to accept it. I will make sure the writeup is reasonable. Moon's writes: ``Oh, right, this only happens if you add the extension that the local precedence order of a class can be a partial order rather than a total order. We have that in Flavors, and it comes in handy, but I'm not proposing to standardize on it at this time.'' I'm not sure what this means, but whether the local precedence order is partial or total the leftmost siblings must come first. Therefore no sibling to the right of a candidate can be a candidate. In CLOS the local precedence order is total on the class itself and its direct siblings. The union of the local precedence orders might be a partial ordering and it might be a total ordering. My example of green-turtles was completely bogus, so forget it. I still think, though, that people will still regard the CPL computation as a black box. The example at the start of this message shows that intuition isn't going to help much in all cases. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 1 Feb 87 00:31:47 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 31 Jan 87 21:26:44 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 59293; Sun 1-Feb-87 00:10:40 EST Date: Sun, 1 Feb 87 00:10 EST From: David A. Moon Subject: CPL etc To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 31 Jan 87 01:18 EST from Dick Gabriel Message-ID: <870201001041.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 30 Jan 87 2218 PST From: Dick Gabriel ....I have some questions about whether we think it is intuitive: (defclass c1 (top) ()) (defclass c2 (top) ()) (defclass c3 (top) ()) (defclass d1 (c1 c2) ()) (defclass d2 (c1 c3) ()) (defclass e1 (d1 d2) ()) At some point Danny mentioned that the ``right'' order for this is (E1 D1 D2 C1 C2 C3 TOP) The new algorithm (and New Flavors, I think) produces (E1 D1 D2 C1 C3 C2 TOP) There's no way to avoid breaking up the superclasses of either D1 or D2, so no order is going to be intuitive by Danny's rule of not breaking up superclasses (equivalently, hiding the implementation of a component class as a single class or a tree of superclasses). The new algorithm keeps D2 together and breaks up D1. The previous order breaks them both up. Not much difference in my opinion. Some people might have been confused by Moon's description. It read: ``When topological sort finds multiple candidates to go in next, choose the candidate that has a direct subclass rightmost in the class precedence list computed so far. ***If that subclass has more than one direct superclass among the candidates, take the superclass that is most specific according to the subclass's local precedence order.***'' The condition described in the sentence between the asterisks cannot happen, so you shouldn't try to understand it. Oh, right, this only happens if you add the extension that the local precedence order of a class can be a partial order rather than a total order. We have that in Flavors, and it comes in handy, but I'm not proposing to standardize on it at this time. I think that in worrying about the CPL we have to keep in mind that most people will operate under the following model: The direct superclasses mentioned in the DEFCLASS form and their relative order are important. The system will then provide some arbitrary total order, and the program will have to be massaged until it works - simply because no one can understand the algorithm. This is the model that KDO will have; KDO is no wimp. KDO is certainly not a wimp, but he is known for massaging things until they work instead of understanding them. Here is a simple example, which many of you have seen before.... ....the user's intuition might be reasonable. He sees that the Turtle noseup-method is good, and that the Green-animals blush method is good, so he inherits from both. But he has to mention Turtles and Green-animals in some order. If he mentions them in the above order, he gets the wrong blush-method; if he reverses them he gets the wrong noseup-method. I think you're mistaken. Animate-things is less specific than both turtles and green-animals, in your diagram, so there is no danger of getting the wrong method. In fact the order of the direct superclasses turtles and green-animals doesn't affect the applicable methods at all. In any event, what we are doing by defining the CPL computation as we are is to provide a mechanism for people to curse the standard. Is this based on the above mistaken example, or on other considerations?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Jan 87 23:58:50 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 31 Jan 87 20:54:00 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 59286; Sat 31-Jan-87 23:52:44 EST Date: Sat, 31 Jan 87 23:52 EST From: David A. Moon Subject: Moon/Bobrow phone conversation To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870131235241.2.MOON@EUPHRATES.SCRC.Symbolics.COM> I made some changes to define-method-combination that Danny Bobrow and I discussed on the phone. The generic-function is no longer in the lambda list, instead it's a wired-in variable name. The lambda-list is still present for expansion, but is () in standard method combination. The short form is described after the long form and the expansion into the long form is shown. compute-effective-method takes 4 arguments. :operator :call-next-method replaces :around t in make-method-call. The short form takes the operator as a keyword argument instead of a positional argument. I think we all agree on this compromise now. I didn't change :allocation :dynamic and :none. They're still in there, but not explained very well.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Jan 87 15:02:55 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 31 Jan 87 11:53:11 PST Received: from ti-csl by csnet-relay.csnet id ak20454; 31 Jan 87 14:16 EST Received: from dsg (juliett.ARPA) by tilde id AA16277; Fri, 30 Jan 87 14:06:06 cst Received: FROM Jenner BY dsg Via CHAOS-NET with CHAOS-MAIL; 30-Jan-87 14:05:34 Message-Id: <2748013225-902979@Jenner> Date: 30-Jan-87 11:00:25 From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET To: Gregor.pa@XEROX.COM Cc: Common-Lisp-Object-System@SU-AI.ARPA Subject: Re: symbols are not generic functions In-Reply-To: In-Reply-To: Msg of 29-Jan-87 19:13:00 from System Files Msg of 29-Jan-87 19 in reference to ensure-generic-function, Moon says: I don't completely understand. Suppose symbol-function of the symbol is already a generic function, but it is of a different class than the kind that you get by default, because someone is using generic-function meta-objects. Would ensure-generic-function accept that generic function, signal an error, or clobber it with a generic function of the default kind? Well, the short lazy answer is ensure-generic-function does whatever add-method was going to do. This function is giong to be used for get-method and remove-method, its behavior needs to be different for those because if there is no generic function fbound to the symbol, we can't create one. The long answer is we need to figure this out. 1. perhaps ensure-generic-function should take a second argument which would be the class of the generic function to make if there isn't one. 2. There is a part of the meta-object protocol which deals with whether or not is is permissible to change the class of a generic function, that part of the protocol should be called here when there is already a generic function but its the wrong class. I agree 3. Perhaps ensure-generic-function should take another argument which could be used to specify that if there is a function in the place, but its not a generic-function, it should become the default method for the new generic function. Also, does ensure-generic-function ever alter the symbol-function of a symbol, or is it just a side-effect free coercion? If the latter, it might be cleaner to use the existing COERCE function, thus (add-method (coerce 'generic-function) ). I am not sure about this given what I said above. I think this is a summary of what we can encounter: Fboundp = nil: (error) | (fdefine symbol (make-instance desired-type)) | (make-instance desired-type) = t: generic-function-p = nil: (error) | (replace-without-default (make-instance desired-type)) |(make-instance desired-type) | (replace-with-default (make-instance desired-type)) |(add-method (make-instance desired-type) .... old-function) = t: (subtypep generic-function-type desired-type) = t: generic-function = nil: (error) |(change-class) |(make-instance desired-type) To cover all the cases, we could have an arglist like this: ensure-generic-function function-name &optional generic-function-type &key :error-if-not-fboundp :error-if-not-generic :error-if-not-subtypep :side-effect-p If side-effect-p is nil, the old function-object is not changed and left in the symbol-function slot of the symbol. If side-effect-p is true, the old function-object is changed. If one has to be created, it is put in the symbol-function of the symbol. It would be useful for the function to return a second values to tell if the symbol-function was returned, changed or if a new generic-function was created. (Like INTERN). Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Jan 87 12:30:27 EST Date: 31 Jan 87 0923 PST From: Dick Gabriel Subject: Common Lisp Types To: common-lisp-object-system@SAIL.STANFORD.EDU I bring up once more the question of classes for Common Lisp types. In particular, the current Design Rationale chapter says there are no classes for these things: `` - Types too specific to be useful to put methods on: bit, keyword, standard-char, string-char - The type implies an implementation, not behavior: bignum, fixnum, simple-array, simple-bit-vector, simple-string, simple-vector - Specification of the type is too vague: common, function, stream - This is the same as (not cons), and we are not yet dealing with not: atom - No object can be an instance of this type: nil'' I propose that we not judge what is too specific to be useful to put methods on. I can imagine system programmers thinking standard-char and string-char are reasonable. I think implementation as a distinguishing characteristic for a class is perfectly reasonable. I think we must try to treat functions well, and that streams are necessary. I agree that NOT classes should not be included. So I propose that every implementation be required to provide the classes explicitly excluded in the design rationale except for negation classes (atom) and Common, though there may be no instances of them, and I presume we can arrange for the metaclass to state that fact. Furthermore, I propose that the structure of the lattice in the vicinity of implementation-dependent types be variable, reflecting the implementation hierarchy. For example, if an implementation has single-floats only, the classes would be: (defclass short-float (single-float)) (defclass long-float (single-float)) (defclass double-float (single-float)) (defclass single-float (float)) and only single-float would have instances. The other permissible float configurations have different topology. For functions, I propose that the Class Function include as instances those objects in the Lisp that are in the range of the function Function. For many implementations this will coincide with Compiled-Function, which would be a subclass of Function. This means that CLOS adopts the attitude that symbols and lists that happen to represent functions are the second-class version of functions. I propose that the class named NIL be at the bottom of the lattice and that it also has no instances. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Jan 87 01:27:18 EST Date: 30 Jan 87 2218 PST From: Dick Gabriel Subject: CPL etc To: common-lisp-object-system@SAIL.STANFORD.EDU After a day of meetings I was finally able to get back to our favorite topic. Moon's tiebreaker variant admits a linear implementation, which is pretty good. I have some questions about whether we think it is intuitive: (defclass c1 (top) ()) (defclass c2 (top) ()) (defclass c3 (top) ()) (defclass d1 (c1 c2) ()) (defclass d2 (c1 c3) ()) (defclass e1 (d1 d2) ()) At some point Danny mentioned that the ``right'' order for this is (E1 D1 D2 C1 C2 C3 TOP) The new algorithm (and New Flavors, I think) produces (E1 D1 D2 C1 C3 C2 TOP) Is this less intuitive? More later. Some people might have been confused by Moon's description. It read: ``When topological sort finds multiple candidates to go in next, choose the candidate that has a direct subclass rightmost in the class precedence list computed so far. ***If that subclass has more than one direct superclass among the candidates, take the superclass that is most specific according to the subclass's local precedence order.***'' The condition described in the sentence between the asterisks cannot happen, so you shouldn't try to understand it. A candidate for entering the final CPL has no predecessors, which means that all of its siblings to the left have already been placed in the CPL, and so none of them can be candidates to go next. I think that in worrying about the CPL we have to keep in mind that most people will operate under the following model: The direct superclasses mentioned in the DEFCLASS form and their relative order are important. The system will then provide some arbitrary total order, and the program will have to be massaged until it works - simply because no one can understand the algorithm. This is the model that KDO will have; KDO is no wimp. Many people will wish they can simply supply their own ordering algorithm. Here is a simple example, which many of you have seen before. There are 4 classes, perhaps poorly chosen: Animate-things blush-method = turn-pink noseup-method = become-haughty | | / \ / \ / \ Turtles Green-animals noseup-method = pick-up-pen blush-method = turn-purple \ / \ / \ / | | Green-turtles Animate-things has two methods, blush-method and noseup-method. The effect of the blush-method is to change colors and the effect of the noseup-method is to change the attitude of the object to haughtiness. The first subclass is Turtles, like LOGO turtles. The noseup-method shadows the animate-things method, and the effect of it is to pick up the pen; the blush-method is ok. The second subclass is Green-animals, and the blush-method is different, because when a green thing turns pink, it really turns purple. The final class is Green-turtles. This might be a dumb thing to do, but the user's intuition might be reasonable. He sees that the Turtle noseup-method is good, and that the Green-animals blush method is good, so he inherits from both. But he has to mention Turtles and Green-animals in some order. If he mentions them in the above order, he gets the wrong blush-method; if he reverses them he gets the wrong noseup-method. The solution is to reformulate the classes into more parts with hairy relationships. A similar problem can happen when a user wants to inherit slots. One can imagine an asymptotic situation where each DEFCLASS has exactly one slot and you build your classes by the shopping cart method. The user of the above class lattice believes that the CPL will reflect a breadth-first CPL. The depth-first nature of all CPL computations so far reflects a desire for ``transparency'' of subclass-superclass inheritance. Perhaps we need to have a notation for inheriting from a set of superclasses in no partocular order, which would signal the CPL computation to go breadth-first. Maybe another partial solution is some means of having generic functions be able to distinguish instances of ``this very class'' rather than instances of this very class or of its subclasses. In any event, what we are doing by defining the CPL computation as we are is to provide a mechanism for people to curse the standard. Perhaps it is necessary to have such a well-defined default, but maybe we should think about a variety of alternatives from which the user can select as well as an alternative to roll your own. -rpg-  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 30 Jan 87 15:00:20 EST Received: from Cabernet.ms by ArpaGateway.ms ; 30 JAN 87 11:35:01 PST Date: 30 Jan 87 11:30 PST From: Gregor.pa@Xerox.COM Subject: Re: questions from JEIDA Object Oriented Programming WG In-reply-to: toru 's message of Wed, 21 Jan 87 10:39:55 To: shochi.ishida@NTT-20.ARPA cc: commonloops.pa@Xerox.COM, ida%todai%NTTLAB.NTT@NTT-20.ARPA Message-ID: <870130-113501-1083@Xerox> Oops I should have answered this message sooner. At present, we have observed the followings. baz-a... invalid(symbolics, Vaxlisp,kcl) 1(symbolics),10(kcl) bar-a... 10(symbolics,Vaxlisp,kcl) 1(symbolics),10(kcl) foo-a... 10(symbolics,Vaxlisp),1(kcl) 1(symbolics,kcl) The result you observed with ndefstruct and defstruct are all correct. ndefstruct with :class class does not define new accessor methods for inherited slots. You should stop using ndefstruct and start using defclass in your code and I think you will find this less confusing. PCL does not handle multi-methods when those arities are different. Right, every method on a generic function must have the same number of required, and optional arguments. In addition, the must all agree about whether &rest is accepted, and they must all accept the same keywords.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Jan 87 00:58:27 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Jan 87 21:51:28 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 58055; Fri 30-Jan-87 00:50:30 EST Date: Fri, 30 Jan 87 00:50 EST From: David A. Moon Subject: Minor things noticed while proofreading documents To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870130005009.5.MOON@EUPHRATES.SCRC.Symbolics.COM> slot-spec syntax: did (slot-name initform) as a convenient abbreviation for (slot-name :initform initform) go away accidentally, or did we really decide to get rid of it? I don't remember discussing this. :accessor-prefix, :reader-prefix: the document says that the argument to these can be a string, a symbol, or nil. My memory is that we got rid of the string and nil cases. True or false? The documentation for get-method says that the specializers argument is a list of parameter specializers. I proposed an alist format instead, to allow extensibility to specializing on keyword arguments in the future. I thought it was accepted. Was it rejected, or did the document just not get updated yet? This applies to make-method also. Should make-generic-function and make-method be flushed in favor of documenting particular sets of arguments to make-instance that perform those functions?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 23:10:47 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Jan 87 20:00:25 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 58015; Thu 29-Jan-87 22:59:23 EST Date: Thu, 29 Jan 87 22:58 EST From: David A. Moon Subject: Gregor's comments on some things To: Common-Lisp-Object-System@Sail.Stanford.edu In-Reply-To: <870129-151241-1183@Xerox> Message-ID: <870129225845.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 29 Jan 87 15:12 PST From: Gregor.pa@Xerox.COM I am amenable to making methods not be funcallable in the way that generic-functions are. OK. Let me take this opportunity to repeat that I am not amenable to allowing the method function of a method not be FUNCALLable with the "natural" arguments. I am fairly certain Danny agrees with me on this issue. I think this is something we need to talk about the next time we get together. I believe that we can show "meta-objecty" programs which may it clear what a pain this would be. Let's plan to talk about this in person, then. --- I believe the simplest way to rephrase the much maligned (and deservedly) phrase "the classes at or above C" is "C and all of its superclasses", or perhaps just "C and its superclasses". That's a good idea. I put it into the document, since I was editing that part. --- What does the phrase "x is of class array mean"? In the first paragraph of the section Integrating Types and Classes in Concepts (draft of 1/23) it is used to mean "x is of class array or some subclass of array"? Is that official? I think so. I believe "X is of class Y" and "X is an instance of Y" mean that (class-of X) is Y or a subclass of Y, rather than (eq (class-of X) Y). -- Args to get-method and make-instance of 'method More along the lines of names not being the same ast the "objects they name", I would like to change get-method and the specializers of a method to be either (QUOTE ) or a class OBJECT. That means that instead of saying: (get-method #'print-object () '(symbol t)) you would say: (get-method #'print-object () (list (class-named 'symbol) (class-named 't))) or use mapcar or something. Admitedly this is somewhat longer, but I believe it is clearer, it keeps to the abstraction that "names are supported by things which start with DEF", but below that level of abstraction we deal with class and generic function objects. This allows programming with anonymous classes and generic functions to be clean since names are not tied in at the low-level of the system. Well, it's pretty weird that symbols are turned into class objects but QUOTE-expressions are not. This doesn't generalize very well to the extension to supporting other Common Lisp type specifiers. Otherwise I have no objection to the proposal, so if you can supply a brief design rationale for doing it that way to go into the document I'm amenable. Of course it makes get-method and related functions useless until we put in the supporting functions such as class-named. Is there any reason that these aren't documented already? That is, are there any outstanding issues on these, or is it only a matter of writing the information down and putting TEX commands into it? Do you Gregor, or anyone else, have a list of these missing functions? I'm not talking about the full meta-object protocol, just the functions needed to program at the next level of abstraction below the defxxx macros. --- Here is my proposal for slot inheritance rules.... I think this is the same as what Sonya and I worked out in the latest version of the document. When you get that document, please read the slot inheritance description and see if you think it says what you want and is clear. If you have trouble retrieving the document from SU-AI we can mail you the TEX source of that part. --- In introduction to generic functions, (also concepts of 1/23), the paragraph (with a bullet) which reads: Generic functions are named precisely as ordinary functions. When a generic functions is associated with a symbol, that name is in a certain package and can be exported... just confuses the issue. The point is that (unfortunately) packages talke about symbols, not definitions or bindings. Symbols can always be exported. I think the point you are really try to make is just that - generic functions are function objects, - the same rules apply as to all other function objects, - as with other function objects, they are often stored in the function cell of a symbol (with defmethod etc.), I think this is the same as what Sonya and I worked out in the latest version of the document. Maybe your bulleted list is a clearer way of saying it though; we'll check on this.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 22:33:59 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Jan 87 19:29:37 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 57970; Thu 29-Jan-87 22:19:56 EST Date: Thu, 29 Jan 87 22:19 EST From: David A. Moon Subject: CPL Tiebreaker To: Common-Lisp-Object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 29 Jan 87 05:06 EST from Dick Gabriel Message-ID: <870129221938.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 29 Jan 87 0206 PST From: Dick Gabriel I think I found the tiebreaker.... ....is based on this reasoning by Danny (I'll paraphrase): ``If the user has a class and splits that class into two classes with no other references to the direct superclass, there should be no chance of any interaction with any other class used as a mixin. Hence one wants all superclasses of a class to follow as soon as possible after the class they are related to.'' I agree. This is very intuitive, and preorder treewalk is very intuitive. So we do Danny's condition first and then preorder treewalk. Danny's condition means this: We define a relation called unique direct subclass. C is the unique direct subclass of D if C is the only direct subclass of D. If class X was just output and X is a unique direct subclass of some class D, D immediately follows X. Otherwise, ties are broken by preorder treewalk (not last-visited). I don't think this really makes it, although it comes quite close and has very much the character of what I've been looking for. One problem is that a class with two direct subclasses shouldn't really be treated completely differently from a class with one direct subclass. A worse problem is multiple superclasses: a single class X can have two direct superclasses Y and Z, where X is a unique direct subclass of both Y and Z. Y and Z can't both go immediately after X, and furthermore when you put in Y you can get direct superclasses of Y, which must go either before or after Z. When I tried this algorithm it soon foundered on those problems, but it did stimulate me to think of another algorithm: When topological sort finds multiple candidates to go in next, choose the candidate that has a direct subclass rightmost in the class precedence list computed so far. If that subclass has more than one direct superclass among the candidates, take the superclass that is most specific according to the subclass's local precedence order. In more technical language, let {N1,...,Nm} be the candidates to go in next and {C1,...,Cn} be the class precedence list constructed so far; C1 is the starting class and is most specific, Cn is least specific. m>=2, n>=1. For i from n down to 1, let {S1,...,Sk} be the direct superclasses of Ci, k>=1, then for j from 1 up to k, if Sj is an element of {N1,...,Nm}, set Cn+1 = Sj and proceed with the topological sort. This algorithm does a good job of keeping related classes together. I like this algorithm and I think we should adopt it. I added the above paragraph to the document version that Sonya just finished editing; it's on SU-AI now and we will be proofreading it tomorrow. My trial implementation of this algorithm is extremely stupid, involving three nested loops and no optimization whatever, yet is not perceptibly slower than any of the others I've been trying, which surprised me. I'm sure an algorithm wizard could write it much better. I've tried this against all the flavors that happened to be defined in my machine and it produces the same result except in the cases where the flavors algorithm is broken. I plan to try it on some other Flavors programs later. In the relatively simple cases (such as the ones I deleted out of the message I'm replying to) this produces the same answer as the previous Gabriel algorithm and the Bobrow algorithm.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 20:41:13 EST Date: 29 Jan 87 1652 PST From: Dick Gabriel Subject: The Real Deadline To: common-lisp-object-system@SAIL.STANFORD.EDU CC: mathis@A.ISI.EDU In order to get the documents out in time for people to prepare for the Palo Alto meeting, I have set the following hard, non-negotiable deadlines: 1. The last technical changes have to be done to both files (CONCEPTS and FUNCTIONS) by midnight, Sunday February 8. At that point I am putting the documents into my technical writing staff maw to check for blatant problems. 2. I will federal express the final documents to Bob Mathis on Friday, February 13. 3. I think this means that Sonya can have the files until Monday, February 2. I think that unless there is a draft of the metaobject stuff by Friday, February 6, we must decide how to proceed - I see the most likely option being to flush metaobjects altogether until a later date. In Gregor's examples there were several functions used that are not specified. I suggest people search their expectations of what should be there and compare them to what actually is there, because on February 9 they cannot be added in this draft - we will look very silly, indeed. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 20:20:38 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 29 Jan 87 17:08:57 PST Received: from Cabernet.ms by ArpaGateway.ms ; 29 JAN 87 15:12:41 PST Date: 29 Jan 87 15:12 PST From: Gregor.pa@Xerox.COM Subject: My comments on some things To: Common-Lisp-Object-System@Sail.Stanford.edu cc: Gregor.pa@Xerox.COM Message-ID: <870129-151241-1183@Xerox> I am amenable to making methods not be funcallable in the way that generic-functions are. Let me take this opportunity to repeat that I am not amenable to allowing the method function of a method not be FUNCALLable with the "natural" arguments. I am fairly certain Danny agrees with me on this issue. I think this is something we need to talk about the next time we get together. I believe that we can show "meta-objecty" programs which may it clear what a pain this would be. --- I believe the simplest way to rephrase the much maligned (and deservedly) phrase "the classes at or above C" is "C and all of its superclasses", or perhaps just "C and its superclasses". --- What does the phrase "x is of class array mean"? In the first paragraph of the section Integrating Types and Classes in Concepts (draft of 1/23) it is used to mean "x is of class array or some subclass of array"? Is that official? -- Args to get-method and make-instance of 'method More along the lines of names not being the same ast the "objects they name", I would like to change get-method and the specializers of a method to be either (QUOTE ) or a class OBJECT. That means that instead of saying: (get-method #'print-object () '(symbol t)) you would say: (get-method #'print-object () (list (class-named 'symbol) (class-named 't))) or use mapcar or something. Admitedly this is somewhat longer, but I believe it is clearer, it keeps to the abstraction that "names are supported by things which start with DEF", but below that level of abstraction we deal with class and generic function objects. This allows programming with anonymous classes and generic functions to be clean since names are not tied in at the low-level of the system. --- Slot inheritance rules. Here is my proposal for slot inheritance rules. It isn't in english, it more of a FSM, but I believe its clear, and if we all agree then it can be put in english. First, what are the default values for the various slot options: :initform defaults to unsupplied, what this means exactly will become clear :type defaults to T :allocation defaults to :instance Now, how are the slot descriptions from all the different defclasses where a slot of a particular name appears merged. First, get the slot descriptions in class-precedence-list order. Then, merge the individual options as follows. :initform, take the most specific :initform which is supplied, or take unsupplied if :initform is not specified in any of the slot descriptions :type The total type is and of all the types specified. :allocation the allocation of the most specific slot. Note that this rule, means that you can't change the default value of a :class variable which you inherited, this is a feature, not a bug, it makes the rules simpler too. Some examples: (defclass foo () ((a :initform 1))) (defclass bar (foo) ((a :initform 2 :type integer))) (defclass baz (bar) ((a :initform 3))) BAZ's effective description for A is: (A :initform 3 :type (and t integer t) :allocation :instance) (defclass foo () ((a :initform 'george)) (defclass bar (foo) ((a :type symbol))) BAR's effective description for A is: (A :initform 'george :type (and t symbol) :allocation :instance) (defclass foo () ((a :allocation :class :initform ())) (defclass bar (foo) ((a :initform *a-default*))) BAR's effective description for A is: (A :initform *a-default* :type (and t t) :allocation :instance) Note that instances of FOO have access to a class variable of the class FOO named A. Instance of BAR each have their own variable named A. --- In introduction to generic functions, (also concepts of 1/23), the paragraph (with a bullet) which reads: Generic functions are named precisely as ordinary functions. When a generic functions is associated with a symbol, that name is in a certain package and can be exported... just confuses the issue. The point is that (unfortunately) packages talke about symbols, not definitions or bindings. Symbols can always be exported. I think the point you are really try to make is just that - generic functions are function objects, - the same rules apply as to all other function objects, - as with other function objects, they are often stored in the function cell of a symbol (with defmethod etc.),  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 20:19:56 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 29 Jan 87 17:09:24 PST Received: from Cabernet.ms by ArpaGateway.ms ; 29 JAN 87 15:59:40 PST Date: 29 Jan 87 15:59 PST From: Gregor.pa@Xerox.COM Subject: Re: Progress is Our Most Important Problem -- Method Combination In-reply-to: Dick Gabriel 's message of 28 Jan 87 19:32 PST To: RPG@SAIL.STANFORD.EDU cc: Bobrow.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870129-155940-1249@Xerox> As for all this fuss about method combination, I have to ask, what do you suppose will be the ratio of define-method-combinations to defmethods in Common Lisp code? 1/1000? 1/10000? 1/100000? Because actual define-method-combination forms are so rare, but interaction with method combination is so common, I think the most important thing about method combination is the abstraction. People need to be able to understand how method combination works a lot more often than they need to be able to type a define-method-combination. I think that a lot of progress has been made in improving the abstraction, and I think thats real good. I believe that both define-method-combination proposals on the table are terribly over-engineered. They have convenience mechanisms and bells and whistles that are not appropriate for such a rarely used form. Including two different versions of define-method-combination is an excellent example of this kind of over-engineering. Because of these beliefs, I prefer Danny's proposal to Moon's just because it is simpler.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 20:18:14 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 29 Jan 87 17:09:35 PST Received: from Cabernet.ms by ArpaGateway.ms ; 29 JAN 87 16:05:48 PST Date: 29 Jan 87 16:05 PST From: Gregor.pa@Xerox.COM Subject: Re: symbols are not generic functions In-reply-to: David A. Moon 's message of Tue, 27 Jan 87 23:05 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@Sail.Stanford.edu Message-ID: <870129-160548-1259@Xerox> in reference to ensure-generic-function, Moon says: I don't completely understand. Suppose symbol-function of the symbol is already a generic function, but it is of a different class than the kind that you get by default, because someone is using generic-function meta-objects. Would ensure-generic-function accept that generic function, signal an error, or clobber it with a generic function of the default kind? Well, the short lazy answer is ensure-generic-function does whatever add-method was going to do. The long answer is we need to figure this out. 1. perhaps ensure-generic-function should take a second argument which would be the class of the generic function to make if there isn't one. 2. There is a part of the meta-object protocol which deals with whether or not is is permissible to change the class of a generic function, that part of the protocol should be called here when there is already a generic function but its the wrong class. 3. Perhaps ensure-generic-function should take another argument which could be used to specify that if there is a function in the place, but its not a generic-function, it should become the default method for the new generic function. Also, does ensure-generic-function ever alter the symbol-function of a symbol, or is it just a side-effect free coercion? If the latter, it might be cleaner to use the existing COERCE function, thus (add-method (coerce 'generic-function) ). I am not sure about this given what I said above.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 20:14:52 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 29 Jan 87 17:07:10 PST Received: from ti-csl by csnet-relay.csnet id ab02015; 29 Jan 87 19:18 EST Received: from dsg (juliett.ARPA) by tilde id AA13743; Thu, 29 Jan 87 17:04:44 cst Received: FROM Jenner BY dsg Via CHAOS-NET with CHAOS-MAIL; 29-Jan-87 16:52:31 Message-Id: <2747948035-1026455@Jenner> Sender: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET Date: 29-Jan-87 16:53:55 From: "Patrick H Dussud %Jenner%ti-csl.csnet"@RELAY.CS.NET To: Danny Bobrow Cc: common-lisp-object-system@SU-AI.ARPA, DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET Subject: Re: Method Combination In-Reply-To: In-Reply-To: Msg of 28-Jan-87 15:40:00 from Danny Bobrow Msg of 28-Jan-87 15 Date: 28-Jan-87 15:40:00 From: Danny Bobrow Date: 27 Jan 87 17:39:46 From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET I agree with the fact than one can define ones own compute-effective-method. The issue has to do with modularity. Compute-effective-method has to find the list of all the method that can be called, find the method combination method, call it to come up with the code for the effective method. We need to keep those operations as independent as possible. If we supply the information as an argument to the method combinator, the user writing a method combination method does not have to worry about how the information was obtained. I agree that finding the list of all the methods that can be called, finding the way to combine methods, and coming up with the code for the combination ought to be kept separate. The following describes my view of the meta-object protocol, and how these are kept separate. The meta-object protocol for building the code for generic functions consists of two parts. The top level is (compute-discriminator-code generic-function) which has as its responsibility building the code that implements the effect of the described four step protocol for calling a method. Its usual implementation caches all the possibly different effective methods for the generic-function, and it produces code to decide which of these effective methods to call for any set of arguments. It is this code that is run when the generic-function is called. The only information compute-discriminator-code can use must be contained in the generic-function object. THERE IS NO OTHER PLACE TO STORE INFORMATION. I don't have problem with this, the problem is how you access it. (See below). As a standard part of the protocol for compute-discriminator-code (which can be overwritten by a specialized method), compute-discriminator-code computes the set of applicable-methods for distinguishable sets of arguments, and for that set calls: (compute-effective-method generic-function combination-type applicable-methods) The combination-type is taken from the generic-function to allow discrimination on an individual (the combination type) to select a specialized method. Other paramaterized information could have been passed in as arguments, but since that information is not being used for discrimination, it might as well be left in the generic function. Ah, this is interesting. The combination type is "taken" from the generic function by compute-effective-method, which might need the sets of arguments you talked about earlier. But then, if you don't pass somehow (arguments, special variable .....) all the information relevant to this combination type, then the user has to "take" it again from the define-combined-method code. This is not the business of the method combination method to know how to "take" it from the generic function. If you wonder why we would have to use the set of arguments to compute the method combination type, you can (re)read my mail about method combination selection that David mentioned in his last message. I don't have time to comment on the rest of the message today. I'll hold off until you have something more concrete on the metaclass protocol since this is what it is all about. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 17:09:42 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Jan 87 13:58:29 PST Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 57520; Thu 29-Jan-87 16:57:05 EST Date: Thu, 29 Jan 87 16:57 EST From: Sonya E. Keene Subject: changes made to documentation To: common-lisp-object-system@sail.stanford.edu Message-ID: <870129165700.9.SKEENE@JUNCO.SCRC.Symbolics.COM> I just wrote new versions of the functions and concepts files. The major changes I made include: Concepts: - Simplified "Defining a Class" - Added section "Redefining a Class" - Rewrote Inheritance of Slots Functions: - Fixed description of arguments to DOCUMENTATION - Made the syntax of options in DEFCLASS stand out better in the description of each option - Fleshed out DEFINE-METHOD-COMBINATION to include a description of each option. Note that these are just one-liners, and the full syntax is still in the Concepts chapter, as are the examples. I think this is the best way we can describe this function. - Rewrote CHANGE-CLASS according to latest proposal - Added description of CLASS-CHANGED - Added several See Also fields. For example, you wanted to discuss "compatibility - Fleshed out the Introduction to mention what role each function and macro plays -- that is, I put them into categories. This should help people put the functions into a context. People at Symbolics who read the drafts of this were put off by the alphabetic (contextless) order of functions, so this should solve that problem. --------------- I also made the changes suggested in Moon's message.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 13:54:38 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 29 Jan 87 10:47:36 PST Received: from Salvador.ms by ArpaGateway.ms ; 29 JAN 87 09:46:31 PST Date: 29 Jan 87 09:11 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Last-Visited Preorder In-reply-to: Dick Gabriel 's message of 28 Jan 87 19:22 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870129-094631-1108@Xerox> If we decide the last-visited preorder is what we want for a tiebreaker, then there is a simple linear way to compute it without having to wonder whether reversed reversed postorder is the same as last-visited preorder. For every class you keep track of the in-degree with respect to the sublattice of interest; the in-degree is the number of direct subclasses of a class. When you walk from the class of interest, you keep track of how many times you've visited that class. When you have visited it the same number of times as its in-degree, you can walk from that class. The exception is the class of interest, which you will visit once more than its in-degree (you visit it once and its in-degree is 0). There is a very simple double recursive program that does the same thing without keeping track of in-degrees. (DEFUN LAST-VISIT-ORDER (LAMBDA (C) (LV1 C NIL)) (DEFUN LV1 (C L) (IF (MEMQ C L) L (LET ((S (DIRECT-SUPERS C))) (PUSHNEW C (IF (NULL S) L (LV2 S L))))) (DEFUN LV2 (S L) (LV1 (CAR S) (IF (NULL (CDR S)) L (LV2 (CDR S) L)))) danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 13:54:32 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 29 Jan 87 10:48:04 PST Received: from Salvador.ms by ArpaGateway.ms ; 29 JAN 87 09:46:59 PST Date: 29 Jan 87 09:38 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Progress is Our Most Important Problem In-reply-to: Dick Gabriel 's message of 28 Jan 87 19:32 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870129-094659-1114@Xerox> 1. We are still arguing over CPL computation. When I asked Ken Olum to tell me what he thought about the possible algorithms for it he said he simply tried things in New Flavors until they worked. He said a good model is that there is some sort of algorithm and you don't try to understand it. Then he ran out of the room. Now that I've beaten everyone's brains out on the issue, I think we can happily settle on topological sort with last-visited preorder as the tiebreaker. The differences are now so small I don't care between B-K and this. I think explainability is paramount. I think my algorithm is explainable simply (e.g. as a local constraint satisfaction algorithm that modifies last-visited tree walk). It does not refer to Knuth though, which has status. 2. I'm inclined to go with Moon's method combination for now, though some of Danny's simplifications are attractive. I really don't want to see two define-method-combination forms. Do you say this because you are tired and don't want to think (argue) through the issues on this, or what? I would like to see Moon's comments on my latest suggestions. As I said, the only real issue is the lambda-list. I don't really care if we have documentation/declarations in the defmacro way, and don't mind seeing as Moon proposed: (1) Make it a method-group keyword option. Thus you say ((around (:around) :call-next-method t) ...other method groups...) What happens if other method-groups have :call-next-method t We could abbreviate the above as in. ((:around t) ... other method groups...) thus assuring it can appear only once in the list, implicitly with :around as the group specifier. It is really short, so users will probably do it, and get it right. However this mixes syntax for specifiers (ugh). Let us argue through lambda-list, have a single define-method-combination and I will edit the rest into the consensus. 3. I don't care about the change-class protocol as long as it works. We seem to have agreement here. 4. I'd like to flush :allocation :dynamic and :allocation :none. If people want :allocation :none, then the inheritance writeup needs work. (Sonya?) I still think both are useful, but the one I have had lots of experience with is :dynamic. I want to keep :dynamic that even if :none goes away. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 10:07:39 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Jan 87 07:01:48 PST Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 56895; Thu 29-Jan-87 09:32:52 EST Date: Thu, 29 Jan 87 09:32 EST From: Sonya E. Keene Subject: Progress is Our Most Important Problem To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 28 Jan 87 22:32 EST from Dick Gabriel Message-ID: <870129093246.4.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: 28 Jan 87 1932 PST From: Dick Gabriel Wasn't that GE's slogan? According to my calculations, we have 3 days left before the document must be ready. I see a number of problems. 1. We are still arguing over CPL computation. When I asked Ken Olum to tell me what he thought about the possible algorithms for it he said he simply tried things in New Flavors until they worked. He said a good model is that there is some sort of algorithm and you don't try to understand it. Then he ran out of the room. Now that I've beaten everyone's brains out on the issue, I think we can happily settle on topological sort with last-visited preorder as the tiebreaker. 2. I'm inclined to go with Moon's method combination for now, though some of Danny's simplifications are attractive. I guess Danny and Gregor are really opposed to the short form of DEFINE-METHOD-COMBINATION. Although I support the high-level goal of keeping the standard lean, I disagree with this particular point. The short form is easy to use, easy to document, and easy to understand. It reduces the need for almost-duplication of code (when defining more than one simple type of method combination). And most of the forms of method combination that we've seen people need and use can be defined that way. 3. I don't care about the change-class protocol as long as it works. I'm adding this to the document right now. 4. I'd like to flush :allocation :dynamic and :allocation :none. If people want :allocation :none, then the inheritance writeup needs work. (Sonya?) I've already rewritten the inheritance section according to suggestions from Moon which you've seen, and comments from some people here. At present, the document goes on the assumption that both :dynamic and :none are still there. I'd also like to flush them, though. I believe the consensus of our in-house reviewers was the same. To me, :dynamic doesn't add anything valuable to the programmer, and :none introduces a lot of complexity and muddies up the model without adding much value. I think we really have until Feb 14 to get this all done, but is there some way I can add to your desires to work hard on this and get it done? My personal desire to work hard on this and get it done is already strong. I should be finished with adding the CHANGE-CLASS protocol and moving some of the DEFINE-METHOD-COMBINATION writeup into the functions chapter by today or tomorrow. I agree with you that getting Problems 1, 2, and 4 settled as soon as possible is the way to go. Number 3 isn't a problem, is it? I had the impression that the mail reached consensus, and it's just a matter of documenting it, which is almost done now anyway. Why do you think we have until Feb 14? -rpg- I'd like to bring up one other point. Right now, only the Concepts and Functions chapters have any real meat in them. I assume everyone agrees that only those two chapters will be distributed in the March meeting. The cover letter should mention that we will continue to work on specifying the remainder of the Programmer Interface, and the Meta-object Protocol.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 05:33:29 EST Date: 29 Jan 87 0206 PST From: Dick Gabriel Subject: CPL Tiebreaker To: Common-Lisp-Object-system@SAIL.STANFORD.EDU Ugh, bletch. I think I am really going to regret having written this message. I think I found the tiebreaker. It passes all of the hard intuitive cases, which I'll list below, along with all of the cases ever mailed out. The tiebreaker applies when there is more than one class with no predecessors. The tiebreaker has two cases. The first case is based on this reasoning by Danny (I'll paraphrase): ``If the user has a class and splits that class into two classes with no other references to the direct superclass, there should be no chance of any interaction with any other class used as a mixin. Hence one wants all superclasses of a class to follow as soon as possible after the class they are related to.'' This is very intuitive, and preorder treewalk is very intuitive. So we do Danny's condition first and then preorder treewalk. Danny's condition means this: We define a relation called unique direct subclass. C is the unique direct subclass of D if C is the only direct subclass of D. If class X was just output and X is a unique direct subclass of some class D, D immediately follows X. Otherwise, ties are broken by preorder treewalk (not last-visited). This means that we treat parts of the lattice that look like this: \|/ D | C /|\ as if they looked like this: \|/ (D,C) /|\ [Actually, the above picture is exactly how I looked when I discovered this tiebreaker.] Here are the hard cases: (DEFCLASS A (B C D E F) ()) (DEFCLASS B (F X) ()) (DEFCLASS C (F Y) ()) (DEFCLASS D (F X) ()) (DEFCLASS E () ()) (DEFCLASS F () ()) (DEFCLASS X () ()) (DEFCLASS Y () ()) (topologically-sort 'a) = (A B C D E F X Y) Well, this is simply preorder treewalk at work. (DEFCLASS PTEST1 (PTEST2 PTEST3 PTEST5) ()) (DEFCLASS PTEST2 (PTEST5) ()) (DEFCLASS PTEST3 (PTEST4) ()) (DEFCLASS PTEST4 () ()) (DEFCLASS PTEST5 () ()) (topologically-sort 'ptest1) = (PTEST1 PTEST2 PTEST3 PTEST4 PTEST5) In this one, PTEST3 is the unique direct subclass of PTEST4, so when PTEST3 is output, PTEST4 and PTEST5 could come next. Preorder would say PTEST5 is next, but Danny's rule overrides that. (DEFCLASS PPTEST1 (PPTEST-MIXIN PPTEST2 PPTEST3) ()) (DEFCLASS PPTEST-MIXIN (PPTEST3) ()) (DEFCLASS PPTEST2 (PPTEST-INTERMEDIATE-1) ()) (DEFCLASS PPTEST3 (PPTEST-INTERMEDIATE-2) ()) (DEFCLASS PPTEST-INTERMEDIATE-1 (PPTEST-BASE) ()) (DEFCLASS PPTEST-INTERMEDIATE-2 (PPTEST-BASE) ()) (DEFCLASS PPTEST-BASE () ()) (topologically-sort 'pptest1) = (PPTEST1 PPTEST-MIXIN PPTEST2 PPTEST-INTERMEDIATE-1 PPTEST3 PPTEST-INTERMEDIATE-2 PPTEST-BASE) This one is nearly the same as the one before. This addition condition adds no complexity to the algorithm, because we compute the in-degrees of each class at DEFCLASS time. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jan 87 01:22:40 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Jan 87 22:13:02 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 56789; Thu 29-Jan-87 01:10:40 EST Date: Thu, 29 Jan 87 01:10 EST From: David A. Moon Subject: Elaboration on the Non-intuitiveness of New Flavors Algorithm... To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 27 Jan 87 21:01 EST from Dick Gabriel Message-ID: <870129011004.3.MOON@EUPHRATES.SCRC.Symbolics.COM> I agree with your [Dick's] analysis of the behavior of the New Flavors algorithm. This funny behavior when multiple passes are required is the same thing that has been bothering me. The New Flavors algorithm produces an "intuitive" result in many cases, but in this complex case it loses. I think we are likely to support some variant of the Gabriel or Bobrow proposed algorithms instead; so far the Bobrow one seems to produce the most consistently intuitive results. I fixed its performance problem that I mentioned yesterday by changing compute-must-precedes-closure; in place of (pushnew precede closure) (walk precede (cons element path)) do (unless (member precede closure) (push precede closure) (walk precede (cons element path))) The case that I gave up on after waiting a minute takes 0.23 seconds now, just about the same as the others (although Bobrow conses 3 times as much). None of the algorithms I've been comparing have been coded with speed paramount. I don't know whether the Bobrow algorithm is easy to explain, though. I also tried a variant of the Bobrow algorithm where the initial elimination of duplicates preserves the first occurrence of each class instead of the last. It's interesting but not really better. I don't think any topological sort tie-breaker based on non-local considerations such as preorder or postorder treewalk is going to produce intuitive results in all cases, because intuition depends on local considerations. I've been trying various tie-breakers but no good results yet. The advantage of the Bobrow algorithm is that it is preorder when that works, and when it doesn't, it moves things the minimum distance required to make them work. It usually produces the same result as the Gabriel-postorder algorithm, but here is an example that shows that the last-visit disambiguation of topological sort is not the same as the Bobrow-Kiczales algorithm. (DEFCLASS A (B C D E F)) (DEFCLASS B (F X)) (DEFCLASS C (F Y)) (DEFCLASS D (F X)) (DEFCLASS E ()) (DEFCLASS F ()) (DEFCLASS X ()) (DEFCLASS Y ()) Flavors, Gabriel-pre, Bobrow produce A B C D E F X Y Gabriel-post produces A B C D E F Y X It's hard to say which is intuitive in this case, so I mention this example only to show that Bobrow and Gabriel-post are not equivalent. I want to continue thinking about a better tie-breaker for topological sort.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 22:49:35 EST Date: 28 Jan 87 1932 PST From: Dick Gabriel Subject: Progress is Our Most Important Problem To: common-lisp-object-system@SAIL.STANFORD.EDU Wasn't that GE's slogan? According to my calculations, we have 3 days left before the document must be ready. I see a number of problems. 1. We are still arguing over CPL computation. When I asked Ken Olum to tell me what he thought about the possible algorithms for it he said he simply tried things in New Flavors until they worked. He said a good model is that there is some sort of algorithm and you don't try to understand it. Then he ran out of the room. Now that I've beaten everyone's brains out on the issue, I think we can happily settle on topological sort with last-visited preorder as the tiebreaker. 2. I'm inclined to go with Moon's method combination for now, though some of Danny's simplifications are attractive. 3. I don't care about the change-class protocol as long as it works. 4. I'd like to flush :allocation :dynamic and :allocation :none. If people want :allocation :none, then the inheritance writeup needs work. (Sonya?) 5. Gregor offered to supply examples. His examples didn't match the current specification very well, and LGD sent them back for more work. All of the functions and macros in the examples ought to be defined in the specification. I think we really have until Feb 14 to get this all done, but is there some way I can add to your desires to work hard on this and get it done? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 22:41:28 EST Date: 28 Jan 87 1922 PST From: Dick Gabriel Subject: Last-Visited Preorder To: common-lisp-object-system@SAIL.STANFORD.EDU If we decide the last-visited preorder is what we want for a tiebreaker, then there is a simple linear way to compute it without having to wonder whether reversed reversed postorder is the same as last-visited preorder. For every class you keep track of the in-degree with respect to the sublattice of interest; the in-degree is the number of direct subclasses of a class. When you walk from the class of interest, you keep track of how many times you've visited that class. When you have visited it the same number of times as its in-degree, you can walk from that class. The exception is the class of interest, which you will visit once more than its in-degree (you visit it once and its in-degree is 0). -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 21:01:21 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jan 87 17:48:23 PST Received: from Cabernet.ms by ArpaGateway.ms ; 28 JAN 87 13:40:25 PST Date: 28 Jan 87 13:40 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Method Combination In-reply-to: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET's message of 27 Jan 87 17:39:46 To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870128-134025-121@Xerox> Date: 27 Jan 87 17:39:46 From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET I agree with the fact than one can define ones own compute-effective-method. The issue has to do with modularity. Compute-effective-method has to find the list of all the method that can be called, find the method combination method, call it to come up with the code for the effective method. We need to keep those operations as independent as possible. If we supply the information as an argument to the method combinator, the user writing a method combination method does not have to worry about how the information was obtained. I agree that finding the list of all the methods that can be called, finding the way to combine methods, and coming up with the code for the combination ought to be kept separate. The following describes my view of the meta-object protocol, and how these are kept separate. The meta-object protocol for building the code for generic functions consists of two parts. The top level is (compute-discriminator-code generic-function) which has as its responsibility building the code that implements the effect of the described four step protocol for calling a method. Its usual implementation caches all the possibly different effective methods for the generic-function, and it produces code to decide which of these effective methods to call for any set of arguments. It is this code that is run when the generic-function is called. The only information compute-discriminator-code can use must be contained in the generic-function object. THERE IS NO OTHER PLACE TO STORE INFORMATION. As a standard part of the protocol for compute-discriminator-code (which can be overwritten by a specialized method), compute-discriminator-code computes the set of applicable-methods for distinguishable sets of arguments, and for that set calls: (compute-effective-method generic-function combination-type applicable-methods) The combination-type is taken from the generic-function to allow discrimination on an individual (the combination type) to select a specialized method. Other paramaterized information could have been passed in as arguments, but since that information is not being used for discrimination, it might as well be left in the generic function. Different implementations of compute-effective-method will be able to call the same method combinator even if they use different ways to come up with the method combination method. It seems more modular and more general than extracting the information in the method. If you want a subfunction that combines method-lists in the same way for differently named method-combination types (say because the lists are computed in different ways), then by all means define a subfunction. That was the reason we wanted make-method-call to be callable any place the generic-function object was accessible. Date: Wed, 28 Jan 87 00:05 EST From: David A. Moon I don't think the short form is vitally important, but until we converge on all details of the long form it's difficult to tell how much syntactic verboseness and error-proneness the short form will save. I suggest that for right now a boldface note be added to the document saying that the short form is still under discussion and there is a good chance it will go away in a future revision. I would rather do it the other way -- to make it easier to read the document and to allow the need for a short form to emerge rather than have it around by default. Only one form should appear in the document, and prhaps we should have a footnote saying that we might consider a short form if necessary. I agree with Patrick's argument that storing parameters in the generic function won't work. I think I have answered Patrick above. If I have misunderstood the thrust of the argument, please explain further. I consider it important to design the lean standard so that such extensions can be added smoothly and painlessly, without making incompatible changes to the original standard. This means that some design choices, which could go either way when considered in isolation, need to go a certain way in order to leave room for possible extensions. Is this agreeable to the other participants? I agree with this in principle, and would want to see the argument in any particular case. This is the reason for the lambda-list. Having to say () now is relatively painless, but adding a lambda-list in the future would be difficult. In fact the lambda-list also turns out to be a better way to provide access to the generic-function object than any other I've thought of. I've answered for the lack of need for the lambda-list above. The lambda-list cannot just be (). In your examples, it was at least (generic-function) or (generic-function order). This is not even the complete lambda-list of compute-effective-method (it doesn't include combination-type and applicable-methods). I would be agreeable to removing the :order keyword if a lean standard is paramount, although it seems to add only minimal complexity and I've seen reversed order of method specificity used quite a lot. Most slightly shorter forms are used if they are available. But I wouldn't cry a lot if this were put back. I'm opposed to using optional arguments instead of keyword arguments, because it makes extensibility much more awkward. This is a case in which allowing for extensions seems to be the paramount issue. Is it really musch easier to start with optionals and then add keywords for extensions than to have all keywords. Not having programmed with them very much, I can't speak from experience. I would be happy to back off on this. Using a special value for the :operator argument instead of a :call-next-method argument would be okay with me, although I suspect it will be difficult to document in a way that does not cause confusion. I think it will be less confusing for users to think of :call-next-method as a special kind of operator. We seem to have no real disagreement here. An argument for using the :call-next-method instead of 'call-next-method (no colon) is to avoid people believing that there is a function by that name, as there is for progn and and. {method-combination-option} :=combination-keyword value The list of method-combination options is optional, and is distinguished from a form because it starts with a keyword. We have this syntax for method-combination options in Flavors and I think it is grotesque. I suggest not including this. Can you say more about why you think it is grotesque. I find it easy to spot and read. The variable {\it generic-function\/} is available in the body forms of the combination definition. That's how we do it in Flavors (the variable name is slightly different) and I think it is grotesque. It's usually better to let the programmer choose her own names for variables. I suggest not doing this, although I don't feel very strongly about it. I think this is the simplest way to get access to the generic-function, and if the programmer wants to use a name of her own, then she can rebind it. Question: How does make-method-call get access to the generic function. I believed that it could assume access to that name in the lexical scope. Or perhaps generic-function should be a dynamic variable, to allow access for an error function. (From Gregor) I like the new :around method-combination option. I think this will make it easier for people to deal with :around methods. We might want to think about changing the "sense" of this option, or changing the default, so that aroundification happens by default. (From Moon) I agree that once it's a yes/no option, it makes sense to have it turned on by default. The next logical step is to say that if you want to turn it off, you should be operating at the meta-object level. Do you ever feel like you're going around in circles? What got us to :around methods in the first place was you guys' dislike of Flavors whoppers, which cannot be turned off. (Obviously if Flavors had meta-objects, whoppers could be turned off at the meta-object level.) Because around methods are still somewhat contentious (e.g. with Fahlman) that I think :around should be explicit in the define-method-combination code, and it should have to be turned on. Standard method combination supports it without having to say something. I understand the motivation for allowing a predicate instead of the templates. I think that motivation should be presented explicitly since without it, the predicate seems like uneeded complexity. I agree. Danny, could you write a paragraph about this? (Am I remembering correctly that you invented the idea of putting the predicate here?) Yes I will. Yes I did. We've found that it's often a good idea to provide a function as an abstraction, even when all that function does is signal a condition. The name of the condition can be the same as the name of the function, so that there aren't any extra names to document. This is what I had in mind here, rather than making a kludge to cope with not having a standard condition system yet. I suggest leaving this the way it is except for documenting the rationale better. I could go either way with this. If we have to document two kinds of errors anyway, I guess it is as well to document functions. I still don't like calling the default kind of method combination standard. I would prefer if we called it default, in fact, it might be better to call it daemon-with-around or some other descriptive name. I disagree. I really liked Danny's suggestion of calling it standard. As you know, I think all the predefined objects that are used by default if you don't make your own should be named standard-xxx (standard-class, standard-method, etc.) I suggest naming it either standard or standard-method-combination. I still like "standard" since it is only used in a context that makes it clear what it is the standard for. One answer is for that library to be available, but not necessary to be preloaded in all implementations. Then the portable programmer can load it if it is not already loaded, but doesn't have to reinvent it. I suggest that the document should mention this issue but that the name of and method combination in the example should still be and. I agree with both of these points. I think talking about standard libraries here would be a good way of getting the point in the large, without committing us to solve a problem. My conclusion is that we should only have one define-method-combination form in the document. The one still contentious issue between Moon's and my ideas on this subject is the lambda-list. I hope this message sheds more light on that issue. We should continue to try to reach some consensus. danny  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 28 Jan 87 18:18:45 EST Received: from Cabernet.ms by ArpaGateway.ms ; 28 JAN 87 12:17:22 PST Return-Path: Received: from vaxa.isi.edu by Xerox.COM ; 28 JAN 87 12:15:04 PST Received: by vaxa.isi.edu (4.12/4.7) id AA20226; Wed, 28 Jan 87 12:14:45 pst From: macgreg@vaxa.isi.edu (Robert MacGregor) Message-Id: <8701282014.AA20226@vaxa.isi.edu> Date: 28 Jan 87 12:14 PST (Wednesday) To: commonloops.pa@Xerox.COM Cc: rbates@vaxa.isi.edu Subject: Problem with get-function and put-function This is a follow up to a message that Ray Bates sent earlier. We have observed that the ndefstruct slot options "get-function" and "put-function" don't work on our Symbolics machines in the last couple of releases of PCL (they worked in a September '86 release). This is true for both the version 6 and 7 releases of the Symbolics environment. We haven't located the precise location of the bug, but we do have some idea of what might be wrong. Consider the forms below: ((lambda (self) (cons self self)) 'abc) (funcall #'(lambda (self) (cons self self)) 'abc) (#'(lambda (self) (cons self self)) 'abc) The first two forms evaluate successfully on a Symbolics machine, while the third form does not. The error message accompanying evaluation of the third form is identical to that which we observe when trying to evaluate slot accessors which have been defined with the "get-function" or "put-function" options. Thus, we are guessing that a form similar to the third is being generated within PCL. Cheers, Bob Mac Gregor  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 13:11:35 EST Date: 28 Jan 87 1005 PST From: Dick Gabriel Subject: Complexity of Topological Sort + single-pass treewalk tiebreaker To: common-lisp-object-system@SAIL.STANFORD.EDU Let n be the number of classes at or above the one for which you which to compute the CPL; let m be the sum of the number of direct superclasses at each class at or above the class of interest. You can do the tiebreaker treewalk in O(n) time; the topological sort O(n+m), so the whole thing is linear. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 10:17:24 EST Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 28 Jan 87 07:13:38 PST Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 44181; Wed 28-Jan-87 10:12:23 EST Date: Wed, 28 Jan 87 10:10 EST From: Daniel L. Weinreb Subject: :allocation :none To: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu cc: CLOS@STONY-BROOK.SCRC.Symbolics.COM In-Reply-To: <870127230108.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <870128101023.4.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Tue, 27 Jan 87 23:01 EST From: David A. Moon In Flavors, we spent a lot of time some years ago discovering that that style doesn't work very well. It worked out a lot better to split the superclass into separate modules and then inherit whichever ones are wanted. I just read an interesting paper about programming style for object oriented programming, written by Dan Halbert and from the Trellis/Owl group at DEC's eastern research lab. It's based on their experience teaching and helping users who were learning object-oriented programming. It comes to the same conclusion, and strongly suggests this kind of organization. It was hard to figure out the implications of :allocation :none. One example of a confusing case is where A inherits from B, B inherits from C, C provides a slot S1, B declares S1 with :allocation :none, and A declares S1 with :allocation :instance. One's "built-in" paradigms about the concepts of "shadowing" and "inheritance from outer blocks" and so on can easily lead to the impresion that A's S1 is distinct from C's S1, whereas they are actually the same slot, and slot attributes are inherited by A from C even though B "doesn't have" slot S1. It's also confusing that instance of B "undermine" inherited methods from C that refer to S1, by making S1 not be there any more. I don't think this paradigm fits well into the overall proposal, and the benefits of this feature seem relatively small compared to the extra complexity and confusion that it adds to the specification. We've run into such things before, many times, during this design process. I suggest that we apply our usual treatment: remove this from the specification per se, and leave it as a possible future feature, or implemention-specific enhancement.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 01:55:03 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jan 87 22:31:53 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 54462; Wed 28-Jan-87 01:30:37 EST Date: Wed, 28 Jan 87 01:30 EST From: David A. Moon Subject: CPL Computation To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 27 Jan 87 15:07 EST from Dick Gabriel Message-ID: <870128013024.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 27 Jan 87 1207 PST From: Dick Gabriel Finally, my algorithms wizard and I studied the New Flavors CPL computation description and think there is a performance problem with the algorithm it describes. Consider the following graph of 4n+1 classes: (defclass Ai (Bi Ci) ()) (defclass Bi (Di Ai+1) ()) (defclass Ci (Di) ()) (defclass Di () ()) for 0 <= i < n. The New Flavors algorithm, as described, seems to take n+1 passes, though there is exactly one total order possible. This is true. I'm not sure that it's significant. Does topological sort run in linear time? Given ... that there is no intuition to any order beyond what the topological sort gives you ... I agree with Danny's disagreement with this. I'm interested in continuing the search for an algorithm that is acceptable to your algorithms wizard and at the same time provides the intuitive behavior. It's getting late for me, but I'll follow up on this tomorrow.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 01:28:06 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jan 87 22:20:43 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 54454; Wed 28-Jan-87 01:19:19 EST Date: Wed, 28 Jan 87 01:19 EST From: David A. Moon Subject: Re: CPL Update To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870127-092639-5358@Xerox> Message-ID: <870128011901.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 27 Jan 87 09:26 PST From: Danny Bobrow I think that [Dick's] algorithm would work the same as New Flavors if you used a last-visited walk.... Dave, could you try my variation on Gabriels algorthm against the new Flavors system? I think this was the first or second modification of Gabriel's algorithm that I tried yesterday. The function is named Gabriel-3, but it looks like I never finished writing Gabriel-2. Unfortunately I had too many other things to do today to follow up on this as I ought to have. Looking back over my notes, I don't have any cases jotted down where this modified Gabriel performs differently from Bobrow (Gregor's code), except when the latter seemed to go into an infinite loop. However, I compared them "exhaustively" just now and found a few cases where they produce different results. I haven't boiled that down to a simple, understandable case yet, though. I do have some cases where both Gabriel-3 and Bobrow produce a different answer from Flavors, but I haven't finished figuring out what's going on there yet. The difference might not be real.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 00:25:32 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jan 87 21:16:27 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 54412; Wed 28-Jan-87 00:05:45 EST Date: Wed, 28 Jan 87 00:05 EST From: David A. Moon Subject: Danny's new version of define-method-combination To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870120-122111-2214@Xerox>, <870120-131551-2295@Xerox> Message-ID: <870128000529.2.MOON@EUPHRATES.SCRC.Symbolics.COM> I said I wasn't going to think about method-combination any more this month, but I changed my mind. The indented messages below are excerpted to show just enough context for my comments to make sense. In the interests of getting the document finished soon, for each point, after general discussion I make a suggestion for what to do; naturally I'm more than willing to listen to arguments that my suggestions are wrong. Date: 20 Jan 87 12:11 PST From: Danny Bobrow 1) There is only one define-method-combination form. I don't think the short form is vitally important, but until we converge on all details of the long form it's difficult to tell how much syntactic verboseness and error-proneness the short form will save. I suggest that for right now a boldface note be added to the document saying that the short form is still under discussion and there is a good chance it will go away in a future revision. 2) There is no lambda-list. It also omits the keyword :order from the method specifier. defgeneric-options is extended to store parameters in the generic function. This can be used to support features like reversed order for combination if desired. I agree with Patrick's argument that storing parameters in the generic function won't work. There is a more general philosophical issue here. Symbolics has agreed to the approach of making a lean proposal, containing only features that are truly necessary and that are well-understood. One can see from reading the document that this policy hasn't been carried out perfectly uniformly, but it's the direction we're aiming. There are a number of extensions that we feel are important in the industrial real world, but that we agree don't belong in the standard right now. If these extensions prove worthwhile, they might be implemented by individual implementations and then eventually added to the standard. I consider it important to design the lean standard so that such extensions can be added smoothly and painlessly, without making incompatible changes to the original standard. This means that some design choices, which could go either way when considered in isolation, need to go a certain way in order to leave room for possible extensions. Is this agreeable to the other participants? This is the reason for the lambda-list. Having to say () now is relatively painless, but adding a lambda-list in the future would be difficult. In fact the lambda-list also turns out to be a better way to provide access to the generic-function object than any other I've thought of. I would be agreeable to removing the :order keyword if a lean standard is paramount, although it seems to add only minimal complexity and I've seen reversed order of method specificity used quite a lot. I suggest not changing anything here. Alternatively, :order could be removed. 3) It is syntactically distinguishable from the current Flavors version of define-method-combination, and hence allows backwards compatiblity. Current Flavors users will bless you. 4) It uses the keyword :call-next-method instead of :around in make-method-call. This is okay with me. [A later message from Danny said:] Because :operator and :call-next-method (nee :around) cannot both appear, I suggest that the syntax of make-method-call be (make-method-call method-list &optional (operator 'progn) (identity-with-one-argument (eq operator 'progn))) Where if operator has the value :call-next-method, it has the same effect as previously providing that argument with t as its value. I'm opposed to using optional arguments instead of keyword arguments, because it makes extensibility much more awkward. Using a special value for the :operator argument instead of a :call-next-method argument would be okay with me, although I suspect it will be difficult to document in a way that does not cause confusion. I suggest changing :around to :call-next-method here, but flushing :around and saying :operator 'call-next-method (no colon) would be okay too. Flushing the idea of controlling it with an argument and going back to a second function, named make-next-method-call or something, would be okay too. Does anyone have a strong preference for one or another of these? {method-combination-option} :=combination-keyword value The list of method-combination options is optional, and is distinguished from a form because it starts with a keyword. We have this syntax for method-combination options in Flavors and I think it is grotesque. I suggest not including this. The keyword options supported are: {\bf :documentation} {\it string\/} documents the method-combination type. I don't see why we shouldn't use the same syntax as defmacro for documentation strings. {\bf :around} {\it boolean\/} If the argument is true (not {\bf nil}), then the form returned by the body of define-method-combination is augmented to support :around methods. I comment on this below, in connection with Gregor's comments on it. The variable {\it generic-function\/} is available in the body forms of the combination definition. That's how we do it in Flavors (the variable name is slightly different) and I think it is grotesque. It's usually better to let the programmer choose her own names for variables. I suggest not doing this, although I don't feel very strongly about it. Date: 20 Jan 87 13:15 PST From: Gregor.pa@Xerox.COM I like the new :around method-combination option. I think this will make it easier for people to deal with :around methods. We might want to think about changing the "sense" of this option, or changing the default, so that aroundification happens by default. I agree that once it's a yes/no option, it makes sense to have it turned on by default. The next logical step is to say that if you want to turn it off, you should be operating at the meta-object level. Do you ever feel like you're going around in circles? What got us to :around methods in the first place was you guys' dislike of Flavors whoppers, which cannot be turned off. (Obviously if Flavors had meta-objects, whoppers could be turned off at the meta-object level.) I have two suggestions here. Either one is okay with me: (1) Make it a method-group keyword option. Thus you say ((around (:around) :call-next-method t) ...other method groups...) (2) Decide the existing mechanism of two nested calls to make-method-call is concise enough. I understand the motivation for allowing a predicate instead of the templates. I think that motivation should be presented explicitly since without it, the predicate seems like uneeded complexity. I agree. Danny, could you write a paragraph about this? (Am I remembering correctly that you invented the idea of putting the predicate here?) I don't really like the fact that information is communicated to make-method-call using special variables. I thought having make-method-call be a lexically bound function was much more elegant, and much more in keeping with the lexically scoped way of doing things. It's a difficult judgement call. What convinced me was that if error reporting is going to use the Common Lisp condition handling standard, that inherently involves dynamic variables, so there is nothing to be gained by making make-method-call not use dynamic variables. I suggest leaving this the way it is. I don't really like method-combination-error and invalid-method-error. They just add complexity to this part of the proposal to make up for the fact that the error system has not been adopted yet. There are many parts of the object system which want to signal special kinds of errors, we don't have special functions for all of them. This is the first place where we have a hook for programmer-defined functions, and those functions have to report errors in a standard way. Perhaps there will be others in the meta-object protocol, but so far there aren't any others. Perhaps what we should do is assume the error system is going to be accepted (seems likely), and then talk about what kind of error is signalled by each part of the object system. This seems more reasonable than introducing a bunch of error functions which will just have to be removed when the error proposal is adopted, or worse yet supported as backwards compatibility for life. We've found that it's often a good idea to provide a function as an abstraction, even when all that function does is signal a condition. The name of the condition can be the same as the name of the function, so that there aren't any extra names to document. This is what I had in mind here, rather than making a kludge to cope with not having a standard condition system yet. I suggest leaving this the way it is except for documenting the rationale better. I still don't like calling the default kind of method combination standard. I would prefer if we called it default, in fact, it might be better to call it daemon-with-around or some other descriptive name. I disagree. I really liked Danny's suggestion of calling it standard. As you know, I think all the predefined objects that are used by default if you don't make your own should be named standard-xxx (standard-class, standard-method, etc.) I suggest naming it either standard or standard-method-combination. What method combination types will we say are defined? There is a definite package problem here. We should probably include some comment on it in the spec. A user can't very well go and do define-method-combination of lisp:and. If they do it "differently" they could break the system or some other application. I think the examples should be re-worked to show users defining method-combinations whose names are symbols which are not in the lisp package. This is a hard problem. It relates to modularity and to the difficulty of legislating programming styles in standards. It's true that redefining lisp:and differently will break other programs. A good programming environment will detect this and won't let it go unchallenged, but if lisp:and is predefined in some environments and not in others, so that every portable program has to define it, that doesn't help. It's really not a good idea for every program to redefine and method combination for itself, with its own name -- that just leads to a Tower of Babel. On the other hand, not everyone seems to agree that there should be a library of a dozen or so useful predefined method combination types. One answer is for that library to be available, but not necessary to be preloaded in all implementations. Then the portable programmer can load it if it is not already loaded, but doesn't have to reinvent it. Discouraging programmers from defining a method-combination type named lisp:and that does something different, e.g. Prolog unification, is fine with me, since I believe it's good style for a method-combination type with the same name as an operator to be derived from that operator in the obvious way. I suggest that the document should mention this issue but that the name of and method combination in the example should still be and.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jan 87 00:22:45 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jan 87 21:16:56 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 54417; Wed 28-Jan-87 00:14:55 EST Date: Wed, 28 Jan 87 00:14 EST From: David A. Moon Subject: Re: --- To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870127-182340-6111@Xerox> Message-ID: <870128001434.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 27 Jan 87 18:23 PST From: Danny Bobrow The issue is whether that information is extracted by the system and made an argument of the method, or extracted in the method. I have suggested that extracting it in the method is the general way to do it. That is not really what you have suggested. You suggested extracting it in the define-method-combination. I suggest doing it in both. That is, any information other than the combination-type (e.g. standard , and) which selects a method is extracted from the generic function. Your suggestion would mean that define-method-combination forms would not be portable between systems that have only one method combination type per generic-function and systems that are more general. What I think Patrick is suggesting is that the extension to allow more general selection of a method-combination type should be orthogonal to the method-combination types themselves. I don't understand how a generic function can have more than one method-combination type. It would be an upward-compatible extension to the standard. One way to do it was proposed by Patrick in his message of 31 October. Another way, which unfortunately only works for classical methods, exists in Flavors now. I also don't understand your last sentence at all. I hope Patrick's latest message clarified it. I was guessing at his suggestion but he said it himself, about modularity and keeping the various operations as independent as possible.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 23:23:37 EST Received: from SCRC-RIVERSIDE.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jan 87 20:02:44 PST Received: from EUPHRATES.SCRC.Symbolics.COM by RIVERSIDE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 96592; Tue 27-Jan-87 23:00:59 EST Date: Tue, 27 Jan 87 23:01 EST From: David A. Moon Subject: :allocation :none To: Common-Lisp-Object-System@sail.stanford.edu cc: CLOS@STONY-BROOK.SCRC.Symbolics.COM In-Reply-To: <870126-143427-4458@Xerox> Message-ID: <870127230108.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 26 Jan 87 14:33 PST From: Ken kahn I thought I should explain the original motivation for :allocation :none. There are two expected uses of it. 1) A subclass implements an inherited slot procedurally (i.e. it defines accessor methods) and doesn't need any storage set aside. :allocation :none just saves some space in each instance but has no semantic import (except maybe with respect to low-level slot access, i.e. slot-value). 2) A slot is not needed by a subclass. Declaring it :allocation :none is both a cheap way to get an error if the instances really do need it and again a way to save space in instances. So I guess I'm agreeing with Moon that the slot continues to exist but certain kinds of access to it are errors. To some extent, the value of :allocation :none depends upon the style of object-oriented programming. One style is to put alot of functionality in the super-classes which sub-classes turn off. E.g. an immovable-window is a subclass of ordinary window and needn't waste space for slots used only in supporting movement. In Flavors, we spent a lot of time some years ago discovering that that style doesn't work very well. It worked out a lot better to split the superclass into separate modules and then inherit whichever ones are wanted. I haven't thought about it real deeply, but I think the Common Lisp object system is similar enough to Flavors that it will work out the same way. If you believe this, maybe we should get rid of :allocation :none, since it seems to make slot inheritance a lot harder to document and to understand.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 23:16:55 EST Received: from SCRC-RIVERSIDE.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jan 87 20:06:38 PST Received: from EUPHRATES.SCRC.Symbolics.COM by RIVERSIDE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 96593; Tue 27-Jan-87 23:04:57 EST Date: Tue, 27 Jan 87 23:05 EST From: David A. Moon Subject: symbols are not generic functions To: Common-Lisp-Object-System@Sail.Stanford.edu In-Reply-To: <870126-141351-4399@Xerox> Message-ID: <870127230506.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 26 Jan 87 14:12 PST From: Gregor.pa@Xerox.COM symbols are not generic functions, they can only be used to name a generic function. The primitive levels of the meta-interpreter deal with generic-function objects. symbols as names of generic functions are a convenience provided by defmethod, defmethod-setf defgeneric-options etc. Consequently, I would like to propose the following change. I suggest that add-method, remove-method and get-method be changed to require that their first argument be a generic-function object. Along with this I would like to introduce a new function which will provide the functionality I am proposing we remove in a more rational way. This change is okay with me. See comments below. ensure-generic-function (or some such name) takes a symbol, or a list (SETF ) and makes sure there is a generic function of the default kind (standard-generic-function) "there". For convenience, ensure-generic-function returns that generic function. I don't completely understand. Suppose symbol-function of the symbol is already a generic function, but it is of a different class than the kind that you get by default, because someone is using generic-function meta-objects. Would ensure-generic-function accept that generic function, signal an error, or clobber it with a generic function of the default kind? Also, does ensure-generic-function ever alter the symbol-function of a symbol, or is it just a side-effect free coercion? If the latter, it might be cleaner to use the existing COERCE function, thus (add-method (coerce 'generic-function) ). This means that (in some of the cases) where you used to write: (add-method 'foo ) you will write (add-method (ensure-generic-function 'foo) ) There is no doubt that this is more verbose in the cases where you have to use ensure-generic-function, but I believe it is much clearer.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 22:20:02 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 27 Jan 87 19:14:20 PST Received: from ti-csl by csnet-relay.csnet id aa05659; 27 Jan 87 20:03 EST Received: from dsg (juliett.ARPA) by tilde id AA04554; Tue, 27 Jan 87 17:39:49 cst Received: FROM Jenner BY dsg Via CHAOS-NET with CHAOS-MAIL; 27-Jan-87 17:38:49 Message-Id: <2747777986-278997@Jenner> Date: 27-Jan-87 17:39:46 From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET To: Danny Bobrow Cc: common-lisp-object-system@SU-AI.ARPA Subject: Re: --- In-Reply-To: In-Reply-To: Msg of 27-Jan-87 15:05:00 from Danny Bobrow Msg of 27-Jan-87 15 Date: 27-Jan-87 15:05:00 From: Danny Bobrow A generic-function can have only one method-combination type -- parametrized or not. Well that's what is in the standard. I consider this assumption being a simplification of a more general model. I understand that we don't want to put the general model in the standard (Size, complexity.....) but we can't lock the standard in a mode where only the simplistic model can be supported without incompatibilities. To get other kinds of extensions, one uses the meta-object protocol, which in this case consists of defining your own method on compute-effective-method. Since this is called by the system when generic function is called with a set of arguments, the only thing it can depend on is information from the generic function (and of course the argument types). The issue is whether that information is extracted by the system and made an argument of the method, or extracted in the method. I have suggested that extracting it in the method is the general way to do it. I agree with the fact than one can define its own compute-effective-method, the issue has to do with modularity. Compute-effective-method has to find the list of all the method that can be called, find the method combination method, call it to come up with the code for the effective method. We need to keep those operations as independent as possible. If we supply the information as an argument to the method combinator, the user writing a method combination method does not have to worry about how the information was obtained. Different implementations of compute-effective-method will be able to call the same method combinator even if they use different ways to come up with the method combination method. It seems more modular and more general than extracting the information in the method. Maybe David has some more (convincing?) arguments. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 22:02:08 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jan 87 18:54:20 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 JAN 87 18:31:18 PST Date: 27 Jan 87 18:31 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Elaboration on the Non-intuitiveness of New Flavors Algorithm... In-reply-to: Dick Gabriel 's message of 27 Jan 87 18:01 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870127-183118-6120@Xerox> Wow. I found your example clever. And I now believe also that last-vist disambiguation of topological sort is the most intuitive, and not the New Flavors one (and that the B-K code will produce the same results ). I wonder if the case that Moon found for ours that was different than new Flavors was of the Me-last sort. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 22:01:31 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jan 87 18:54:10 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 JAN 87 18:23:40 PST Date: 27 Jan 87 18:23 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: --- In-reply-to: David A. Moon 's message of Tue, 27 Jan 87 20:49 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870127-182340-6111@Xerox> The issue is whether that information is extracted by the system and made an argument of the method, or extracted in the method. I have suggested that extracting it in the method is the general way to do it. That is not really what you have suggested. You suggested extracting it in the define-method-combination. I suggest doing it in both. That is, any information other than the combination-type (e.g. standard , and) which selects a method is extracted from the generic function. Your suggestion would mean that define-method-combination forms would not be portable between systems that have only one method combination type per generic-function and systems that are more general. What I think Patrick is suggesting is that the extension to allow more general selection of a method-combination type should be orthogonal to the method-combination types themselves. I don't understand how a generic function can have more than one method-combination type. I also don't understand your last sentence at all. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 21:22:44 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jan 87 14:30:11 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 JAN 87 13:05:43 PST Date: 27 Jan 87 13:05 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: --- In-reply-to: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET's message of 27 Jan 87 11:33:22 To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870127-130543-5661@Xerox> A generic-function can have only one method-combination type -- parametrized or not. Well that's what is in the standard. I consider this assumption being a simplification of a more general model. I understand that we don't want to put the general model in the standard (Size, complexity.....) but we can't lock the standard in a mode where only the simplistic model can be supported without incompatibilities. To get other kinds of extensions, one uses the meta-object protocol, which in this case consists of defining your own method on compute-effective-method. Since this is called by the system when generic function is called with a set of arguments, the only thing it can depend on is information from the generic function (and of course the argument types). The issue is whether that information is extracted by the system and made an argument of the method, or extracted in the method. I have suggested that extracting it in the method is the general way to do it. I take this message as support for including this version of define-method-combination as the one in the specification. I agree with Gabriel that this committee should really amke up its mind. You're jumping to conclusion. Convergence means that each additional proposal has negligible added value. I really meant this as a prod to get us to think about this some more. We need to be talking about it. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 21:11:48 EST Date: 27 Jan 87 1801 PST From: Dick Gabriel Subject: Elaboration on the Non-intuitiveness of New Flavors Algorithm... To: common-lisp-object-system@SAIL.STANFORD.EDU ...and other related issues. Remember the funny little configuration of classes mentioned in an earlier message (defclass Ai (Bi Ci) ()) (defclass Bi (Di Ai+1) ()) (defclass Ci (Di) ()) (defclass Di () ()) for 0 <= i < n. Here's what it looks like: A1 D0 / | \ / | \/ | /\ | / \ B0 C0 \ / \ / \/ A0 Suppose we are following the New Flavors description of how to compute the CPL for A0. We start walking through this in depth-first manner starting at A0. We visit/output A0, visit/output B0, visit D0, visit A1, visit/output C0, and then visit/output D0. There is no path in depth-first order with which to get to A1 again, so the first depth-first pass is over. We notice A1 has not been output and walk it again, outputting A1 last. If A1 is the root of another copy of this, we cannot visit up through it on the first pass. If there are classes to the right of A0, they wil be visited and probably output during the first pass. When the second pass is made, A1 will be output. Let's call this configuration the ``MeLast.'' Now consider the following configuration: T1 T2 T3 | | | D E F \ | / \ | / \ | / \|/ C where C is a class and T1, T2, T3 are independent lattices, except for a common top. What does intuition say? It says that all of T1 should be together, all of T2 should be together, and all of T3 should be together, each group in in some order relative to one another, and the order within each group unknown. One could argue T1 should precede T2 should precede T3, but I won't. Suppose that T1 has a MeLast in it, and neither T2 nor T3 does. Then some part of T1 - namely A0, B0, C0, and D0 - will come early on, then parts of T2 and T3, and finally A1 will be last. Similar situations hold for T2 and T3, but in all cases, A1 will be last, assuming there are no other MeLast-like configurations in the T groups. The intuition is gone. Here is an example: MeLast | X Y Z \ | / \|/ W The New Flavors order is: W,X,Y,A0,B0,C0,D0,Z,A1 The gabriel order is: W,X,Y,A0,B0,C0,D0,A1,Z Notice that in the gabriel order, the Y/MeLast guys are together between Y and Z. The existence of a MeLast configuration is purely an artifact of the multiple passes that the New Flavors CPL computation does. If it had a way to remember to redo A1 as soon as its predecessor, D0, was cleared up, it would not need to make another pass through the lattice. The MeLast configuration also proves that no algorithm based on topological sort with a tiebreaker that is like a single-pass, single-stack treewalk is equivalent to the New Flavors computation. I haven't thought through the exact constraints, but preorder, reversed reversed postorder, and things like that as the tiebreaker in conjunction with topological sort cannot be the same as New Flavors, because they will put classes in the groups T1, T2, and T3 together. This increases the strength of my belief that the New Flavors algorithm is not suitable for the CLOS standard. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 21:10:52 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jan 87 18:04:20 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 JAN 87 17:06:27 PST Date: 27 Jan 87 17:06 PST From: Bobrow.pa@Xerox.COM Subject: Re: CPL Update To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870127-170627-5999@Xerox> I'm also working on finding a New Flavors equivalent that works within the topological sort framework. I have one such equivalent, which can be explained in either of two ways. I think I have a second algorithm that produces the same results as the New Flavors algorithm which can be described differently from the topological sort algorithms and the New Flavors algorithm - it is of the form of a certain weird treewalk and doesn't do multiple depth-first walks. I think that your algorithm would work the same as New Flavors if you used a last-visited walk, that is used the following algorithm for your walk to dismbiguate in case of choice. In my hand simulations of your algorithm it does: ``A last-visited treewalk is defined in terms of the order in which classes are visited while performing a process called ``walking from a class.'' The following is a recursive definition of walking from a class. Let C be a class and let C1...Cn be its direct superclasses in the local precedence order. Nodes are visited unless they WILL BE LATER visited. To walk from C, first C is visited, then we walk from C1, then we walk from C2, and so on until we finally walk from Cn.'' This is equivalent to laying out a linearization visiting each class as many times as you get to it, and removing all but the last occurrence. (Also sometimes described as left-to-right depth first up to joins.) I haven't tried coding Danny's algorithm (proposed a month or two ago) yet. I wonder if it does the same thing as either of these other algorithms. I've been playing around with this (code from Gregor's message of Dec 2). It usually does what I consider the right thing, but sometimes it does something different from both Gabriel and Flavors I haven't been able to boil that down to a small test case yet. The Bobrow algorithm also goes into an infinite loop in some cases (again, not yet boiled down to a simple case). It is my belief that Gregor's code was an implementation of my algorithm, so you need not recode -- I would be very interested in a simple example for Gregors code, or even a complex one that I could look at and analyze. General conclusion. In all the cases I have seen, I have agreed that the New Flavors ordering is good. I believed my algorithm also computed it. Dave, could you try my variation on Gabriels algorthm against the new Flavors system?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 21:00:22 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jan 87 17:50:57 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 54288; Tue 27-Jan-87 20:49:39 EST Date: Tue, 27 Jan 87 20:49 EST From: David A. Moon Subject: Re: --- To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870127-130543-5661@Xerox> Message-ID: <870127204942.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 27 Jan 87 13:05 PST From: Danny Bobrow A generic-function can have only one method-combination type -- parametrized or not. Well that's what is in the standard. I consider this assumption being a simplification of a more general model. I understand that we don't want to put the general model in the standard (Size, complexity.....) but we can't lock the standard in a mode where only the simplistic model can be supported without incompatibilities. To get other kinds of extensions, one uses the meta-object protocol, which in this case consists of defining your own method on compute-effective-method. Since this is called by the system when generic function is called with a set of arguments, the only thing it can depend on is information from the generic function (and of course the argument types). The issue is whether that information is extracted by the system and made an argument of the method, or extracted in the method. I have suggested that extracting it in the method is the general way to do it. That is not really what you have suggested. You suggested extracting it in the define-method-combination. That's entirely different from extracting it in a method that is defined by someone using the meta-object protocol. Your suggestion would mean that define-method-combination forms would not be portable between systems that have only one method combination type per generic-function and systems that are more general. What I think Patrick is suggesting is that the extension to allow more general selection of a method-combination type should be orthogonal to the method-combination types themselves.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 17:35:19 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jan 87 14:29:59 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 JAN 87 13:00:35 PST Date: 27 Jan 87 13:00 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: CPL Computation In-reply-to: Dick Gabriel 's message of 27 Jan 87 12:07 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870127-130035-5654@Xerox> Given that reversed reversed postorder treewalk (or last-visited preorder) is the tiebreaker, that there is at least one suspicious Flavors-order example, that people can formulate their lattices as they want to get the right inheritance, that there is no intuition to any order beyond what the topological sort gives you, and there is a possible performance problem with the algorithm described in the New Flavors document, I have now flipped my bit on this issue from wanting to mimic the Flavors order to insisting on preorder tiebreaker with topological sort. Everything says pt5 should precede pt4, but Flavors doesn't. I believe this to be a serious problem. I don't believe this. The argument for the New Flavors (and Bobrow/Kiczales) ordering is the following. If the user has a class (a mixin), and for reasons known to them splits that class into two classes e.g. (p3' into p3 and p4), with no other references, there should be no chance of any interaction with any other class used as a mixin. Hence one wants all superclasses of a class to follow as soon as possible after the class they are referred to. As soon as possible is what you get from last-visited pre-order walk. Moon-walk (which is what is in B/K) is a reasonable implementation of "last-visited pre-order walk". We don't have to describe the algorithm and the effect in one paragraph. The effect is a linearization of a full tree walk maintaining only the last visit. The computation computes it from the rear to avoid revisits. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 15:17:16 EST Date: 27 Jan 87 1207 PST From: Dick Gabriel Subject: CPL Computation To: common-lisp-object-system@SAIL.STANFORD.EDU As I've mentioned earlier, I wasn't interested in proposing a new definition of the CPL computation different from what Flavors presents but in proposing a clear way of describing it. I took Moon's suggestion and looked for a different ``tiebreaker'' from preorder treewalk. I have a simple way to describe it, but the naive implementation has bad running behavior. The fast version is describable, but the description is horrendous. I think we want to consider what this all means once the algorithms are presented. The algorithm is precisely as before, but when the topological sort would nondeterministically select one class from among a set of equally good ones, you choose based on a last-visited preorder treewalk. A last-visited preorder treewalk is defined in terms of the order in which classes are visited while performing a process called ``walking from a class.'' The following is a recursive definition of walking from a class. Let C be a class and let {C1...Cn} be its direct superclasses in the local precedence order. To walk from C, first C is visited, then we walk from C1, then we walk from C2, and so on until we finally walk from Cn. If a class has been visited before, you ignore that visit. That is, the order is the order in which the last visits to a node are made. Normally, one computes the preorder treewalk order as a number attached to the class. Again normally, this number is computed by performing the preorder treewalk and INCFing a counter. In a preorder treewalk, when a class already has a preorder number, you do not re-visit that class; the modification to normal preorder treewalk to obtain last-visited preorder treewalk is to eliminate this last pruning. The tiebreaker simply looks at these preorder numbers, choosing the class with the smallest preorder number. Notice that a lot of pruning might have been done by the original preorder walk and that the last-visited preorder walk eliminates all of the pruning. Here is some crufty code to compute the normal preorder number into a slot of the class called the PREORDER: (defun preorder-walk (class) (cond ((< 0 (preorder class))) ;already visited (t (setf (preorder class) (incf *preorder-counter*)) (dolist (superclass (direct-superclasses class)) (preorder-walk superclass))))) Here is the modified code: (defun lv-preorder-walk (class) (setf (preorder class) (incf *preorder-counter*)) (dolist (superclass (direct-superclasses class)) (lv-preorder-walk superclass))) This is, of course, less efficient than the previous code, though it looks simpler. One can get a fast algorithm by doing what could be called a reversed reversed postorder treewalk (``moonwalk,'' for short). We define reversed postorder treewalk and then modify that to be reversed reversed postorder treewalk. A reversed postorder treewalk is defined in terms of the order in which classes are visited while performing a process called ``walking from a class.'' The following is a recursive definition of walking from a class. Let C be a class and let {C1...Cn} be its direct superclasses in the local precedence order. Classes are visited unless they have already been visited. To walk from C, first we walk from Cn, then we walk from Cn-1, and so on until we finally walk from C1. Finally we visit C. A reversed reversed postorder treewalk visits classes in precisely the reverse order that they are visited in a reversed postorder treewalk. Implementationally, moonwalk isn't too bad. You place reversed postorder numbers on each class at or above the class of interest, and ties are broken by selecting the class with the largest reversed postorder number (note that we chose the smallest number in the preorder tiebreaker). Selecting the largest effects the second reversing. Here is the code to do this: (defun walk (class) (cond ((< 0 (rpostorder class))) (t (dolist (superclass (reverse (direct-superclasses class))) (walk superclass)) (setf (rpostorder class) (incf *counter*))))) This algorithm works on all of the examples I sent before plus the two killers Moon sent Sunday. The question now becomes: Is this what we really want? I claim that it doesn't matter too much what the tiebreaker is, because it is always possible to reformulate the lattice and use direct superclasses to achieve the desired effect. The fact the there are millions of flavors that use the moonwalk tiebreaker doesn't support the claim that the moonwalk tiebreaker is right: Perhaps the flavors have been carefully crafted to inherit properly. The explicit local precedence orders are the means by which programmers specify the ordering they want. The tiebreaker simply makes the total order well-defined. The tiebreaker is not intended to be a ``model'' of the class precedence list. If the topological sort produces a unique order, that order is intuitive; the cases where tiebreaking happens is ad hoc and is no intuitive. In the spirit of trying to figure out the New Flavors algorithm in order to be able to present it well, my algorithms wizard and I have tried come up with a more easily explainable algorithm that mimics the New Flavors and does not have topological sort as an explicit part of it. We failed, though we have not yet written down an example for which it fails. [I only mention this because I promised to show this algorithm in my last message.] Finally, I'm not sure that the first of Moon's killers has a very intuitive Flavors order. Here it is again: (DEFCLASS PTEST1 (PTEST2 PTEST3 PTEST5) ()) (DEFCLASS PTEST2 (PTEST5) ()) (DEFCLASS PTEST3 (PTEST4) ()) (DEFCLASS PTEST4 () ()) (DEFCLASS PTEST5 () ()) The Flavors order is (ptest1 ptest2 ptest3 ptest4 ptest5). Why is ptest4 before ptest5? Here's what the thing looks like: top------ | | pt4 | | | |-----------pt5 | | / pt2 pt3 / \ | / \ | / pt1 pt5 is a direct superclass of pt1 and pt4 isn't. One could argue that pt5 is the last of the direct superclasses, so it should come after the earlier direct superclasses and all of their superclasses; in this case you get to pt4 first because it is above pt3, which precedes pt5. But, does being mentioned first in a defclass count for anything? If so, you get to pt5 by passing through the first of the direct superclasses of pt1 (pt1 to pt2 to pt5) whereas you get to pt4 by passing through the second of the direct supeclasses of pt1 (pt1 to pt3 to pt4), and there are exactly the same number of intermediate classes. Everything says pt5 should precede pt4, but Flavors doesn't. I believe this to be a serious problem. Finally, my algorithms wizard and I studied the New Flavors CPL computation description and think there is a performance problem with the algorithm it describes. Consider the following graph of 4n+1 classes: (defclass Ai (Bi Ci) ()) (defclass Bi (Di Ai+1) ()) (defclass Ci (Di) ()) (defclass Di () ()) for 0 <= i < n. Here are the classes for n=2. (defclass a0 (b0 c0) ()) (defclass b0 (d0 a1) ()) (defclass c0 (d0) ()) (defclass d0 () ()) (defclass a1 (b1 c1) ()) (defclass b1 (d1 a2) ()) (defclass c1 (d1) ()) (defclass d1 () ()) The New Flavors algorithm, as described, seems to take n+1 passes, though there is exactly one total order possible. Given that reversed reversed postorder treewalk (or last-visited preorder) is the tiebreaker, that there is at least one suspicious Flavors-order example, that people can formulate their lattices as they want to get the right inheritance, that there is no intuition to any order beyond what the topological sort gives you, and there is a possible performance problem with the algorithm described in the New Flavors document, I have now flipped my bit on this issue from wanting to mimic the Flavors order to insisting on preorder tiebreaker with topological sort. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 14:18:29 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 27 Jan 87 11:10:37 PST Received: from ti-csl by csnet-relay.csnet id af00212; 27 Jan 87 13:18 EST Received: from dsg (juliett.ARPA) by tilde id AA20573; Tue, 27 Jan 87 11:33:35 cst Received: FROM Jenner BY dsg Via CHAOS-NET with CHAOS-MAIL; 27-Jan-87 11:33:04 Message-Id: <2747756002-313686@Jenner> Date: 27-Jan-87 11:33:22 From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET To: Danny Bobrow Cc: common-lisp-object-system@SU-AI.ARPA Subject: Re: --- In-Reply-To: In-Reply-To: Msg of 26-Jan-87 14:58:00 from Danny Bobrow Msg of 26-Jan-87 14 Date: 26-Jan-87 14:58:00 From: Danny Bobrow 2) There is no lambda-list. It also omits the keyword :order from the method specifier. defgeneric-options is extended to store parameters in the generic function. This can be used to support features like reversed order for combination if desired. There is a problem in tying up the parameters of the method combination to the generic function. If the user has to access those from the generic function, extensions where there can be several method combinations defined for the same generic function will not work. Parameters passed explicitly to the method combination function avoid this problem. In both versions of define-method-combination, the parameters passed are a function of the particular generic-function. That's true but david's one allows for extensions, yours does not. If the mechanism that fetches the parameters is encapsulated, the parameters don't have to be a function of the generic function only. If the user has to get them explictly from the generic function slot, it becomes apparent that they have to be a function of the particular generic-function only. A generic-function can have only one method-combination type -- parametrized or not. Well that's what is in the standard. I consider this assumption being a simplification of a more general model. I understand that we don't want to put the general model in the standard (Size, complexity.....) but we can't lock the standard in a mode where only the simplistic model can be supported without incompatibilities. I am not sure that the :around keyword actually simplifies things. It hides the around mechanism, but seeing the actual code helps people to get the right model in their minds. The point here is that we want to make it easy to suport :around methods, and it is such a common idiom that we want to make it short. By showing the translation (which people can understand once) we hope to give people the right model in their minds. I don't care that much about this point. Either way would be fine with me. Despite these points, we seem to be converging on this issue. I take this message as support for including this version of define-method-combination as the one in the specification. I agree with Gabriel that this committee should really amke up its mind. You're jumping to conclusion. Convergence means that each additional proposal has negligible added value.If we truly converge, we could leave David's write-up because yours wouldn't bring much more. See, the argument goes both ways! More seriously, I think that David's proposal augmented with predicates looks good to me, I would prefer it to yours for the reasons I brought earlier. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 12:32:17 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jan 87 09:27:04 PST Received: from Cabernet.ms by ArpaGateway.ms ; 27 JAN 87 09:26:39 PST Date: 27 Jan 87 09:26 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: CPL Update In-reply-to: Dick Gabriel 's message of 27 Jan 87 00:27 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870127-092639-5358@Xerox> I'm also working on finding a New Flavors equivalent that works within the topological sort framework. I have one such equivalent, which can be explained in either of two ways. I think I have a second algorithm that produces the same results as the New Flavors algorithm which can be described differently from the topological sort algorithms and the New Flavors algorithm - it is of the form of a certain weird treewalk and doesn't do multiple depth-first walks. I think that your algorithm would work the same as New Flavors if you used a last-visited walk, that is used the following algorithm for your walk to dismbiguate in case of choice. In my hand simulations of your algorithm it does: ``A last-visited treewalk is defined in terms of the order in which classes are visited while performing a process called ``walking from a class.'' The following is a recursive definition of walking from a class. Let C be a class and let C1...Cn be its direct superclasses in the local precedence order. Nodes are visited unless they WILL BE LATER visited. To walk from C, first C is visited, then we walk from C1, then we walk from C2, and so on until we finally walk from Cn.'' This is equivalent to laying out a linearization visiting each class as many times as you get to it, and removing all but the last occurrence. (Also sometimes described as left-to-right depth first up to joins.) I haven't tried coding Danny's algorithm (proposed a month or two ago) yet. I wonder if it does the same thing as either of these other algorithms. I've been playing around with this (code from Gregor's message of Dec 2). It usually does what I consider the right thing, but sometimes it does something different from both Gabriel and Flavors I haven't been able to boil that down to a small test case yet. The Bobrow algorithm also goes into an infinite loop in some cases (again, not yet boiled down to a simple case). It is my belief that Gregor's code was an implementation of my algorithm, so you need not recode -- I would be very interested in a simple example for Gregors code, or even a complex one that I could look at and analyze. General conclusion. In all the cases I have seen, I have agreed that the New Flavors ordering is good. I believed my algorithm also computed it. Dave, could you try my variation on Gabriels algorthm against the new Flavors system? danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 03:34:58 EST Date: 27 Jan 87 0027 PST From: Dick Gabriel Subject: CPL Update To: common-lisp-object-system@SAIL.STANFORD.EDU I'm also working on finding a New Flavors equivalent that works within the topological sort framework. I have one such equivalent, which can be explained in either of two ways. I think I have a second algorithm that produces the same results as the New Flavors algorithm which can be described differently from the topological sort algorithms and the New Flavors algorithm - it is of the form of a certain weird treewalk and doesn't do multiple depth-first walks. I'll send out the details once I consult with my algorithms wizard, which should be tomorrow afternoon. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 00:32:48 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 Jan 87 21:27:36 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 52441; Tue 27-Jan-87 00:25:15 EST Date: Tue, 27 Jan 87 00:25 EST From: David A. Moon Subject: Re: change-class and class redefinition To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870123-114021-2379@Xerox> Message-ID: <870127002518.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 23 Jan 87 11:40 PST From: Gregor.pa@Xerox.COM I like this argument, and am now happy with the change-class, class-changed part of this. Since we seem to be in agreement, I asked Sonya to put a somewhat cleaned up version of what I mailed out into the document in the next round of editing. You'll see it there and can comment further. There are still a few open questions, maybe the right thing is just to list the open questions in the document and deal with them later. In this case, I think the open questions are open because no one has an opinion, rather than because we have too many contradictory opinions.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jan 87 00:01:15 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 Jan 87 20:56:10 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 52426; Mon 26-Jan-87 23:54:29 EST Date: Mon, 26 Jan 87 23:54 EST From: David A. Moon Subject: Class-precedence-list computation To: Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870126005535.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <870126235427.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Status update on this: Date: Mon, 26 Jan 87 00:55 EST From: David A. Moon Dick, your algorithm does not produce the same results as the Flavors.... the most productive thing for me to do next would be to think about a coherent statement of that Flavors rule designed to fit into the framework of Dick's explanation of class precedence computation, where the preorder treewalk is now. I've tried several ideas for this but haven't found one that works yet. I'll keep at it. I haven't tried coding Danny's algorithm (proposed a month or two ago) yet. I wonder if it does the same thing as either of these other algorithms. I've been playing around with this (code from Gregor's message of Dec 2). It usually does what I consider the right thing, but sometimes it does something different from both Gabriel and Flavors; I haven't been able to boil that down to a small test case yet. The Bobrow algorithm also goes into an infinite loop in some cases (again, not yet boiled down to a simple case). I don't know for sure whether it's truly an infinite loop or just a combinatorial explosion; I gave up after a minute or so in one case, and after a few seconds in several other cases (normally the algorithm takes much less than a second).  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 26 Jan 87 21:10:51 EST Received: from Cabernet.ms by ArpaGateway.ms ; 26 JAN 87 16:26:24 PST Date: 26 Jan 87 16:23 PST From: Gregor.pa@Xerox.COM Subject: new version of PCL - 1/26/87 To: CommonLoops.pa@Xerox.COM To: ehl%cogsci.Berkeley.EDU@berkeley.edu To: ricks@shambhala.BERKELEY.EDU To: DOUGR@EDDIE.MIT.EDU To: CARNESE@SPAR-20.ARPA cc: Gregor.pa@Xerox.COM Message-ID: <870126-162624-4639@Xerox> There is a new version of PCL on parcvax.xerox.com. The *pcl-system-date* is "1/26/87". This version works in Genera (Symbolics 7.0), Lucid, and Franz (ExCL 1.5) Common Lisps. I have not tested it personally in other implementations. It includes: - the ExCL environment patch - a work-around for the previous Lucid compiler bug. - a fix of the infamous slot values don't override bug, this fix was done by re-writing the code involved to use a modularity which separates ordering slots from merging their descriptions. Please use this version rather than the fix mailed out by Ricks which causes a different bug to crop up.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Jan 87 19:11:19 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 26 Jan 87 15:58:45 PST Received: from Cabernet.ms by ArpaGateway.ms ; 26 JAN 87 14:34:27 PST Date: 26 Jan 87 14:33 PST Sender: kahn.pa@Xerox.COM From: Ken kahn Subject: :allocation :none To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870126-143427-4458@Xerox> I thought I should explain the original motivation for :allocation :none. There are two expected uses of it. 1) A subclass implements an inherited slot procedurally (i.e. it defines accessor methods) and doesn't need any storage set aside. :allocation :none just saves some space in each instance but has no semantic import (except maybe with respect to low-level slot access, i.e. slot-value). 2) A slot is not needed by a subclass. Declaring it :allocation :none is both a cheap way to get an error is the instances really do need it and again a way to save space in instances. So I guess I'm agreeing with Moon that the slot continues to exist but certain kinds of access to it are errors. To some extent, the value of :allocation :none depends upon the style of object-oriented programming. One style is to put alot of functionality in the super-classes which sub-classes turn off. E.g. an immovable-window is a subclass of ordinary window and needn't waste space for slots used only in supporting movement. ----- ken  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Jan 87 18:34:45 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 26 Jan 87 14:13:36 PST Received: from Cabernet.ms by ArpaGateway.ms ; 26 JAN 87 14:13:51 PST Date: 26 Jan 87 14:12 PST From: Gregor.pa@Xerox.COM Subject: symbols are not generic functions To: Common-Lisp-Object-System@Sail.Stanford.edu cc: Gregor.pa@Xerox.COM Message-ID: <870126-141351-4399@Xerox> symbols are not generic functions, they can only be used to name a generic function. The primitive levels of the meta-interpreter deal with generic-function objects. symbols as names of generic functions are a convenience provided by defmethod, defmethod-setf defgeneric-options etc. Consequently, I would like to propose the following change. I suggest that add-method, remove-method and get-method be changed to require that their first argument be a generic-function object. Along with this I would like to introduce a new function which will provide the functionality I am proposing we remove in a more rational way. ensure-generic-function (or some such name) takes a symbol, or a list (SETF ) and makes sure there is a generic function of the default kind (standard-generic-function) "there". For convenience, ensure-generic-function returns that generic function. This means that (in some of the cases) where you used to write: (add-method 'foo ) you will write (add-method (ensure-generic-function 'foo) ) There is no doubt that this is more verbose in the cases where you have to use ensure-generic-function, but I believe it is much clearer.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Jan 87 17:20:37 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 26 Jan 87 14:12:38 PST Received: from Cabernet.ms by ArpaGateway.ms ; 26 JAN 87 12:58:10 PST Date: 26 Jan 87 12:58 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: --- In-reply-to: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET's message of 23 Jan 87 15:15:45 To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870126-125810-4306@Xerox> 2) There is no lambda-list. It also omits the keyword :order from the method specifier. defgeneric-options is extended to store parameters in the generic function. This can be used to support features like reversed order for combination if desired. There is a problem in tying up the parameters of the method combination to the generic function. If the user has to access those from the generic function, extensions where there can be several method combinations defined for the same generic function will not work. Parameters passed explicitly to the method combination function avoid this problem. In both versions of define-method-combination, the parameters passed are a function of the particular generic-function. a generic-function can have only one method-combination type -- parametrized or not. I am not sure that the :around keyword actually simplifies things. It hides the around mechanism, but seeing the actual code helps people to get the right model in their minds. The point here is that we want to make it easy to suport :around methods, and it is such a common idiom that we want to make it short. By showing the translation (which people can understand once) we hope to give people the right model in their minds. Despite these points, we seem to be converging on this issue. I take this message as support for including this version of define-method-combination as the one in the specification. I agree with Gabriel that this committee should really amke up its mind. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Jan 87 01:00:11 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 25 Jan 87 21:57:13 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 51424; Mon 26-Jan-87 00:55:43 EST Date: Mon, 26 Jan 87 00:55 EST From: David A. Moon Subject: Class-precedence-list computation To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870126005535.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Dick, your algorithm does not produce the same results as the Flavors algorithm, assuming that I didn't make any mistakes in coding it based on the description in the current document. The topological sort is the same, but the resolution of cases where the topological sort has several choices is not the same. The simplest test case I could construct to demonstrate this is: (DEFCLASS PTEST1 (PTEST2 PTEST3 PTEST5) ()) (DEFCLASS PTEST2 (PTEST5) ()) (DEFCLASS PTEST3 (PTEST4) ()) (DEFCLASS PTEST4 () ()) (DEFCLASS PTEST5 () ()) (PREORDER 'PTEST1) is (PTEST1 PTEST2 PTEST5 PTEST3 PTEST4) Flavors order is (PTEST1 PTEST2 PTEST3 PTEST4 PTEST5 T) Gabriel order is (PTEST1 PTEST2 PTEST3 PTEST5 PTEST4 T) I couldn't find a test case with fewer than five classes. I wrote a program to try both sets of rules on a bunch of Flavors-based programs and show the difference not only in the class precedence list, but in the inheritance of methods. I haven't fully evaluated the results yet, but they seem to show that the Gabriel algorithm, although it seems very straightforward, actually produces rather surprising results. Here is an example that I boiled down from a real Flavors example (the real example had a lot more classes, but the bulk of them were irrelevant to the issue). I changed all the names to protect the innocent: (DEFCLASS PPTEST1 (PPTEST-MIXIN PPTEST2 PPTEST3) ()) (DEFCLASS PPTEST-MIXIN (PPTEST3) ()) (DEFCLASS PPTEST2 (PPTEST-INTERMEDIATE-1) ()) (DEFCLASS PPTEST3 (PPTEST-INTERMEDIATE-2) ()) (DEFCLASS PPTEST-INTERMEDIATE-1 (PPTEST-BASE) ()) (DEFCLASS PPTEST-INTERMEDIATE-2 (PPTEST-BASE) ()) (DEFCLASS PPTEST-BASE () ()) Flavors order: PPTEST1, PPTEST-MIXIN, PPTEST2, PPTEST-INTERMEDIATE-1, PPTEST3, PPTEST-INTERMEDIATE-2, PPTEST-BASE, T Gabriel order: PPTEST1, PPTEST-MIXIN, PPTEST2, PPTEST3, PPTEST-INTERMEDIATE-2, PPTEST-INTERMEDIATE-1, PPTEST-BASE, T Here the surprising thing is that PPTEST-INTERMEDIATE-1 is made less specific than PPTEST-INTERMEDIATE-2. That's because PPTEST2 comes -after- PPTEST3 in the preorder treewalk, even though PPTEST2 is explicitly specified to come before PPTEST3 in the class precedence list. PPTEST3 sneaks into the preorder treewalk early via PPTEST-MIXIN, but cannot be earlier than PPTEST2 in the class precedence list. The preorder is: (PPTEST1 PPTEST-MIXIN PPTEST3 PPTEST-INTERMEDIATE-2 PPTEST-BASE PPTEST2 PPTEST-INTERMEDIATE-1) I think this shows that the preorder treewalk is not a very good model of the desired precedence order. It's intended as an approximation to the Flavors rule of putting things in as they are encountered in the treewalk (that damn rule for which we have yet to come up with a coherent statement, except in Lisp code, that makes sense to anyone), but it's an insufficient approximation. It's true that the user did not explicitly declare that PPTEST-INTERMEDIATE-1 is more specific than PPTEST-INTERMEDIATE-2, but it's a surprise to find that the superclasses are in the reverse order of the subclasses. For more discussion of that, see the message I sent on 22 November. I'm not sure yet where we should go from here. Flavors-based programs are the only reservoir of real-world examples easily available to me. Someone might want to argue that they are all garbage and we have no lessons to learn from them, but I won't be convinced by anything less than another body of real-world experience that produces opposite conclusions. Probably the most productive thing for me to do next would be to think about a coherent statement of that Flavors rule designed to fit into the framework of Dick's explanation of class precedence computation, where the preorder treewalk is now. I haven't tried coding Danny's algorithm (proposed a month or two ago) yet. I wonder if it does the same thing as either of these other algorithms.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Jan 87 21:44:11 EST Received: from SCRC-RIVERSIDE.ARPA by SAIL.STANFORD.EDU with TCP; 25 Jan 87 18:39:25 PST Received: from EUPHRATES.SCRC.Symbolics.COM by RIVERSIDE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 95927; Sun 25-Jan-87 21:37:36 EST Date: Sun, 25 Jan 87 21:37 EST From: David A. Moon Subject: Gabriel's comments To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 25 Jan 87 19:52 EST from Dick Gabriel Message-ID: <870125213743.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 25 Jan 87 1652 PST From: Dick Gabriel Moon writes: ``Huh? I can't figure out what, if anything, this is supposed to mean.'' This was about a terse comment acncerning naming generic functions. In a previous draft there were several sentences talking about the names of generic functions as if there were such things. ``The name of a generic function is in a certain package and can be...'' ``Typically a generic-function object is stored as the function definition of the symbol that is the name of the generic function...'' These two sentences gave the impression that generic functions are named in a way that functions are not. The sentence Moon objects to, ``The naming conventions for generic functions are precisely the same as those for ordinary Common Lisp functions,'' is an attempt to eliminate that impression. Elsewhere in my comments I suggested saying very explicitly that generic functions are named in the same way as regular functions, and describing quite explicitly the way that defmethod and defgeneric-options call symbol-function, so this can be folded into that. We're agreeing with each other, and we just need to wring out ambiguities of English. The definition of superclass should really read.... Your revised definition is good. Moon writes about ``classes at or above a given class'': ``Ugh! Can't we find a more concise term for this?'' It's not worse than ``less than or equal,'' which was the model for it. I, apparently, was the only person to try to think of a name, so someone else should propose one. I've proposed one. Several times. Remember "component"? Moon writes: ``This whole paragraph doesn't make complete sense, because there is not -one- local precedence order; there is a separate local precedence order for each component class, and all of them are taken into account.'' And then he proposes an alternate explanation. I think that breaking things down into a lattice with ordered direct superclasses makes understanding easier than clumping things together. Either you didn't understand what I said or I didn't understand what you just said. I don't see that any concepts that ought to be separate would be clumped together. My suggestion would allow you to eliminate the references to C-sub-l and speak only of C-sub-P (using the terminology in the latest version of the file). It also would not be necessary to speak of the second and third partial order any more. The whole explanation would get simpler. You'd be describing the same program behavior with half as many words and concepts, so it would be correspondingly easier for the reader. It also gives the readers something to hang onto that they already understand - lattices. I'm not sure that's a virtue, since the rules here are different from the rules for lattices and intuition about lattices might be misleading. However, the thought that giving readers a lattice to hang onto might still be useful is why I suggested maybe using lattices as a heuristic. Also, we don't have to think of a name for the class inheritance structure. The description of the computation has been clarified somewhat over what Moon has seen. Actually I was reading your new version. That allowed me to omit a lot of comments addressed to problems in the previous version that you had already corrected. Moon then comments on the ``flood of mathematics'' in the description of the CPL computation. The description of the CPL computation is meant to be precise. We are writing a specification, not a user's guide. Let the companies write user's guides. My own canvassing of readers showed that the explanation based on local rules - the explanation that was in CONCEPTS earlier and which I replaced with the current explanation - was not understandable by a range of people, including algorithms hackers. The most experienced algorithms hackers were not entirely sure that the rules provided a well-defined total ordering, nor did they completely believe that the algorithm would run in reasonable time. I think I was the first to say that the previous explanation was not good. Your replacement explanation is definitely better. I am trying to improve it further with my suggestions. I will need major convincing that a second explanation is needed. Perhaps we need to work on the current one to make it understandable to casual readers, but that is a separate affair. I will take a try at re-writing the computation description using the local precedence order definition Moon suggested. Please note that I did not suggest adding a second explanation. I suggested eliminating unnecessary complexity from the current one (with no thought of casual readers, incidentally), plus adding some motivation (partly for casual readers, partly so the X3J13 committee will be able to understand what we are presenting them with in a reasonable amount of time). In making a proposal, I believe that motivation for why things are proposed to be a certain way is nearly as important as a precise description of the particular way they are proposed to be. This makes it much easier to evaluate the proposal, and it makes implementors likely to implement the proposal with fewer mistakes. Moon writes: ``I found the description of preorder treewalk virtually incomprehensible.`` Gabriel collapses. I really, really find this hard to believe. Let's look at it: ``A preorder treewalk is defined in terms of the order in which classes are visited while performing a process called ``walking from a class.'' The following is a recursive definition of walking from a class. Let C be a class and let C1...Cn be its direct superclasses in the local precedence order. Nodes are visited unless they have already been visited. To walk from C, first C is visited, then we walk from C1, then we walk from C2, and so on until we finally walk from Cn.'' I can write the program to do this from this description. So can I. I don't see what that has to do with it. It took me just as long to understand the English as it would have taken to write and debug the program, and I don't see why we can't do better than that. If we can't, let's put the program in the document and take out the English. This description is about as closely copied from Knuth as it can be, given that we don't have trees and that the same classes can be encountered by different paths.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Jan 87 19:56:36 EST Date: 25 Jan 87 1652 PST From: Dick Gabriel Subject: Moon's comments To: common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: ``Huh? I can't figure out what, if anything, this is supposed to mean.'' This was about a terse comment acncerning naming generic functions. In a previous draft there were several sentences talking about the names of generic functions as if there were such things. ``The name of a generic function is in a certain package and can be...'' ``Typically a generic-function object is stored as the function definition of the symbol that is the name of the generic function...'' These two sentences gave the impression that generic functions are named in a way that functions are not. The sentence Moon objects to, ``The naming conventions for generic functions are precisely the same as those for ordinary Common Lisp functions,'' is an attempt to eliminate that impression. The definition of superclass should really read: We will say that a class $C\sub{n}$ is a {\bit superclass\/} of a class $C\sub{1}$ if there exists a series of classes $C\sub{2},\ldots,C\sub{n-1}$ such that $C\sub{i+1}$ is a direct superclass of $C\sub{i}$, for $1 \leq i Subject: Comments on Concepts chapter 1/23/87 To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870125182731.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Here are my comments on the latest Concepts chapter, except for minor editorial points. Indented text is from the document source. Page numbers are from the Jan 15 version, but should be close. I've omitted comments that have already been resolved in the Jan 23 source; I haven't seen a Jan 23 hardcopy yet, so I might later have more comments on things that were added in that version. p1-3: The naming conventions for generic functions are precisely the same as those for ordinary Common Lisp functions. Huh? I can't figure out what, if anything, this is supposed to mean. A method---also called a {\bit method object}---is a function that can be used in any of the ways that ordinary functions can be used in Common Lisp. Is this intended to imply that FUNCALL of a method object is allowed? I strongly disagree with that. We agreed that FUNCALL of a generic-function object is allowed, but that is an entirely different story. I strongly believe that the standard should specify that methods can only be called by the internal mechanisms of the implementation of generic functions, not directly by the user. A method object contains a method function and a set of {\bit parameter specializers\/} that specify when the given method is applicable. Qualifiers, too. p.1-5: Like other objects, all classes are themselves instances of classes.... This paragraph is too early. Metaclasses should not be mentioned until the basics of classes have been discussed. A good place would be at the end of this subsection, right before \beginsubSection{Defining Classes}. We will say that a class, $C\sub{1}$, is a {\bit superclass\/} of a class, $C\sub{n}$, if there exists series of classes, $C\sub{2},\ldots,C\sub{n-1}$ such that $C\sub{i+1}$ is a direct superclass of $C\sub{i}$, for $1 \leq i "a series" The last occurrence of "superclass" should be "subclass" (no wonder no one could understand this paragraph!). We refer to the set of classes consisting of some given class $C$ along with all of its superclasses as ``the classes at or above $C$.'' Ugh! Can't we find a more concise term for this? At least in the latest version (unlike Jan 15) the term seems to be used consistently. Classes are organized into a {\bit lattice}, which gives them a.... This whole paragraph doesn't make complete sense, because there is not -one- local precedence order; there is a separate local precedence order for each component class, and all of them are taken into account. The discussion would be clearer if the local precedence order of a class was defined to be the list formed by consing the name of the class onto the front of its list of direct superclasses. This local precedence order, as a total order, expresses all of the constraints. The computation of the overall class precedence list can be described entirely in terms of the local precedence lists, without the confusing extra complexity of the lattice. The lattice concept could be dumped entirely, or could be retained for explanatory purposes in other parts of the document, but when describing the class precedence list it just gets in the way. Thus I would rewrite these two paragraphs as follows: When a class is defined, the order in which its direct superclasses are mentioned in the defining form is important. Each class has a {\bit local precedence order\/}, which is a list consisting of the class, followed by its direct superclasses in the order mentioned in the defining form, followed by the class {\bf t}. Each class has a {\bit class precedence list}, which is a total order on the set of classes at or above a given class. The total order is expressed as a list ordered from most specific to least specific. The class precedence list is used in several ways. In general, more specific classes override features inherited from less specific classes. The method selection and combination process uses the class precedence list to order methods from most specific to least specific. When one class has several superclasses, a more specific class can override some of the options declared in the {\bf defclass} form of a less specific class. A class precedence list is always consistent with the local precedence order of each class in the list. The classes in each local precedence order appear within the class precedence list in the same order. If the local precedence orders are inconsistent with each other, no class precedence list can be constructed, and an error will be signalled. The class precedence list and its computation will be discussed at length below. p.1-7: The detailed description of the syntax of defclass ("first element", "second element") might better be left to Chapter 2. Too much information from preceding and following sections is duplicated here, and often what is said here is incomplete or incorrect. If a local description of a slot is provided, it completely overrides any description of that slot inherited from a superclass. This is not true. The fourth element is the set of class options, which.... The class options are the rest of the form, not an element of the form. p.1-8: The concept of slot is never really explained. "The Structure of Instances" would be a good section in which to explain it. The explanation should start with the concept that there is a list of names (symbols, with the same restrictions as variable names in LET) not containing any duplicates, and with each name can be associated a value and some slot options. The scope of the association depends on the :allocation. Creating a type by means of {\bf defstruct} creates a class in this lattice. Such a class is an instance of {\bf structure-class} and a direct subclass of the class that corresponds to the type given as its {\bf :includes} argument. If no classes are included, the new class is a direct subclass of the class {\bf t}. I think the last sentence should be deleted, because I'm not sure it's true and because I don't think it matters whether something is a direct subclass of T. As far as I can tell that either has no effect, or makes the class precedence list computation signal an error, depending on whether T is in the middle or at the end of the list of direct superclasses. Just qualify the second-to-last sentence with "if any." p1-12 {Inheritance}: In spite of several go-rounds, the slot inheritance discussion is complicated and confusing. This may be partly a reflection of the design, but lacking any ideas for improving the design right now, let me suggest improving the discussion. I think a lot of the problem is the confusing concept of slots provided by or belonging to a superclass; there is no such thing: only instances have slots, what a superclass provides is a slot-description, not a slot. Also I think the whole superclass/subclass orientation of the presentation is more confusing than helpful. Instead, I would speak of slot descriptions provided by classes in the class precedence list. Case 1 in the existing text is the case where only one class provides a slot description, which is quite simple. The existing explanation is almost okay. The other case is where -more- -than- -one- class in the class precedence list provides a slot description with a given name. There is always only one slot created, and its characteristics involve some combination of the several slot descriptions. The slot options provided by the various slot descriptions combine as follows: :allocation comes from the most specific slot description -- if it doesn't specify :allocation explicitly, :allocation :instance by default. :initform comes from the most specific slot description that specifies :initform explicitly. :type is the AND of all the :types. [At least, this seems to be the only rule that makes it possible for the compiler to exploit the :type information at all, other than requiring each slot-description to specify exactly the same :type.] :reader and :accessor create methods at defclass time, and these methods are applicable, but the slot options themselves don't do anything at class combination time. This should be a lot simpler. Somewhere (I have it written on the Inheritance page, but I think it might belong with the not-yet-existent general discussion of slots) it should be clarified that methods know only the slot names. (The above isn't strictly true now that :type has been introduced. Methods know the slot names -and- types, which is why types can only be restricted, not expanded, by inheritance.) Thus a method expecting to access a :allocation :class slot, applied to an instance of a subclass that redefines the slot with that name to be a :allocation :instance slot, will access the instance slot instead. Question about :allocation :none. Does this mean that there is no slot by this name, or that there is a slot but an error is signalled if you access it? The difference would be in the set of lexically apparent variables created by with-slots. I think the answer should be that there is a slot. p.1-24 {Determining the Class Precedence List} (moved to an earlier page in the latest version of the document, which I think was an improvement): When one class has several superclasses, a more specific class can override.... This happens even with one superclass, so delete the "when" clause. See my previous comment that the local precedence order concept provides all of the constraints and the lattice concept is not needed. With that simplification, I think this way of describing the class precedence computation would be okay with me. My only other complaint is that the original concept of local rules controlling what happens, so that the programmer can understand things locally without having to take a global view, has been buried under a flood of mathematics. The concept is still there, but it takes a determined reader to find it. I think it would be better to start this section with that concept, perhaps using some text from the previous version of the section, and use that as motivation for the mathematical discussion. I found the description of preorder treewalk virtually incomprehensible. I know what it's trying to say, and agree with that, but the way it is said needs to be rewritten or clarified. p.16 {Introduction to Generic Functions}: Typically a generic function object is stored as the function definition of the symbol that is the name of the generic function. This sentence should be put in its own paragraph and augmented with a clarification that this is the -only- association from the name to the generic function. Both defgeneric-options and defmethod use symbol-function of the name to find the generic-function. The next paragraph only mentions defgeneric-options, but most of what it says applies to defmethod, too. (And the -setf versions also, of course. Their difference is that they use get-setf-generic-function in place of symbol-function.) SETF generic functions are never explained anywhere. Most Symbolics design reviewers found them completely incomprehensible. A section explaining them should be added between {Introduction to Generic Functions} and {Introduction to Methods}. If no one can be found to write this, put in a blank section as a placeholder. p.1-17 {Introduction to Methods}: Only required parameters can be specialized. I would add "A future extension might allow optional and keyword parameters to be specialized" so that people know where we are coming from. A parameter specializer is a list, {\tt ({\it variable-name parameter-specializer\/})}, where {\it parameter-specializer\/} is one of: This is using "parameter specializer" to mean two different things. Someone changed the previous text "A specialized parameter specifier is a list..." to this; the previous version was at least correct, although awkward. "Parameter specifier" is a term defined in CLtL. The separate bullets for "any class" and "standard type class" are extremely confusing. The reader wonders why "standard type class" is mentioned separately and whether "any class" somehow doesn't include it. Note that a parameter specializer cannot be a type specifier list, such as {\tt ({\bf vector single-float})}. This seems to be the last residue of a discussion of the relationship between parameter specializers and type-specifiers. I strongly believe that the rest of that discussion should be restored. The point is that parameter specializers are a subset of type-specifiers, and thus discrimination can be understood in terms of typep, and more importantly, we are extending the Common Lisp type system upward compatibily, not creating yet another type system. Also the requirement that Common Lisp be modified to include (deftype quote (object) `(member ,object)) has been removed from the document and needs to be restored. p1-19 {Method Selection and Combination}: The \numitem headings don't stand out adequately. Someone who knows TEX should fix this section to use a more appropriate TEX feature. At the end of step 2, or perhaps at the end of the section, add a remark that two methods with identical specializers but different qualifiers will not be ordered by this algorithm. Normally this is okay, because the two methods will play different roles in the effective method because they have different qualifiers, and no matter which order they appear in, in the result of step 2, the effective method will be the same. If the two methods play the same role, so that their order matters, implementations are encouraged to signal an error (this would happen as part of qualifier-pattern matching in define-method-combination). I don't mind requiring instead of encouraging signalling an error, but this verges on program development tools so perhaps others would object. It is impossible for there to be two methods for a single generic function with identical specializers -and- identical qualifiers, because defining the second would replace the first (see defmethod, add-method). p1-27: {Short Form of Define-method-combination}: I'm tempted to eliminate the operator as a positional argument and replace it with a :operator keyword option. The operator is usually the same symbol as the name. p1-28 {Long Form of Define-method-combination}: Could someone who knows TEX convert the syntax expression to TEX? Thus a qualifier-pattern can be the empty list {\bf ()} (which matches primary methods, which are always unqualified) This is wrong. "Primary methods" and "unqualified methods" are two separate concepts. For standard method combination they happen to be equal sets of methods, but that's essentially a coincidence. The correct parenthetical expression is "(which matches unqualified methods)". p1-34 Meta objects: \CLOS\ provides several predefined meta-objects: {\bf generic-function} (the default class of a generic function), {\bf method} (the default class of a method), {\bf class} (the default class of a user-defined class), and the standard method-combination type). I thought method combination types were not objects in their own right, but were just methods. I have no real objection to making them into objects, although it doesn't seem like anything would be gained by doing so. I also thought we were going to change these names, but maybe that discussion is still ongoing.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jan 87 18:30:48 EST Date: 24 Jan 87 1528 PST From: Dick Gabriel Subject: Alternatives To: common-lisp-object-system@SAIL.STANFORD.EDU We should avoid writing alternatives into the document at almost any cost. The purpose of this subgroup is to present our best proposal with as few choices left open as possible. If we leave alternatives in the document we invite perpetual and irritating debate. I do not want to have two nearly identical define-method-combination writeups. I do not want a precise CPL computation section followed by a ``you can predict'' section. If {we | this group | this committee | Danny, Gregor, Moon, and I} {cannot | will not} {make | come to | agree upon} {a reasonable | an acceptable} {decision | consensus}, how can the committee as a whole? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jan 87 00:43:52 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 23 Jan 87 21:38:58 PST Received: from ti-csl by csnet-relay.csnet id ba04256; 24 Jan 87 0:26 EST Received: from Jenner (jenner.ARPA) by tilde id AA23277; Fri, 23 Jan 87 15:17:06 cst To: Bobrow.pa@XEROX.COM Cc: common-lisp-object-system@SU-AI.ARPA Date: 23-Jan-87 15:15:45 From: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET Message-Id: Subject: Re: New version of define-method-combination The following is an alternate version of define-method-combination. It has the following properties: 1) There is only one define-method-combination form. It allows easy support of around methods, and supports error checking. Defining simple combinations is easy and concise. Sounds good to me. 2) There is no lambda-list. It also omits the keyword :order from the method specifier. defgeneric-options is extended to store parameters in the generic function. This can be used to support features like reversed order for combination if desired. There is a problem in tying up the parameters of the method combination to the generic function. If the user has to access those from the generic function, extensions where there can be several method combinations defined for the same generic function will not work. Parameters passed explicitly to the method combination function avoid this problem. 4) It uses the keyword :call-next-method instead of :around in make-method-call. This eliminates confusion with respect to use of this keyword with primary methods, and with respect to the new :around keyword in method-combination options used to support around methods. Thus (make-method-call primary :around t) becomes (make-method-call primary :call-next-method t) This renaming needs to be carried through to the functi chapter. I don't have any feeling for this one. Text that looks similar to that in the concep chapter was in fact taken from there, and no changes were made in most paragraphs. I am recommending that we include this instead of the current version in concep. The rest of the message (TEX source) is painful to read. *** Extension to defgeneric-options defgeneric-options {\bf :method-combination } The list that is cdr of the option form is stored in the generic-function object in the slot {\it method-combination\/}. Example: (:method-combination and :most-specific-last) stores {\it (and :most-specific-last)\/} in the slot {\it method-combination\/}. The body of compute-effective-method can get this information from the generic-function using the slot-accessor. *** *** Alternate version of define-method-combination*** \beginSection{Declarative Method Combination} \beginsubSection{Defining Form for Method Combination} The programmer can define new forms of method combination using the {\bf define-method-combination} macro. This allows customization of step~3 of the method combination procedure. The body of {\bf define-method-combination\/} used resembles {\bf defmacro\/} in that the body is an expression that computes a Lisp form, usually using backquote. Thus, an arbitrary combination of methods can be constructed. %The following syntax expressions need to be converted to TEX (DEFINE-METHOD-COMBINATION name [macro] ({method-group-specifier}+ ) [({method-combination-option}*)] {form}*) {method-group-specifier}:= (variable { {qualifier-pattern}+ | predicate} {keyword argument}*) The method-group-specifier predicate is a good thing to have. {method-combination-option} :=combination-keyword value {\bf :around} {\it boolean\/} If the argument is true (not {\bf nil}), then the form returned by the body of define-method-combination is augmented to support :around methods. See examples below. This keyword option is a convenience and does not add any expressive power. It is provided so that programmers are not tempted to omit support for :around methods. Methods matching (:around) are extracted first from the list of applicable methods. If {\bf :around} is not specified, it defaults to {\bf nil}. The argument {\it boolean\/} is not evaluated. ;The default method-combination, the hard way (define-method-combination standard ((around (:around)) (before (:before)) (primary ()) (after (:after))) (unless primary (method-combination-error "A primary method is required.")) (make-method-call `(,@around (multiple-value-prog2 ,(make-method-call before) ,(make-method-call primary :call-next-method t) ,(make-method-call (reverse after)))) :call-next-method t)) ;The default method-combination using keyword options (define-method-combination standard ((before (:before)) (primary () :required t) (after (:after))) (:around t) (multiple-value-prog2 ,(make-method-call before) ,(make-method-call primary :call-next-method t) ,(make-method-call (reverse after)))) I am not sure that the :around keyword actually simplifies things. It hides the around mechanism, but seeing the actual code helps people to get the right model in their minds. Despite these points, we seem to be converging on this issue. Patrick.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 23 Jan 87 20:32:52 EST Received: from Cabernet.ms by ArpaGateway.ms ; 23 JAN 87 15:39:45 PST Date: 23 Jan 87 15:38 PST From: Gregor.pa@Xerox.COM Subject: bug in compute-class-precedence-list in sun CL In-reply-to: primerd!DOUG@ENX.Prime.PDN.ARPA's message of 22 Jan 87 09:51:17 EDT To: primerd!DOUG@ENX.Prime.PDN.ARPA cc: COMMONLOOPS.PA@Xerox.COM Message-ID: <870123-153945-2736@Xerox> I am in the process of getting a patch from Lucid for this problem. Until then, the patch which Doug Rand sent out will fix it. (the one that replaces the hairy nested labels with a support function and a flet).  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 16:55:06 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jan 87 13:49:01 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 50466; Fri 23-Jan-87 16:49:43 EST Date: Fri, 23 Jan 87 16:47 EST From: David A. Moon Subject: Symbolics design review To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870123164705.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Symbolics is having an ongoing in-house design review of the proposed standard. The reviewers understand that the proposal isn't finished yet, but it seemed like a good idea to get some review before we mail it out to the X3J13 folks. We had a meeting yesterday. Here are some highlights of comments that people had. I've omitted editorial comments on the document (although some were quite important) and also omitted comments that were minor, that only indicated that things were hard to understand, or where I wanted to think about it more before I could figure out how to summarize what was said. I'll keep relaying additional comments as they crystallize. The proposal in its current form is quite incomplete. Many functions that one would expect to be there are missing, for instance there are functions get class and method objects but little you can do with one once you've gotten one. I explained that these were in the meta-object protocol that wasn't written yet. It's really not that simple; there is a gray area between full meta-objects (where the programmer is trying to use the standard facilities as an assist in creating her own object-oriented programming system) and simply wanting to access the standard meta-objects without creating any new meta-object classes. The lambda-list congruence rules need re-examination. Detailed comments later. Several people thought WITH-SLOTS was awfully verbose. No real conclusions were drawn other than that Symbolics would continue to support the Flavors' syntax of DEFMETHOD, with its useful implicit WITH-SLOTS. Everyone found :allocation :none confusing and ill-motivated. A real example of how to use it would help a lot. At first it seems to be subtractive inheritance, a la Alan Snyder's Common Objects, but this example shows that it doesn't do that: (defclass c1 () (a :initform 2)) (defclass c2 (c1) ((a :allocation :none))) (defclass c3 (c2) (a)) and the A slot of a C3 is initialized to 2. The group also wasn't happy with the idea that c2 "breaks" c1. Maybe :allocation :none is really for something else, such as "abstract" slots that show up in with-slots and have access methods, but aren't explicitly stored? Anyway we'd like to see some motivation and an example, or if there isn't any then we think it should be flushed, because it is so confusing and hard to explain. Many things are not explained very well and people couldn't understand them from the document; they had to be explained verbally. I guess we ought to put together a list of these. ADD-METHOD, REMOVE-METHOD, GET-METHOD don't seem to work right; things that should work signal an error (details later). The Design Rationale section is out of date and extremely incomplete. It's important to flesh this out. That's it for today.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 15:49:49 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jan 87 11:41:56 PST Received: from Cabernet.ms by ArpaGateway.ms ; 23 JAN 87 11:40:21 PST Date: 23 Jan 87 11:40 PST From: Gregor.pa@Xerox.COM Subject: Re: change-class and class redefinition In-reply-to: David A. Moon 's message of Thu, 22 Jan 87 00:57 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870123-114021-2379@Xerox> Moon says: However, this is missing the major point. I believe that "copying the slots" is the wrong model of what is happening. A slot is a conceptual entity, not a word of computer storage at a particular address. No slot contents are being copied or changed. Some slots are being deleted, some other slots are being newly created and therefore initialized, and the rest of the slots remain unchanged. If a particular implementation happens to work by moving the representation of a slot from location 1000 to location 1492, that's an implementation detail and not something the programmer should see. At the level of abstraction that programmers should deal with, a slot is a slot and nothing is being copied. I like this argument, and am now happy with the change-class, class-changed part of this.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 15:48:06 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jan 87 11:41:42 PST Received: from Cabernet.ms by ArpaGateway.ms ; 23 JAN 87 11:37:05 PST Date: 23 Jan 87 11:37 PST From: Gregor.pa@Xerox.COM Subject: Re: standard-type-classes In-reply-to: David A. Moon 's message of Fri, 23 Jan 87 14:21 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870123-113705-2375@Xerox> Moon says: I agree. Actually I'd like to strengthen it: to me, class-of is like type-of and shouldn't be guaranteed portable. Specifically, when the standard says an object is "of class X", that should -always- mean that class-of the object is allowed to be a subclass of X. To be more specific, it isn't portable to say. (eq (class-of *terminal-io*) 'stream), but it is portable to say (member (class-named 'stream) (class-class-precedence-list (class-of *terminal-io*))). The distiniction I am drawing is that class-of, unlike type-of is required to return the most specific class of which its argument is an instance. But, when we specify classes, as when we specify types, we mean that the object in question must be an instance of that class or some subclass.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 15:47:53 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jan 87 11:25:08 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 50244; Fri 23-Jan-87 14:26:04 EST Date: Fri, 23 Jan 87 14:23 EST From: David A. Moon Subject: Re: Inheritance of Methods To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870122-163948-1501@Xerox> Message-ID: <870123142329.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 16:40 PST From: Masinter.pa@Xerox.COM Here's another alternative which is more precise than "inheritance of behavior": "Inheritance of method applicability" That is, what subclasses inherit from their superclasses is the applicability of methods to instances of them. In some cases, the class of more than one argument comes into play, but the share of responsibility for determining applicability is inherited. That's good.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 15:46:51 EST Date: 23 Jan 87 1241 PST From: Dick Gabriel Subject: Strenuously To: common-lisp-object-system@SAIL.STANFORD.EDU Seeing how this how much Moon would object to Danny's alternative to define-method-combination, we should possibly talk this one out face-to-face in March. Which brings up the topic: Shall we meet before the X3J13 meeting in Palo Alto to iron out some more details? I'd like to say that the current writeup of method combination is vastly better than anything I've seen so far, and that I don't quite understand the ramifications of Danny's variant. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 15:41:57 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jan 87 12:36:15 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 50329; Fri 23-Jan-87 15:09:56 EST Date: Fri, 23 Jan 87 15:07 EST From: David A. Moon Subject: Re: standard-type-classes To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870123-113705-2375@Xerox> Message-ID: <870123150719.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 23 Jan 87 11:37 PST From: Gregor.pa@Xerox.COM The distinction I am drawing is that class-of, unlike type-of is required to return the most specific class of which its argument is an instance. But, when we specify classes, as when we specify types, we mean that the object in question must be an instance of that class or some subclass. I agree. (My previous message saying class-of is like type-of might have been taken as disagreement, but it wasn't.)  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 15:06:41 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jan 87 12:03:57 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 50251; Fri 23-Jan-87 14:28:15 EST Date: Fri, 23 Jan 87 14:25 EST From: David A. Moon Subject: Re: change-class and class redefinition To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870122-165918-1546@Xerox> Message-ID: <870123142540.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 17:00 PST From: Danny Bobrow Then "specializable" means "this standard says you are supposed to specialize this function as part of your normal programming", which is not the same as the negation of "it is impossible to specialize this function." How about the term "tailorable function" for the sense of user is expected to be able to tailor the system by providing a special method? Tailorable or specializable are equally okay with me. print-object this one is callable. The second sentence of its documentation says it isn't. Dave, Did you see (and have a quick reaction) to the alternative define-method-combination. I gave it a quick read but I'm not working on method combination this month. It's too easy to use up all the time polishing the last details of one issue to the total neglect of other equally important issues. I wanted the bit of: how much would you object if this were put in instead of the writeup you worked on? Strenuously. (It is a start) If you object too much, and if we are not going to argue it out before the draft goes out, then we should put in both choices. Go ahead.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 14:48:41 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jan 87 11:41:42 PST Received: from Cabernet.ms by ArpaGateway.ms ; 23 JAN 87 11:37:05 PST Date: 23 Jan 87 11:37 PST From: Gregor.pa@Xerox.COM Subject: Re: standard-type-classes In-reply-to: David A. Moon 's message of Fri, 23 Jan 87 14:21 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870123-113705-2375@Xerox> Moon says: I agree. Actually I'd like to strengthen it: to me, class-of is like type-of and shouldn't be guaranteed portable. Specifically, when the standard says an object is "of class X", that should -always- mean that class-of the object is allowed to be a subclass of X. To be more specific, it isn't portable to say. (eq (class-of *terminal-io*) 'stream), but it is portable to say (member (class-named 'stream) (class-class-precedence-list (class-of *terminal-io*))). The distiniction I am drawing is that class-of, unlike type-of is required to return the most specific class of which its argument is an instance. But, when we specify classes, as when we specify types, we mean that the object in question must be an instance of that class or some subclass.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 14:38:05 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jan 87 11:31:26 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 50251; Fri 23-Jan-87 14:28:15 EST Date: Fri, 23 Jan 87 14:25 EST From: David A. Moon Subject: Re: change-class and class redefinition To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870122-165918-1546@Xerox> Message-ID: <870123142540.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 17:00 PST From: Danny Bobrow Then "specializable" means "this standard says you are supposed to specialize this function as part of your normal programming", which is not the same as the negation of "it is impossible to specialize this function." How about the term "tailorable function" for the sense of user is expected to be able to tailor the system by providing a special method? Tailorable or specializable are equally okay with me. print-object this one is callable. The second sentence of its documentation says it isn't. Dave, Did you see (and have a quick reaction) to the alternative define-method-combination. I gave it a quick read but I'm not working on method combination this month. It's too easy to use up all the time polishing the last details of one issue to the total neglect of other equally important issues. I wanted the bit of: how much would you object if this were put in instead of the writeup you worked on? Strenuously. (It is a start) If you object too much, and if we are not going to argue it out before the draft goes out, then we should put in both choices. Go ahead.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 14:28:19 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jan 87 11:23:10 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 50242; Fri 23-Jan-87 14:24:24 EST Date: Fri, 23 Jan 87 14:21 EST From: David A. Moon Subject: Re: standard-type-classes To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870122-220155-1729@Xerox> Message-ID: <870123142149.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 22:03 PST From: Masinter.pa@Xerox.COM "Question. Should the same object have the same class (with the same name) in all standard Common Lisp systems? What do we do about the float set which has several different classes that may be collapsed. This seems like a reason to omit (some) implementation dependent classes." There are a number of examples where it seems clear that we want to make no such requirement. For example, we don't want to require that implementations *not* use the class system to implement stream classes, e.g. (class-of (make-two-way-stream a b)) should not be required to be the class STREAM but merely STREAM or some subclass of STREAM. I think the floating point classes are in the same category, i.e., they are "implementation-dependent classes" and code that discriminates on them is allowed and implementation-dependent. I agree. Actually I'd like to strengthen it: to me, class-of is like type-of and shouldn't be guaranteed portable. Specifically, when the standard says an object is "of class X", that should -always- mean that class-of the object is allowed to be a subclass of X. It's worth pointing out again that the distinction between SINGLE-FLOAT and DOUBLE-FLOAT is qualititatively different from the distinction between FIXNUM and BIGNUM. The float types have behavioral differences and implementations aren't allowed to convert one into the other, with two exceptions: the clearly defined rules of floating point contagion; and an implementation is allowed to collapse these into a single type. FIXNUM and BIGNUM on the other hand are purely implementation types and behave identically (except for speed).  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jan 87 01:04:05 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 22:01:31 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 22:01:55 PST Date: 22 Jan 87 22:03 PST From: Masinter.pa@Xerox.COM Subject: Re: standard-type-classes In-reply-to: Danny Bobrow 's message of 22 Jan 87 15:10 PST To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870122-220155-1729@Xerox> "Question. Should the same object have the same class (with the same name) in all standard Common Lisp systems? What do we do about the float set which has several different classes that may be collapsed. This seems like a reason to omit (some) implementation dependent classes." There are a number of examples where it seems clear that we want to make no such requirement. For example, we don't want to require that implementations *not* use the class system to implement stream classes, e.g. (class-of (make-two-way-stream a b)) should not be required to be the class STREAM but merely STREAM or some subclass of STREAM. I think the floating point classes are in the same category, i.e., they are "implementation-dependent classes" and code that discriminates on them is allowed and implementation-dependent.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 20:06:38 EST Date: 22 Jan 87 1701 PST From: Dick Gabriel Subject: Inheritance of Methods To: Common-lisp-object-system@SAIL.STANFORD.EDU I agree with the following statement: a subclass inherits methods in the sense that any method applicable to an instance of a class is also applicable to instances of any subclass (all other arguments to the method being the same). For methods that have only one specialized argument, for example the accessors of a class, we say that subclasses inherit the use of those methods from the super class. I do not agree that we should say that. I think it is forcing an inappropriate metaphor too far. On a related topic. Suppose C1 is a class with a slot named FOO and an accessor method, C2 is a subclass with FOO subtracted out (the :allocation is :none for that slot), and suppose that C3 is a subclass of C2 without an accessor method. Does the accessor method for FOO work on instances of C2? Of C3? Are errors signalled? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 20:05:32 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 16:59:54 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 16:59:18 PST Date: 22 Jan 87 17:00 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: change-class and class redefinition In-reply-to: David A. Moon 's message of Thu, 22 Jan 87 18:58 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870122-165918-1546@Xerox> Then "specializable" means "this standard says you are supposed to specialize this function as part of your normal programming", which is not the same as the negation of "it is impossible to specialize this function." How about the term "tailorable function" for the sense of user is expected to be able to tailor the system by providing a special method? print-object this one is callable. I agree with the rest of your examples, reprinted here to try out the word tailorable. make-method is callable, not tailorable, and not generic, and get-method is callable, generic, and not tailorable at the outer layer of the standard, Dave, Did you see (and have a quick reaction) to the alternative define-method-combination. I gave it a quick read but I'm not working on method combination this month. It's too easy to use up all the time polishing the last details of one issue to the total neglect of other equally important issues. I wanted the bit of: how much would you object if this were put in instead of the writeup you worked on? (It is a start) If you object too much, and if we are not going to argue it out before the draft goes out, then we should put in both choices. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 19:57:11 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 16:53:59 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 16:48:22 PST Date: 22 Jan 87 16:50 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: standard-type-classes In-reply-to: David A. Moon 's message of Thu, 22 Jan 87 18:49 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870122-164822-1526@Xerox> The draft specification as it stands contains neither CLASS-NAME nor anonymous classes. Can we assume that someone is going to get their act together and propose those at some point? The document should say something like: Classes are first class objects. Unnamed classes can exist, created by, for example, by (MAKE-INSTANCE class direct-supers ...) The user interface suports the notion of class-names to allow defclass definitions to use names. The function interface to those classes defined by DEFCLASS consists of: (CLASS-NAMED &optional (no-error ()) which returns the class currently having the name or signals an error if there is no such class if no-error is NIL. If no-error is non-NIL, then CLASS-NAMED returns NIL if there is no such class. (CLASS-NAME class &optional (unnamed-class-response 'NO-NAME)) This function returns the name originally provided by defclass if this class still has that name, the value of unnamed-class-response if the class has none. It is a hint in that it is NOT guaranteeed that (CLASS-NAMED (CLASS-NAME class)) = class The "natural" value of unnamed-class-response is () but this conflicts with our desire to have a class named NIL. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 19:44:57 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 16:42:36 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 16:39:48 PST Date: 22 Jan 87 16:40 PST From: Masinter.pa@Xerox.COM Subject: Re: Inheritance of Methods In-reply-to: David A. Moon 's message of Thu, 22 Jan 87 19:07 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870122-163948-1501@Xerox> I don't feel very strongly about the wording, and was just wanting to offer some alternatives. Here's another alternative which is more precise than "inheritance of behavior": "Inheritance of method applicability" That is, what subclasses inherit from their superclasses is the applicability of methods to instances of them. In some cases, the class of more than one argument comes into play, but the share of responsibility for determining applicability is inherited. Larry (I started to explain how you could call the ownership of multi-methods a partnership where the left-most class was the senior partner, but that's certainly going to far down metaphor road. ouch -- lm :-)  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 19:14:59 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Jan 87 16:09:42 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 49698; Thu 22-Jan-87 19:10:30 EST Date: Thu, 22 Jan 87 19:07 EST From: David A. Moon Subject: Re: Inheritance of Methods To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870122-105900-1394@Xerox> Message-ID: <870122190755.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 10:59 PST From: Masinter.pa@Xerox.COM What gets inherited is more than accessors and less than methods, that is, a subclass inherits the accessors, since, in some sense, the accessors "belong" to the class. We are reluctant to say that subclasses inherit "methods" because a multi-method may not "belong" to any one class, and the analogy of inheritance implies the analogy of possesion. I don't think that this slight flaw in the analogy is good grounds for abandoning it, since it's such a powerful analogy. Multi-methods are inherited from the several classes they belong to, by all of the subclasses of each of those classes. I don't think this is stretching the analogy out of shape. What is important is that behavior, reflected in the availability of accessors and the participation in method lookup, is inherited. What do you think of "Inheritance of Behavior" for a section title? The document is already too vague. I don't think we should be adding more vague words like "behavior" if we can help it. Everyone knows it is really methods we are talking about, so we should say what we mean.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 19:09:43 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Jan 87 16:02:16 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 49676; Thu 22-Jan-87 19:00:55 EST Date: Thu, 22 Jan 87 18:58 EST From: David A. Moon Subject: Re: change-class and class redefinition To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870122-145237-1241@Xerox> Message-ID: <870122185820.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 14:54 PST From: Danny Bobrow I like the name class-changed. I also agree with DLW that we should invent a term for generic-functions which you are not supposed to call yourself. We will need this term in the meta-object protocol chapter. As an initial proposal, we could have "callable functions", "specializable functions", and "functions that are both callable and specializable". If they aren't specializable it's none of your business whether or not they are generic, which is why I said "functions" instead of "generic functions." Specializable means you can define methods for them. I don't claim this is the best terminology in the world! I agree we need a term. Ones I like slightly better are "external" and "internal" instead of callable/not callable since clearly someone calls these functions someplace. It is just whether they are internal to the implementation or not. The reason I don't like "external" and "internal" is that these seem to refer to the visibility of the name. An "internal" function that is "specializable" by someone on the outside seems like a contradiction to me. In other words, nothing obviously says that "external" and "internal" refer to the calling side rather than the specializing side. We already have the notion of specializable which means that methods may be defined for a function that otherwise has none. But is this a case in which what is intended by non-speicalizable does not imply that there are no methods -- only that "user" whoever that is, should not add any more. Right. Under what circumstances does this make sense. Why should functions ever be unspecializable. Only for implementation reasons I feel (where assumptions have been bound into the code that is compiled). Then "specializable" means "this standard says you are supposed to specialize this function as part of your normal programming", which is not the same as the negation of "it is impossible to specialize this function." I can see this is going to be hard to explain in a document, because there are all these subtle distinctions. To take examples from the current draft proposal, print-object is specializable and not callable, while make-method is callable, not specializable, and not generic, and get-method is callable, generic, and not specializable at the outer layer of the standard, but may be specializable (for some reason that isn't obvious to me) at the meta-object layer of the standard. I don't know whether these examples make it clearer or more obscure! ps Dave, Did you see (and have a quick reaction) to the alternative define-method-combination. I gave it a quick read but I'm not working on method combination this month. It's too easy to use up all the time polishing the last details of one issue to the total neglect of other equally important issues.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 19:09:21 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Jan 87 16:02:53 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 49678; Thu 22-Jan-87 19:02:13 EST Date: Thu, 22 Jan 87 18:59 EST From: David A. Moon Subject: Re: Inheritance of Methods To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870122-143844-1217@Xerox> Message-ID: <870122185939.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 14:41 PST From: Danny Bobrow We can say that a subclass inherits methods in the sense that any method applicable to an instance of a class is also applicable to instances of any subclass (all other arguments to the method being the same). For methods that have only one specialized argument, for example the accessors of a class, we say that subclasses inherit the use of those methods from the super class. I agree with this.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 19:00:13 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Jan 87 15:51:14 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 49659; Thu 22-Jan-87 18:51:52 EST Date: Thu, 22 Jan 87 18:49 EST From: David A. Moon Subject: Re: standard-type-classes To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870122-150825-1274@Xerox> Message-ID: <870122184913.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Jan 87 15:10 PST From: Danny Bobrow NIL seems like a good name for the bottom of the class lattice, but if CLASS-NAME can return NIL for unnamed classes, then NIL isn't such a good name (too bad though). How about BOTTOM, or NOT-T, or EMPTY? Unless Common Lisp is going to change the name of the type specifier for the bottom of its type (not-really-a-)lattice, I think it's much better to change what CLASS-NAME returns for unnamed classes than to change the name of the bottom class. If we need a bottom class, I think it needs to be named NIL, because that is less confusing to a Common Lisp programmer than any other name. I don't have a strong opinion yet on whether or not we need a bottom class. The draft specification as it stands contains neither CLASS-NAME nor anonymous classes. Can we assume that someone is going to get their act together and propose those at some point?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 18:34:56 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 15:19:29 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 14:38:44 PST Date: 22 Jan 87 14:41 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Inheritance of Methods In-reply-to: Masinter.pa's message of 22 Jan 87 10:59 PST To: Masinter.pa@Xerox.COM cc: skeene@STONY-BROOK.SCRC.Symbolics.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870122-143844-1217@Xerox> We can say that a subclass inherits methods in the sense that any method applicable to an instance of a class is also applicable to instances of any subclass (all other arguments to the method being the same). For methods that have only one specialized argument, for example the accessors of a class, we say that subclasses inherit the use of those methods from the super class. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 18:34:12 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 15:19:49 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 15:08:25 PST Date: 22 Jan 87 15:10 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: standard-type-classes In-reply-to: Dick Gabriel 's message of 21 Jan 87 14:21 PST To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870122-150825-1274@Xerox> I think that the minimum standard for having a class is that a) all instances of the class (or any subclass) can be identified as being of that type. FUNCTION has a problem in that respect wrt lists. b) all instances have to support a well defined ordering on any two classes of which it is a subtype. ATOM cannot be a class i.e. which is more specific a STREAM or ATOM (unless of course we install ATOM above all user defined types etc.). c) The class of any instance should be quickly determinable. Thus standard-char might be a case which is outlawed since it is a char that is member of a set. Probably bit (represented by an integer that is either 1 or 0) also falls in this category. Question. Should the same object have the same class (with the same name) in all standard Common Lisp systems? What do we do about the float set which has several different classes that may be collapsed. This seems like a reason to omit (some) implementation dependent classes. NIL seems like a good name for the bottom of the class lattice, but if CLASS-NAME can return NIL for unnamed classes, then NIL isn't such a good name (too bad though). How about BOTTOM, or NOT-T, or EMPTY? danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 18:33:15 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 15:20:02 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 15:16:01 PST Date: 22 Jan 87 15:18 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: [Gregor Kiczales : Re: STANDARD-TYPE-CLASS] To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870105-135407-3657@Xerox> *** There were no comments on the following proposal from Gregor. I think it is correct. Do we have a consensus on this? The most controversial is the mixin stuff. Please respond right away with at least one of YES NO - and here's what I think no, and I'll get back to this later. I am writing on the meta-object protocol and need to know. **** The concept of built-in-class and standard-type-class as defined by Dick are important and make sense. I think these should be mixin's though since there are several possible reasonable combinations. Something like the following seems right: (defclass class () ()) ;the top (defclass built-in-class-mixin (class) ()) ;microcode knows about these (defclass standard-type-class-mixin (class) ()) ;Steele knows about these (defclass standard-class (class) ()) ;defclass makes these ;;; ;;; Important combinations of the above: ;;; (defclass standard-extensible-class (class standard-type-class-mixin) ()) (defclass standard-built-in-class (built-in-class-mixin standard-type-class-mixin) ()) The following are values that MANY, but not all implementations would return. (class-of (class-named 'pathname)) ==> standard-extensible-class (class-of (class-named 'cons)) ==> standard-built-in-class (class-of (class-named 'stream)) ==> standard-class-mixin These say that: PATHNAME is a standard class defined by Steele, in addition, it can be specified as a direct-superclass in a defclass form. FIXNUM is a standard class defined by Steele. In addition, it is represented "fundamentally" by this Lisp. STREAM is a standard class defined by Steele. It is not represented fundamentally by this Lisp, but it may not be included as a direct superclass in a defclass form.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 18:32:18 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 15:19:35 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 14:52:37 PST Date: 22 Jan 87 14:54 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: change-class and class redefinition In-reply-to: David A. Moon 's message of Thu, 22 Jan 87 00:57 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870122-145237-1241@Xerox> I like the name class-changed. I also agree with DLW that we should invent a term for generic-functions which you are not supposed to call yourself. We will need this term in the meta-object protocol chapter. As an initial proposal, we could have "callable functions", "specializable functions", and "functions that are both callable and specializable". If they aren't specializable it's none of your business whether or not they are generic, which is why I said "functions" instead of "generic functions." Specializable means you can define methods for them. I don't claim this is the best terminology in the world! I agree we need a term. Ones I like slightly better are "external" and "internal" instead of callable/not callable since clearly someone calls these functions someplace. It is just whether they are internal to the implementation or not. We already have the notion of specializable which means that methods may be defined for a function that otherwise has none. But is this a case in which what is intended by non-speicalizable does not imply that there are no methods -- only that "user" whoever that is, should not add any more. Under what circumstances does this make sense. Why should functions ever be unspecializable. Only for implementation reasons I feel (where assumptions have been bound into the code that is compiled). If we can't finish change-class until we finish initialization I will go back to working on initialization. I've been working on that, in between interruptions, but don't have anything to report yet. I think initialization is more important (and I feel that we are sufficiently close on change-class) that I would want to understand the two together. I feel it would be worth more to see your ideas on initialization sooner. The rule is that newly created slots are initialized to the value of their :initform. I'm assuming that the :initforms for different slots are independent of each other and that the language makes no commitment about the order in which :initforms will be evaluated; are you assuming something different from that? I agree with this. It is the assumption underlying the rule we proposed for initialization that all initforms are run before further initialization takes place. ... A slot is a conceptual entity, not a word of computer storage at a particular address. No slot contents are being copied or changed... I like this model. danny ps Dave, Did you see (and have a quick reaction) to the alternative define-method-combination. danny  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jan 87 17:56:53 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 10:21:00 PST Return-Path: Received: from ucbvax.Berkeley.EDU by Xerox.COM ; 22 JAN 87 10:18:50 PST Received: by ucbvax.Berkeley.EDU (5.53/1.20) id AA08026; Wed, 21 Jan 87 20:25:11 PST Received: by shambhala.berkeley.edu (1.2/5.6) id AA03848; Wed, 21 Jan 87 20:22:48 pst From: ricks%shambhala.Berkeley.EDU@BERKELEY.EDU (Rick L Spickelmier) Message-Id: <8701220422.AA03848@shambhala.berkeley.edu> Date: 21 Jan 87 20:22 PST (Wednesday) To: commonloops.pa@Xerox.COM Subject: compiling files in PCL 1/19/87 PCL 1/19/87 under VAXLISP/ULTRIX works for interpreted files, but dies when trying to 'compile-file' a file that contains a 'with'. It seems that the environment gets set to '(nil nil nil nil) and 'expand-with-slots' gets passed bogus arguments, so the class of the arguments to the 'with' can not be figured out.... Rick Spickelmier  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 14:46:18 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 11:40:19 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 11:13:43 PST Date: 22 Jan 87 11:14 PST From: Masinter.pa@Xerox.COM Subject: [Masinter.pa: Handling Common Lisp built in types] To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870122-111343-1424@Xerox> I found the old mail, but it isn't as relevant as I thought. Just "for the record" .... I thought it was interesting to see what was "wrong" here. ----- Begin Forwarded Messages ----- Date: 18 Jul 85 07:43 PDT From: Masinter.pa Subject: Handling Common Lisp built in types I think that we can regularize the handling of Common Lisp standard type specifiers by categorizing them. I've been working on this for a while, but still don't have it 100% right; but what do you think about the general direction? - - - abstract - - - - - - - Abstract classes have no immediate instances, but are umbrellas for various implementation-specific types. An :include of these types inherits no structure or accessor functions. atom, common, float, integer, t array vector string bit-vector (array * (* * ...)) for between 0 and array-rank-limit *. [Being able to :include these has implications for implementation of vectorp, atom, etc.] - - - virtual-structure - - - - - - Some should be treated "as if" they had structure. An :include of these inherits the slots as noted, and the corresponding accessor functions. (Note that this may require special implementation, eg., if cons cells are cdr-coded, but structures that :include them are not.) Implementations may have other components, but the ones specified are the only ones inherited. cons (car cdr) complex (realpart imagpart) ratio (numerator denominator) character (code bits font) Except for conses and symbols, the slots are read-only. Note: I'm reluctant to add symbol (plist package name) to this list. - - - - - implementation - - - - - - - Some are implementation-specific classes, with no visible internal structure. One cannot :include these, although they can be used in type specifiers. bignum, fixnum, double-float, short-float, single-float (vector type *), (simple-vector type (n)) (array type [*|(*+)]), (simple-array type (n)), when "type" is "OK" (implementation or abstract or immutable-predicate). Note that (array t (3 3)) is mutable, since you can displace an array. {Do I understand this?} (All vector and array constructed types excluding the ones allowed above as "abstract". Note that we've made a distinction between "string" and "(vector string-char)", requiring only that (vector string-char) be a subtype of "string".) - - - - - should-be-implementation - - - - - Some should have been specified as having distinct data types, but weren't. We could propose changing the Common Lisp spec to make it so, but it would probably cause some trouble. stream, package, readtable, hash-table, pathname, random-state (It would actually be reasonable to make these abstract types. The problem is that their place in the class hierarchy is ambiguous. It would be better if we could specify that those types are also disjoint with number, array, symbol, list. They then could be "abstract with unspecified implementation", i.e., one could :include them, but would inherit no structure even though any implementation would have structure.) - - - - - - - immutable-predicate - - - - - - - - These are predicates which don't rely on mutable properties, but are still not usually thought of in the class heirarchy: bit, (integer low high) (mod n), (signed-byte s) (unsigned-byte s) (rational low high) (*float low high) (and type1 type2 ...), (or type1 type2 ...), (not type1) (when the subtypes are OK, of course) - - - - - - - - mutable-predicate - - - - - These can't be :included, and allowing them in discrimiantors leads to problems too: (*string size) (since you can change the size of a string) keyword (since you can change the package of a symbol) - - - - - - - oddities - - - - - - Now, here come the ones left over: compiled-function I'm reluctant to put this in with the "should be implementation", but its out of place here. function "may be used only for declaration and not for discrimination" values "this type specifier is extremely restricted" keyword (mutable, since you can change the package) - - - - - - - - - - - - Need a section "include: of classes with different metaclass". If you include a class which has a different metaclass, the implementation of the subclass may be completely different than the implementation of the parent. In that case, the structure of slots isn't shared, and it may be necessary to "copy down" any methods which refer to the parents implementation! - - - - - - - - - - - - - - - ----- End Forwarded Messages -----  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 14:45:29 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Jan 87 11:40:07 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 10:59:00 PST Date: 22 Jan 87 10:59 PST From: Masinter.pa@Xerox.COM Subject: Re: Inheritance of Methods In-reply-to: Sonya E. Keene 's message of Thu, 22 Jan 87 11:09 EST To: skeene@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870122-105900-1394@Xerox> What gets inherited is more than accessors and less than methods, that is, a subclass inherits the accessors, since, in some sense, the accessors "belong" to the class. We are reluctant to say that subclasses inherit "methods" because a multi-method may not "belong" to any one class, and the analogy of inheritance implies the analogy of possesion. What is important is that behavior, reflected in the availability of accessors and the participation in method lookup, is inherited. What do you think of "Inheritance of Behavior" for a section title?  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jan 87 12:12:44 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 08:30:32 PST Return-Path: Received: from ucbvax.Berkeley.EDU by Xerox.COM ; 22 JAN 87 08:29:19 PST Received: by ucbvax.Berkeley.EDU (5.53/1.20) id AA04375; Wed, 21 Jan 87 16:16:47 PST Received: by shambhala.berkeley.edu (1.2/5.6) id AA03653; Wed, 21 Jan 87 16:14:29 pst From: ricks%shambhala.Berkeley.EDU@BERKELEY.EDU (Rick L Spickelmier) Message-Id: <8701220014.AA03653@shambhala.berkeley.edu> Date: 21 Jan 87 16:14 PST (Wednesday) To: commonloops.pa@Xerox.COM Subject: BUG and FIX? for PCL 1/19/87 There seems to be an error in the 'collect-slotds' method for 'basic-class' in the 1/19/87 and 12/2/86 versions of PCL. This causes slots to be inherited incorrectly. In the old PCL (11/11/86), the 'shadow-or-add-slot' for 'local-slots' was done before the 'shadow-or-add-slot' calls for the supers; now it is done afterwards. Was this change intensional? It causes the following to happen: Lisp> (defclass bob () ((a :initform 12)) (:accessor-prefix ||)) BOB Lisp> (defclass bill (bob) ((a :initform 23)) (:accessor-prefix ||)) BILL Lisp> (make-bill) #S(BILL A 12) <- should be #S(BILL A 23) Changing 'collect-slotds' back to the old ordering solves this problem... Rick Spickelmier UC Berkeley P.S. at the bottom of this message are the changes to PCL to make it run on VAXLISP/ULTRIX. collect-slotds (from pcl of 1/19/87): (iterate ((ls in (cdr cpl))) (iterate ((instance-slot in (class-instance-slots ls))) (shadow-or-add-slot instance-slot all-slots)) (iterate ((non-instance-slot in (class-non-instance-slots ls))) (shadow-or-add-slot non-instance-slot all-slots))) (iterate ((include-slot in include-slots)) (shadow-or-add-slot include-slot all-slots rplaca (error "The slot ~S appeared in the :include option of the defstruct~%~ for the class ~S. But this slot does not appear in any of the~%~ class's superclasses." (slotd-name include-slot) (class-name class)))) -> (iterate ((local-slot in local-slots)) (shadow-or-add-slot local-slot all-slots)) pcl of 11/11/86 -> (iterate ((local-slot in local-slots)) (shadow-or-add-slot local-slot all-slots)) (iterate ((ls in (cdr cpl))) (iterate ((instance-slot in (class-instance-slots ls))) (shadow-or-add-slot instance-slot all-slots)) (iterate ((non-instance-slot in (class-non-instance-slots ls))) (shadow-or-add-slot non-instance-slot all-slots))) (iterate ((include-slot in include-slots)) (shadow-or-add-slot include-slot all-slots rplaca (error "The slot ~S appeared in the :include option of the defstruct~%~ for the class ~S. But this slot does not appear in any of the~%~ class's superclasses." (slotd-name include-slot) (class-name class)))) VAXLISP/ULTRIX fixes GET RID OF THE 'IGNORE' DEFMACRO - causes fits for VAXLISP In defsys.lsp, for *pcl-pathname-defaults* #+(and DEC common vax VMS) (pathname "[gregor]") #+(and DEC common vax ULTRIX) (pathname "/eros1/ricks/pcl/new/") for *pathname-extensions* #+(and dec common VMS) ("LSP" . "FAS") #+(and dec common ULTRIX) ("lsp" . "fas")  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jan 87 12:12:32 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 08:09:58 PST Return-Path: Received: from ucbarpa.Berkeley.EDU by Xerox.COM ; 22 JAN 87 08:08:24 PST Received: by ucbarpa.Berkeley.EDU (5.57/1.20) id AA03910; Thu, 22 Jan 87 08:08:58 PST Received: from ficl by franz (5.5/3.14) id AA02129; Thu, 22 Jan 87 07:13:50 PST Received: by ficl (5.5/3.14) id AA13945; Thu, 22 Jan 87 07:15:00 PST From: franz!ficl!jkf@ucbarpa.Berkeley.EDU (John Foderaro) Return-Path: Message-Id: <8701221515.AA13945@ficl> To: ehl%cogsci.Berkeley.EDU@BERKELEY.EDU (Edward H. Lay) Cc: commonloops.pa@Xerox.COM, excl-users@ucbarpa.Berkeley.EDU Subject: Re: Multiple-value-setq in excl In-Reply-To: Your message of Wed, 21 Jan 87 22:25:53 PST. <8701220625.AA18567@cogsci.berkeley.edu> Date: Thu, 22 Jan 87 07:14:57 PST There is a hidden (not on the function cell) macro definition for multiple-value-setq and all other special forms which aren't 'official'. While macroexpand knows how to find them, macro-function does not. This is a bug and the next update will contain the fix.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jan 87 12:12:19 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 JAN 87 07:38:21 PST Return-Path: Received: from EDDIE.MIT.EDU ([18.62.0.6]) by Xerox.COM ; 22 JAN 87 07:36:58 PST Received: by EDDIE.MIT.EDU (5.31/4.7) id AA29022; Thu, 22 Jan 87 10:38:35 EST Received: by prime.uucp (1.1/SMI-3.0DEV3) id AA14619; Thu, 22 Jan 87 10:28:52 EST Message-Id: <8701221528.AA14619@prime.uucp> Received: (from user DOUG) by ENX.Prime.PDN; 22 Jan 87 09:51:16 EDT To: COMMONLOOPS.PA@Xerox.COM From: primerd!DOUG@ENX.Prime.PDN.ARPA Date: 22 Jan 87 09:51:17 EDT To: Common LOOPS mailing list (commonloops.pa@xerox.com) From: Doug Rand (DOUGR@EDDIE.MIT.EDU) Date: 22 Jan 87 9:48 AM Subject: Bug in PCL on LUCID Their is a bug in LUCID's handling of the labels construct. Patched code for class-prot.lisp (replace compute-class-precedence-list): (defun walk-supers (class &optional precedence) (let ((elem (assq class must-precede-alist))) (if elem (setf (cdr elem) (union (cdr elem) precedence)) (push (cons class precedence) must-precede-alist))) (let ((rsupers (reverse (cons class (class-local-supers class))))) (iterate ((sup in rsupers) (pre on (cdr rsupers)) (temp = nil)) ;; Make sure this element of supers is OK. ;; Actually, there is an important design decision hidden in ;; here. Namely, at what time should symbols in a class's ;; local-supers be changed to the class objects they are ;; forward referencing. ;; 1. At first make-instance (compute-class-precedence-list)? ;; 2. When the forward referenced class is first defined? ;; This code does #1. (cond ((classp sup)) ((and (symbolp sup) (setq temp (class-named sup t))) ;; This is a forward reference to a class which is ;; now defined. Replace the symbol in the local ;; supers with the actual class object, and set sup. (nsubst temp sup (class-local-supers class)) (setq sup temp)) ((symbolp sup) (error "While computing the class-precedence-list for ~ the class ~S.~%~ The class ~S (from the local supers of ~S) ~ is undefined." (class-name root) sup (class-name class))) (t (error "INTERNAL ERROR --~%~ While computing the class-precedence-list for ~ the class ~S,~%~ ~S appeared in the local supers of ~S." root sup class))) (walk-supers sup pre)) (unless (memq class cpl) (push class cpl)))) (defmethod compute-class-precedence-list ((root class)) (declare (special root)) (let ((cpl ()) (must-precede-alist ())) (declare (special cpl must-precede-alist)) ;; We start by computing two values. ;; CPL ;; The depth-first left-to-right up to joins walk of the supers tree. ;; This is equivalent to breadth-first left-to-right walk of the ;; tree with all but the last occurence of a class removed from ;; the resulting list. This is in fact how the walk is implemented. ;; ;; MUST-PRECEDE-ALIST ;; An alist of the must-precede relations. The car of each element ;; of the must-precede-alist is a class, the cdr is all the classes ;; which either: ;; have this class as a local super ;; or ;; appear before this class in some other class's local-supers. ;; ;; Thus, the must-precede-alist reflects the two constraints that: ;; 1. A class must appear in the CPL before its local supers. ;; 2. Order of local supers is preserved in the CPL. ;; ;; (labels (flet ((must-move-p (element list &aux move) (dolist (must-precede (cdr (assq element must-precede-alist))) (when (setq move (memq must-precede (cdr list))) (return move)))) (find-farthest-move (element move) (let ((closure (compute-must-precedes-closure element))) (dolist (must-precede closure) (setq move (or (memq must-precede move) move))) move)) (compute-must-precedes-closure (class) (let ((closure ())) (labels ((walk (element path) (when (memq element path) (class-ordering-error root element path must-precede-alist)) (dolist (precede (cdr (assq element must-precede-alist))) (pushnew precede closure) (walk precede (cons element path))))) (walk class nil) closure)))) (walk-supers root) ;Do the walk ;; For each class in the cpl, make sure that there are no classes after ;; it which should be before it. We do this by cdring down the list, ;; making sure that for each element of the list, none of its ;; must-precedes come after it in the list. If we find one, we use the ;; transitive closure of the must-precedes (call find-farthest-move) to ;; see where the class must really be moved. We use a hand-coded loop ;; so that we can splice things in and out of the CPL as we go. (let ((tail cpl) (element nil) (move nil)) (loop (when (null tail) (return)) (setq element (car tail) move (must-move-p element tail)) (cond (move (setq move (find-farthest-move element move)) (setf (cdr move) (cons element (cdr move))) (setf (car tail) (cadr tail)) ;Interlisp delete is OK (setf (cdr tail) (cddr tail)) ;since it will never be ;last element of list. ) (t (setq tail (cdr tail))))) (copy-list cpl)))))  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 11:14:04 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Jan 87 08:10:38 PST Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 49103; Thu 22-Jan-87 11:11:50 EST Date: Thu, 22 Jan 87 11:09 EST From: Sonya E. Keene Subject: Inheritance of Methods To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 21 Jan 87 23:10 EST from Dick Gabriel Message-ID: <870122110907.4.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: 21 Jan 87 2010 PST From: Dick Gabriel There is now a section in concepts about inheritance of methods. The description of this inheritance makes most sense for ``classical'' methods; some would argue that those are the only methods for which this description makes sense. CONCEPTS now does not contain the phrase ``classical method,'' and this description does not jive with the section ``Method Selection and Combination.'' Though this might have been a useful way to conceptualize methods in the old days, I think it is outmoded, and we plan to delete the subsection of ``Inheritance'' called ``Inheritance of Methods.'' -rpg- Note that this section does not contain the phrase "classical method" either. The "Inheritance" chapter mostly talks about the inheritance of slots and DEFCLASS options. But you have to talk about methods here, to some degree. It would be misleading to say "The :accessor slot-option is not inherited". That statement alone implies that if a superclass gives the :accessor option, it has no effect on the subclass. But in fact, that method is applicable for the subclass. It's important to state that explicitly. Also, it's important to mention that a class can have an applicable method for accessing a slot, but if the class used :allocation :none for that slot, using the method will result in an error. The section also notes that the inheritance of methods works the same way, regardless of whether the method was defined by DEFMETHOD or by one of the DEFCLASS options. I would suggest that we rewrite that short "Inheritance of Methods" section if you want, but not remove it. One suggestions is to rename it "Inheritance of Accessor Methods" and discuss it from that perspective.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jan 87 02:15:07 EST Received: from Cabernet.ms by ArpaGateway.ms ; 21 JAN 87 22:26:16 PST Return-Path: Received: from cogsci.berkeley.edu ([128.32.130.5]) by Xerox.COM ; 21 JAN 87 22:25:22 PST Received: by cogsci.berkeley.edu (5.57/1.20) id AA18567; Wed, 21 Jan 87 22:25:53 PST Date: Wed, 21 Jan 87 22:25:53 PST From: ehl%cogsci.Berkeley.EDU@berkeley.edu (Edward H. Lay) Message-Id: <8701220625.AA18567@cogsci.berkeley.edu> To: commonloops.pa@Xerox.COM Subject: Multiple-value-setq in excl Cc: excl-users@ucbarpa.Berkeley.EDU is a special form so you either have to write your own walker template for it or else you have to shadow it with your own macro definition for the walker to win. ed  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jan 87 02:14:57 EST Received: from Cabernet.ms by ArpaGateway.ms ; 21 JAN 87 22:11:11 PST Return-Path: Received: from cogsci.berkeley.edu ([128.32.130.5]) by Xerox.COM ; 21 JAN 87 22:10:21 PST Received: by cogsci.berkeley.edu (5.57/1.20) id AA18459; Wed, 21 Jan 87 22:10:22 PST Date: Wed, 21 Jan 87 22:10:22 PST From: ehl%cogsci.Berkeley.EDU@berkeley.edu (Edward H. Lay) Message-Id: <8701220610.AA18459@cogsci.berkeley.edu> To: commonloops.pa@Xerox.COM Subject: PCL and Lucid Anyone tried the lucid code recently? Compiling compute-class-precedence-list for class caused the compiler to cons all remaining storage and die. Apparently, this isn't a new bug -- it can be duplicated in the 12/2 This happened to me as well although I have only tried it in the 12/2 version of PCL. ed  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 01:54:19 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Jan 87 22:48:50 PST Received: from Cabernet.ms by ArpaGateway.ms ; 21 JAN 87 22:46:38 PST From: masinter.pa@Xerox.COM Date: 21 Jan 87 22:46:35 PST Subject: Re: standard-type-classes In-reply-to: RPG@SAIL.STANFORD.EDU's message of 21 Jan 87 14:21 PST To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870121-224638-1317@Xerox> I'll try to dig out the old mail on this, as I remember going into it in some detail in the past. The reason for avoiding "bit" is similar to the reason for avoiding (integer 0 1) and (integer -3 3) as "classes"... there's not much special about one integer range over another, and arbitrary ranges give the same problems as arbitrary types. The reason for avoiding "keyword" is that it is (unfortunately) a mutable property, in that it is possible to dynamically modify the home package of a symbol (in a way that would not, for example, invoke class-changed.) The reason for avoiding standard-char is that it is again not a significant "class" distinction. While it was interesting to use the type system to categorize those characters which were somehow standard, it was probably incorrect, the use of standard-char-p being in the same space (in my mind) as evenp rather than integerp. (This isn't a really good reason. I'll work on it.) The reason for avoiding string-char is that it is too implementation dependent whether a given actual character is in the class. (I'm less convinced about this one than about the others.) About FUNCTION: I agree that it is important to clean up the FUNCTION class in Common Lisp. However, doing so implies more global changes than are in the scope of the Object proposal; for example, it means requiring that class FUNCTION be disjoint from other classes (including ARRAY, LIST, and SYMBOL), and that FUNCTIONP be changed incompatibly. This is thus a strategic issue: is the object proposal strong enough to carry this cleanup of CL along with it, or should it be separated? (Or, perhaps, the wording should be something like: when CL-cleanup votes to clean up FUNCTION so that it is well specified, the FUNCTION class will be part of the required hierarchy.) I'm typing this in with no text editor so forgive my spelling, organization. Larry  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jan 87 01:04:12 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Jan 87 21:59:45 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 48870; Thu 22-Jan-87 01:00:26 EST Date: Thu, 22 Jan 87 00:57 EST From: David A. Moon Subject: Re: change-class and class redefinition To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870121-133259-194@Xerox> Message-ID: <870122005751.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 21 Jan 87 13:32 PST From: Gregor.pa@Xerox.COM .... The most important comment I have is that I would like to have the default method on class-changed be responsible for copying over slots. I understand that the reason you put the responsibility for initializing the slots of the "new" instance and copying the slots in the same place (in change-class itself) is to prevent running the :initform of slots which already existed in the "old" instance. Was this for efficiency or because you preferred those semantics? It's for semantics. I believe it's important not to evaluate initforms that aren't going to be used. However, that isn't the only reason, or even the most important reason, why I proposed it the way I did. I want the copying of the slots to be the responsibility of the implementation, not of the programmer, for several reasons. Some of these reasons involve implementation-dependent issues that are beyond the scope of the standard, but that doesn't make the reasons any less valid. Here are the reasons that apply to the Symbolics implementation. I expect there are additional reasons in certain other implementations: (1) Reading an uninitialized slot of course signals an error, so copying the contents of a slot has to check for that. (2) When a new piece of storage has to be allocated, the moving of the slot contents from the old piece of storage to the new piece and the redirection of the instance to its new piece of storage have to be an atomic operation. Remember that the Symbolics implementation is a multiple process implementation. (3) Slots that contain special kinds of things, for instance logic variables a la Prolog, may require special care to copy. (4) I believe the current instance should be completely operable at the time the class-changed methods are called, because the class-changed methods may want to perform generic operations on the current instance, as well as on the previous instance. The instance can't be completely operable if the slot values aren't there yet. However, this is missing the major point. I believe that "copying the slots" is the wrong model of what is happening. A slot is a conceptual entity, not a word of computer storage at a particular address. No slot contents are being copied or changed. Some slots are being deleted, some other slots are being newly created and therefore initialized, and the rest of the slots remain unchanged. If a particular implementation happens to work by moving the representation of a slot from location 1000 to location 1492, that's an implementation detail and not something the programmer should see. At the level of abstraction that programmers should deal with, a slot is a slot and nothing is being copied. .... My reasoning, is that I think things are more complicated when the rules about when the various :initforms are run get complicated. This is reflected in my initialization protocol which has the :initforms all being run all at once. I don't think it's complicated. The rule is that newly created slots are initialized to the value of their :initform. I'm assuming that the :initforms for different slots are independent of each other and that the language makes no commitment about the order in which :initforms will be evaluated; are you assuming something different from that? Differing assumptions might be the underlying reason why we're disagreeing. If we can't finish change-class until we finish initialization I will go back to working on initialization. I've been working on that, in between interruptions, but don't have anything to report yet. I like the name class-changed. I also agree with DLW that we should invent a term for generic-functions which you are not supposed to call yourself. We will need this term in the meta-object protocol chapter. As an initial proposal, we could have "callable functions", "specializable functions", and "functions that are both callable and specializable". If they aren't specializable it's none of your business whether or not they are generic, which is why I said "functions" instead of "generic functions." Specializable means you can define methods for them. I don't claim this is the best terminology in the world! The paragraph which says that previous has dynamic extent and also says it can be passed around needs to be re-worked. What it says is exactly right, its just that its confusing. It is very important to stress that previous has dynamic extent. All of my English is pretty poor and will have to be gone over once we have agreed on the facts.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jan 87 00:22:39 EST Received: from Cabernet.ms by ArpaGateway.ms ; 21 JAN 87 20:27:35 PST Return-Path: Received: from SPAR-20.ARPA ([128.58.1.2]) by Xerox.COM ; 21 JAN 87 20:26:10 PST Date: Wed, 21 Jan 87 20:25:40 PST From: Dan Carnese Subject: pcl in lucid To: commonloops.pa@Xerox.COM Reply-To: carnese@[128.58.1.2] Message-ID: <12272844011.26.CARNESE@SPAR-20.ARPA> Anyone tried the lucid code recently? Compiling compute-class-precedence-list for class caused the compiler to cons all remaining storage and die. Apparently, this isn't a new bug -- it can be duplicated in the 12/2 version. -- Dan -------  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Jan 87 23:18:19 EST Date: 21 Jan 87 2010 PST From: Dick Gabriel Subject: Inheritance of Methods To: common-lisp-object-system@SAIL.STANFORD.EDU There is now a section in concepts about inheritance of methods. The description of this inheritance makes most sense for ``classical'' methods; some would argue that those are the only methods for which this description makes sense. CONCEPTS now does not contain the phrase ``classical method,'' and this description does not jive with the section ``Method Selection and Combination.'' Though this might have been a useful way to conceptualize methods in the old days, I think it is outmoded, and we plan to delete the subsection of ``Inheritance'' called ``Inheritance of Methods.'' -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Jan 87 20:57:57 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Jan 87 17:55:30 PST Received: from Cabernet.ms by ArpaGateway.ms ; 21 JAN 87 13:32:59 PST Date: 21 Jan 87 13:32 PST From: Gregor.pa@Xerox.COM Subject: Re: change-class and class redefinition In-reply-to: David A. Moon 's message of Mon, 19 Jan 87 23:56 EST To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870121-133259-194@Xerox> The first part (1-4) of this looks good. I haven't yet had a chance to think about the details of Restrictions on when CHANGE-CLASS can be called or what DEFCLASS does. I do have some comments about the first part though. The most important comment I have is that I would like to have the default method on class-changed be responsible for copying over slots. I understand that the reason you put the responsibility for initializing the slots of the "new" instance and copying the slots in the same place (in change-class itself) is to prevent running the :initform of slots which already existed in the "old" instance. Was this for efficiency or because you preferred those semantics? If it was for semantics, here is an alternate proposal: Let change-class create a new-instance, but not call INITIALIZE on it. Then it passes the "old" and "new" instances to class-changed. class-changed can call initialize if it wants, or it can just copy old slots or whatever. My reasoning, is that I think things are more complicated when the rules about when the various :initforms are run get complicated. This is reflected in my initialization protocol which has the :initforms all being run all at once. I like the name class-changed. I also agree with DLW that we should invent a term for generic-functions which you are not supposed to call yourself. We will need this term in the meta-object protocol chapter. The paragraph which says that previous has dynamic extent and also says it can be passed around needs to be re-worked. What it says is exactly right, its just that its confusing. It is very important to stress that previous has dynamic extent.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Jan 87 20:57:36 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Jan 87 17:55:44 PST Received: from Cabernet.ms by ArpaGateway.ms ; 21 JAN 87 16:10:45 PST Date: 21 Jan 87 16:12 PST Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Small additional suggestion wrt Method-combination To: Common-Lisp-Object-System@Sail.stanford.edu cc: Bobrow.pa@Xerox.COM Message-ID: <870121-161045-107@Xerox> Because :operator and :call-next-method (nee :around) cannot both appear, I suggest that the syntax of make-method-call be (make-method-call method-list &optional (operator 'progn) (identity-with-one-argument (eq operator 'progn))) Where if operator has the value :call-next-method, it has the same effect as previously providing that argument with t as its value. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Jan 87 19:37:47 EST Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 21 Jan 87 16:32:11 PST Received: from hplabsc by hplabs.HP.COM ; Wed, 21 Jan 87 15:32:22 pst Received: by hplabsc ; Wed, 21 Jan 87 15:25:43 pst Date: Wed, 21 Jan 87 15:25:43 pst From: Jim Kempf Message-Id: <8701212325.AA06103@hplabsc> To: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: standard-type-classes Yes, Gabrial has made a good point. Unless boolean classes (i.e. classes which are `not' something) are to be admitted, ATOM is probably a candidate not to have a class for. Most of the others look like they could have classes though. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Jan 87 17:27:31 EST Date: 21 Jan 87 1421 PST From: Dick Gabriel Subject: standard-type-classes To: common-lisp-object-system@SAIL.STANFORD.EDU Referring to the design rationale chapter, there are comments about what Common Lisp types should have classes. Some of the reasoning for exclusion needs to be re-examined: ``Types too specific to be useful to put methods on: bit, keyword, standard-char, string-char.'' Hm, I need more convincing than this. ``The type implies an implementation, not behavior.'' What's wrong with being able to write programs that reason about this? If we had BUILT-IN-CLASS and STANDARD-TYPE-CLASS, we could distinguish implementation details. ``Specification of the type is too vague.'' Included in this last case is FUNCTION. The rationale then says that there is no function to make functions. Maybe so, but functions get made and returned, and the user is quite aware, by design, of when it happens. One can argue that a user might be aware of the fact that he is making bignums, but he isn't required to be so aware. With functions you don't start off with an array and when it becomes too complex it turns into a function; there is nothing that gets turned into a function without a user knowing it in the same way that a fixnun becomes a bignum. I see no reason to further demean functions than they aleady are in Common Lisp. ``No object can be an instance of this type: nil'' I want to call the class miasma a lattice to avoid having to mention exceptions everywhere. A class with no instances is reasonable for this. Also, Larry Masinter pointed out that this could be a way to solve the unsupplied optionals problem. An unsupplied optional ``matches'' a parameter specifier that of this class. Maybe we don't want to call it NIL, but it's the logical name for it. I don't like the heuristic of only admitting types that have makers or no single function that is a maker, because the user simply wants to reason about the things that are, not the things that came into being by some particular mode. If it's bad to reason about the implementation technique, it's almost as bad to reason about the history of a thing. -rpg-