Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Apr 88 13:05:47 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 28 Apr 88 09:53:27 PDT Received: by labrea.Stanford.EDU; Thu, 28 Apr 88 09:53:23 PDT Received: from bhopal.lucid.com by edsel id AA00488g; Thu, 28 Apr 88 07:13:26 PDT Received: by bhopal id AA00769g; Wed, 27 Apr 88 19:10:14 PDT Date: Wed, 27 Apr 88 19:10:14 PDT From: Jon L White Message-Id: <8804280210.AA00769@bhopal.lucid.com> To: Moon@stony-brook.scrc.symbolics.com Cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: David A. Moon's message of Wed, 27 Apr 88 14:29 EDT <19880427182909.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Subject: "Written Responses" to CLOS 88-002: SETF Functions re: If X3J13 has adopted setf functions, I agree that the CLOS spec does not need to discuss them. If X3J13 is still dithering, I think the writeup should stay in the CLOS spec. If X3J13 has rejected setf functions, then we have a problem. SETF functions foundered on issues having nothing to do with function specs. I say, "foundered", not meaning that they were rejected, but that substantial issues were raised (mostly by Sandra Loosemore), and the discussion didn't come to completion by the end of the day. You missed the "Definitions Specs" presentation; there seemed to be unanimous approval for continuing that proposal. Even if there is continuing objection/discussion (and I don't think there will be) to the particulars of the "setf functions" semantics, there doesn't seem to be objections to "function specs". I believe that most of Sandra's objections were met by our collective responses that day. For example, she wanted to know why their syntax differed from that suggested by DEFSETF -- why the "new value" was the first argument rather than the last. We replied that it is necessary to be able to discriminate on the class of the "new value", and there is no easy syntax for defining a method that discriminates on the last argument rather than the first several. However, under no circumstances can one justify leaving a "fix up" of CL in the CLOS spec. At best, CLOS should have an appendix explaining any non-standard assumptions about the CL language -- an appendix which itself isn't an integral part of the spec, but only an aid for those who are not yet familiar with other X3J13 activity. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Apr 88 12:46:27 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 28 Apr 88 09:33:39 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 APR 88 09:32:23 PDT Date: 28 Apr 88 09:32 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Reinitialization In-reply-to: David A. Moon 's message of Wed, 27 Apr 88 20:20 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Bobrow.pa@Xerox.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <880428-093223-7329@Xerox> From: Danny Bobrow (unless (check-keyword-arguments (cons (class-prototype class) initargs) (list #'allocate-instance #'initialize-instance #'initialize-new-instance) (class-slot-initargs class)) (error "illegal initarg")) But this doesn't work because each one of allocate-instance, initialize-instance, and initialize-new-instance takes slightly different arguments. Unfortuntately, right. I have two patches for this, since I think the idea is good. Both patches have problems. Here are the alternative patches. 1) The difference in arguments is that #'initialize-instance takes a second required argument, slots-using-initforms. Instead, make slots-using-initforms be a keyword argument. This implies that callers of make-instance and reinitialize-instance could specify which slots they wanted filled with a value computed from initforms. I can think of some uses for this, but it may be exposed at the wrong level. I don't consider this a strong argument (either way). 2) Change the argument structure for check-keyword-arguments check-keyword-arguments required-arguments key-word-arguments generic-functions &optional extra-allowed-keywords Make required arguments be a list that can select the appropriate methods from each generic funcion. If the list is too short, consider it equivalent to being filled out with enough nils to be of the right length. --- In either case I envision the code for check-keyword-arguments to use something like keywords-for-applicable-methods (I called this generic function method-applicable-keywords in Chapter 3). (defmethod keywords-for-applicable-methods ((g-fn standard-generic-function) required-arguments) ;; find the list of applicable methods for ;; required arguments given ;; possibly filling out list of required arguments with nils ;; take the union of these keywords ) However, there is a problem in using keywords-for-applicable-methods in check-keyword-arguments. What value does it return if &rest or &allow-other-keys appears in any method? If we take Moon's suggestion of returning the symbol &allow-other-keys in this case, then check-keyword-arguments cannnot use this value, since the default methods for initialize-instance and allocate-instance have an &rest argument. If we take my suggestion of including &allow-other-keys in the list of allowable keyword arguments, then we suffer from what Moon calls the "untasteful but legal use of &allow-other-keys as a keyword argument." Perhaps we could outlaw that use as a keyword in CLOS. Perhaps we could use another key -- is either T or NIL outlawed as a keyword? In general, where one wants to provide a common set of keyword arguments to a set of functions, all must accept the keywords of the other functions. We need some mechanism for knowing the explicitly handled keywords. That was the intent of my last suggestion. Ideas? Comments?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 20:47:14 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Apr 88 17:20:40 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 393344; Wed 27-Apr-88 20:20:35 EDT Date: Wed, 27 Apr 88 20:20 EDT From: David A. Moon Subject: Re: Reinitialization To: Danny Bobrow cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <880427-170445-6290@Xerox> Message-ID: <19880428002009.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: 27 Apr 88 17:03 PDT From: Danny Bobrow (unless (check-keyword-arguments (cons (class-prototype class) initargs) (list #'allocate-instance #'initialize-instance #'initialize-new-instance) (class-slot-initargs class)) (error "illegal initarg")) But this doesn't work because each one of allocate-instance, initialize-instance, and initialize-new-instance takes slightly different arguments.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 20:23:21 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 27 Apr 88 17:12:00 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 APR 88 17:04:45 PDT Date: 27 Apr 88 17:03 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Reinitialization In-reply-to: David A. Moon 's message of Tue, 26 Apr 88 16:30 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <880427-170445-6290@Xerox> check-initargs has to be called from four different places now, as there are four updating functions that have initargs arguments. I think the best way is to give check-initargs another argument, which is a list of generic functions. An initarg is acceptable if it's a slot-filling initarg or if any of the generic functions in the list accepts it. make-instance would pass (list #'allocate-instance #'initialize-instance #'initialize-new-instance). reinitialize-instance would pass (list #'reinitialize-instance #'initialize-new-instance). The only problem with this is that each of these takes idiosyncratic arguments, which check-initargs has to take into account when computing the applicable methods. Is there a better idea? The basic goal is that for each of the seven functions that take initargs as arguments (make-instance, allocate-instance, initialize-new-instance, reinitialize-instance, update-instance-for-redefined-class, update-instance-for-different-class, and initialize-instance), the keyword arguments accepted without error are the initargs for slot filling and the initargs accepted by applicable methods for any generic function that is going to see these initargs, and only those. The following is an alternative that would be more generally useful. It provides a more general form of the functionality described above. It will be useful anytime keyword arguments are going to be combined and passed to multiple generic functions. The idea is to have a function that would check a set of keyword arguments against those accepted by a set of methods. The set of methods would be the methods from the supplied generic functions that are applicable to the supplied arguments. In addition, it is possible to specify additional acceptable keywords. check-keyword-arguments arguments generic-functions &optional extra-allowed-keywords make instance would call check-keyword-arguments this way (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (unless (check-keyword-arguments (cons (class-prototype class) initargs) (list #'allocate-instance #'initialize-instance #'initialize-new-instance) (class-slot-initargs class)) (error "illegal initarg")) . . .) Clearly the first value returned by this function is T or NIL. There is some question as to whether it should return other values saying which keyword arguments were illegal, and what the total set of legal keyword arguments is.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 17:20:37 EDT Date: 27 Apr 88 1407 PDT From: Dick Gabriel Subject: Editorial Comments and My Disposition of Them To: common-lisp-object-system@SAIL.Stanford.EDU Here is a series of excerpts from Gregor's message and how I dealt with them: From: Dan L. Pierson Page 1-9, Add to the list of things provided by slot options and class options: o Specifying the legal data types of the slot contents. (Of course, this can be found elsewhere in the document, but my impression on reading this introductory list was that for some reason you couldn't do this.) [RPG: ok] Page 1-11, Paragraphs 3 and 7 Why are reader, writer, and with-slots *required* to be implemented using SLOT-VALUE? I don't doubt that you have a good reason, but it's not obvious to a relative novice. [These must call slot value because the implementation of slot-value for a particular class can be changed using the MOP. We don't want to go into that at this point in the document, but perhaps a simple forward reference would be appropriate. Paragraphs 7 and 8 This implies that WITH-SLOTS can access slots without accessors but WITH-ACCESSORS can't. This is reasonable but should probably be made explicit. Some people may feel that this makes WITH-SLOTS unsafe. [Yes this needs to be made explicit.] [RPG: ok] Page 1-26, Paragraph 2, Sentence 2 The following are my exact notes as I read this section: What about methods in both old and new? Are they "added"? If so, in what way is this definition different from saying that the "contents" of the old generic function are trashed and replaced by the new generic function? AHA! Some methods could have been defined by DEFMETHOD, but the wording is still confusing. [RPG: Maybe it is, but it is quite precise. I think it's ok.] Paragraph 6, Sentence 3 The wording is a bit confusing. [RPG: either I cannot find what he is talking about or else he is very confused. The sentence he refers to simply lists the forms in a category that was just defined.] Page 1-28, Paragraph 2, Sentence 4 and example line Has this been submitted to cleanup? I don't recognize it. [He is confused by the use of the expression "This proposal" to describe the CLOS specification. That should be clarified somehow.] [RPG: ok] Page 1.29, Paragraph 1 The wording implies that: (EQUAL '(A (B C)) '((A B) C)) is T, which is certainly false. Note that cleanup is entertaining proposal to flush EQUAL and EQUALP. [Just change this to the lists of qualifiers are EQUAL?] [RPG: The prose already states that we are dealing with lists of qualifiers and not with anything resembling his point.] Page 1-32, At this point I made a note: In general, this draft details the complex, general case before the simpler, common special case. This *may* be appropriate for a standards document but it certainly isn't for a manual. [Sonya already explained to him that this wasn't a manual. I will include this criticism in the ones we respond to in written form so that we can answer it for everyone.] Date: Wed, 13 Apr 88 10:32 PDT From: Sonya E. Keene The section "Determining the Class Precedence List" has examples where defclass is used to define classes, and the CPL is computed from those definitions. However, the CPLs shown don't include standard-object (they do include t). We should really fix this. [RPG: Fixed] The table in Figure 1-1 has two columns, labelled "Predefined Common Lisp Type" and "Class Precedence List". The first column heading isn't right; actually, it is correct, but it misses the point. They are Common Lisp types, but the important thing is that CLOS has classes corresponding to those types. I think that column heading should be simply "Classes" or "Predefined Classes" (since "Classes Corresponding to Common Lisp Types" is too long). [RPG: Fixed] Also, the section "Standard Meta-objects" says "The class named standard-object is an instance of the class standard-class and is a superclass of every class that is an instance of standard-class except itself." I believe that the MOP (p 3-10) contradicts this statement, since the class structure-object is an instance of the class standard-class, yet it doesn't have standard-object as a superclass. [The draft of the MOP you were reading was wrong here. structure-object is an instance of structure-class.] [RPG: Clarified the wording.] Date: Thu, 21 Apr 88 19:32:30 JST From: Masayuki Ida Comments on CLOS ch1 and ch2. 1. explanation around the mixture of defmethod and defun. I could not find the specification on the mixture of defmethod and defun with the same name. is it error ? is it allowed in what sense? [Somehow we need to make the following clear. defun calls setf of symbol-fucntion, so defun totally wipes out what used to be in the symbols `function cell'. If the symbol used to name a function it now names a new function. If the symbol used to name a generic function, that generic function is gone and the symbol now just names the new function defmethod calls ensure-generic-function which signals an error if the symbol already names an ordinary function or macro. Here is the state table, it might be a good idea to put this in the document? function macro generic function ---------------------------------------------- | defun | fn is macro is generic function | replaced replaced is replaced | defmacro | fn is macro is generic function | replaced replaced is replaced | defmethod | error error method is added to | signalled signalled generic function, | existing method may | be replaced ] [RPG: I think this is already clear. There is a section on naming generic functions which states that generic functions are named exactly as normal functions are. There are clear passages that state that trying to add methods to non-generic functions cause errors to be signaled. Trying to define a function on top of a generic function is covered by the naming discussion. I think if we say anything more than what is already said, we will be specifying CL more than CL is currently specified. There is already no discussion of what the following does in CL except for the function naming disucssion in CLtL: (defun f ...) (defun f ...) For example, we don't know what this does either: (defun f ...) (defmacro f ...) So, the best we can do is to state that the generic function names are exactly like CL ones and leave as an implication that your implementation will do to generic functions whatever it does to ordinary functions under DEFUN and DEFMACRO.]  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 16:57:48 EDT Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 27 Apr 88 13:45:28 PDT Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Wed 27 Apr 88 13:39:58-PDT Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 27 Apr 88 12:44:44 PST Received: from hplwhh.HPL.HP.COM (hplwhh.hpl.hp.com) by hplms2.HP.COM; Wed, 27 Apr 88 13:44:26 pdt Received: from hplwhh by hplwhh.HPL.HP.COM; Wed, 27 Apr 88 13:42:59 pdt To: Jon L White Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named X-Mailer: mh6.5 In-Reply-To: Your message of Tue, 26 Apr 88 21:25:20 -0700. <8804270425.AA03970@bhopal.lucid.com> Date: Wed, 27 Apr 88 13:42:57 PDT Message-Id: <7701.578176977@hplwhh> From: Warren Harris SYMBOL-CLASS is poorly named I've often thought this too, since there is no CLASS slot on symbol objects (nor would I want there to be). Although you've given very good arguments in favor of the alternative name CLASS-NAMED, you might also consider the name FIND-CLASS. This would correpsond with other CL naming functions like FIND-SYMBOL and FIND-PACKAGE. I would also then suggest renaming GET-METHOD to FIND-METHOD to fit into this scheme.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 14:41:34 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Apr 88 11:29:48 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 392897; 27 Apr 88 14:29:31 EDT Date: Wed, 27 Apr 88 14:29 EDT From: David A. Moon Subject: "Written Responses" to CLOS 88-002: SETF Functions To: Jon L White cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8804270356.AA03909@bhopal.lucid.com> Message-ID: <19880427182909.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 26 Apr 88 20:56:52 PDT From: Jon L White "Introduction to Setf Functions" Belongs in CLtL, not CLOS ....there is no need, now, to have this in the CLOS spec, since it has already been tentatively approved by the Cleanup committee. My notes from the March X3J13 meeting say that X3J13 failed to make a decision on the setf functions issue, because it got tied up with a larger issue of "function specs" that a different committee was going to work on. Was a decision made late Thursday afternoon, after I left? I seem to have lost my copy of the minutes of the meeting, or maybe they have not been mailed out yet. If X3J13 has adopted setf functions, I agree that the CLOS spec does not need to discuss them. If X3J13 is still dithering, I think the writeup should stay in the CLOS spec. If X3J13 has rejected setf functions, then we have a problem.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 14:38:14 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Apr 88 11:26:17 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 392888; Wed 27-Apr-88 14:25:51 EDT Date: Wed, 27 Apr 88 14:25 EDT From: Sonya E. Keene Subject: belated editorial comment To: Gregor.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880427175914.4.GREGOR@PORTNOY.parc.xerox.com>, <8804270356.AA03909@bhopal.lucid.com>, Your message, The message of 26 Apr 88 23:56 EDT from Jon L White Message-ID: <19880427182516.5.SKEENE@JUNCO.SCRC.Symbolics.COM> Line-fold: No Date: Wed, 27 Apr 88 10:59 PDT From: Gregor.pa@Xerox.COM I believe that this one of jonl's belated messages should be dealt with by putting a comment at the front of this section saying this is just a summary of something the cleanup committee is already dealing with. Either that or it should be removed entirely. Until Common Lisp itself has a spec in which all of the Cleanup issues are documented, I think it best to keep this section in the CLOS spec. Date: Tue, 26 Apr 88 20:56 PDT From: Jon L White To: common-lisp-object-system@sail.stanford.edu Subject: "Written Responses" to CLOS 88-002: SETF Functions "Introduction to Setf Functions" Belongs in CLtL, not CLOS The title of this response says it all. How many times have we heard CLOS subcommittee members invoke a shield against criticism by saying "CLOS can't hope to fix Common Lisp's problems.". But the Setf Functions section does exactly that! More to the point, there is no need, now, to have this in the CLOS spec, since it has already been tentatively approved by the Cleanup committee. At worst, the CLOS spec may want to contain this exposition as a kind of extended footnote, so that newer readers not familiar with the other X3J13 work will know what is going on. I believe the CLOS spec will have many readers who are not familiar with the other X3J13 work that is going on. -- JonL -- -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 14:20:41 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 27 Apr 88 11:07:52 PDT Received: from Semillon.ms by ArpaGateway.ms ; 27 APR 88 11:06:43 PDT Date: Wed, 27 Apr 88 10:59 PDT From: Gregor.pa@Xerox.COM Subject: belated editorial comment To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Included-msgs: <8804270356.AA03909@bhopal.lucid.com>, The message of 26 Apr 88 20:56 PDT from edsel!jonl@labrea.Stanford.EDU, The message of 26 Apr 88 20:56 PDT from Jon L White Message-ID: <19880427175914.4.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no I believe that this one of jonl's belated messages should be dealt with by putting a comment at the front of this section saying this is just a summary of something the cleanup committee is already dealing with. Either that or it should be removed entirely. Date: Tue, 26 Apr 88 20:56 PDT From: Jon L White To: common-lisp-object-system@sail.stanford.edu Subject: "Written Responses" to CLOS 88-002: SETF Functions "Introduction to Setf Functions" Belongs in CLtL, not CLOS The title of this response says it all. How many times have we heard CLOS subcommittee members invoke a shield against criticism by saying "CLOS can't hope to fix Common Lisp's problems.". But the Setf Functions section does exactly that! More to the point, there is no need, now, to have this in the CLOS spec, since it has already been tentatively approved by the Cleanup committee. At worst, the CLOS spec may want to contain this exposition as a kind of extended footnote, so that newer readers not familiar with the other X3J13 work will know what is going on. -- JonL -- -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 00:43:54 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 21:31:31 PDT Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 21:31:40 PDT Received: from bhopal.lucid.com by edsel id AA13042g; Tue, 26 Apr 88 21:23:16 PDT Received: by bhopal id AA03970g; Tue, 26 Apr 88 21:25:20 PDT Date: Tue, 26 Apr 88 21:25:20 PDT From: Jon L White Message-Id: <8804270425.AA03970@bhopal.lucid.com> To: common-lisp-object-system@sail.stanford.edu Subject: "Written Responses" to CLOS 88-002: SYMBOL-CLASS is poorly named SYMBOL-CLASS is poorly named The close binding of classes to symbols as names is a poor choice; there really is no analogy with the other CL constructs that are currently closely bound in with symbols (i.e., the ones that have "slots" in the symbol reserved for them). Thus the following functions should renamed (or removed!): symbol-class cboundp cmakunbound A reasonable renaming for 'symbol-class' is 'class-named'; a reasonable replacement for 'cboundp' is simply whether or not 'class-named' returns non-nil; a reasonable replacement for 'cmakunbound' is simply (setf (class-named ) nil) Current CL "slot" names for symbols are in fact defensible. Generally, there are two grounds: (1) every symbol has a SYMBOL-NAME component, and virtually every symbol has a SYMBOL-PACKAGE component; thus for storage efficiency, having a slot in the symbol structure is best. (2) many symbols have either a symbol-function or symbol-value component; but more importantly, these properties implement two of the basic features of the Lisp programming lanugage syntax -- function-call to dynamically-linked functions and free-variable access to dynamic bindings; thus for running-speed considerations, these should be a "slot" (i.e., the access from a symbol to its global function or its dynamic value must be very fast). (*) SYMBOL-PLIST is the weakest case of the existing slots; probably no one would grieve if it were not implemented as a slot (but rather as, say, a hashtable lookup). Some persons have pointed out that CLtL does not require actual "slots" -- and that a deep-bound implementation of Common Lisp would not, for example, implement SYMBOL-VALUE as a slot access. But this is a red-herring, since even in deep-bound implementations there is the need for "global value" slot for exactly the same reasons. Furthermore, nearly every commercial implementation does indeed implement these particular symbol properties as "slots"; one must assume that these vendors have reasonable grounds for doing so, such as the above-mentioned ones. However, there is no need for a "slot" for classes. Rather, the tendency now is to prepare for names which are not symbols -- i.e., the "Definition Specs" proposal before X3J13 [but since only symbols can name functions in program syntax, there still is no need for name-to-function mapping to be fast except on symbols]. It makes perfectly good sense to be able to name classes with non-symbol "definition specs", although I wouldn't suggest that these non-symbol "specs" be permissible as parameter-specializer-names; at worst this would limit such names to classes that are "built up" with primitives lower than DEFMETHOD etc. Instead of the paradigm SYMBOL-, there is similar use of the paradigm -NAMED elsewhere. In Gregor's slides before the recent X3J13 meeting, he actually used CLASS-NAMED in a place or two, proving that that is the more "natural" name for this feature. In a preprint of the paper "An Object-Oriented Database System to Support an Integrated Programming Environment", by Dan Weinreb et. al. of Symbolics, the authors describe a database system linked closely with CLOS. "Entities" in this database scheme have a name (always a symbol); the example entities which have a NAME slot all have an "inverse" name mapping function called "-NAMED". The PERSON entity has a NAME slot -- presumably to be accessed as PERSON-NAME; and it also has, explicitly, the inverse PERSON-NAMED. Similarly for DEPARTMENT-NAME and DEPARTMENT-NAMED. This is independent evidence of a widespread convention: for a category of named things , the name-to-thing mapping should be called -NAMED. One possible objection: a named object with components will frequently have names assigned to the components by suffixing "-" to the object name. Thus CLASS-NAMED might be mistaken for the NAMED slot of classes. I claim it will never be so mistaken, primarily because of the wide-spread use of the protocol just described, and also because there is a tendency *not* to give names to components that are parsable (in English) as a word in the past tense. Thus NAME and FROB are good component names for classes, but NAMED and FROBBED are not. It just doesn't happen. If someone wanted, say, a REDEFINED slot, as a way of remembering whether or not the class had ever been redefined, he _probably_ would call it REDEFINED-P. Note also that in the database paper just cited, there is an entity COURSE with a TITLE slot; and the inverse name mapping is, very appropriately, called COURSES-ENTITLED -- the "past tense" protocol. [I might even suggest this simple linguistic device is worth noting somewhere as a "good style" note.] Benefits: (1) refrain from making the mistake of suggesting that symbols have a "class" slot; reduce false cognates on names like SYMBOL-PACKAGE. (2) remove artificial blocks to the use of non-symbol names. (3) align with the common protocol of using "-named" as the mapping from names to 's. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 00:43:37 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 21:31:43 PDT Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 21:31:48 PDT Received: from bhopal.lucid.com by edsel id AA13049g; Tue, 26 Apr 88 21:25:02 PDT Received: by bhopal id AA03975g; Tue, 26 Apr 88 21:27:04 PDT Date: Tue, 26 Apr 88 21:27:04 PDT From: Jon L White Message-Id: <8804270427.AA03975@bhopal.lucid.com> To: common-lisp-object-system@sail.stanford.edu Subject: "Written Responses" to CLOS 88-002: (Re)Initialization Strong Similarity between Initialization/Reinitialization The strong similarity between the Initialization and Reinitialization protocols makes me wonder why there need to be two. Couldn't more be factored out into a single protocol? The state of the design circa November 1987 was unacceptably confusing to me; the situation in CLOS 88-002 appears to be one of avoiding the problem. I am aware that significant discussion has been taking place on the electronic mailing list during March and April 1988, so I'm sure something will be done; I just want to register a "Response" so that at least the situation will not be the same as it was during the winter of 1987-88. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Apr 88 00:26:29 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 21:15:02 PDT Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 21:15:12 PDT Received: from bhopal.lucid.com by edsel id AA12851g; Tue, 26 Apr 88 20:54:49 PDT Received: by bhopal id AA03909g; Tue, 26 Apr 88 20:56:52 PDT Date: Tue, 26 Apr 88 20:56:52 PDT From: Jon L White Message-Id: <8804270356.AA03909@bhopal.lucid.com> To: common-lisp-object-system@sail.stanford.edu Subject: "Written Responses" to CLOS 88-002: SETF Functions "Introduction to Setf Functions" Belongs in CLtL, not CLOS The title of this response says it all. How many times have we heard CLOS subcommittee members invoke a shield against criticism by saying "CLOS can't hope to fix Common Lisp's problems.". But the Setf Functions section does exactly that! More to the point, there is no need, now, to have this in the CLOS spec, since it has already been tentatively approved by the Cleanup committee. At worst, the CLOS spec may want to contain this exposition as a kind of extended footnote, so that newer readers not familiar with the other X3J13 work will know what is going on. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Apr 88 22:27:29 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 26 Apr 88 19:15:23 PDT Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 19:13:29 PDT Date: Tue, 26 Apr 88 19:11 PDT From: Gregor.pa@Xerox.COM Subject: editorial comments To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880427021133.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Here are the editorial comments I have culled from the messages we received. After some of the comments I put my own opinion in brackets. From: Dan L. Pierson Page 1-9, Add to the list of things provided by slot options and class options: o Specifying the legal data types of the slot contents. (Of course, this can be found elsewhere in the document, but my impression on reading this introductory list was that for some reason you couldn't do this.) Page 1-11, Paragraphs 3 and 7 Why are reader, writer, and with-slots *required* to be implemented using SLOT-VALUE? I don't doubt that you have a good reason, but it's not obvious to a relative novice. [These must call slot value because the implementation of slot-value for a particular class can be changed using the MOP. We don't want to go into that at this point in the document, but perhaps a simple forward reference would be appropriate. Paragraphs 7 and 8 This implies that WITH-SLOTS can access slots without accessors but WITH-ACCESSORS can't. This is reasonable but should probably be made explicit. Some people may feel that this makes WITH-SLOTS unsafe. [Yes this needs to be made explicit.] Page 1-26, Paragraph 2, Sentence 2 The following are my exact notes as I read this section: What about methods in both old and new? Are they "added"? If so, in what way is this definition different from saying that the "contents" of the old generic function are trashed and replaced by the new generic function? AHA! Some methods could have been defined by DEFMETHOD, but the wording is still confusing. Paragraph 6, Sentence 3 The wording is a bit confusing. Page 1-28, Paragraph 2, Sentence 4 and example line Has this been submitted to cleanup? I don't recognize it. [He is confused by the use of the expression "This proposal" to describe the CLOS specification. That should be clarified somehow.] Page 1.29, Paragraph 1 The wording implies that: (EQUAL '(A (B C)) '((A B) C)) is T, which is certainly false. Note that cleanup is entertaining proposal to flush EQUAL and EQUALP. [Just change this to the lists of qualifiers are EQUAL?] Page 1-32, At this point I made a note: In general, this draft details the complex, general case before the simpler, common special case. This *may* be appropriate for a standards document but it certainly isn't for a manual. [Sonya already explained to him that this wasn't a manual. I will include this criticism in the ones we respond to in written form so that we can answer it for everyone.] Page 2-27, Next to last paragraph Can extension slot options appear more than once in a single slot description (it appears reasonable, but it's not clear from this whether it's legal). [Make it clear that extension slot options can appear more than once.] Last paragraph The slot can also be accessed by WITH-SLOTS, since WITH-SLOTS uses SLOT-VALUE. [Sonya doesn't feel it is necessary to make this explicit.] Page 2-35, Paragraphs 7 and 8 These paragraphs don't specify how to distinguish a predicate from the first keyword option since they are both distinguished by being symbols other than * (or NIL). [The predicate is distinguished by position. Either it or the list of qualifiers or () or * must be in the same position. Somehow the text should make this clear.] Date: Fri, 15 Apr 88 13:43 PDT From: David N Gray On page 2-8, the description "... of the form S or of the form S*" is a little confusing because S is not defined. I think it would be helpful if locally defined macros and functions (such as CALL-METHOD and CALL-NEXT-METHOD) had a syntax line that said "Local Macro" or "Local Function" instead of just "Macro" or "Function". [I think this is a good idea.] On page 2-25, third paragraph, the sentence "The slot name argument is a symbol that can be used as a Common Lisp variable name." is confusing. It seems to be saying that the name becomes defined such that it can be accessed just like a variable (as in flavors), but this is only true through the use of WITH-SLOTS, which is not mentioned here. Probably what was intended was that the slot name must satisfy the same syntactic requirements as a variable name, i.e. a symbol which is not a keyword, nil, or t. Date: Wed, 13 Apr 88 10:32 PDT From: Sonya E. Keene The section "Determining the Class Precedence List" has examples where defclass is used to define classes, and the CPL is computed from those definitions. However, the CPLs shown don't include standard-object (they do include t). We should really fix this. The table in Figure 1-1 has two columns, labelled "Predefined Common Lisp Type" and "Class Precedence List". The first column heading isn't right; actually, it is correct, but it misses the point. They are Common Lisp types, but the important thing is that CLOS has classes corresponding to those types. I think that column heading should be simply "Classes" or "Predefined Classes" (since "Classes Corresponding to Common Lisp Types" is too long). Also, the section "Standard Meta-objects" says "The class named standard-object is an instance of the class standard-class and is a superclass of every class that is an instance of standard-class except itself." I believe that the MOP (p 3-10) contradicts this statement, since the class structure-object is an instance of the class standard-class, yet it doesn't have standard-object as a superclass. [The draft of the MOP you were reading was wrong here. structure-object is an instance of structure-class.] Date: Thu, 21 Apr 88 19:32:30 JST From: Masayuki Ida Comments on CLOS ch1 and ch2. 1. explanation around the mixture of defmethod and defun. I could not find the specification on the mixture of defmethod and defun with the same name. is it error ? is it allowed in what sense? [Somehow we need to make the following clear. defun calls setf of symbol-fucntion, so defun totally wipes out what used to be in the symbols `function cell'. If the symbol used to name a function it now names a new function. If the symbol used to name a generic function, that generic function is gone and the symbol now just names the new function defmethod calls ensure-generic-function which signals an error if the symbol already names an ordinary function or macro. Here is the state table, it might be a good idea to put this in the document? function macro generic function ---------------------------------------------- | defun | fn is macro is generic function | replaced replaced is replaced | defmacro | fn is macro is generic function | replaced replaced is replaced | defmethod | error error method is added to | signalled signalled generic function, | existing method may | be replaced ] typos 5. 2-79 symbol-macrolet examples ;;; not (let 'foo (let (('foo 'bar)) 'foo)). ===> ;;; not (list 'foo (let (('foo 'bar)) 'foo)). ^^^^ Ambiguous 6. 2-8 line 9 Osub1 | ... | Osubn and line 14 .... for some 1 <= k <= n, ... 'n' is ambiguous to the 'n' of line 13. ====> line 9 Osub1 | ... | OsubN and line 14 ... for some 1 <= k <= N, ... replacing small 'n' to large 'N'. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Apr 88 21:57:41 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 26 Apr 88 18:46:08 PDT Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 18:39:47 PDT Date: Tue, 26 Apr 88 18:37 PDT From: Gregor.pa@Xerox.COM Subject: dealing with 1+2 comments To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880427013737.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no I am getting ready to address the comments we have received on chapter 1 and 2. This message explains how I intend to proceed, what I am going to do, and what I am going to ask others to do. I am going to start by separating the comments into editorial comments and technical comments. An editorial comment is one which is directed at the text of the specification. These need to be addressed by clarifying some part of the specification. This usually means adding a small amount of text explaining a particular situation. A technical comment is one which is directed at the actual design of CLOS. These comments need to be addressed by either explaining why we choose to leave CLOS as it is, or what change we made to address the comment and why we made that change. I will collect all the editorial comments that have been sent to the mailing list into one message. I will send this message to the whole list. I will ask someone else to volunteer to address these comments by making the appropriate changes in the specification. I will then take the technical comments and, with David's help, I will come to a preliminary decision as to what our response should be. As described above, the response may suggest that we make some change to the design, or it may just be an explanation of why we chose to leave things as they were. I will write up these preliminary responses and send them to the entire mailing list. At that point, everyone should comment on the appropriateness of the responses David and I came up with. The usual round robin of messages can be used to reach closure on this. I will then rework the responses to conform to what we have decided. I will let someone else volunteer to make the appropriate changes to the specification. The bad news is that we have less than two weeks to do this whole thing, including reach closure on the open issues having to do with reinitialization. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Apr 88 20:14:48 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 15:57:12 PDT Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 15:56:19 PDT Received: from sunvalleymall.lucid.com by edsel id AA11062g; Tue, 26 Apr 88 14:32:31 PDT Received: by sunvalleymall id AA16752g; Tue, 26 Apr 88 14:34:10 PDT Date: Tue, 26 Apr 88 14:34:10 PDT From: Jan Zubkoff Message-Id: <8804262134.AA16752@sunvalleymall.lucid.com> To: common-lisp-object-system@sail.stanford.edu Cc: edsel!jlz@labrea.Stanford.EDU Subject: X3 subcommittee meeting in June We're set for 10:00am Tuesday, June 14 in the Bonaire meeting room on the first floor of Symbolics. Symbolics has a secure building and will wait for all of you to arrive before guiding us to the room. We need to be out by 5:30 when they close. ---jan---  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Apr 88 16:46:07 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Apr 88 13:31:04 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 392001; Tue 26-Apr-88 16:30:50 EDT Date: Tue, 26 Apr 88 16:30 EDT From: David A. Moon Subject: Re: Reinitialization To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <19880426203020.4.MOON@EUPHRATES.SCRC.Symbolics.COM> This issue has not been addressed yet, I think. Date: Wed, 20 Apr 88 23:51 EDT From: David A. Moon check-initargs has to be called from four different places now, as there are four updating functions that have initargs arguments. I think the best way is to give check-initargs another argument, which is a list of generic functions. An initarg is acceptable if it's a slot-filling initarg or if any of the generic functions in the list accepts it. make-instance would pass (list #'allocate-instance #'initialize-instance #'initialize-new-instance). reinitialize-instance would pass (list #'reinitialize-instance #'initialize-new-instance). The only problem with this is that each of these takes idiosyncratic arguments, which check-initargs has to take into account when computing the applicable methods. Is there a better idea? The basic goal is that for each of the seven functions that take initargs as arguments (make-instance, allocate-instance, initialize-new-instance, reinitialize-instance, update-instance-for-redefined-class, update-instance-for-different-class, and initialize-instance), the keyword arguments accepted without error are the initargs for slot filling and the initargs accepted by applicable methods for any generic function that is going to see these initargs, and only those. I hope you can understand that run-on sentence. Thus for example I can define (defmethod initialize-instance :after ((i my-class) ignore &key moo) ...) and now reinitialize-instance of my-class accepts :moo without my having to say anything else. The above idea for changing check-initargs isn't such a great one. Other ideas: split check-initargs into seven functions for the seven cases. Make allocate-instance, initialize-new-instance, and initialize-instance never check their arguments, since they're only "supposed to be" called from other functions that already checked the arguments, thus needing only four versions of check-initargs (I don't like this idea). Give check-initargs a flag argument which is the name of the function on whose behalf it has been called. Invent some new way for generic functions to communicate with each other and negotiate for who handles each initarg. Any bright ideas?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Apr 88 16:06:44 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 12:51:18 PDT Date: Tue, 26 Apr 88 12:46 PDT From: Gregor.pa@Xerox.COM Subject: Re: defclass in CLOS & 7.2 To: kanderso@WILMA.BBN.COM cc: Jim Kelly , rshapiro@vax.bbn.com, kanderson@vax.bbn.com, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: The message of 26 Apr 88 08:38 PDT from kanderso@WILMA.BBN.COM Message-ID: <19880426194626.3.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no This message is only of interest to people who run PCL on Symbolics 36xx machines. As near as I can tell, PCL doesn't work at all in 7.2. The hacks which I wrote to cause the compiler to compile random top-level forms don't work, the fixes I made to the compiler to treat #, properly don't work, and as a result nothing really works for beans. I suggest that you wait at least a few days before trying to run PCL in 7.2. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Apr 88 14:49:43 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 26 Apr 88 11:39:09 PDT Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 11:31:48 PDT Date: Tue, 26 Apr 88 11:29 PDT From: Gregor.pa@Xerox.COM Subject: Re: Reinitialization To: Sonya E. Keene cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <19880426165158.1.SKEENE@JUNCO.SCRC.Symbolics.COM> Message-ID: <19880426182922.4.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no I like these names just fine. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Apr 88 13:07:46 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Apr 88 09:52:28 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 391724; 26 Apr 88 12:52:32 EDT Date: Tue, 26 Apr 88 12:51 EDT From: Sonya E. Keene Subject: Re: Reinitialization To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <19880426165158.1.SKEENE@JUNCO.SCRC.Symbolics.COM> This message suggests some better names. I'm willing to take a shot at putting this new material into Chapters 1 and 2. Date: Wed, 20 Apr 88 23:51 EDT From: David A. Moon This message comments on the proposed revamping of the ch1 object creation protocol in support of ch3. Date: 13 Apr 88 11:15 PDT From: Danny Bobrow The four updating functions are: initialize-new-instance instance &rest initialization-arguments reinitialize-instance instance &rest initialization-arguments update-instance-structure instance added-slots discarded-slots property-list &rest initialization-arguments update-instance-with-new-class previous current &rest initialization-arguments This suggests renaming update-instance-structure to update-instance-with-redefined-class. With that change all five names look consistent and fairly clear as to their meanings. Suggestion 1 (to be superseded below by Suggestion 2): How about these two names instead of "-with-new-class" and "-with-redefined-class"? "With" seems overloaded, and this use of it is inconsistent with "with-open-file", etc. Also, "new class" is overloaded; it means both "newly-created class" and "different class". update-instance-structure-for-different-class update-instance-structure-for-redefined-class Suggestion 2 (this one I prefer): Let's get rid of the "-structure" from these names, and use the following names: update-instance-for-different-class update-instance-for-redefined-class Why? Well, take a look at pages 1-15 and 1-16. The chapter on Redefining Classes explains that this is a two-step process. Step 1 is "Modifying the Structure of Instances", which is done by an un-named process. Step 2 is called "Initializing Newly-added Local Slots", which is done by the generic function currently called update-instance-structure. Thus update-instance-structure has nothing to do with updating the instance structure, because it is called AFTER the instance structure has been updated. Just plain update-instance-for-different-class and update-instance-for-redefined-class seem to describe what they actually do, where "update-instance-" is shorthand for "update the appropriate slots of the instance to have the correct values".  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Apr 88 11:58:22 EDT Received: from Salvador.ms by ArpaGateway.ms ; 26 APR 88 08:44:58 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 26 APR 88 08:41:31 PDT To: Jim Kelly cc: rshapiro@vax.bbn.com, kanderson@vax.bbn.com, CommonLoops.pa@Xerox.COM Subject: Re: defclass in CLOS & 7.2 In-reply-to: Your message of Mon, 25 Apr 88 21:04:43 -0400. Date: Tue, 26 Apr 88 11:38:24 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880426-084458-2690@Xerox> Replied: Tue, 26 Apr 88 05:23:37 -0400 Replied: "Jim Kelly rshapiro@vax.bbn.com, kanderson@vax.bbn.com" Received: from vax.bbn.com by WILMA.BBN.COM id aa11591; 25 Apr 88 21:10 EDT Date: Mon, 25 Apr 88 21:04:43 EDT From: Jim Kelly To: rshapiro@vax.bbn.com, kanderson@vax.bbn.com cc: jkelly@vax.bbn.com Subject: defclass in CLOS & 7.2 In trying to compile a defclass I got the following errror: "Maximum stack level for this function (230) exceeds architectural limit (224)." This compiled fine in PCL (ie: the old version) and 7.1 - the error occurs with CLOS loaded in 7.2. The error happens after the file is 100% read in - in the bottom right the message "Compiling (PCL:TOP-LEVEL-FORM (DEFCLASS SCHEDULE-D))" appears and the "completion bar" underneath indicates that it's about half done when it dies. Perhaps the new version can't handle as many slots as the older one (although I don't know what the 230 in the message means - the defclass has 221 slots). Any comments, suggestions? (The file I was trying to compile was conger:>aiis>defclasses>taxforms>schedule-d.lisp if it's any help). Basically you are running into limitations of the Symbolics, and i presume other systems have their own limitations. It is typical for automatically generated code to run into such problems. If you break up your class into smaller mixins it should work. Let me know if this doesn't work. Here's what seems to be happening: DEFCLASS expands into a form like (load-defclass ... (list (list* :name slot-1 :initfunction #'false '(:init-form nil :accessor slot-1)) ... many other slots ...)) LIST can only handle about 256 arguments. If you rewrite the above form into an nconc of smaller lists, you run into another limitation on the number of constants you can have in a function from all the '(:init-form ...)'s. I couldn't think of a way around that. k  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Apr 88 11:34:02 EDT Received: from Salvador.ms by ArpaGateway.ms ; 26 APR 88 08:23:23 PDT Return-Path: Redistributed: commonloops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 26 APR 88 08:20:54 PDT To: "Paul P. Maglio" cc: commonloops.pa@Xerox.COM Subject: Re: type specifiers in slot descriptors In-reply-to: Your message of Wed, 20 Apr 88 12:57:53 -0400. <8804201657.AA03331@faron.sun.uucp> Date: Tue, 26 Apr 88 11:17:27 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880426-082323-2650@Xerox> I think the following patch fixes the problem you described. In the original, the order of the dolist forms below were reversed. This added new accessors and then deleted them. k ;;; KRA: reversed order of dolist forms. (defun update-slot-accessors--class-2 (class slotd forcep new old acc/rea) (flet ((get-gf (name) (ensure-generic-function name))) (dolist (gf-name old) (when (or forcep (not (memq gf-name new))) (ecase acc/rea (:accessor (remove-reader-method class slotd (get-gf gf-name)) (remove-writer-method class slotd (get-gf `(setf ,gf-name)))) (:reader (remove-reader-method class slotd (get-gf gf-name)))))) (dolist (gf-name new) (when (or forcep (not (memq gf-name old))) (ecase acc/rea (:accessor (add-reader-method class slotd (get-gf gf-name)) (add-writer-method class slotd (get-gf `(setf ,gf-name))) (do-defmethod-setf-defsetf gf-name (list (or (class-name class) 'x)))) (:reader (add-reader-method class slotd (get-gf gf-name))))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Apr 88 11:33:44 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 08:22:46 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 26 APR 88 08:19:52 PDT To: "Richard L. Piazza" cc: CommonLoops.pa@Xerox.COM Subject: Re: :initform and :allocation :class In-reply-to: Your message of Tue, 19 Apr 88 18:17:55 -0400. <8804192217.AA00409@orbit.sun.uucp> Date: Tue, 26 Apr 88 11:14:33 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880426-082246-2647@Xerox> I changed your "(EVAL INITFORM)" to "(FUNCALL INITFUNCTION)" which is a little more consistent, though maybe this patch should go somewhere else altogether. k (defmethod PARSE-CLASS-SLOT ((class standard-class) slot) . . . (make-slotd class :name name :keyword (make-keyword name) :initform (IF (EQ ALLOCATION :CLASS) (FUNCALL INITFUNCTION) initform) :initfunction initfunction :initargs initargs :allocation allocation :type type :accessors accessors :readers readers)))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Apr 88 11:27:20 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 APR 88 08:11:44 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 26 APR 88 08:08:22 PDT To: CommonLoops.pa@Xerox.COM Subject: Bug macroexpanding a defclass form Date: Tue, 26 Apr 88 10:53:23 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880426-081144-2630@Xerox> In Symbolics 3640 Zwei in Genera 7.1, IP-TCP 52.16, BBN site system 2.8, Color Support 11.4, Color 331.5, Color Editor 313.0, Fortran 6.27, Graph 13.0, Scientific Graphs 6.3, Window Support 10.1, Essential Window Support 9.2, PCI Data Loaded. 9.0, One More Nice Inheritance System for PCI 6.0, PCI Data-Loading Essentials. 1.0, Experimental Ken Anderson's Initial Environment 8, CL Object System 4.5, microcode 3640-FPA-MIC 396, FEP 127, fep0:>v127-lisp.flod(64), fep0:>v127-loaders.flod(64), fep0:>v127-info.flod(64), fep0:>v127-debug.flod(34), Machine serial number 4146, Make rel 7 debugger know about PCL Generic functions. (from CLOS:CLOS;7DEBUG.LISP.2), on Rhythm & Blues: with the cursor at the beginning of form: (defclass foo () ()) the command META-X macroexpand expression all produces the following error, while META-X macroexpand expression works ok. It looks like top-level-form is not getting macroexpanded right somehow. Error: Incorrect arguments to DEFCLASS: The macro's argument pattern (NAME INCLUDES SLOTS &REST OPTIONS) does not match the form (DEFCLASS FOO). While in the function DEFCLASS  SI:MACROEXPAND-1-INTERNAL The condition signalled was SI:DEFMACRO-ARGUMENT-ERROR DEFCLASS: (P.C. = 15) (from CONGER:>pcl>new>defclass) Arg 0 (SI:.FORM.): (DEFCLASS FOO) Arg 1 (SI:.ENV.): (NIL NIL NIL NIL NIL NIL NIL) Local 2: DEFCLASS Local 3 (NAME): (NAME INCLUDES SLOTS &REST OPTIONS) Local 4 (INCLUDES): (DEFCLASS FOO) SI:MACROEXPAND-1-INTERNAL: (P.C. = 201) Arg 0 (SI:MACRO-CALL): (DEFCLASS FOO) Arg 1 (SI:ENV): (NIL NIL NIL NIL NIL NIL NIL) Arg 2 (SI:RUN-STYLE-CHECKERS-P): NIL Arg 3 (SI:DONT-EXPAND-SPECIAL-FORMS): NIL MACROEXPAND-1: (P.C. = 10) Arg 0 (SI:MACRO-CALL): (DEFCLASS FOO) Arg 1 (SI:ENV): (NIL NIL NIL NIL NIL NIL NIL) --Defaulted args:-- Arg 2 (SI:DONT-EXPAND-SPECIAL-FORMS): NIL COMPILER:OPTIMIZE-FORM: (P.C. = 320) (from SYS:PATCH;SYSTEM-349-234) Arg 0 (SYS:FORM): (DEFCLASS FOO) Arg 1 (COMPILER:ENV): (NIL NIL NIL NIL NIL NIL NIL) Rest arg (ZL:ARGS): (:ALLOW-OTHER-KEYS T :ENVIRONMENT NIL :DO-INLINE-FORMS T :DO-MACRO-EXPANSION T :ALLOW-OTHER-KEYS T ...) (:INTERNAL COMPILER:OPTIMIZE-TOP-LEVEL-FORM 0): (P.C. = 23) Arg 0 (COMPILER:.LEXICAL-ENVIRONMENT-POINTER.): # Arg 1 (SYS:FORM): (DEFCLASS FOO) Arg 2 (COMPILER:KIND): NIL Arg 3 (COMPILER:USAGE): LT:EFFECT LT::MAPFORMS-CALL: (P.C. = 12) Arg 0 (SYS:FORM): (DEFCLASS FOO) Arg 1 (LT::KIND): NIL Arg 2 (LT::USAGE): LT:EFFECT --Defaulted args:-- Arg 3 (FUNCTION): # LT:COPYFORMS-1: (P.C. = 20) Arg 0 (LT::ORIGINAL-FORM): (DEFCLASS FOO) Arg 1 (LT::USAGE): LT:EFFECT LT::MAPFORMS-LIST: (P.C. = 15) Arg 0 (LT::ORIGINAL-LIST): ((DEFCLASS FOO) (COMPILE LOAD EVAL) (LET NIL (LOAD-DEFCLASS (QUOTE STANDARD-CLASS) (QUOTE FOO) (QUOTE NIL) (LIST) (LIST)))) Arg 1 (LT::CURRENT-LIST): ((DEFCLASS FOO) (COMPILE LOAD EVAL) (LET NIL (LOAD-DEFCLASS (QUOTE STANDARD-CLASS) (QUOTE FOO) (QUOTE NIL) (LIST) (LIST)))) Arg 2 (LT::TAIL-TO-DO): ((DEFCLASS FOO) (COMPILE LOAD EVAL) (LET NIL (LOAD-DEFCLASS (QUOTE STANDARD-CLASS) (QUOTE FOO) (QUOTE NIL) (LIST) (LIST)))) Arg 3 (LT::ALL-BUT-LAST-USAGE): LT:EFFECT Arg 4 (LT::LAST-USAGE): EVAL LT::MAPFORMS-TEMPLATE-1: (P.C. = 247) (from SYS:PATCH;SYSTEM-349-13) Arg 0 (LT::ORIGINAL-ARGL): ((DEFCLASS FOO) (COMPILE LOAD EVAL) (LET NIL (LOAD-DEFCLASS (QUOTE STANDARD-CLASS) (QUOTE FOO) (QUOTE NIL) (LIST) (LIST)))) Arg 1 (LT::TEMPLATE): LT:BODY LT::MAPFORMS-TEMPLATE: (P.C. = 43) Arg 0 (LT::ORIGINAL-FORM): (DEFCLASS FOO NIL NIL) Arg 1: (TOP-LEVEL-FORM (DEFCLASS FOO) (COMPILE LOAD EVAL) (LET NIL (LOAD-DEFCLASS (QUOTE STANDARD-CLASS) (QUOTE FOO) (QUOTE NIL) (LIST) (LIST)))) Arg 2 (LT::TEMPLATE): LT:BODY Arg 3: EVAL LT:COPYFORMS-1: (P.C. = 400) Arg 0 (LT::ORIGINAL-FORM): (DEFCLASS FOO NIL NIL) Arg 1 (LT::USAGE): EVAL LT:COPYFORMS: (P.C. = 65) Arg 0: # Arg 1 (SYS:FORM): (DEFCLASS FOO NIL NIL) Rest arg: (:ENVIRONMENT NIL) COMPILER:OPTIMIZE-TOP-LEVEL-FORM: (P.C. = 20) Arg 0 (SYS:FORM): (DEFCLASS FOO NIL NIL) Rest arg (ZL:ARGS): (:ENVIRONMENT NIL :DO-INLINE-FORMS T :DO-MACRO-EXPANSION T :ALLOW-OTHER-KEYS T :ALL-LEVELS T) SI:MEXP-EXPAND-FORM: (P.C. = 35) Arg 0 (SYS:FORM): (DEFCLASS FOO NIL NIL) Arg 1 (SI:ENV): NIL Rest arg (SI:OPTIONS): (:ALL-LEVELS T) ZWEI:MACRO-EXPAND-COMMAND: (P.C. = 25) Rest arg (ZWEI:OPTIONS): (:ALL-LEVELS T) ZWEI:COM-MACRO-EXPAND-EXPRESSION-ALL: (P.C. = 4) (FLAVOR:METHOD SI:WITH-PROCESS-NON-INTERACTIVE-PRIORITY-INTERNAL SI:PROCESS): (P.C. = 43) Arg 0 (SCL:SELF): # Arg 1 (SYS:SELF-MAPPING-TABLE): SI:PROCESS Arg 2 (FLAVOR::.GENERIC.): # Arg 3 (SI:CONTINUATION): # Rest arg: NIL ZWEI:COMMAND-EXECUTE: (P.C. = 57) Arg 0 (ZWEI:COMMAND): ZWEI:COM-MACRO-EXPAND-EXPRESSION-ALL Arg 1 (ZWEI:CHAR): #\m-sh-M Arg 2 (ZWEI:PREFIX-CHAR): NIL Arg 3 (ZWEI:HOOK-LIST): NIL ZWEI:PROCESS-COMMAND-CHAR: (P.C. = 14) Arg 0 (ZWEI:CH): #\m-sh-M (FLAVOR:METHOD :EDIT ZWEI:EDITOR): (P.C. = 316) Arg 0 (SCL:SELF): # Arg 1 (SYS:SELF-MAPPING-TABLE): # Arg 2 (FLAVOR::.GENERIC.): :EDIT --Defaulted args:-- Arg 3 (ZWEI:TOP-LEVEL-P): T Arg 4 (ZWEI:DESCRIPTION): NIL (:INTERNAL (FLAVOR:COMBINED :EDIT ZWEI:ZMACS-TOP-LEVEL-EDITOR) 1): (P.C. = 20) Arg 0 (SCL:SELF): # Arg 1 (SYS:SELF-MAPPING-TABLE): # Arg 2 (FLAVOR::.GENERIC.): :EDIT Rest arg (FLAVOR::.DAEMON-CALLER-ARGS.): NIL (FLAVOR:METHOD SI:WITH-PROCESS-INTERACTIVE-PRIORITY-INTERNAL SI:PROCESS): (P.C. = 40) Arg 0 (SCL:SELF): # Arg 1 (SYS:SELF-MAPPING-TABLE): SI:PROCESS Arg 2 (FLAVOR::.GENERIC.): # Arg 3 (SI:CONTINUATION): # Rest arg: NIL (FLAVOR:WHOPPER :EDIT ZWEI:EDITOR): (P.C. = 20) Arg 0 (SCL:SELF): # Arg 1 (SYS:SELF-MAPPING-TABLE): # Arg 2 (FLAVOR::.WHOPPER-CONTINUATION.): # Arg 3 (FLAVOR::.OLD-SELF-MAPPING-TABLE.): # Arg 4 (FLAVOR::.GENERIC.): :EDIT Rest arg (ZWEI:ARGUMENTS): NIL (FLAVOR:COMBINED :EDIT ZWEI:ZMACS-TOP-LEVEL-EDITOR): (P.C. = 317) Arg 0 (SCL:SELF): # Arg 1 (SYS:SELF-MAPPING-TABLE): # Arg 2 (FLAVOR::.GENERIC.): :EDIT Rest arg (FLAVOR::.DAEMON-CALLER-ARGS.): NIL ZWEI:ZMACS-WINDOW-TOP-LEVEL: (P.C. = 55) (from SYS:PATCH;SYSTEM-349-88) SI:PROCESS-TOP-LEVEL: (P.C. = 45) Arg 0 (IGNORE): NIL ------- End of Forwarded Message  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Apr 88 20:13:09 EDT Date: 25 Apr 88 1700 PDT From: Dick Gabriel Subject: reinitialization etc To: common-lisp-object-system@SAIL.Stanford.EDU I have been silent because I have a particularly deadly version of the flu. When I read Danny's message and Moon's clarifications of reinitialization, I wasn't sure I understood the implications, so I'm not sure how well I can do incorporating them. I have done Chapmans's chapter 1 comments, and LGD is doing her chapter 2 ones. There are some comments by Sonya that need incorporation. I've had to cancel some trips and things to accommodate my flu, so I nervous about my ability to do a lot of work in the next week or so. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Apr 88 19:27:19 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 25 Apr 88 16:15:56 PDT Received: from Semillon.ms by ArpaGateway.ms ; 25 APR 88 16:07:25 PDT Date: Mon, 25 Apr 88 16:05 PDT From: Gregor.pa@Xerox.COM Subject: subcommittee meeting To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880425230532.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no In Danny's absence, I propose that we plan to meet all day Tuesday. If nobody disagrees, I will assume that Dick took care of letting Jan know about this. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Apr 88 15:34:23 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 25 Apr 88 12:20:47 PDT Received: from Semillon.ms by ArpaGateway.ms ; 25 APR 88 11:39:28 PDT Date: Mon, 25 Apr 88 11:26 PDT From: Gregor.pa@Xerox.COM Subject: Re: Reinitialization To: David A. Moon cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <19880425182606.0.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 20 Apr 88 23:51 EDT From: David A. Moon I think there is a little more technical fleshing out to be done before this is reduced to purely editorial work, but it looks plausible. Do any of the other committee members have an opinion on this? Are we going overboard on generality, or is this a good change that makes the language more consistent and hence easier to understand? I believe we should go ahead and do this. It is clearly an improvement to chapter 1+2, and should be treated as such. How should this be handled? Dick and Linda, do you want to take a stab at incorporating this? I assume the minor editorial comments from Kathy Chapman have already be incorporated. How should we handle the other comments? I am willing to take half of them and draft replies. Dave, would you be willing to draft replies to the rest? For any that we have problems on, we can get help from the rest of the list. Then we can put them all together and send it out with the -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Apr 88 12:12:55 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 APR 88 08:57:41 PDT Return-Path: Redistributed: commonloops.pa Received: from ucsd.edu by Xerox.COM ; 22 APR 88 08:46:37 PDT Received: from sdics.ucsd.edu by ucsd.edu (5.58/UCSD-1.0); Fri, 22 Apr 88 08:47:29 PDT id AA16486 for commonloops.pa@xerox.com From: hartung%ics@ucsd.edu (Jeff Hartung) Message-Id: <8804221545.AA09317@sdics.ICS> Received: by sdics.ICS scf2.7vax; Fri, 22 Apr 88 07:45:47 PST Date: 22 Apr 88 08:44 PDT (Friday) To: burdorf@rand-unix.arpa Subject: Re: Is PCL and CLOS the same thing? Cc: commonloops.pa@Xerox.COM >Please pardon me if I am sorely incorrect, but aren't PCL and CLOS supposed >to be the same thing. As far as I have been able to gather, CLOS is the Common Lisp Object System standard and PCL is a version of CLOS. As you have noticed, some features in the CLOS documentation are yet-to-be-implemented in PCL. > They seem at least close. I have found the following >discrepancies: > > No defgeneric in PCL > Under KCL with-slots and with-slots* don't work ^^^^^^^^^^^^^^^^^^^^^^ > The :writer option doesn't work in defclass > There is no with-accessors ^^^^^^^^^^^^^^^^^^^^^^^^^^ At present, there is, as you mentioned, no with-accessors. There is, however, WITH-ACCESSORS* which works as in the CLOS documentation (3/88). I am puzzled by your comment that WITH-SLOTS* doesn't work when PCL is run on KCL, though. We are using PCL run on KCL and it works fine. There may have been some fixes made to get it to work that I am unaware of, though. Another slot option that doesn't work with DEFCLASS which I have noticed is the :DOCUMENTATION option. It is accepted as a legal option, but produces nothing. I have used SETF to attach documentation to already defined classes as a way around this. I am unaware whether this is a problem specific to PCL run on KCL or not. --Jeff Hartung-- hartung@sdics.ucsd.edu  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Apr 88 22:15:38 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 21 APR 88 18:59:53 PDT Return-Path: Redistributed: commonloops.pa Received: from rand-unix.arpa by Xerox.COM ; 21 APR 88 18:58:31 PDT Received: by rand-unix.arpa; Thu, 21 Apr 88 18:24:05 PDT Message-Id: <8804220124.AA01745@rand-unix.arpa> To: commonloops.pa@Xerox.COM Cc: steph%ixta@rand-unix.ARPA, David_McArthur Subject: Is PCL and CLOS the same thing? Date: Thu, 21 Apr 88 18:24:00 PDT From: burdorf@rand-unix.ARPA Please pardon me if I am sorely incorrect, but aren't PCL and CLOS supposed to be the same thing. They seem at least close. I have found the following discrepancies: No defgeneric in PCL Under KCL with-slots and with-slots* don't work The :writer option doesn't work in defclass There is no with-accessors  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Apr 88 12:32:33 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Apr 88 09:20:18 PDT Received: from Semillon.ms by ArpaGateway.ms ; 21 APR 88 09:18:16 PDT Date: Thu, 21 Apr 88 09:18 PDT From: Gregor.pa@Xerox.COM Subject: Re: dependent update protocol To: Danny Bobrow cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, kanderso@WILMA.BBN.COM, common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <880420-160912-1489@Xerox> Message-ID: <19880421161804.4.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: 20 Apr 88 16:08 PDT From: Danny Bobrow Danny's message prompted me to realize that there was a minor ommission in the protocol. Specifically, the updated class should be passing the actual reinitialization arguments to the update-dependent generic function. I think the way to think of this is as a mechanism which enables objects, when they are updated, to pass special information to their priviledged dependees describing how they were changed. Unpriveledged dependees receive no special information, they only receive the reinitialization arguments which caused the update. So for example, when a class is updated, any of its dependents can see the reinitialization arguments which caused the change. From those reinitialization arguments the dependents can infer what they will about how the class changed. But, a specific class of class (a metaclass) may provide some sort of special information to its priviledged dependents. This might include things like a bit saying whether or not the order of the class's slots changed or something. Some metaclass may choose to document the format and meaning of this information, but standard-class does not do so. This means that to write the kind of code you suggest you could do the following: (defmethod update-dependent ((class standard-class) (dependent class-browser-element) reinitargs plist) (when (getf reinitargs :direct-superclasses) ;; The supers may have changed. Check our local cache ;; to see if they actually have. ...)) You don't have access to the information in the plist because it is implementation dependent, but you do have free access to the reinitargs. The distinction between priviledged and unpriveledged information is made clear by which plist the information is in. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Apr 88 12:32:01 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Apr 88 09:20:13 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 21 APR 88 09:17:14 PDT Date: 21 Apr 88 09:16 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: dependent update protocol In-reply-to: David A. Moon 's message of Wed, 20 Apr 88 23:11 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880421-091714-2738@Xerox> Because of the way the default methods for before-reinitialization and after-reinitialization are defined, and because there is no ordering constraint that forces updateable-object to be least specific in the class precedence list, it is possible for these default methods accidentally to shadow real methods for those generic functions. The best way to fix this is to use method combination to ensure that all the methods are called and the value returned by each method is passed in as the plist argument to the next method. I think it would be a good idea to use method combination, but I don't understand how. Are you suggesting a different method combination type which has this property. If so, what is its definition. If it uses standard method combination and before methods, what is the sample code that avoids the bug (does one smash the plist???). danny  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Apr 88 12:12:35 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 21 Apr 88 09:01:53 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA01289; Thu, 21 Apr 88 08:59:54 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA19379; Thu, 21 Apr 88 08:58:55 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA02282; Thu, 21 Apr 88 08:52:35 PDT Message-Id: <8804211552.AA02282@suntana.sun.com> To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Sun Opposition To Chapter 3 Hereby Tendered Date: Thu, 21 Apr 88 08:52:33 -0700 From: kempf@Sun.COM I hereby withdraw my support from the current and any future drafts of Chapter 3, and tender Sun's opposition, unless substantial changes are made. The purpose of CLOS is to provide a standard for object-oriented programming in Common Lisp. While the design specified in Chapters 1 & 2 occasionally required features to be added which current object-oriented languages do not have, the rationale behind these features and the effects on implementation were understood to a large degree. I do not feel that is the case with Chapter 3. There are many issues involved in supporting metaobject programming which are not understood. I feel that the current design effort is making the wrong choices in certain areas without understanding the consequences. Solidifying these choices into a standard runs the risk of hindering further developments. Should the issue of Chapter 3 come to a vote before the full committee, I will recommend that Sun vote against it. I will continue to support Chapters 1 & 2 wholeheartly, since I believe the language specified therein offers application programmers the best alternative among the current object-oriented languages for flexible and efficient applications development. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Apr 88 10:17:02 EDT Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 21 Apr 88 07:06:58 PDT Received: from relay2.cs.net by RELAY.CS.NET id ab16910; 21 Apr 88 8:34 EDT Received: from utokyo-relay by RELAY.CS.NET id ad06511; 21 Apr 88 7:46 EDT Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET) id AA04555; Thu, 21 Apr 88 20:02:23 JST Received: by aoyama.cc.aoyama.junet (3.2/6.3Junet-1.0) id AA07837; Thu, 21 Apr 88 19:32:30 JST Date: Thu, 21 Apr 88 19:32:30 JST From: Masayuki Ida Return-Path: Message-Id: <8804211032.AA07837@aoyama.cc.aoyama.junet> To: common-lisp-object-system@SAIL.STANFORD.EDU, ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET Subject: some comments on CLOS Comments on CLOS ch1 and ch2. (since I have been on this list from two day ago, so I do not know the current context.) 1. explanation around the mixture of defmethod and defun. I could not find the specification on the mixture of defmethod and defun with the same name. is it error ? is it allowed in what sense? 2. for user convenience, explicit interface of 'make-specializable' in the former version is better than the current way for doing the same thing using 'user-added-method' or something. 3. Removal of a class and a method. how user can remove one method ? how user can remove a class ? 4. Enumeration in the individual method. (defmethod foo ((x (eql A))) ...) (defmethod foo ((x (eql B))) ...) I have an experience to write methods which have several sigular points, and whose bodies are same. I feel happy if a syntax like, (defmethod foo ((x (member A B C D))) ...) which shares the same body for the enumerated individuals will be in the specificaton. typos 5. 2-79 symbol-macrolet examples ;;; not (let 'foo (let (('foo 'bar)) 'foo)). ===> ;;; not (list 'foo (let (('foo 'bar)) 'foo)). ^^^^ Ambiguous 6. 2-8 line 9 Osub1 | ... | Osubn and line 14 .... for some 1 <= k <= n, ... 'n' is ambiguous to the 'n' of line 13. ====> line 9 Osub1 | ... | OsubN and line 14 ... for some 1 <= k <= N, ... replacing small 'n' to large 'N'. Comment 7. 1-19 to 1-21 Integrating Types and Classes Fig 1-1. I prefer 'sequence first rule'. For instance, the class precedence list of 'null' should be (null list symbol sequence t) or (null list sequence symbol t) rather than (null symbol list sequence t) which is on Fig 1-1. How are the discussions on the issue ? (defmethod foo ((x list)) ...) (defmethod foo ((x symbol)) ...) (foo nil) ? I feel we cannot absolutely define the precedence among them. meta object protocol will solve this problem ? 8. 1-21 pathname and stream should at least be defined to correspond to classes independent from the context of 1-21. (since several file handling are OK for pathnames and streams) say, (defmethod device-analysis ((x pathname)) ...) (defmethod device-analysis ((x stream)) ...) ------- Masayuki Ida  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Apr 88 00:03:36 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 20:52:18 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386318; Wed 20-Apr-88 23:52:07 EDT Date: Wed, 20 Apr 88 23:51 EDT From: David A. Moon Subject: Re: Reinitialization To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <880413-111606-16288@Xerox> Message-ID: <19880421035154.2.MOON@EUPHRATES.SCRC.Symbolics.COM> This message comments on the proposed revamping of the ch1 object creation protocol in support of ch3. Date: 13 Apr 88 11:15 PDT From: Danny Bobrow The four updating functions are: initialize-new-instance instance &rest initialization-arguments reinitialize-instance instance &rest initialization-arguments update-instance-structure instance added-slots discarded-slots property-list &rest initialization-arguments update-instance-with-new-class previous current &rest initialization-arguments This suggests renaming update-instance-structure to update-instance-with-redefined-class. With that change all five names look consistent and fairly clear as to their meanings. These all call: initialize-instance instance slots-for-initform &rest initialization-arguments The value of slots-for-initform can be a list of slot-names (possibly nil) or T, which is equivalent to specifying all slots of the instance. For each slot on the list, if it is uninitialized, and it has an initfunction, it is initialized with the value of applying the initfunction to NIL. What value does each of each of the updating functions pass to initialize-intance for this argument. The call from initialize-new-instance passes T of course. The call from reinitialize-instance passes NIL The call from update-instance-structure passes added-slots The call from update-instance-with-new-class passes new-slots Gregor and I previously argued that reinitialize-instance should try to reinitialize all the slots that were unititialized. We claimed that this would allow a specialized reinitialization method to call slot-makunbound on just those slots wanted reinitialized. However, achieving this is still easy. The specialized method still makes these slots unbound, and passes along the list of slots that have been made unbound to initialize-instance. All four pass the initialization-arguments to initialize-instance. The call to update-instance-structure from the system of course passes NIL as the initialization-arguments. So does the call to update-instance-with-new-class. However, an :around method on either of these latter can compute some interesting initialization-arguments and do a call-next-method. As an example of the use, consider the following around method for update-instance-structure for point the above example: (defmethod update-instance-structure :around ((p point) ... ;;push :x and :y on the initarg list and call-next-method ) That only works if you change your method (defmethod initialize-instance :after ((p point)) &key :x :y) ;; if x and y are provided, use (setf point-x) (setf point-y) ;; to compute the appropriate values for rho and theta ) to be an initialize-new-instance method instead of an initialize-instance method, and give it an ignored 2nd argument. It seems likely that if you made this error, many users will make it too, especially since the two names are so similar. I don't have any suggestions I like for how to fix this. Then the answers you propose to my seven issues are: (1) How much should be shared among the four updating functions? The (new) initialize-instance generic function, thus as much or as little as you want. (2) What should be shared among the four updating functions? There are actually three different things: (a) the code to fill slots from initialization arguments (b) the code to fill slots from values of initialization forms (c) user-defined methods All three, but under complete control through arguments. (3) We've discussed several clever/kludgey ways to tweak the shared code. Do none of them. (4) A subtle semantic change to class-changed and update-instance-structure Don't do it. (5) Do we really need four different updating functions? Yes. (6) Why do the four updating functions have such inconsistent interfaces? Because any alternative we could think of created more problems than it solved, e.g. tempting the user to invoke methods that won't work. (7) What are good names for these five functions? See above. I'm happy with this. Let's do it. Let's see, what are the actual changes to chapters 1 and 2? Rename initialize-instance to initialize-new-instance. Rename update-instance-structure to update-instance-with-redefined-class (if you like my proposed name) and change its arguments. Rename class-changed to update-instance-with-new-class and change its arguments. Add new functions reinitialize-instance and initialize-instance. Adjust the procedural description of make-instance accordingly. Change all places that talk about filling slots to say it's done by the default primary method for (the new) initialize-instance. Add explanations of how the default primary methods for the four updating functions call initialize-instance, where it now says how they fill slots on their own. check-initargs has to be called from four different places now, as there are four updating functions that have initargs arguments. I think the best way is to give check-initargs another argument, which is a list of generic functions. An initarg is acceptable if it's a slot-filling initarg or if any of the generic functions in the list accepts it. make-instance would pass (list #'allocate-instance #'initialize-instance #'initialize-new-instance). reinitialize-instance would pass (list #'reinitialize-instance #'initialize-new-instance). The only problem with this is that each of these takes idiosyncratic arguments, which check-initargs has to take into account when computing the applicable methods. Is there a better idea? I think there is a little more technical fleshing out to be done before this is reduced to purely editorial work, but it looks plausible. Do any of the other committee members have an opinion on this? Are we going overboard on generality, or is this a good change that makes the language more consistent and hence easier to understand?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 23:35:47 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 20:25:35 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386302; Wed 20-Apr-88 23:25:30 EDT Date: Wed, 20 Apr 88 23:25 EDT From: David A. Moon Subject: Re: Reinitialization To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <880413-111606-16288@Xerox> Message-ID: <19880421032519.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 13 Apr 88 11:15 PDT From: Danny Bobrow (6) Why do the four updating functions have such inconsistent interfaces?.... so the real issue is why don't class-changed and update-instance-structure take similar arguments? We decided that there was no reasonable way to specify what it meant to keep around a copy of an obsolete-class and its methods, and therefore we had to use the list descriptions of the old instance. On the other hand, for class-changed, the methods and classes are current. Hence it is reasonable to leave in the users hands the problem of keeping the method for class-changed current. Oh, right. Suppose that instead of its present arguments, update-instance-structure took an old-instance and a new-instance, where the old-instance was of an old-class that was a direct subclass of the class being redefined. old-instance and old-class have dynamic extent. Suppose further that old-class has no methods of its own, so exactly the same methods are applicable to old-instance as are applicable to new-instance (barring bizarre use of methods on individuals). If we do this, then in the rho/theta/x/y example, you can't use accessor methods to get the old information, just as you can't use accessor methods now. The difference is that an update-instance-structure method would use slot-value to get the old slot values, and would use normal chapter 3 facilities to find out what slots were added and removed, instead of getting that information in an idiosyncratic way. I think a change like that would make the language a little more consistent. However, I don't feel strongly about it, as even with that change there would still be no shortage of minor inconsistencies.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 23:22:24 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 20:11:58 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386293; Wed 20-Apr-88 23:11:52 EDT Date: Wed, 20 Apr 88 23:11 EDT From: David A. Moon Subject: dependent update protocol To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880420214048.1.GREGOR@PORTNOY.parc.xerox.com>, <880420-160912-1489@Xerox> Message-ID: <19880421031140.0.MOON@EUPHRATES.SCRC.Symbolics.COM> The combination of these two messages (sent respectively by Gregor and by Danny earlier today) looks like the right thing, although I suppose I ought to take the time to think about it harder before agreeing with it for sure. The only problem I noticed is the usual bug with mixins that use call-next-method instead of method combination. Because of the way the default methods for before-reinitialization and after-reinitialization are defined, and because there is no ordering constraint that forces updateable-object to be least specific in the class precedence list, it is possible for these default methods accidentally to shadow real methods for those generic functions. The best way to fix this is to use method combination to ensure that all the methods are called and the value returned by each method is passed in as the plist argument to the next method. This might also help fix the bug where your second example after-reinitialization method forgot to return its result. A worse way to fix it would be to put in a bunch of (and (next-method-p) (call-next-method)) forms.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 23:03:31 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 19:53:53 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386282; Wed 20-Apr-88 22:53:50 EDT Date: Wed, 20 Apr 88 22:53 EDT From: David A. Moon Subject: comments on CLOS draft 88-2 To: common-lisp-object-system@SAIL.STANFORD.EDU References: The message of 8 Apr 88 14:13 EDT from "mike@gold-hill.com any day now" , <8804132019.AA00841@mist.UUCP>, <8804150413.AA17656@aoyama.cc.aoyama.junet>, <2786129024-9418538@Kelvin> Message-ID: <19880421025339.9.MOON@EUPHRATES.SCRC.Symbolics.COM> The four referenced messages are ones I've been saving as official comments received that we need to address. We cannot complete the revisions of chapters 1 and 2 without addressing these comments. I'm not sure we completed discussing Pierson's comments, and I haven't seen any discussion at all of Ohkubo's and Gray's comments. Did I miss some mail? I'm willing to spend a little time putting together a summary of these comments and a draft of the committee response, but I probably can't do it until early next week.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 22:59:50 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 19:48:55 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386276; Wed 20-Apr-88 22:48:47 EDT Date: Wed, 20 Apr 88 22:48 EDT From: David A. Moon Subject: Re: method-lambda and apply-method-lambda To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <880414150957.6.GREGOR@SPIFF.parc.xerox.com> Message-ID: <19880421024826.8.MOON@EUPHRATES.SCRC.Symbolics.COM> I agree with what Gregor said in the referenced message, except for two small points noted below. Does any of this affect chapters 1 and 2? It would only affect CALL-METHOD, and I don't think it does, so we can defer completing the last details of this for a few days. Date: Thu, 14 Apr 88 15:09 PDT From: Gregor.pa@Xerox.COM make-method-function (generic-function method lambda-list body) This has to take a macroexpand-environment also. This sometimes needs to do code analysis of the body, at least for some method calling sequences, and it is impossible to do correct code analysis of a piece of code without having a macroexpand-environment. apply-method-function generic-function method function info &rest args This is also a generic function. It tends to be specialied on its first two arguments as well. For the case where generic-function and method are both standard, the info argument is a list of the next methods. I still believe that the representation of the info used for call-next-method has to be abstract. CLOS should not dictate that it is represented as a list. Note that I am not only saying that user-defined method calling sequences should be able to use any representation they want; I am also saying that CLOS should not dictate what representation the standard method calling sequence uses. See my message of 8 April for the two functions that have to be added to the system to abstract this.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 22:20:18 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 18:54:57 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 386222; Wed 20-Apr-88 21:06:26 EDT Date: Wed, 20 Apr 88 21:06 EDT From: David A. Moon Subject: DEADLINE for finishing 1 and 2 To: Jon L White cc: Gregor.pa@xerox.com, common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8804202339.AA12537@bhopal.lucid.com> Message-ID: <19880421010607.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: Wed, 20 Apr 88 16:39:58 PDT From: Jon L White There have been a flurry of messages on (re)initialization, and I'm not sure if it all settled down. As a reminder, at the last X3J13 meeting, I brought up the matter of the similarity of the initialization protocols and the re-initialization ones; someone (probably you or moon) suggested that this issue would be dealt with in the mails, and that I should hold my question until something more concrete appears. I think I'm still waiting? I think your question is exactly what we've been working on.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 21:10:20 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 APR 88 17:56:05 PDT Return-Path: Redistributed: commonloops.pa Received: from SPICE.CS.CMU.EDU by Xerox.COM ; 20 APR 88 17:46:59 PDT Date: Wed, 20 Apr 88 15:05 EDT From: Jamie.Zawinski To: commonloops.pa@Xerox.COM Subject: Prettier generic function arglists Message-ID: <880420-175605-1746@Xerox> A while back someone posted a suggestion for a way to get more readable arglists from generic functions. I thought that was a great idea, so, I wrote some code that does this. Say you do this: (defmethod foo ((self class1) &rest rest-list &key a b &allow-other-keys) ... ) (defmethod foo ((self class2) &rest rest-list &key c (d 5) &allow-other-keys) ... ) (defmethod foo ((self class3) &rest other-stuff &key &allow-other-keys) ... ) Then, with the code that follows, the arglist of the generic function FOO would be (SELF &REST OTHER-STUFF &KEY A B C D &ALLOW-OTHER-KEYS) instead of (#:|Disc-Fn-Arg-0| &REST #:|Disc-Fn-&Rest-Arg|) Making the world a safer place to hack, Jamie --- like, cut here --- ;;; -*- Mode:Lisp; Syntax:Common-Lisp; Package:PCL -*- ;;; Prettier arglists in PCL (in-package "PCL") (defun parse-method-pretty-arglist (meth) "Given a STANDARD-METHOD, returns five values: a list of the required arguments; a list of the optional arguments; a symbol, the rest arg, or NIL; a list of the keyword arguments; T or NIL, whether &ALLOW-OTHER-KEYS was present. All elements of the returned lists will be symbols." (let* ((required ()) (optional ()) (rest nil) (keywords ()) (allow-other-p nil) (arglist (method-arglist meth)) (current-type :required)) (dolist (token arglist) (case token (&optional (setq current-type :optional)) (&rest (setq current-type :rest)) (&key (setq current-type :keyword)) (&allow-other-keys (setq allow-other-p t)) (&aux (setq current-type :aux)) (t (unless (member token LAMBDA-LIST-KEYWORDS :test #'eq) ;; If we get a non-CommonLisp lambda-list keyword, we just ;; pretend it wasn't there: (a &special b) ==> (a b) (ecase current-type (:required (push token required)) (:optional (push token optional)) (:rest (setq rest token)) (:keyword (push token keywords)) (:aux nil)))))) (labels ((safe-car (x) (if (consp x) (safe-car (car x)) x))) ;; SAFE-CAR is to handle FOO and (FOO 5), as well as &KEY ((:FOO *FOO*) 5) (setq required (mapcar #'safe-car required)) (setq optional (mapcar #'safe-car optional)) (setq keywords (mapcar #'safe-car keywords))) (values (nreverse required) (nreverse optional) rest (nreverse keywords) allow-other-p))) (defun generic-function-comprehensive-arglist (gf) "Returns a lambda list describing the generic function GF. This list is derived by looking at the arglists of all the methods." (let* ((required ()) (optional ()) (rest nil) (keywords ()) (allow-other-keys-p nil)) (dolist (meth (generic-function-methods gf)) (multiple-value-bind (req opt rst key otherp) (parse-method-pretty-arglist meth) ;; Since all methods must have parallel arglists, the following ;; form is a little redundant. KEYWORDS is really the only variable ;; that must be set for each method. But we set the others so we ;; (lazilly) don't have to special case the first or last iteration ;; through the loop. (setq required req optional opt rest (or rest rst) keywords (nconc key keywords) allow-other-keys-p (or allow-other-keys-p otherp)))) (setq keywords (delete-duplicates keywords)) (let* ((result required)) (when optional (setq result (nconc result (cons '&optional optional)))) (when rest (setq result (nconc result (list '&rest rest)))) (when keywords (setq result (nconc result (cons '&key keywords)))) (when allow-other-keys-p (setq result (nconc result (list '&allow-other-keys)))) result))) ;;; The next bit will install this code into the ARGLIST function in ;;; Lucid Lisp. It would probably be cooler if this code was instead ;;; hooked in to the place in PCL where the generic function's arglist is ;;; calculated, but I don't want to deal with figuring out where that is... ;;; #+LUCID (sys::defadvice (sys::arglist generic-function-arglist) (function) (when (symbolp function) (setq function (symbol-function function))) (if (generic-function-p function) (generic-function-comprehensive-arglist function) (sys::advice-continue function)))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 20:54:46 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 20 Apr 88 17:43:53 PDT Received: by labrea.Stanford.EDU; Wed, 20 Apr 88 16:43:17 PST Received: from bhopal.lucid.com by edsel id AA14363g; Wed, 20 Apr 88 16:38:19 PDT Received: by bhopal id AA12537g; Wed, 20 Apr 88 16:39:58 PDT Date: Wed, 20 Apr 88 16:39:58 PDT From: Jon L White Message-Id: <8804202339.AA12537@bhopal.lucid.com> To: Gregor.pa@xerox.com Cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: Gregor.pa@Xerox.COM's message of Wed, 20 Apr 88 09:46 PDT <19880420164612.1.GREGOR@PORTNOY.parc.xerox.com> Subject: DEADLINE for finishing 1 and 2 re: It seems that the issue of re-working the initialization mechanism must be done before then. I haven't seen any messages on this in a while. There have been a flurry of messages on (re)initialization, and I'm not sure if it all settled down. As a reminder, at the last X3J13 meeting, I brought up the matter of the similarity of the initialization protocols and the re-initialization ones; someone (probably you or moon) suggested that this issue would be dealt with in the mails, and that I should hold my question until something more concrete appears. I think I'm still waiting? -- JonL --  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 20:19:14 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 17:08:05 PDT Return-Path: Redistributed: CommonLoops.pa Received: from CLI.COM by Xerox.COM ; 20 APR 88 17:04:42 PDT Received: by CLI.COM (4.0/1); Wed, 20 Apr 88 19:04:49 CDT Date: Wed, 20 Apr 88 19:04:49 CDT From: Bill Schelter Message-Id: <8804210004.AA16407@CLI.COM> To: Gregor.pa@Xerox.COM Cc: fritzson@PRC.Unisys.COM, CommonLoops.pa@Xerox.COM In-Reply-To: Gregor.pa@Xerox.COM's message of Wed, 20 Apr 88 09:33 PDT <19880420163352.8.GREGOR@PORTNOY.parc.xerox.com> Subject: pcl Reply-To: wfs@cli.com I had wanted to see if there were any bugs in AKCL (available publicly by ftp here on rascal.ics.utexas.edu 128.83.144.1) which prevented PCL from working correctly, so that I could fix them. There do not seem to be any problems except for the ones inside with-slots. I had to comment out the two tests starting: ;(do-test "Simple with-slots test -- does not really exercise the walker." and ;(do-test "Simple with-slots test (:use-accessors nil)." ; ((:functions foo bar)) due to with-slot problems: All other tests gave OK. Is this the case with other lisps? Thank you for including the tests--it is very helpful. Bill  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 19:28:05 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 16:14:39 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 APR 88 16:09:12 PDT Date: 20 Apr 88 16:08 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: dependent update protocol In-reply-to: Gregor.pa's message of Wed, 20 Apr 88 14:40 PDT To: Gregor.pa@Xerox.COM cc:Moon@STONY-BROOK.SCRC.Symbolics.COM, Bobrow.pa@Xerox.COM, kanderso@WILMA.BBN.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880420-160912-1489@Xerox> I had originally proposed the property list scheme. I claimed that properties would have advertised names, and advertised meanings. Interference of property names would then be intentional, or a bug. For example, for class updating I had specified that the resulting arguments delivered to all dependents would be a property list containing three flags, :supers-changed :slots-changed and :options-changed. Alternatively, the specification might be that there were simply one flag, :changed, with value an integer between 0 and 7 whose bits indicated the same changes. These flags could be used by all dependents of the class to determine if they were interested in the change. For example, the class itself would be interested in any change, a subclass might ignore options, and a class browser would ignore :slots-changed and :options-changed. I want to write (defmethod update-dependent ((dependent class-browser-element) (class standard-class) &key supers-changed &allow-other-keys T) (when supers-changed (recompute-my-browser-display dependent))) The point I am making is that we cannot encapsulate the information that is to be passed to dependents if we do not know the full set of dependents. If the properties are not advertised as part of the protocol for a particular class, I don't see how a new kind of dependent could get any clue about what had happened to the instance. On the other hand, there is absolutely no such restriction on the information that before-reinitialization passes to after reinitialization, and I think in that case the class-keyed property list might be OK.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 18:05:21 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 14:52:24 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 APR 88 14:43:36 PDT Date: Wed, 20 Apr 88 14:40 PDT From: Gregor.pa@Xerox.COM Subject: dependent update protocol To: David A. Moon , Danny Bobrow , kanderso@WILMA.BBN.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <880411113858.6.GREGOR@SPIFF.parc.xerox.com>, <19880411195010.7.MOON@EUPHRATES.SCRC.Symbolics.COM>, <880414-114257-18564@Xerox>, <19880420170053.2.GREGOR@PORTNOY.parc.xerox.com>, <19880420182225.3.MOON@EUPHRATES.SCRC.Symbolics.COM>, The message of 19 Apr 88 12:26 PDT from kanderso@WILMA.BBN.COM Message-ID: <19880420214048.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 20 Apr 88 14:22 EDT From: David A. Moon And will clearly break if misused. Here's an idea: someone, I forget who, suggested using a property list as the state that's passed around, instead of letting each class's methods decide how they are going to encapsulate the next class's state. If you do that, then methods getting out of sync cannot cause any damage. The only way for one class to damage another would be for both to use the same property name, but the property names can be class objects. Incorporating this with what we had previously is fairly easy. It looks something like this: - there is a separate mixin for the dependents stuff, that mixin is used by standard-class to do dependents updating. Users can use it in their code to particpate in that dependent updating protocol. - There is a mechanism for allowing the modified object to pass information describing the modification to all the dependents. This mechanism is designed to allow subclassing to work. That is, a given class (say standard-class) may use this mechanism to pass information to its dependents. The format of the information is a plist which each class in the chain can put information into and take it back out of. Each class is expected to put one entry in the PLIST, and should use the actual class object as the key. This will prevent name conflicts in the plist. The format of the individual entries in the plist is completely unspecified. It is undefined what happens if system information in the plist is modified or removed. It is undefined what system information will be in the plist. CLOS supports a general mechanism for registering dependents of objects, and updating those objects on change. It does this through the medium of a mixin class, updatable-object-mixin, that supports updating of dependents. A dependent of an object O1 is any object that may need to be updated when O1 changes. An object becomes a dependent only by explicitly registering itself as one. The dependent registering protocol allows redundant registering of dependents; this means that code which wants an object to be registered as a dependent of an object should always do so. It should never depend on the particular implementation to do so since specific implementations may use the dependent updating protocol in different ways. Some examples of the use are: 1) A screen view of an object (perhaps a class) needs to update itself when the object (class definition) changes. To do this it registers itself as a dependent of that object, whenever the object changes it will update all its dependents. 2) A subclass of a class wants to recompute its class precedence list when the class changes its direct superclasses. The subclass registers itself as a dependent of the class, whenever the class changes, the subclass is updated and can recompute its class precedence list. 3) Some set of objects needs to be updated when a class changes. This can be handled in one of two ways, all the objects can be registered as dependents, or a single object can be created which encapsulates all the other objects. The single `large' object can be registered as a dependent. (defclass updatable-object-mixin () ()) This class supports two protocols, registration and updating of dependents. The registration protocol is comprised of the generic functions add-dependent, remove-dependent, and map-dependents. The updating protocol is comprised of methods on reinitialize-instance, and the generic functions before-reinitialization, after-reinitialization and update-dependent. The Registration Protocol \Defmeth add-dependent ((object updatable-object-mixin) new-dependent) adds new-dependent as a new dependent of object. Does nothing if new-dependent is already a dependent of object. \Defmeth remove-dependent ((object updatable-object-mixin) dependent) removes dependent as one of the dependents of object. Does nothing if dependent is not already one of the dependents of object. \Defmeth map-dependents ((instance updatable-object-mixin) function) For all dependents of instance, applies function to the dependent. The Updating Protocol The updating protocol has two parts. The first part is an :around method on reinitialize-instance which causes all the dependents of an object to be updated whenever the object is reinitialized. This part of the protocol also provides a mechanism which allows the object to pass information to its dependents describing the change effected by reinitializing the object. This mechanism is provided by having the :around method on reinitialize-instance call the generic-function before-reinitialization before the reinitialization, and the generic-function after-reinitializing after the reinitialization. The value returned by after-reinitialization is passed in the call to update-dependent on each of the dependents. [We are still actively soliciting suggestions for better names for before-reinitialization and after-reinitialization.] (defmethod reinitialize-instance :around ((object updatable-object-mixin) &rest reinitargs) (let ((dependents ())) ;; Collect all the dependents ahead of time. The fact that ;; a list is used here means nothing. The fact that this ;; code preserves the order that map-dependents does it in ;; is important though. (map-dependents object #'(lambda (x) (push x dependents))) (setq dependents (reverse dependents)) ;; Collect the before-reinitialization information. This will be ;; a plist. (let ((before (apply #'before-reinitialization object reinitargs))) (call-next-method) ;; Collect the after-reinitialization information. This will ;; also be plist. (let ((after (apply #'after-reinitialization object before reinitargs))) (dolist (dep dependents) (update-dependent object dep after)))))) The updatable-object-mixin provides implementations of before-reinitialization, after-reinitialization, and update-dependent. (defmethod before-reinitialization ((object updateable-object) &rest ignore) ()) (defmethod after-reinitialization ((object updateable-object) before-reinitialization &rest ignore) ()) (defmethod update-dependent ((dependent updateable-object) (object updateable-object) after-reinitialization) ()) Example: This example shows how this protocol might be used. In particular, it demonstrates the proper style of using the plist to pass information around. The standard methods on before-reinitialization, after-reinitialization and update-dependent are there to support this. Suppose that a specific kind of metaclass wants to propagate special information when used as a submetaclass of itself. (defclass my-class (standard-class) ()) (defmethod before-reinitialization ((c my-class) &rest reinitiargs) (let ((plist (call-next-method))) (setf (getf plist (class-named 'my-class)) ()) plist)) (defmethod after-reinitialization ((c my-class) before &rest reinitargs) (let ((plist (call-next-method))) (setf (getf plist (class-named 'my-class)) ()))) (defmethod update-dependent ((dependent my-class) (object my-class) plist) (let ((magic-info (getf plist (class-named 'my-class)))) () (call-next-method) ())) -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 15:18:33 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 12:05:20 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 385909; Wed 20-Apr-88 14:22:33 EDT Date: Wed, 20 Apr 88 14:22 EDT From: David A. Moon Subject: dependent update protocol To: Gregor.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880420170053.2.GREGOR@PORTNOY.parc.xerox.com> Supersedes: <19880420182131.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Comments: Crucial word "not" was missing. Sorry about that. Message-ID: <19880420182225.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: Wed, 20 Apr 88 10:00 PDT From: Gregor.pa@Xerox.COM Date: Mon, 11 Apr 88 15:50 EDT From: David A. Moon Also, since the style you propose depends on three methods for three different generic functions to be kept in sync, and does something unpredictable without necessarily signalling an error if one of the methods is left out, it doesn't seem very robust. I would prefer to see either a more abstract data structure than a list, so that leaving out a method (or forgetting to call cdr) for one class would not damage the data seen by other class's methods, or else to use one generic function instead of three, so that all the code for one class would be in a single place and hence less likely to be out of sync. In the latter case, this generic function would be called multiple times and one of its arguments would indicate whether state was being collected or distributed. I think these might be good ideas. Unfortunately, in the abscence of a specific proposal for how to make this work I think we are going to make only the two changes described in this message. We don't have the time to figure out how to incorporate this comment given that what we have will clearly work. And will clearly break if misused. Here's an idea: someone, I forget who, suggested using a property list as the state that's passed around, instead of letting each class's methods decide how they are going to encapsulate the next class's state. If you do that, then methods getting out of sync cannot cause any damage. The only way for one class to damage another would be for both to use the same property name, but the property names can be class objects. Let me know if this is not a specific enough proposal and I'll somehow, I don't know how, find the time to write it up more clearly.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 15:17:48 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 Apr 88 12:04:56 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 385908; Wed 20-Apr-88 14:21:41 EDT Date: Wed, 20 Apr 88 14:21 EDT From: David A. Moon Subject: dependent update protocol To: Gregor.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880420170053.2.GREGOR@PORTNOY.parc.xerox.com> Message-ID: <19880420182131.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: Wed, 20 Apr 88 10:00 PDT From: Gregor.pa@Xerox.COM Date: Mon, 11 Apr 88 15:50 EDT From: David A. Moon Also, since the style you propose depends on three methods for three different generic functions to be kept in sync, and does something unpredictable without necessarily signalling an error if one of the methods is left out, it doesn't seem very robust. I would prefer to see either a more abstract data structure than a list, so that leaving out a method (or forgetting to call cdr) for one class would not damage the data seen by other class's methods, or else to use one generic function instead of three, so that all the code for one class would be in a single place and hence less likely to be out of sync. In the latter case, this generic function would be called multiple times and one of its arguments would indicate whether state was being collected or distributed. I think these might be good ideas. Unfortunately, in the abscence of a specific proposal for how to make this work I think we are going to make only the two changes described in this message. We don't have the time to figure out how to incorporate this comment given that what we have will clearly work. And will clearly break if misused. Here's an idea: someone, I forget who, suggested using a property list as the state that's passed around, instead of letting each class's methods decide how they are going to encapsulate the next class's state. If you do that, then methods getting out of sync can cause any damage. The only way for one class to damage another is for both to use the same property name. But the property names can be class objects. Let me know if this is not a specific enough proposal and I'll somehow, I don't know how, find the time to write it up more clearly.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 13:21:23 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 10:06:59 PDT Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 10:01:25 PDT Date: Wed, 20 Apr 88 10:00 PDT From: Gregor.pa@Xerox.COM Subject: dependent update protocol To: David A. Moon cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <19880411195010.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <19880420170053.2.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Mon, 11 Apr 88 15:50 EDT From: David A. Moon Actually your example shows that it's not really true that the format of the information is unspecified. What is specified is that it is a list with one element for each interested class, in most-specific-first order. What is unspecified is the format of the list elements. No, the format of the information itself is unspecified. Any given layer could choose to encapsulate the next layer of information any way it wants. Its true that the example I used builds a list, but some level might just as well use an array. It's usually better not to try to pass extra args through a mapping function; instead the function being mapped can be a closure that knows the extra args. This is more flexible, and is how all eight functions in CLtL whose names start with "map" work. Thus I would make map-dependents take only two arguments. Good point. We will make this change. (defmethod reinitialize-instance :around ((object updatable-object-mixin) &rest reinitargs) (let ((before (apply #'before-reinitialization object reinitargs))) (call-next-method) (let ((update-args (apply #'after-reinitialization object before reinitargs))) (map-dependents object #'update-dependent object update-args)))) I don't see how this can work if reinitialize-instance changes the set of dependents. The map-dependents will map over the new dependents, and any old dependents that were removed will never be updated. Maybe you can say that remove-dependent, or by convention each caller of it, calls update-dependent or a variant of it on the dependent being removed. However, I suspect that is not flexible enough. I know some of our analogues to this have to start by collecting all the dependents into a table that is independent of the dependency structure. I don't have an answer here; I think more thought is required. As Danny said, the method on reinitialize-instance itself wan't intended to change the set of dependents. We could get that functionality easily enough by having the :around method collect all the dependents ahead of time as you mentioned. We will make this change. If that's true I would prefer to have the style (collecting lists of values returned by each interested method, and taking them apart again) be enforced by method combination, instead of leaving it up to each programmer to get it right. Also, since the style you propose depends on three methods for three different generic functions to be kept in sync, and does something unpredictable without necessarily signalling an error if one of the methods is left out, it doesn't seem very robust. I would prefer to see either a more abstract data structure than a list, so that leaving out a method (or forgetting to call cdr) for one class would not damage the data seen by other class's methods, or else to use one generic function instead of three, so that all the code for one class would be in a single place and hence less likely to be out of sync. In the latter case, this generic function would be called multiple times and one of its arguments would indicate whether state was being collected or distributed. I think these might be good ideas. Unfortunately, in the abscence of a specific proposal for how to make this work I think we are going to make only the two changes described in this message. We don't have the time to figure out how to incorporate this comment given that what we have will clearly work. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 13:16:23 EDT Received: from Salvador.ms by ArpaGateway.ms ; 20 APR 88 10:02:11 PDT Return-Path: Redistributed: commonloops.pa Received: from mitre-bedford.ARPA by Xerox.COM ; 20 APR 88 09:59:05 PDT Posted-From: The MITRE Corp., Bedford, MA Received: from faron.sun.uucp by linus.MENET (3.2/4.7) id AA18559; Wed, 20 Apr 88 12:58:01 EDT From: Paul P. Maglio Posted-Date: Wed, 20 Apr 88 12:57:53 EDT Received: by faron.sun.uucp (3.2/SMI-3.0DEV3) id AA03331; Wed, 20 Apr 88 12:57:53 EDT Date: Wed, 20 Apr 88 12:57:53 EDT Message-Id: <8804201657.AA03331@faron.sun.uucp> To: commonloops.pa@Xerox.COM Subject: type specifiers in slot descriptors type specifiers in slot descriptors In the St. Patrick's Day release of PCL we have found the following silly behavior: When defining a class with a slot whose type specifier is a list and which has an accessor, e.g. (defclass foo () ((slot1 :type (or integer symbol) :accessor foo-slot1)) ) no accessor FOO-SLOT1 gets defined. If the type specifier had NOT been a list, e.g. :TYPE INTEGER, no problem would have occurred. FURTHERMORE, (here's the punch line), even if you REDEFINE the class FOO so that slot SLOT1's type specifier is atomic, you will NEVER get that accessor. There is effectively a black mark against that accessor. So if you now do this: (defclass foo () ((slot1 :type integer :accessor foo-slot1)) ) you won't get any accessor because of the black mark mentioned above. But if you then do this: (defclass foo () ((slot1 :type integer :accessor bar-slot1)) ) you will get the proper accessor, BAR-SLOT1. In trying to figure out why this happens, we came across a related, though minor, bug. A redefinition of a slot's accessor APPEARS to be forced whenever the new slot's type specifier is NEQ the old slot's type specifier, (in the function PCL::UPDATE-SLOT-ACCESSORS--CLASS-1). Of course, this is always the case when the type specifier is non-atomic. Thus a slot's accessor APPEARS to be redefined whenever the slots's type specifier is a list, e.g. (OR INTEGER SYMBOL). We say the redefinition APPEARS to be forced because, as we mentioned above, the accessor is forgotten by the time DEFCLASS returns. For now, our solution is to remove our type specifiers altogether. John Burger Paul Maglio  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Apr 88 13:06:01 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Apr 88 09:53:25 PDT Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 09:46:18 PDT Date: Wed, 20 Apr 88 09:46 PDT From: Gregor.pa@Xerox.COM Subject: DEADLINE for finishing 1 and 2 To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880420164612.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Its getting about time to send out chapter 2 to X3J13. I think we should try to send it as close to the end of the month as we can in order for them to have plenty of time to read it. It seems that the issue of re-working the initialization mechanism must be done before then. I haven't seen any messages on this in a while. Does that mean that we are going for some version of Danny's last proposal? Does anyone have other proposals or comments? -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 12:53:08 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 APR 88 09:37:11 PDT Date: Wed, 20 Apr 88 09:33 PDT From: Gregor.pa@Xerox.COM Subject: pcl To: wfs@cli.com cc: fritzson@PRC.Unisys.COM, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8804201347.AA12126@CLI.COM> Message-ID: <19880420163352.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no The best thing to do is to ignore the fact that the test file is blowing up on this case, and convert all your personal code to use with-slots* or with-accessors*. with-slots* behaves the way with-slots is described in the specification, with-accessors* behaves the way with-accessors is described to behave. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 12:27:39 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 09:13:00 PDT Return-Path: Redistributed: CommonLoops.pa Received: from postgres.Berkeley.EDU by Xerox.COM ; 20 APR 88 09:08:56 PDT Received: by postgres.Berkeley.EDU (5.57/1.26) id AA29769; Wed, 20 Apr 88 09:08:57 PDT Message-Id: <8804201608.AA29769@postgres.Berkeley.EDU> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: Richard L. Piazza Cc: CommonLoops.pa@Xerox.COM Precedence: special-delivery In-Reply-To: Your message of Tue, 19 Apr 88 18:17:55 EDT <8804192217.AA00409@orbit.sun.uucp> Subject: Re: :initform and :allocation :class Date: Wed, 20 Apr 88 09:08:56 PDT Sender: dcmartin%postgres.Berkeley.EDU@Berkeley.EDU Yeah, I came across that problem long ago and my fix was to check for a correct value in the slot when I first wished to reference it. (defclass foo (object) ((a :initform nil :type hash-table :allocation :class)) (:constructor make-foo)) (defmethod foo-a ((self foo)) (let ((a (slot-value self 'a))) (when (null a) (setq a (make-hash-table)) (setf (slot-value self 'a) a)) a)) The other way to do it is to check on first instantiation of an instance. As for subtypep, why not use subclassp? (defclass foo () (x y z)) # (defclass goo (foo) (blah blaz blub)) # (subclassp 'goo 'foo) ; which is what you meant, right? (# # #) In addition, the following functions might be useful, but note that they depend on Gregor continuing to store class slots values in the initform slot of the slotd object. Gregor - are you still passing out my PCL modifications? (defun class-slot-value (class name) "Return the value of the class slot from the specified class. The class may be either a class object or the symbol which is the class name." ;; test if class specified is a symbol (if (symbolp class) ;; get class object (setq class (class-named class))) ;; test if class (if (not (classp class)) ;; signal error (error "class-slot-value: invalid object ~s" class)) ;; get all class slots and desired slot (let* ((class-slots (class-non-instance-slots class)) (slot (find name class-slots :key #'slotd-name))) ;; test if slot was found (if (not (null slot)) ;; return value (slotd-initform slot)))) (defun setf-class-slot-value (class name value) "Return the value of the class slot from the specified class. The class may be either a class object or the symbol which is the class name." ;; test if class specified is a symbol (if (symbolp class) ;; get class object (setq class (class-named class))) ;; test if class (if (not (classp class)) ;; signal error (error "class-slot-value: invalid object ~s" class)) ;; get all class slots and desired slot (let* ((class-slots (class-non-instance-slots class)) (slot (find name class-slots :key #'slotd-name))) ;; test if slot was found (if (not (null slot)) ;; test if types match (if (typep value (slotd-type slot)) ;; set value (setf (slotd-initform slot) value) ;; signal error (error "class-slot-value: value not of type ~s" (slotd-type slot))))) ;; return value value) (defsetf class-slot-value setf-class-slot-value) -------- Your message: We've run into the following problems when using the St. Patrick's Day release of PCL: (Symbolics) 1) Compiling or evaluating the form, (defclass foo () ((bar :initform 'bar :allocation :class))) creates a class whose "bar" slot is initialized to "'bar", rather than "bar" as the CLOS specification dictates. Further, if the quote is left off of the argument to :initform, the compiler complains that "bar is unknown and has been declared special" but creates a class that behaves as if the argument was not evaluated (which turns out to be a problem in the initfunction that is created by cannonicalize-slot-description). The documentation indicates that an :initform that is allocated at the class should be EVALUATED at evaluation/compile time. This does not take place, leading to the behavior mentioned above. We have thought of the following fix to parse-class-slot: (defmethod PARSE-CLASS-SLOT ((class standard-class) slot) . . . (make-slotd class :name name :keyword (make-keyword name) :initform (IF (EQ ALLOCATION :CLASS) (EVAL INITFORM) initform) :initfunction initfunction :initargs initargs :allocation allocation :type type :accessors accessors :readers readers))) The change is highlighted in caps. Has anyone come across this error and come up with a better fix? 2) subtypep doesn't work on classes. For instance: (defclass foo () (x y z)) (defclass goo (foo) (blah blaz blub)) (subtypep 'foo 'goo) => nil nil Rich Piazza --------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 12:19:15 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 09:05:32 PDT Return-Path: Redistributed: CommonLoops.pa Received: from SAPSUCKER.SCRC.Symbolics.COM ([128.81.41.223]) by Xerox.COM ; 20 APR 88 09:02:11 PDT Received: from EVENING-GROSBEAK.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 229307; Wed 20-Apr-88 11:35:12 EDT Date: Wed, 20 Apr 88 11:33 EDT From: Scott McKay Subject: ["R. Shapiro": CLOS in 7.2] To: kanderso@wilma.bbn.com, CommonLoops.pa@Xerox.COM cc: CJoor@wilma.bbn.com, MThome@wilma.bbn.com, RShapiro@wilma.bbn.com, tmitchell@wilma.bbn.com, marcos@austin.lockheed.com, treinhardt@labs-n.bbn.com, gsmith@scotland.bbn.com, nlt@scotland.bbn.com, psykes@scotland.bbn.com, springen@austin.lockheed.com In-Reply-To: <880420-023535-1554@Xerox> Message-ID: <19880420153325.2.SWM@EVENING-GROSBEAK.SCRC.Symbolics.COM> Date: Tue, 19 Apr 88 21:32:13 -0400 From: kanderso@wilma.bbn.com ------- Forwarded Message Date: Tue 19 Apr 88 17:38:22-EDT From: "R. Shapiro" Subject: CLOS in 7.2 To: 3600-users@g.bbn.com cc: kanderson@g.bbn.com, mthome@g.bbn.com If you're using CLOS in 7.2, you should be aware of the following: a CLOS bug causes any entry into the debugger to generate recursive errors (resulting eventually in a stack overflow & leaving you in the unfriendly Emergency Debugger). You can fix this by loading the file CLOS:CLOS;DEBUGGER-FIX. It will be made a patch shortly, but until then you probably want to load this file [an announcement will be made when the patch is made]. - ------- I don't understand what this fixes. How exactly is it that you manage to get into FRAME-INTERESTING-P before BOOTSTRAP-*UNINTERESTING-FUNCTIONS* ever gets run (since that is the only way *UNINTERESTING-FUNCTIONS* can be a list instead of a hash-table)? ------- End of Forwarded Message Here is clos:clos;debugger-fix.lisp: ;;; -*- Mode: LISP; Package: DEBUGGER; Patch-File: Yes; Syntax: Zetalisp -*- In any event, the supplied fix is incorrect. For 7.2, it should at least be this (changes in capital letters): (defun (LFRAME-INTERESTING-P LISP-LANGUAGE-DEBUGGING-INSTANCE) (frame &optional (censor-invisible-frames *censor-invisible-frames*)) (labels ((uninternalize-fspec (fspec) ;; Internal functions of uninteresting functions are uninteresting (if (and (listp fspec) (eq (first fspec) :internal)) (if (and (or (eq (fourth fspec) 'si:with-process-interactive-priority-body) (eq (fourth fspec) 'si:with-process-non-interactive-priority-body)) (not (memq :process-priority *invisible-frame-types-to-show*))) ;; These things aren't interesting (return-from frame-interesting-p nil) (uninternalize-fspec (second fspec))) fspec)) (uninteresting-function-p (fspec) (cond ((cl:hash-table-p *uninteresting-functions*) (gethash fspec *uninteresting-functions*)) ((or (listp *uninteresting-functions*) (cl:vectorp *uninteresting-functions*)) (CL:MEMBER fspec *uninteresting-functions*))))) (if (and censor-invisible-frames (frame-invisible-p frame)) nil (let* ((function (frame-function frame)) (fspec (uninternalize-fspec (function-name-for-debugger frame)))) (and (neq fspec function) ;Not an unnamed LAMBDA expression (not (uninteresting-function-p fspec)) (not (member fspec si:*digested-special-forms*))))))) ;; True if frame is not just an internal frame of an interpreted function (defun frame-interesting-p (...) ...)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 10:00:17 EDT Received: from Salvador.ms by ArpaGateway.ms ; 20 APR 88 06:49:18 PDT Return-Path: Redistributed: CommonLoops.pa Received: from CLI.COM by Xerox.COM ; 20 APR 88 06:48:04 PDT Received: by CLI.COM (4.0/1); Wed, 20 Apr 88 08:47:40 CDT Date: Wed, 20 Apr 88 08:47:40 CDT From: Bill Schelter Message-Id: <8804201347.AA12126@CLI.COM> To: fritzson@PRC.Unisys.COM Cc: wfs@cli.com, wfs@cli.com, fritzson@bigburd.PRC.Unisys.COM, CommonLoops.pa@Xerox.COM In-Reply-To: Richard Fritzson's message of 20 Apr 88 07:33 EDT (Wednesday) <8804201133.AA21988@bigburd.PRC.Unisys.COM> Subject: pcl Reply-To: wfs@cli.com My question is "Is the code in test.lisp obsolete, or is my compilation of pcl incorrect?" Actually I just loaded the test.lisp file, and came to the error. I did not type it in at top level. So the with-slots was in a defmethod. The code from test.lisp is: (do-test "Simple with-slots test -- does not really exercise the walker." ((:functions foo bar)) (defmethod foo1 ((obj test-class-1)) (with-slots (obj) (list x y))) ... > PCL>Warning: The with-slots macro is now obsolete. You should convert to > with-slots* or with-accessors* as soon as possible. > Error: The class of OBJ was not specified and could not > be inferred from the lexical context. > Error signalled by FUNCALL. From your reply I believe I should replace obj by (obj :class test-class-1). Is this correct? Bill Schelter.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 09:28:41 EDT Received: from Salvador.ms by ArpaGateway.ms ; 20 APR 88 06:16:14 PDT Return-Path: Redistributed: CommonLoops.pa Received: from EMS.MEDIA.MIT.EDU by Xerox.COM ; 20 APR 88 06:14:55 PDT Received: by EMS.MEDIA.MIT.EDU (5.54/4.8) id AA28035; Wed, 20 Apr 88 09:14:10 EST Date: Wed, 20 Apr 88 09:14:10 EST From: smh@EMS.MEDIA.MIT.EDU (Steven Haflich) Message-Id: <8804201414.AA28035@EMS.MEDIA.MIT.EDU> To: fritzson@prc.unisys.com Cc: wfs@cli.com, CommonLoops.pa@Xerox.COM In-Reply-To: Richard Fritzson's message of 20 Apr 88 07:33 EDT (Wednesday) <8804201133.AA21988@bigburd.PRC.Unisys.COM> Subject: pcl From: fritzson@prc.unisys.com (Richard Fritzson) Date: 20 Apr 88 07:33 EDT (Wednesday) The syntax of the PCL with-slots does not adhere to the current version of the CLOS standard. That's why it is "obsolete". PCL has two forms "with-slots*" and "with-accessors*" which behave the way the CLOS spec says "with-slots" and "with-accessors" should. Eventually the obsolete forms will disappear and the "*" version will be renamed. One additional confusion: WITH-SLOTS* is not exported from the PCL package. Was this omission an oversight, or does it reflect the "temporary" nature of WITH-SLOTS* ? Either way, it discourages use.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 07:59:29 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 APR 88 04:36:24 PDT Return-Path: Redistributed: CommonLoops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 20 APR 88 04:33:45 PDT Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA20171; Wed, 20 Apr 88 07:33:19 EDT Received: by bigburd.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA21988; Wed, 20 Apr 88 07:33:15 EDT From: fritzson@PRC.Unisys.COM (Richard Fritzson) Message-Id: <8804201133.AA21988@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd.PRC.Unisys.COM with PUP; Wed, 20 Apr 88 07:33 EDT To: wfs@cli.com Date: 20 Apr 88 07:33 EDT (Wednesday) Subject: Re: pcl In-Reply-To: wfs@cli.com's message of Tue, 19 Apr 88 01:10:01 CDT To: wfs@cli.com Cc: fritzson@bigburd.PRC.Unisys.COM, CommonLoops.pa@Xerox.COM > The test.lisp file uses with-slots, yet with-slots says it is obsolete. > In any event I get an error in pcl on kcl when expanding the > with-slots macro in test.lisp The syntax of the PCL with-slots does not adhere to the current version of the CLOS standard. That's why it is "obsolete". PCL has two forms "with-slots*" and "with-accessors*" which behave the way the CLOS spec says "with-slots" and "with-accessors" should. Eventually the obsolete forms will disappear and the "*" version will be renamed. > The code from test.lisp is: > > (with-slots (obj) > (list x y))) > > PCL>Warning: The with-slots macro is now obsolete. You should convert to > with-slots* or with-accessors* as soon as possible. > Error: The class of OBJ was not specified and could not > be inferred from the lexical context. > Error signalled by FUNCALL. > This looks like you actually typed in the with-slots form at the top level, instead of leaving it embedded in the "defmethod". The obsolete with-slots form doesn't support that type of use without an explicit specification of the class of "obj". For example, (with-slots ((obj :class test-class-1)) (list x y)) will work (assuming obj has some global value). Also, with-slots* will work when typed in directly. That is, typing (with-slots* (x y) obj (list x y)) at the top level should work. -Rich Fritzson Unisys - Paoli Research Center ARPA: fritzson@prc.unisys.com UUCP: {sdcrdcf, psuvax1, cbmvax}!burdvax!fritzson  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 05:45:19 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 APR 88 02:35:35 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 19 APR 88 20:58:07 PDT To: CommonLoops.pa@Xerox.COM cc: CJoor@WILMA.BBN.COM, MThome@WILMA.BBN.COM, RShapiro@WILMA.BBN.COM, tmitchell@WILMA.BBN.COM, marcos@austin.lockheed.com, treinhardt@labs-n.bbn.com, gsmith@scotland.bbn.com, nlt@scotland.bbn.com, psykes@scotland.bbn.com, springen@austin.lockheed.com Subject: ["R. Shapiro": CLOS in 7.2] Date: Tue, 19 Apr 88 21:32:13 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880420-023535-1554@Xerox> ------- Forwarded Message Date: Tue 19 Apr 88 17:38:22-EDT From: "R. Shapiro" Subject: CLOS in 7.2 To: 3600-users@g.bbn.com cc: kanderson@g.bbn.com, mthome@g.bbn.com If you're using CLOS in 7.2, you should be aware of the following: a CLOS bug causes any entry into the debugger to generate recursive errors (resulting eventually in a stack overflow & leaving you in the unfriendly Emergency Debugger). You can fix this by loading the file CLOS:CLOS;DEBUGGER-FIX. It will be made a patch shortly, but until then you probably want to load this file [an announcement will be made when the patch is made]. - ------- ------- End of Forwarded Message Here is clos:clos;debugger-fix.lisp: ;;; -*- Mode: LISP; Package: DEBUGGER; Patch-File: Yes; Syntax: Zetalisp -*- ;; True if frame is not just an internal frame of an interpreted function (defun frame-interesting-p (frame &optional (censor-invisible-frames *censor-invisible-frames*)) (labels ((uninternalize-fspec (fspec) ;; Internal functions of uninteresting functions are uninteresting (if (and (listp fspec) (eq (first fspec) :internal)) (if (and (or (eq (fourth fspec) 'si:with-process-interactive-priority-body) (eq (fourth fspec) 'si:with-process-non-interactive-priority-body)) (not (memq :process-priority *invisible-frame-types-to-show*))) ;; These things aren't interesting (return-from frame-interesting-p nil) (uninternalize-fspec (second fspec))) fspec)) (uninteresting-function-p (fspec) (cond ((cl:hash-table-p *uninteresting-functions*) (gethash fspec *uninteresting-functions*)) ((or (listp *uninteresting-functions*) (cl:vectorp *uninteresting-functions*)) (member fspec *uninteresting-functions*))))) (if (and censor-invisible-frames (frame-invisible-p frame)) nil (let* ((function (frame-function frame)) (fspec (uninternalize-fspec (function-name-for-debugger frame)))) (and (neq fspec function) ;Not an unnamed LAMBDA expression (not (uninteresting-function-p fspec)) (not (member fspec si:*digested-special-forms*)))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 04:00:33 EDT Received: from Semillon.ms by ArpaGateway.ms ; 19 APR 88 19:29:02 PDT Return-Path: Redistributed: CommonLoops.pa Received: from mitre-bedford.ARPA by Xerox.COM ; 19 APR 88 19:26:50 PDT Posted-From: The MITRE Corp., Bedford, MA Received: from orbit.sun.uucp by linus.MENET (3.2/4.7) id AA19642; Tue, 19 Apr 88 18:17:57 EDT From: Richard L. Piazza Posted-Date: Tue, 19 Apr 88 18:17:55 EDT Received: by orbit.sun.uucp (3.2/SMI-3.0DEV3) id AA00409; Tue, 19 Apr 88 18:17:55 EDT Date: Tue, 19 Apr 88 18:17:55 EDT Message-Id: <8804192217.AA00409@orbit.sun.uucp> To: CommonLoops.pa@Xerox.COM Subject: :initform and :allocation :class We've run into the following problems when using the St. Patrick's Day release of PCL: (Symbolics) 1) Compiling or evaluating the form, (defclass foo () ((bar :initform 'bar :allocation :class))) creates a class whose "bar" slot is initialized to "'bar", rather than "bar" as the CLOS specification dictates. Further, if the quote is left off of the argument to :initform, the compiler complains that "bar is unknown and has been declared special" but creates a class that behaves as if the argument was not evaluated (which turns out to be a problem in the initfunction that is created by cannonicalize-slot-description). The documentation indicates that an :initform that is allocated at the class should be EVALUATED at evaluation/compile time. This does not take place, leading to the behavior mentioned above. We have thought of the following fix to parse-class-slot: (defmethod PARSE-CLASS-SLOT ((class standard-class) slot) . . . (make-slotd class :name name :keyword (make-keyword name) :initform (IF (EQ ALLOCATION :CLASS) (EVAL INITFORM) initform) :initfunction initfunction :initargs initargs :allocation allocation :type type :accessors accessors :readers readers))) The change is highlighted in caps. Has anyone come across this error and come up with a better fix? 2) subtypep doesn't work on classes. For instance: (defclass foo () (x y z)) (defclass goo (foo) (blah blaz blub)) (subtypep 'foo 'goo) => nil nil Rich Piazza  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 04:00:18 EDT Received: from Semillon.ms by ArpaGateway.ms ; 19 APR 88 19:18:53 PDT Return-Path: Redistributed: commonloops.pa Received: from SPICE.CS.CMU.EDU by Xerox.COM ; 19 APR 88 19:16:26 PDT Date: Tue, 19 Apr 88 22:05 EDT From: Jamie.Zawinski To: commonloops.pa@Xerox.COM Subject: defclass/accessor problem Message-ID: <880419-191853-1147@Xerox> I do something like (defclass foo (parenta parentb parentc) ((slot-a :accessor foo-slot-a) (slot-b :accessor foo-slot-b))) When I call FOO-SLOT-A I get the error >> There are no methods on the generic-function #, so it is an error to call it. And sure enough, (pcl::generic-function-methods #'foo-slot-a) returns NIL. But FOO-SLOT-B is perfectly cool. I do not in any way specialize FOO-SLOT-A or FOO-SLOT-B. Re-evaluating the defclass does not make the problem go away, but doing (defclass foo () ()) and THEN re-evaluating the original makes the correct definition of FOO-SLOT-A exist. Evaluating the defclass again after that makes it go away again. This is not an especially reproducible problem. The actual class that I am having this problem with has about twenty slots, and inherits about thirty more. The slots that have this problem are the last three. The problem exhibits itself after instances have been made. I'm using Lucid Lisp 3.0 on a Sun 3. Any ideas? Jamie  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Apr 88 03:59:44 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 18 APR 88 23:12:08 PDT Return-Path: Redistributed: CommonLoops.pa Received: from CLI.COM by Xerox.COM ; 18 APR 88 23:09:50 PDT Received: by CLI.COM (4.0/1); Tue, 19 Apr 88 01:10:01 CDT Date: Tue, 19 Apr 88 01:10:01 CDT From: Bill Schelter Message-Id: <8804190610.AA03068@CLI.COM> To: CommonLoops.pa@Xerox.COM Subject: pcl Reply-To: wfs@cli.com I am confused about with-slots. The test.lisp file uses with-slots, yet with-slots says it is obsolete. In any event I get an error in pcl on kcl when expanding the with-slots macro in test.lisp The code from test.lisp is: (with-slots (obj) (list x y))) PCL>Warning: The with-slots macro is now obsolete. You should convert to with-slots* or with-accessors* as soon as possible. Error: The class of OBJ was not specified and could not be inferred from the lexical context. Error signalled by FUNCALL. Broken at WITH-SLOTS. Type :H for Help. The pcl files I have were ftp'd from parc today (April 19). Thanks ---Bill Schelter  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Apr 88 19:22:12 EDT Received: from WILMA.BBN.COM ([128.89.1.216]) by SAIL.Stanford.EDU with TCP; 19 Apr 88 16:10:39 PDT Received: by WILMA.BBN.COM id aa23673; 19 Apr 88 19:00 EDT To: Gregor.pa@xerox.com cc: common-lisp-object-system@sail.stanford.edu Subject: Re: dependent update protocol In-reply-to: Your message of Mon, 11 Apr 88 11:38:00 -0700. <880411113858.6.GREGOR@SPIFF.parc.xerox.com> Date: Tue, 19 Apr 88 15:26:26 -0400 From: kanderso@WILMA.BBN.COM Although i didn't like the way you cons/cdr'ed things on reinitargs, i guess it is safe as long as everyone uses it that way. I can't seem to find a better way. k  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Apr 88 22:33:18 EDT Received: from Salvador.ms by ArpaGateway.ms ; 18 APR 88 17:45:52 PDT Return-Path: <@cadre.dsl.pittsburgh.edu:jas@dsl.pittsburgh.edu> Redistributed: commonloops.pa Received: from cadre.dsl.pittsburgh.edu by Xerox.COM ; 18 APR 88 17:44:39 PDT Received: by cadre.dsl.pittsburgh.edu id AA15863; Mon, 18 Apr 88 20:42:18 Date: Mon, 18 Apr 88 20:42:18 id AA15863; Mon, 18 Apr 88 20:42:18 From: jas@cadre.dsl.pittsburgh.edu (Jeffrey A. Sullivan) Message-Id: <8804190042.AA15863@cadre.dsl.pittsburgh.edu> To: commonloops.pa@Xerox.COM Subject: Generic Function parameter list Cc: jas@dsl.pittsburgh.edu Is there any way to get a generic function (or method object) to branch on specific argtypes if the significant argtype is a class? E.g., (defmethod tst ((arg t)) 'gen) (defmethod tst ((arg frame-item) 'frame) ;frame-item is a class, all instances ; of frame-item or its subclasses will et dispatched to here. But say I have this: (defclass frame2 (frame-item) ... ) and I want my tst to branch on IT as well. Can I do this? .......................................................................... Jeffrey Sullivan | University of Pittsburgh jas@cadre.dsl.pittsburgh.edu | Intelligent Systems Studies Program jasper@PittVMS.BITNET, jasst3@cisunx.UUCP | Graduate Student  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Apr 88 19:25:59 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 18 APR 88 11:20:14 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 18 APR 88 10:34:02 PDT To: CommonLoops.pa@Xerox.COM cc: CJoor@WILMA.BBN.COM, MThome@WILMA.BBN.COM, RShapiro@WILMA.BBN.COM, tmitchell@WILMA.BBN.COM, marcos@austin.lockheed.com, treinhardt@labs-n.bbn.com Subject: [Postmaster@bbn.com: Unable to deliver letter] Date: Mon, 18 Apr 88 09:22:52 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880418-112014-2292@Xerox> Sorry if this wen't out twice. I had a mailer problem. ------- Forwarded Message Received: from R&B.bbn.com by CONGER.bbn.com via CHAOS with CHAOS-MAIL id 44801; Sun 17-Apr-88 16:49:19 EDT Date: Sun, 17 Apr 88 16:49 EDT From: Kenneth R. Anderson Subject: next-method-p To: commonloops.pa@xerox.com cc: kanderson@bbn.com Message-ID: <880417164933.1.KANDERSON@R&B.bbn.com> ;;; From boot.lisp ;;; KRA: Added next-method-p as lexical function like call-next-method. ;;; Since we are walking the code, we could be a bit smarter about inlining special ;;; cases. (export 'next-method-p 'pcl) (defun expand-defmethod-body-internal (generic-function-name lambda-list specializers body env) (multiple-value-bind (doc declares real-body) (extract-declarations body env) (declare (ignore doc)) ;We drop it on the floor ;since it gets recorded ;elsewhere. (let ((class-declarations `(declare ,@(mapcar #'(lambda (a s) (and (symbolp s) `(class ,a ,s))) lambda-list specializers))) (call-next-method-p nil) (next-method-p nil) ; KRA (save-original-args nil) (original-args ()) (applyp nil) (walked-lambda nil)) (flet ((walk-function (form context env &aux temp) (cond ((not (eq context ':eval)) form) ((not (listp form)) form) ((eq (car form) 'call-next-method) (setq call-next-method-p 't save-original-args (not (cdr form))) form) ((and (eq (car form) 'function) (eq (cadr form) 'call-next-method)) (setq call-next-method-p 't save-original-args 't) form) ((eq (car form) 'next-method-p) ; KRA (setq next-method-p t) form) ((and (eq (car form) 'function) ; KRA (eq (cadr form) 'next-method-p)) (setq next-method-p t) form) ((and (or (eq (car form) 'slot-value) (eq (car form) 'set-slot-value)) (symbolp (cadr form)) (constantp (caddr form)) (setq temp (variable-class (cadr form) env)) (or (not (symbolp temp)) (setq temp (class-named temp 't)))) (ecase (car form) (slot-value (optimize-slot-value temp form)) (set-slot-value (optimize-set-slot-value temp form)))) (t form)))) (setq walked-lambda (walk-form `(lambda ,lambda-list ,class-declarations ,@declares (block ,generic-function-name ,@real-body)) env #'walk-function)) (when save-original-args ;; We are going to have to be able to store away the original ;; arguments to the function. Get ourselves an argument list ;; to do this with. (dolist (a lambda-list) (if (member a lambda-list-keywords) (if (eq a '&aux) (return) (progn (setq applyp t) (push '&rest original-args) (push (gensym) original-args) (return))) (push (gensym) original-args))) (setq original-args (reverse original-args))) (multiple-value-bind (doc walked-declares walked-lambda-body) (extract-declarations (cddr walked-lambda)) (declare (ignore doc)) (cond ((not (or call-next-method-p next-method-p)) walked-lambda) ((null save-original-args) `(lambda ,lambda-list ,@walked-declares (let ((.next-method. (car *next-methods*)) (*next-methods* (cdr *next-methods*))) (flet ((call-next-method (&rest cnm-args) (apply .next-method. cnm-args)) ,@(if next-method-p '((next-method-p () .next-method.)) ())) ,@walked-lambda-body)))) ((null applyp) `(lambda ,original-args (let ((.next-method. (car *next-methods*)) (*next-methods* (cdr *next-methods*))) (flet ((call-next-method (&rest cnm-args) (if cnm-args (apply .next-method. cnm-args) (funcall .next-method. ,@original-args))) ,@(if next-method-p '((next-method-p () .next-method.)) ())) (let ,(mapcar #'list lambda-list original-args) ,@walked-declares ,@walked-lambda-body))))) (t `(lambda ,original-args (let ((.next-method. (car *next-methods*)) (*next-methods* (cdr *next-methods*))) (flet ((call-next-method (&rest cnm-args) (if cnm-args (apply .next-method. cnm-args) (apply .next-method. ,@(remove '&rest original-args)))) ,@ (if next-method-p '((next-method-p () .next-method.)) ())) (apply (function ,walked-lambda) ,@(remove '&rest original-args)))))))))))) ------- End of Forwarded Message  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Apr 88 19:24:35 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 17 APR 88 19:10:45 PDT Return-Path: Redistributed: commonloops.pa Received: from ECLA.USC.EDU by Xerox.COM ; 17 APR 88 19:09:15 PDT Date: Sun, 17 Apr 88 18:57:06 PDT From: Kim A. Barrett Subject: Re: Method Selection Error revisited To: jas@CADRE.DSL.PITTSBURGH.EDU cc: commonloops.pa@Xerox.COM, IIM@ECLA.USC.EDU In-Reply-To: <8804152329.AA22606@cadre.dsl.pittsburgh.edu> Message-ID: <12391306054.18.IIM@ECLA.USC.EDU> Your problem is in the argument being given to STORE. It is the result of calling make-frame with type :class, which is going to be (in your problem code) the CLASS BLOCK, not an INSTANCE of the class BLOCK. (METHOD CLOS-INDEX (BLOCK)) will only be selected if the argument is an instance of block. kab -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Apr 88 19:24:02 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 APR 88 14:07:41 PDT Return-Path: <@CONGER.bbn.com:kanderson@VAX.bbn.com> Redistributed: commonloops.pa Received: from CONGER.bbn.com by Xerox.COM ; 17 APR 88 14:05:13 PDT Received: from R&B.bbn.com by CONGER.bbn.com via CHAOS with CHAOS-MAIL id 44801; Sun 17-Apr-88 16:49:19 EDT Date: Sun, 17 Apr 88 16:49 EDT From: Kenneth R. Anderson Subject: next-method-p To: commonloops.pa@Xerox.COM cc: kanderson@bbn.com Message-ID: <880417164933.1.KANDERSON@R&B.bbn.com> ;;; From boot.lisp ;;; KRA: Added next-method-p as lexical function like call-next-method. ;;; Since we are walking the code, we could be a bit smarter about inlining special ;;; cases. (export 'next-method-p 'pcl) (defun expand-defmethod-body-internal (generic-function-name lambda-list specializers body env) (multiple-value-bind (doc declares real-body) (extract-declarations body env) (declare (ignore doc)) ;We drop it on the floor ;since it gets recorded ;elsewhere. (let ((class-declarations `(declare ,@(mapcar #'(lambda (a s) (and (symbolp s) `(class ,a ,s))) lambda-list specializers))) (call-next-method-p nil) (next-method-p nil) ; KRA (save-original-args nil) (original-args ()) (applyp nil) (walked-lambda nil)) (flet ((walk-function (form context env &aux temp) (cond ((not (eq context ':eval)) form) ((not (listp form)) form) ((eq (car form) 'call-next-method) (setq call-next-method-p 't save-original-args (not (cdr form))) form) ((and (eq (car form) 'function) (eq (cadr form) 'call-next-method)) (setq call-next-method-p 't save-original-args 't) form) ((eq (car form) 'next-method-p) ; KRA (setq next-method-p t) form) ((and (eq (car form) 'function) ; KRA (eq (cadr form) 'next-method-p)) (setq next-method-p t) form) ((and (or (eq (car form) 'slot-value) (eq (car form) 'set-slot-value)) (symbolp (cadr form)) (constantp (caddr form)) (setq temp (variable-class (cadr form) env)) (or (not (symbolp temp)) (setq temp (class-named temp 't)))) (ecase (car form) (slot-value (optimize-slot-value temp form)) (set-slot-value (optimize-set-slot-value temp form)))) (t form)))) (setq walked-lambda (walk-form `(lambda ,lambda-list ,class-declarations ,@declares (block ,generic-function-name ,@real-body)) env #'walk-function)) (when save-original-args ;; We are going to have to be able to store away the original ;; arguments to the function. Get ourselves an argument list ;; to do this with. (dolist (a lambda-list) (if (member a lambda-list-keywords) (if (eq a '&aux) (return) (progn (setq applyp t) (push '&rest original-args) (push (gensym) original-args) (return))) (push (gensym) original-args))) (setq original-args (reverse original-args))) (multiple-value-bind (doc walked-declares walked-lambda-body) (extract-declarations (cddr walked-lambda)) (declare (ignore doc)) (cond ((not (or call-next-method-p next-method-p)) walked-lambda) ((null save-original-args) `(lambda ,lambda-list ,@walked-declares (let ((.next-method. (car *next-methods*)) (*next-methods* (cdr *next-methods*))) (flet ((call-next-method (&rest cnm-args) (apply .next-method. cnm-args)) ,@(if next-method-p '((next-method-p () .next-method.)) ())) ,@walked-lambda-body)))) ((null applyp) `(lambda ,original-args (let ((.next-method. (car *next-methods*)) (*next-methods* (cdr *next-methods*))) (flet ((call-next-method (&rest cnm-args) (if cnm-args (apply .next-method. cnm-args) (funcall .next-method. ,@original-args))) ,@(if next-method-p '((next-method-p () .next-method.)) ())) (let ,(mapcar #'list lambda-list original-args) ,@walked-declares ,@walked-lambda-body))))) (t `(lambda ,original-args (let ((.next-method. (car *next-methods*)) (*next-methods* (cdr *next-methods*))) (flet ((call-next-method (&rest cnm-args) (if cnm-args (apply .next-method. cnm-args) (apply .next-method. ,@(remove '&rest original-args)))) ,@ (if next-method-p '((next-method-p () .next-method.)) ())) (apply (function ,walked-lambda) ,@(remove '&rest original-args))))))))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Apr 88 19:41:57 EDT Received: from Salvador.ms by ArpaGateway.ms ; 15 APR 88 16:33:01 PDT Return-Path: <@cadre.dsl.pittsburgh.edu:jas@dsl.pittsburgh.edu> Redistributed: commonloops.pa Received: from cadre.dsl.pittsburgh.edu by Xerox.COM ; 15 APR 88 16:31:37 PDT Received: by cadre.dsl.pittsburgh.edu id AA22606; Fri, 15 Apr 88 19:28:58 YP Date: Fri, 15 Apr 88 19:28:58 YP From: jas@cadre.dsl.pittsburgh.edu (Jeffrey A. Sullivan) Message-Id: <8804152329.AA22606@cadre.dsl.pittsburgh.edu> To: commonloops.pa@Xerox.COM Subject: Method Selection Error revisited Cc: jas@dsl.pittsburgh.edu Here is a code sample of the problem. I am unable to decipher the problem, though I suspect that it lies in the time at which my make-frame macro is expanded . Here is the code: ? (setq *INFO-ITEM* (pcl:defclass INFO-ITEM () ((time-tag :accessor time-tag :initform (get-internal-real-time))) (:documentation "The Generic Information Item holds only time tag."))) # ? (pcl:defmethod query ((item t) &rest therest) ; Create a list of the query, backward-chained results, and justifications (list ; Retrieve the query using a specialized generic function (CLOS-retrieve item (car therest)) ; Attempt to backward chain for more answers (CLOS-backward-chain item) ; Support hooks for a Truth Maintenance System (CLOS-support item))) # ? (pcl:defmethod store ((item t)) ; Support hooks to Truth Maintenance System (list (CLOS-support item) ; Store the item using a specialized generic function (CLOS-index item) ; Forward-chain from the item (CLOS-forward-chain item))) # ? ;;; Generic SUPPORT function does nothing but return nil (pcl:defmethod CLOS-support ((item t)) nil) # ? ;;; Generic CLOS-forward-chain function does nothing but return the item (pcl:defmethod CLOS-forward-chain ((item t)) item) # ? ;;; Generic CLOS-backward-chain function does nothing but return the item (pcl:defmethod CLOS-backward-chain ((item t)) nil) # ? ;;; Add a specific retrieval method for predicate-items. Matches most of functionality ;;; of PC-RETRIEVE backward-chaining in handled in CLOS-BACKWARD-CHAIN. Returns a list ;;; of pairs. The car of each pair is a copy of the query form with variables replaced. ;;; the cadr is the varlist. (pcl:defmethod CLOS-retrieve ((item t) vars) (declare (ignore vars)) 'generic-index) # ? ;;; PC-item CLOS-BACKWARD-CHAIN method calls FROM-BACKWARD-CHAINING in ded retriever. (pcl:defmethod CLOS-backward-chain ((item t)) 'gener-back-chain) # ? ;;; Add a specific storage method for predicate-items. Matches most of the functionality ;;; of PC-STORE in the deductive retriever. backward-chain is handled by the ;;; CLOS-backward-chain function. (pcl:defmethod CLOS-index ((item t)) ;make sure pat isn't null. 'generic-index) # ? ;;; PC-item CLOS-forward-CHAIN method calls FROM-FORWARD-CHAINING in ded retriever. (pcl:defmethod CLOS-forward-chain ((item t)) 'gener-for-chain) # ? ;;;;;; ;;;; PC-item Test cases ;;; ;; ; (store '(on sphere3 block2)) (NIL GENERIC-INDEX GENER-FOR-CHAIN) ? (store '(on triangle1 block1)) (NIL GENERIC-INDEX GENER-FOR-CHAIN) ? (store '(on block3 rhombus1)) (NIL GENERIC-INDEX GENER-FOR-CHAIN) ? (store '(on block2 rhombus2)) (NIL GENERIC-INDEX GENER-FOR-CHAIN) ? (defvar *FRAME-DataBase* (Make-hash-table)) *FRAME-DATABASE* ? (setf (gethash '*FRAME-NAMES* *FRAME-DataBase*) (make-hash-table)) # ? (setf (gethash '*SLOT-NAMES* *FRAME-DataBase*) (make-hash-table)) # ? (setq *FRAME-ITEM* (pcl:defclass FRAME-ITEM (INFO-ITEM) ((database :reader database :initform *FRAME-DATABASE* :allocation :class) (*FRAME-TYPE* :initform nil) (*FRAME-NAME* :initform nil) (FRAME-ID :accessor ID :initform (gensym "FRAME"))) (:documentation "Frame Information Item"))) # ? (defmacro make-frame (frame-name parents type &rest slot-args) (cond ((equal type :CLASS) (let ((par (append parents '(FRAME-ITEM)))) `(let ((theframe (pcl:defclass ,frame-name ,par ,@slot-args))) (index-frame-name theframe ',frame-name) (pcl:defmethod CLOS-index ((item ,frame-name)) item) theframe))) ((equal type :INSTANCE) `(let ((theframe (pcl:make-instance ',parents ,@slot-args :*FRAME-TYPE* :INSTANCE :*FRAME-NAME* ',frame-name))) (index-frame-name theframe ',frame-name) (index-slot-names theframe) theframe)) ((equal type :PATTERN) `(let ((theframe (pcl:make-instance ',parents ,@slot-args :*FRAME-TYPE* :PATTERN :*FRAME-NAME* ',frame-name))) ; No need to index patterns theframe)) (t nil))) MAKE-FRAME ? ;;; ;;; Frame-item interface methods ;;; ;;; Add a specific storage method for frame-items (pcl:defmethod CLOS-index ((theframe frame-item)) ; We already called the Make-frame function in the argument. theframe) # ? (pcl:defmethod CLOS-retrieve ((theframe frame-item) vars) ; We already called the Make-frame function in the argument. (match-frame theframe :variables vars)) # ? ;;;;;; ;;;; frame-item Test cases ;;; ;; ; (make-frame block () :class ((color) (len) (wid) (height))) # ? (store (make-frame block () :class ((color) (len) (wid) (height)))) (NIL GENERIC-INDEX GENER-FOR-CHAIN) ? --------------------- comments continue --------------- As you can see, the result of calling STORE with a call to MAKE-FRAME is not the execution of the method for FRAME-ITEMs, but is the GENERIC CLOS-index. I suspect this is due to the fact that make-frame is a macro, and that what store gets is not the result of the macro expansion, but the macro closure itself, which is not a FRAME-ITEM, so the generic CLOS-index is called. As you can see, I can't make MAKE-FRAME into a function because DEFCLASS is a macro, and when I try to pass arguments to it, they are quoted and are therefore the names of the variables holding the values, rather than the values themselves. Any help would be appreciated. I suspect this may be a more CL-oriented question than CLOS, but here it is. thanks, .......................................................................... Jeffrey Sullivan | University of Pittsburgh jas@cadre.dsl.pittsburgh.edu | Intelligent Systems Studies Program jasper@PittVMS.BITNET, jasst3@cisunx.UUCP | Graduate Student  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Apr 88 16:54:35 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 15 Apr 88 13:45:29 PDT Received: by ti.com id AA14433; Fri, 15 Apr 88 15:43:22 CDT Received: from Kelvin by tilde id AA27176; Fri, 15 Apr 88 15:44:53 CDT Message-Id: <2786129024-9418538@Kelvin> Sender: GRAY@Kelvin.csc.ti.com Date: Fri, 15 Apr 88 15:43:44 CDT From: David N Gray To: Common-lisp-object-system@sail.stanford.edu Cc: Gray@DSG.csc.ti.com Subject: CLOS comments Comments on section 2 of the "Common Lisp Object System Specification" (X3J13 document 88-002 dated March 1988): Functionality comments: ----------------------- DEFCLASS needs to permit a slot option of the form: (:DOCUMENTATION doc-string) Any implementation would be permitted to ignore this, but the standard should recommend that the specified doc-string should become the value to be returned by the DOCUMENTATION function for any reader methods created for the slot by the :READER or :ACCESSOR options. I recognize that an implementation is already permitted to support this as an extension, but since the use of documentation should be encouraged rather than made more difficult, I think it is unacceptable to require users to write code that looks like this: ... (:READER FOO) #+(OR TI ...) ; implementations that I happen to know accept this (:DOCUMENTATION "...") ... when it is trivial for an implementation to just ignore the option if it doesn't wish to support it. It is not apparent why GENERIC-FUNCTION needs to be a special form instead of a macro. The CLOS standard should specify that implementations which support it should include the symbol :CLOS in their *FEATURES* list. Editorial comments: ------------------- On page 2-8, the description "... of the form S or of the form S*" is a little confusing because S is not defined. I think it would be helpful if locally defined macros and functions (such as CALL-METHOD and CALL-NEXT-METHOD) had a syntax line that said "Local Macro" or "Local Function" instead of just "Macro" or "Function". On page 2-25, third paragraph, the sentence "The slot name argument is a symbol that can be used as a Common Lisp variable name." is confusing. It seems to be saying that the name becomes defined such that it can be accessed just like a variable (as in flavors), but this is only true through the use of WITH-SLOTS, which is not mentioned here. Probably what was intended was that the slot name must satisfy the same syntactic requirements as a variable name, i.e. a symbol which is not a keyword, nil, or t. -- David Gray, Texas Instruments  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Apr 88 13:58:53 EDT Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Apr 88 10:46:35 PDT Received: from relay2.cs.net by RELAY.CS.NET id an24019; 15 Apr 88 11:25 EDT Received: from utokyo-relay by RELAY.CS.NET id ar20898; 15 Apr 88 11:14 EDT Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET) id AA20202; Fri, 15 Apr 88 13:30:41 JST Received: by aoyama.cc.aoyama.junet (3.2/6.3Junet-1.0) id AA17656; Fri, 15 Apr 88 13:13:54 JST Date: Fri, 15 Apr 88 13:13:54 JST From: Masayuki Ida Return-Path: Message-Id: <8804150413.AA17656@aoyama.cc.aoyama.junet> To: common-lisp-object-system@SAIL.STANFORD.EDU, ida%aoyama.cc.aoyama.junet@UTOKYO-RELAY.CSNET Subject: Comment on CLOS I got a mail which is attached at the bottom from Mr. Ohkubo who is chairing the subcommitte for OOPS under my Jeida Common Lisp Committee. My personal opinion is not included here. But, I feel several of them are agreeable. I will send my comment in a separate mail. PLEASE INCLUDE MY NAME IN THE LIST AS "IDA%AOYAMA.JUNET@RELAY.CS.NET". Thank you. Masayuki Ida -------------------------- The mail I got -------------------------------- From ohkubo@pfrad.pf.fujitsu.junet Thu Apr 14 15:32:01 1988 Date: Wed, 13 Apr 88 17:05:24 JST Subject: Please forward this mail to CLOS mailing-list Dear Prof. Ida, Please forward this mail to CLOS mailing-list. Thanks in advance. ohkubo ------------------------------------------------------------------------------- Here are some questions and problems about the CLOS draft. I hope this will help to refine the CLOS specification. --- ohkubo (ohkubo%pfrad.pf.fujitsu.junet@uunet.uu.NET) 1. About the error signaled when next method doesn't exit. The CLOS spec intends the user should check whether the next method exits by next-method-p, but it will degrade the modularity, because the user should concern about his method might have a method with the same name which discriminate on the super class or combined with method combination. In the system where multiple inheritance is supported, next method of some method doesn't mean one unique method. There is a case where same method have a next method in on case, and there isn't next method in another case, depending on the context. (On the other hand, in Smalltalk 'super' method can be decided statically). The method combination facility further complicates the decision whether next method might be exit. This might enforce the user should always use next-method-p. To solve this problem, Object System should call a generic function named such as 'no-next-method', when call-next-method is invoked but there isn't such method, and the default method of 'no-next-method' should signal an error. With this modification user can write 'no-next-method' which does nothing or invokes error notifier. This mechanism is the same as 'no-applicable-method'. 2. Who and when remove a method defined on 'update-instance-structure'? Updating instances with class redefinition is important, but the procedure should be existed temporarily while only updating. With the current specification, the method defined on 'update-instance-structure' will become a garbage who will never be called again. Because the class specified at its parameter-specializer is obsolete after redefining the class, but the method will last until someone removes it. If user intends to remove the 'obsolete method', he can't have a confidence that the method is obsolete and never be used agained. Because some implementation might postpone updating instance until the object will actually be used. My proposal with this problem, see 3. 3. CLOS doesn't support updating a slot structure. Update-instance-structure gives chance to revise an instance structure while redefining class, but it can't be used to revise a slot strucure. For example, some slot now holding a list and the user find it can be an array and want to convert slot structure of the existing instances for compacting memory. In this case, class definition itself need not be changed, so updating-instance-strucure doesn't be called. If the user redefines the class with the same class description intentionally, update-instance- structure can't get proper arguments, because slot name remaines unchanged. To solve the problems stated at 2 and 3, CLOS should include 'all-instances' with the same function as 'allInstances' of Smalltalk. I know this is very difficult for some implementation. But 'all-instances' is very convenient while maintaining objects in virtual image. It will not be appropriate to demand 'all-instances' be implemented fast enough as other lisp functions. 4. CLOS doesn't specify what will be happen when defining an ordinary function or a macro which has the same name with the existing generic function. 5. When defining a generic function having the same name with the preexisting ordinary function, current spec says it is error. Is it a proper definition? In contrast to the case of defgeneric or defmethod, add-method includes the ordinary function as a default method. What is this rationale? Might it be rather proper to retain consistency? 6. 'delete-class' and 'delete-generic-function' should be defined. It isn't easy and isn't clear to delete a class or a generic function as the case of deleting a structure or a function for the user. It also depends heavily on each implementation. CLOS should define user interface to delete a class and a generic function, and also provide sufficient mechanism for the programmer writing a programming environment. 7. Will it properly work when there are methods with the parameter specializers whose meta classes are different in one generic function? 8. Introducing private slot. In classical object systems such as Smalltalk or Flavors, there are methods they have special semantics for a particular class. This is implied by each method is belonged to some class. In the methods defined on this class or its subclasses, instance variables defined in this class are freely accessible. This makes it possible some slot, which only accessible in some group of methods, doesn't need to define an accessor. But in CLOS, there isn't a class which have special semantics for a method. CLOS should provide the mechanism which allows to access a slot only in some group of methods. In the current spec, someone want to read a slot and define reader then all the people can read it. 9. At the first line of page 1-35 in CLOS draft, "Declaring Method Combination" might be better than "Declarative Method Combinarion". Declarative method combination means for some reader the demon method such as :before and :after method, and procedural method combination means 'super', 'run-super', or 'call-next-method'. -------------------------------------------------------------------------------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Apr 88 09:01:29 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 15 APR 88 05:44:15 PDT Return-Path: <@cadre.dsl.pittsburgh.edu:jas@dsl.pittsburgh.edu> Redistributed: commonloops.pa Received: from cadre.dsl.pittsburgh.edu by Xerox.COM ; 15 APR 88 05:42:19 PDT Received: by cadre.dsl.pittsburgh.edu id AA15316; Fri, 15 Apr 88 00:58:17  Date: Fri, 15 Apr 88 00:58:17  From: jas@dsl.pittsburgh.edu (Jeffrey A. Sullivan) Message-Id: <8804150458.AA15316@cadre.dsl.pittsburgh.edu> To: commonloops.pa@Xerox.COM Subject: CLOS/PCL problem I am having a problem with PCL (the "2/27/88 Post ISO PCL"version). When I defmethod a method with generic argument types, then define other methods on the same generic function, my more specific argument templates are not being used correctly. An example of the problem is: (defmethod test ((arg1 t) (arg2 t)) arg1) and a more specific version: (defmethod test ((arg1 frame-item) (arg2 pattern)) (do-frame-pattern-match arg1 arg2)) When I run (tst x y) where x and y are frame-items and patterns, respectively, it still executes the first vewrsion of the method, which does the wrong stuff. Am I doing something worng here? .......................................................................... Jeffrey Sullivan | University of Pittsburgh jas@cadre.dsl.pittsburgh.edu | Intelligent Systems Studies Program jasper@PittVMS.BITNET, jasst3@cisunx.UUCP | Graduate Student  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 18:24:21 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 15:14:34 PDT Received: from Semillon.ms by ArpaGateway.ms ; 14 APR 88 15:10:58 PDT Date: Thu, 14 Apr 88 15:09 PDT From: Gregor.pa@Xerox.COM Subject: Re: method-lambda and apply-method-lambda To: Patrick H Dussud , kempf@Sun.COM, David A. Moon cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <2785937331-3382088@Jenner>, <8804131720.AA07908@suntana.sun.com>, <19880413183155.2.MOON@EUPHRATES.SCRC.Symbolics.COM>, <8804140006.AA21809@suntana.sun.com>, <8804142044.AA00351@suntana.sun.com>, <19880414190146.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <880414150957.6.GREGOR@SPIFF.parc.xerox.com> Line-fold: no I am not even going to try to yank in all the relevant parts of all these messages and match them up where they meet. After talking to Patrick on the phone and thinking long and hard about what he was proposing, I now believe it can work and is a good idea. So this message just summarizes what I believe is a correct proposal. make-method-function (generic-function method lambda-list body) This is a generic function. It tends to be specialized on the class of the generic-function and method arguments. The returned result satisfies the criterion outlined by Moon in one of his messages. apply-method-function generic-function method function info &rest args This is also a generic function. It tends to be specialied on its first two arguments as well. For the case where generic-function and method are both standard, the info argument is a list of the next methods. Each of these functions are generic on both the generic-function and the method to reflect the fact that both are involved in determining the method calling contract. The metacircularity can bottom out without problems because the standard-method on compute discriminator code can tell than any of the calls it should make to apply-method-function will actually end up invoking the standard method and so it can short circuit the call to the actual generic function. User code which wants real high method lookup performance will end up having to do something similar to the extent it wants to support this piece of the method lookup protocol. We will not provide any mechanisms to make this easy. As far as the interaction with `combined methods' goes I think its quite simple. Make-method-call actually expands something like this: (progn (make-method-call #)) (progn (apply-method-function # # # (method list) .args.)) The actual function (maybe called make-method-function) which converts the effective method form into something else takes care doing this expansion of make-method-call of course. But that function is not documented needless to say. I also don't think we should have a function like handler-for. I think that is too implementation specific. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 17:40:41 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 14 Apr 88 14:30:49 PDT Received: by ti.com id AA07954; Thu, 14 Apr 88 16:28:43 CDT Received: from Jenner by tilde id AA29151; Thu, 14 Apr 88 16:21:06 CDT Message-Id: <2786045229-9864708@Jenner> Date: Thu, 14 Apr 88 16:27:09 CDT From: Patrick H Dussud To: common-lisp-object-system@sail.stanford.edu Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD In-Reply-To: Msg of Thu, 14 Apr 88 15:01 EDT from "David A. Moon" I see. Here's another way to write it that might make what you're doing easier to understand: (defmethod compute-discriminator-code ((generic-function standard-generic-function)) (let ((f (get-handler-for #'compute-effective-method generic-function (generic-function-method-combination generic-function) nil))) #'(lambda (&rest args) (let* ((applicable-methods (compute-applicable-methods generic-function args)) (effective-method-form (funcall f generic-function (generic-function-method-combination generic-function) applicable-methods)) .... get-handler-for is a new primitive that provides a proper separation between the act of finding the effective method function and the act of applying it. This pulls the generic dispatch for compute-effective-method out of the loop. This is mere code hoisting, except that it shows where to put the special case to break the circularity. Reactions? I am not too concerned by the circularity. It amounts to a bootstrapping problem. All the chapter 3 generic function are instances of standard-generic-function. An implementation will code the discriminator code for standard generic functions in a way that it does not have to interpret its way through compute-applicable-method, compute-effective-method, etc. every time those standard-generic-functions are called. However it probably has to do it at least once sometimes. I don't think that the guts of compute-discriminator-code, and the code it produces should be standardized. I don't see any problem in exposing the sub primitives as long as they don't have to be not called every time a generic function is called. I think it should be explained the same way make-instance is explained: logically, things happen like this (gregor code, kempf code or moon's code), but implementations can short cut any of this as long as the desired effect is obtained. Patrick.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 17:01:54 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 13:52:24 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA24022; Thu, 14 Apr 88 13:51:22 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA19841; Thu, 14 Apr 88 13:50:41 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA00351; Thu, 14 Apr 88 13:44:09 PDT Message-Id: <8804142044.AA00351@suntana.sun.com> To: David A. Moon Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD In-Reply-To: Your message of Thu, 14 Apr 88 15:01:00 -0400. <19880414190146.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 14 Apr 88 13:44:07 -0700 From: kempf@Sun.COM >The method combination can be obtained from the generic function by >calling generic-function-method-combination, so the only reason to >pass it as an argument to compute-discriminator-code is if it's needed >for method selection. Right, so it can go back to just one parameter. >I see. Here's another way to write it that might make what you're doing >easier to understand: > > (defmethod compute-discriminator-code > ((generic-function standard-generic-function)) > (let ((f (get-handler-for #'compute-effective-method > generic-function > (generic-function-method-combination > generic-function) > nil))) > #'(lambda (&rest args) > (let* ((applicable-methods > (compute-applicable-methods generic-function args)) > (effective-method-form > (funcall f generic-function > (generic-function-method-combination > generic-function) > applicable-methods)) .... > >get-handler-for is a new primitive that provides a proper separation >between the act of finding the effective method function and the act of >applying it. This pulls the generic dispatch for >compute-effective-method out of the loop. This is mere code hoisting, >except that it shows where to put the special case to break the >circularity. Yes, this would be a more general primitive. This looks good. Reactions from others? Patrick, Gregor? It would be particularly interesting to hear how people feel about letting compute-discriminator-code and make-method-function negotiate their own contract for the calling interface in method metaclasses other than the default. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 15:11:39 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Apr 88 12:01:49 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382411; Thu 14-Apr-88 15:01:37 EDT Date: Thu, 14 Apr 88 15:01 EDT From: David A. Moon Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8804140006.AA21809@suntana.sun.com> Message-ID: <19880414190146.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Comments on the rest of your message later, but two comments now: Date: Wed, 13 Apr 88 17:06:22 -0700 From: kempf@Sun.COM 3) The creation of the dispatcher function is parameterized by both the generic function and the method combination. There is really no choice here, because the algorithm for calculating the effective method depends on both the list of applicable methods (which the generic function provides) and the method combination type. The method combination can be obtained from the generic function by calling generic-function-method-combination, so the only reason to pass it as an argument to compute-discriminator-code is if it's needed for method selection. I think some of the problems in the discussion about bottoming out of metacircularity come from the fact that we made method combination metacircular without taking into account that calculating the effective method, which is parameterized by method combination, is a fundamental part of generic dispatch, and therefore we introduced an infinite loop. This proposal unrolls the loop. I see. Here's another way to write it that might make what you're doing easier to understand: (defmethod compute-discriminator-code ((generic-function standard-generic-function)) (let ((f (get-handler-for #'compute-effective-method generic-function (generic-function-method-combination generic-function) nil))) #'(lambda (&rest args) (let* ((applicable-methods (compute-applicable-methods generic-function args)) (effective-method-form (funcall f generic-function (generic-function-method-combination generic-function) applicable-methods)) .... get-handler-for is a new primitive that provides a proper separation between the act of finding the effective method function and the act of applying it. This pulls the generic dispatch for compute-effective-method out of the loop. This is mere code hoisting, except that it shows where to put the special case to break the circularity. Reactions?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 14:58:23 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 11:47:19 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 14 APR 88 11:42:57 PDT Date: 14 Apr 88 11:42 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: dependent update protocol In-reply-to: David A. Moon 's message of Mon, 11 Apr 88 15:50 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880414-114257-18564@Xerox> I am answering Moon's message, but will only include the parts that I want to comment on. \Defmeth map-dependents ((instance updatable-object-mixin) function args) For all dependents of instance, applies function to instance, the dependent and args. It's usually better not to try to pass extra args through a mapping function; instead the function being mapped can be a closure that knows the extra args. This is more flexible, and is how all eight functions in CLtL whose names start with "map" work. Thus I would make map-dependents take only two arguments. (defmethod reinitialize-instance :around ((object updatable-object-mixin) &rest reinitargs) (let ((before (apply #'before-reinitialization object reinitargs))) (call-next-method) (let ((update-args (apply #'after-reinitialization object before reinitargs))) (map-dependents object #'update-dependent object update-args)))) I agree. I don't see how this can work if reinitialize-instance changes the set of dependents. The map-dependents will map over the new dependents, and any old dependents that were removed will never be updated. Maybe you can say that remove-dependent, or by convention each caller of it, calls update-dependent or a variant of it on the dependent being removed. I don't see this as a problem. The semantics of dependency that I see are that a dependent wants to know when its "master" changes. But if it is no longer a dependent, then it has no more "need to know". It may then become a dependent on something else, and will be updated at that time. If one wants to ensure that an object of type T1 takes special action when a dependency is removed, then an :after method on remove-dependent can do whatever is necessary. Also, since the style you propose depends on three methods for three different generic functions to be kept in sync, and does something unpredictable without necessarily signalling an error if one of the methods is left out, it doesn't seem very robust. I would prefer to see either a more abstract data structure than a list, so that leaving out a method (or forgetting to call cdr) for one class would not damage the data seen by other class's methods, or else to use one generic function instead of three, so that all the code for one class would be in a single place and hence less likely to be out of sync. In the latter case, this generic function would be called multiple times and one of its arguments would indicate whether state was being collected or distributed. The intent of the before-reinitialization is to capture the appropriate state of the instance before it changes, and that of after-reinitialization is to capture some summary of what changed (note that these methods only look at the state of the master object, and the inputs, not any dependent). An alternative I prefer (please comment) is to specify that before-reinitialization and after-reinitialization both return property lists. For example, I would specify that before-reinitialization for standard-class returns a property list that contains (at least) old direct-superclasses, direct-slots, and direct-options if these arguments are provided as reinit-args. After-reinitialization for standard-class returns a property list which has properties with value T for each of direct-superclasses, direct-slots, and direct-options if that info in the class changed. By specifying property lists, the shadowing properties are well undertood, and it is easy to arrange for noninterference with superclass properties. Also with this form, error checking can be implemented as property list or argument list checks.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 14:43:25 EDT Date: 14 Apr 88 1135 PDT From: Dick Gabriel Subject: Responses To: common-lisp-object-system@SAIL.Stanford.EDU last[cls,lsp] is a file with what I take to be remarks to which we must respond. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 14:39:37 EDT Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 14 Apr 88 11:30:39 PDT Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP id AA09658; Thu, 14 Apr 88 14:30:26 EDT Received: by mcvax.cwi.nl; Thu, 14 Apr 88 15:25:41 +0200 (MET) Received: from cl.cam.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa10821; 13 Apr 88 20:18 BST Via: harlqn; 13 Apr 88 20:16 BST (UK.AC.Cam.CL.Jenny) Received: from jung.harlqn.uucp (jung) by harlqn.uucp; Wed, 13 Apr 88 19:30:17 BST Received: by jung.harlqn.uucp (3.2/SMI-3.2) id AA15523; Wed, 13 Apr 88 19:28:50 BST Date: Wed, 13 Apr 88 19:28:50 BST Message-Id: <8804131828.AA15523@jung.harlqn.uucp> To: common-lisp-object-system@sail.stanford.edu From: Chris Richardson Sender: mcvax!harlqn.co.uk!chris@uunet.UU.NET Subject: CLOS consortium Some time ago I saw a news item proposing that a consortium should be set up to develop a high performance implementation of CLOS Has this proposal been developed further? Thanks. --chris richardson (ukc!harlqn!chris), Harlequin Ltd, England  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 13:30:34 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Apr 88 10:21:37 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 14 APR 88 10:18:50 PDT Date: 14 Apr 88 10:17 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: promises In-reply-to: Sonya E. Keene 's message of Thu, 14 Apr 88 09:06 EDT To: skeene@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880414-101850-18376@Xerox> I think we have to keep a record of all "official responses". We should make sure that we can extract these from the archive. But I think we need to ask Mathis what is official policy for X3. danny  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 13:01:47 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Apr 88 09:50:42 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382230; Thu 14-Apr-88 12:50:31 EDT Date: Thu, 14 Apr 88 12:50 EDT From: David A. Moon Subject: promises To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880414130645.8.SKEENE@JUNCO.SCRC.Symbolics.COM> Message-ID: <19880414165040.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 14 Apr 88 09:06 EDT From: Sonya E. Keene At the vote at the last meeting, we promised to respond to people's comments on Chapters 1 and 2 "in writing". Does this mean we can respond to them individually, or do we have to collect all the comments and responses and present that information to the X3J13 committee as a whole? I have yet to read the X3 rule book, but my guess would be that we should do the latter. To do that, we need to designate someone as the editor of this, to maintain the collection of information and make sure nothing has been lost. I've been saving the 3 or 4 pieces of electronic mail that seemed to belong to this. I understand there were also some written comments from Kathy Chapman. I'm not aware of any other comments received yet; has anyone received any?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 09:40:31 EDT Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 14 Apr 88 06:30:26 PDT Received: by multimax.ARPA (5.51/25-eef) id AA00517; Thu, 14 Apr 88 09:28:40 EDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382033; Thu 14-Apr-88 09:05:18 EDT Date: Thu, 14 Apr 88 09:04 EDT From: Sonya E. Keene Subject: Re: Chapter 1 and 2 Last Chance Review To: pierson%mist@MULTIMAX.ARPA Cc: skeene%STONY-BROOK.SCRC.Symbolics.COM@MULTIMAX.ARPA, common-lisp-object-system%sail.stanford.edu@MULTIMAX.ARPA In-Reply-To: <8804132136.AA01079@mist.UUCP> Message-Id: <19880414130455.7.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: Wed, 13 Apr 88 17:36:10 EDT From: Dan L. Pierson (2) Calls from outside the package may store incorrect types (so even if your portable code is self-consistent you could wind up with undetected type errors). I don't know what you mean by (2). Let's say you're implementing a window system which has slots WINDOW-WIDTH and WINDOW-HEIGHT. You define these slots to be of type integer *and* ensure that your code never puts a non-integer in them. You still have to explicitly check the type of the slot value every time any code that you didn't write could have run because a user program could have put a non-integer in the slot without getting an error in some implementations. OK. You're right, you would have to do that if you want to have portable code. You can do it pretty easily by defining two methods for the writer generic function yourself (instead of using an automatically-generated method). One method specializes the new value parameter on integer (the desired type of value), and writes the value into the slot. The other method doesn't specialize the new value parameter, so it gets selected on undesired types of values, and it signals an error. Or you could define a before-method on the writer that checks the type of the new value and signals an error if it isn't an integer. If it is an integer, the before-method just returns and lets the primary method write the value into the slot. If you do this type-checking in methods for accessors, you have to depend on your clients calling the accessors and not using slot-value.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Apr 88 09:15:14 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Apr 88 06:07:13 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 382034; Thu 14-Apr-88 09:07:06 EDT Date: Thu, 14 Apr 88 09:06 EDT From: Sonya E. Keene Subject: promises To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <19880414130645.8.SKEENE@JUNCO.SCRC.Symbolics.COM> At the vote at the last meeting, we promised to respond to people's comments on Chapters 1 and 2 "in writing". Does this mean we can respond to them individually, or do we have to collect all the comments and responses and present that information to the X3J13 committee as a whole?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 13 Apr 88 23:28:24 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 13 APR 88 20:18:02 PDT Return-Path: Redistributed: commonloops.pa Received: from ai.CEL.FMC.COM by Xerox.COM ; 13 APR 88 20:17:01 PDT Received: from unixb.CEL.FMC.COM (unixb.ARPA) by ai.CEL.FMC.COM with Sendmail (4.12/4.7) id AA01823; Wed, 13 Apr 88 20:16:32 pst Received: by unixb.CEL.FMC.COM with Sendmail (4.12/4.7) id AA00584; Wed, 13 Apr 88 20:16:27 pst From: sridhara@cel.fmc.com (Sridharan) Message-Id: <8804140416.AA00584@unixb.CEL.FMC.COM> Date: 13 Apr 88 20:16:25 PST (Wed) To: commonloops.pa@Xerox.COM Subject: delete name Please excise my name from this mailing list..it is interesting, but I need to cut out. Thanks, Sri N.S. Sridharan  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 20:25:34 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 17:14:46 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA11703; Wed, 13 Apr 88 17:13:40 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA24132; Wed, 13 Apr 88 17:12:59 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA21809; Wed, 13 Apr 88 17:06:24 PDT Message-Id: <8804140006.AA21809@suntana.sun.com> To: David A. Moon Cc: kempf@Sun.COM, common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD In-Reply-To: Your message of Wed, 13 Apr 88 14:31:00 -0400. <19880413183155.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 13 Apr 88 17:06:22 -0700 From: kempf@Sun.COM >But compute-effective-method has to be generic! That's the whole basis of >the meta-objectification of method combination. If this is another >non-terminating circularity, then it's another defect in the meta-circular >description of CLOS. In an implementation all these circularities have to >be broken by special-casing, as in any meta-circular interpreter. OK, I'll buy that. I misunderstood the specification for compute-effective-method. Further comment on the implications below, plus the special casing which is needed. >What compute-effective-method returns is neither a function nor a method >object. It actually returns a Lisp form. See 88-002 p.1-32. This Right. That explains what the undocumented function make-effective-method-function does in the example on pg. 3-59. It takes the generic function and the effective method form, and returns a function which can be applied to start the method rolling. It also hides the implementation dependencies necessary for setting up the environment so that call-next-method works. And that is where the metacircular recursion bottoms out, since it returns a function and not a generic function. >I can't be sure your code is wrong since I have >yet to see a satisfactory explanation of what compute-discriminator-code >is for. compute-discriminator-code does precisely the same thing for generic dispatch that compute-effective-method does for method combination. It is where code for customized generic dispatch gets generated. It needs to work together with make-method-function to assure that customized control flow changes like call-next-method get done correctly, because the generic dispatch code has to know what sort of interface the method functions require and what specialized features of the execution environment need to be set up. In the default case, make-effective-method-function takes care of most of that. Here's what I'd expect compute-discriminator-code to look like in the default case: (defmethod compute-discriminator-code ((generic-function standard-generic-function) (method-combination standard-method-combination) ) #'(lambda (&rest args) (let* ( (applicable-methods (compute-applicable-methods generic-function args) ) (effective-method-form (compute-standard-effective-method-form generic-function method-combination applicable-methods ) ) (effective-method-function (make-effective-method-function generic-function effective-method-form ) ) ) (check-keyword-arguments generic-function methods args) (apply effective-method-function args) ) ) ;lambda ) ; compute-discriminator-code There are a couple things to note here: 1) Everything called by compute-discriminator-code is a function. These are: compute-applicable-methods, compute-standard-effective-method-form, and make-effective-method-function. If this is not the case, the metacircularity does not bottom out. 2) New in this list is compute-standard-effective-method-form. It takes the generic function, a standard-method-combination object, and the list of applicable methods, and returns the effective method form. The compute-effective-method method for standard-method-combination would have the application of this function as its body. This is the special casing. Side note: the method combination object might not be needed as an argument, since the function already knows the kind of method combination. 3) The creation of the dispatcher function is parameterized by both the generic function and the method combination. There is really no choice here, because the algorithm for calculating the effective method depends on both the list of applicable methods (which the generic function provides) and the method combination type. 4) Functions similar to compute-standard-effective-method-form would be needed for other system provided method combination types, of course. I think some of the problems in the discussion about bottoming out of metacircularity come from the fact that we made method combination metacircular without taking into account that calculating the effective method, which is parameterized by method combination, is a fundamental part of generic dispatch, and therefore we introduced an infinite loop. This proposal unrolls the loop. As an example of how this could be used with make-method-function to introduce a customized control flow primitive, consider the following modification, which we had suggested in the specification paper. It allows any more general method to be invoked, depending on the arguments, rather than just the next most general method: ;;uses no method combination, and simply takes the first method ;; on the list to start the ball rolling. (defmethod compute-discriminator-code ((generic-function my-generic-function) method-combination) #'(lambda (&rest args) (let* ( (applicable-methods (my-compute-applicable-methods generic-function args) ) ) (apply (method-function (car applicable-methods)) (cdr applicable-methods) args ) ) ) ;lambda ) ; compute-discriminator-code (defmethod make-method-function ((method my-method) (generic-function my-generic-function) specializers qualifiers lambda-exp &optional macroexpand-env ) `(lambda (rest-applicable-methods &rest args) (flet ( (my-call-next-method (&rest call-args) (let* ( (matching-method (get-more-general-method rest-applicable-methods call-args) ) (next-rest-applicable-methods (member matching-method rest-applicable-methods) ) ) (if matching-method (apply (method-function matching-method) (cdr next-rest-applicable-methods) call-args ) (apply #'no-applicable-method ,generic-function call-args) ) ) ;let* ) ;my-call-next-method ) (apply (function ,lambda-exp) args) ) ;flet ) ;lambda ) ;make-method-function Here, compute-discriminator-code and make-method-function implement the communication of the applicable method list via a hidden argument. The only thing I don't like about this is that compute-discriminator-code returns a function object while make-method-function returns the code for a function (maybe the names should be interchanged?). But, given that function objects are atomic in Common Lisp, there probably isn't any better way to do this, except by having compute-discriminator-code return the code, so the caller would have to turn it into a function, or have make-method-function call eval on the code to make the function. Does this make any sense? The fact that we're having such a hard time converging on this is an indication to me that we're venturing into little understood territory. However, as Gregor mentioned, we need to come to convergence on this soon. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 17:43:27 EDT Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 13 Apr 88 14:34:58 PDT Received: by multimax.ARPA (5.51/25-eef) id AA04246; Wed, 13 Apr 88 17:35:02 EDT Received: from localhost by mist.UUCP (3.2/4.7) id AA01079; Wed, 13 Apr 88 17:36:12 EDT Message-Id: <8804132136.AA01079@mist.UUCP> To: "Sonya E. Keene" Cc: common-lisp-object-system%sail.stanford.edu@MULTIMAX.ARPA Subject: Re: Chapter 1 and 2 Last Chance Review In-Reply-To: Your message of Wed, 13 Apr 88 17:12:00 -0400. <19880413211239.3.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: Wed, 13 Apr 88 17:36:10 EDT From: Dan L. Pierson (2) Calls from outside the package may store incorrect types (so even if your portable code is self-consistent you could wind up with undetected type errors). I don't know what you mean by (2). Let's say you're implementing a window system which has slots WINDOW-WIDTH and WINDOW-HEIGHT. You define these slots to be of type integer *and* ensure that your code never puts a non-integer in them. You still have to explicitly check the type of the slot value every time any code that you didn't write could have run because a user program could have put a non-integer in the slot without getting an error in some implementations.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 17:23:50 EDT Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 13 Apr 88 14:14:11 PDT Received: by multimax.ARPA (5.51/25-eef) id AA04140; Wed, 13 Apr 88 17:13:39 EDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381660; Wed 13-Apr-88 17:13:02 EDT Date: Wed, 13 Apr 88 17:12 EDT From: Sonya E. Keene Subject: Chapter 1 and 2 Last Chance Review To: pierson%mist@MULTIMAX.ARPA Cc: common-lisp-object-system%sail.stanford.edu@MULTIMAX.ARPA In-Reply-To: <8804132019.AA00841@mist.UUCP> Message-Id: <19880413211239.3.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: Wed, 13 Apr 88 16:19:19 EDT From: Dan L. Pierson Comments on Chapters 1 and 2 of the CLOS Spec (Edition of 2/8/88) Hey, you actually read it! Thanks for the useful comments. Page 1-9, Add to the list of things provided by slot options and class options: o Specifying the legal data types of the slot contents. (Of course, this can be found elsewhere in the document, but my impression on reading this introductory list was that for some reason you couldn't do this.) Good idea. (I think originally this section was intended to be an overview of the more interesting features, but eventually all of the features got added except for the :type constraint.) Page 1-11, Paragraphs 3 and 7 Why are reader, writer, and with-slots *required* to be implemented using SLOT-VALUE? I don't doubt that you have a good reason, but it's not obvious to a relative novice. Some background is: we know that any implementation of CLOS will have to have a primitive that does what SLOT-VALUE does. Otherwise you couldn't implement readers or writers at all. So we document that primitive (SLOT-VALUE) so that all implementations give it the same name, arguments, and behavior, and therefore users can write portable code that calls it. The goal is to expose the underlying mechanisms if they are generally useful. The purpose of WITH-SLOTS is just to be a shortcut syntax for using SLOT-VALUE all over the place. It's "required" to be implemented with SLOT-VALUE because that's just the definition of what it does. As for why readers and writers are "required" to be implemented using SLOT-VALUE, hmmm, I'm not sure. I don't think there's any reason why you wouldn't implement readers and writers with SLOT-VALUE, since SLOT-VALUE does the thing you want to do. Paragraphs 7 and 8 This implies that WITH-SLOTS can access slots without accessors but WITH-ACCESSORS can't. This is reasonable but should probably be made explicit. Some people may feel that this maked WITH-SLOTS unsafe. The implication was intended; that's the difference between the two macros. I personally agree with people who feel WITH-SLOTS is unsafe. We could add a sentence to imply what we mean more directly. Page 1-13, Paragraph 4 This paragraph appears self-contradictory. I think that it means that portable code cannot depend on slot types since: (1) Some implementations may not provide type errors (therefore reducing the value of slot types for debugging), and Yes, it does mean (1). This is also said in the first bullet on page 1-13. (2) Calls from outside the package may store incorrect types (so even if your portable code is self-consistent you could wind up with undetected type errors). I don't know what you mean by (2). The wording of this paragraph leads me to suspect that this issue has already been argued to death on the CLOS list. (Don't let the wording fool you. We argue every issue to death.) Page 1-26, Paragraph 2, Sentence 2 The following are my exact notes as I read this section: What about methods in both old and new? Are they "added"? If so, in what way is this definition different from saying that the "contents" of the old generic function are trashed and replaced by the new generic function? AHA! Some methods could have been defined by DEFMETHOD, but the wording is still confusing. Your point about "some methods could have been defined by DEFMETHOD" is correct, and we should probably add a sentence to that effect. Page 1-32, At this point I made a note: In general, this draft details the complex, general case before the simpler, common special case. The section in page 1-32 doesn't present the simpler, common special case first and then get into details that include the hairy, rare cases. It does all cases at once. This is a very central part of CLOS, and it is somewhat complex, so readers are going to have to read the section on Method Selection and Combination a couple times or more. I think it's OK as it is. This *may* be appropriate for a standards document but it certainly isn't for a manual. Right. Manuals have a lot more freedom. Page 2-27, Next to last paragraph Can extension slot options appear more than once in a single slot description (it appears reasonable, but it's not clear from this whether it's legal). Last paragraph The slot can also be accessed by WITH-SLOTS, since WITH-SLOTS uses SLOT-VALUE. Do you think we need to say that explicitly? Since WITH-SLOTS is defined in terms of SLOT-VALUE, I think most readers will figure this out, as you did. Page 2-35, Paragraphs 7 and 8 These paragraphs don't specify how to distinguish a predicate from the first keyword option since they are both distinguished by being symbols other than * (or NIL).  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 16:53:29 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 13:43:51 PDT Received: from Semillon.ms by ArpaGateway.ms ; 13 APR 88 13:39:31 PDT Date: Wed, 13 Apr 88 13:38 PDT From: Gregor.pa@Xerox.COM Subject: add-named-xxx To: Patrick H Dussud cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <2785949234-4097219@Jenner> Message-ID: <880413133840.1.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: Wed, 13 Apr 88 13:47:14 CDT From: Patrick H Dussud Date: Fri, 8 Apr 88 14:52 EDT From: "David A. Moon" Subject: add-named-xxx Date: Mon, 4 Apr 88 11:20 PDT From: Gregor.pa@Xerox.COM After thinking about the above three paragraphs a bit, I think this is wrong modularity, by your own arguments. I think the caller of add-named-method should -always- call ensure-generic-function himself. That is, defmethod really consists of two parts, defining the generic function if not already defined, and defining/replacing the method. These two parts should not be combined in the macro expansion. Thus the arguments to add-named-method should be a prototype method (the usual kludge for class-discriminating methods) and some keyword arguments that include a generic function object, qualifiers, specializers, the method function, and some others that are optional. I agree with this proposal. At the meeting I proposed that the first argument be the generic function object, but I think now that this is better. It provides the right modularity between the class of the generic function and the class of the method. I also like this. We will put something like it in the next draft. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 16:27:40 EDT Received: from multimax.ARPA by SAIL.Stanford.EDU with TCP; 13 Apr 88 13:18:36 PDT Received: by multimax.ARPA (5.51/25-eef) id AA03659; Wed, 13 Apr 88 16:18:16 EDT Received: from localhost by mist.UUCP (3.2/4.7) id AA00841; Wed, 13 Apr 88 16:19:25 EDT Message-Id: <8804132019.AA00841@mist.UUCP> To: common-lisp-object-system%sail.stanford.edu@multimax Subject: Chapter 1 and 2 Last Chance Review Date: Wed, 13 Apr 88 16:19:19 EDT From: Dan L. Pierson Comments on Chapters 1 and 2 of the CLOS Spec (Edition of 2/8/88) Page 1-9, Add to the list of things provided by slot options and class options: o Specifying the legal data types of the slot contents. (Of course, this can be found elsewhere in the document, but my impression on reading this introductory list was that for some reason you couldn't do this.) Page 1-11, Paragraphs 3 and 7 Why are reader, writer, and with-slots *required* to be implemented using SLOT-VALUE? I don't doubt that you have a good reason, but it's not obvious to a relative novice. Paragraphs 7 and 8 This implies that WITH-SLOTS can access slots without accessors but WITH-ACCESSORS can't. This is reasonable but should probably be made explicit. Some people may feel that this maked WITH-SLOTS unsafe. Page 1-13, Paragraph 4 This paragraph appears self-contradictory. I think that it means that portable code cannot depend on slot types since: (1) Some implementations may not provide type errors (therefore reducing the value of slot types for debugging), and (2) Calls from outside the package may store incorrect types (so even if your portable code is self-consistent you could wind up with undetected type errors). The wording of this paragraph leads me to suspect that this issue has already been argued to death on the CLOS list. Page 1-26, Paragraph 2, Sentence 2 The following are my exact notes as I read this section: What about methods in both old and new? Are they "added"? If so, in what way is this definition different from saying that the "contents" of the old generic function are trashed and replaced by the new generic function? AHA! Some methods could have been defined by DEFMETHOD, but the wording is still confusing. Paragraph 6, Sentence 3 The wording is a bit confusing. Page 1-28, Paragraph 2, Sentence 4 and example line Has this been submitted to cleanup? I don't recognize it. Page 1.29, Paragraph 1 The wording implies that: (EQUAL '(A (B C)) '((A B) C)) is T, which is certainly false. Note that cleanup is entertaining proposal to flush EQUAL and EQUALP. Page 1-32, At this point I made a note: In general, this draft details the complex, general case before the simpler, common special case. This *may* be appropriate for a standards document but it certainly isn't for a manual. Page 2-27, Next to last paragraph Can extension slot options appear more than once in a single slot description (it appears reasonable, but it's not clear from this whether it's legal). Last paragraph The slot can also be accessed by WITH-SLOTS, since WITH-SLOTS uses SLOT-VALUE. Page 2-35, Paragraphs 7 and 8 These paragraphs don't specify how to distinguish a predicate from the first keyword option since they are both distinguished by being symbols other than * (or NIL).  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 14:54:50 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Apr 88 11:45:19 PDT Received: by ti.com id AA00317; Wed, 13 Apr 88 13:43:17 CDT Received: from Jenner by tilde id AA06124; Wed, 13 Apr 88 13:40:53 CDT Message-Id: <2785949234-4097219@Jenner> Date: Wed, 13 Apr 88 13:47:14 CDT From: Patrick H Dussud To: common-lisp-object-system@sail.stanford.edu Subject: add-named-xxx Date: Fri, 8 Apr 88 14:52 EDT From: "David A. Moon" Subject: add-named-xxx Date: Mon, 4 Apr 88 11:20 PDT From: Gregor.pa@Xerox.COM After thinking about the above three paragraphs a bit, I think this is wrong modularity, by your own arguments. I think the caller of add-named-method should -always- call ensure-generic-function himself. That is, defmethod really consists of two parts, defining the generic function if not already defined, and defining/replacing the method. These two parts should not be combined in the macro expansion. Thus the arguments to add-named-method should be a prototype method (the usual kludge for class-discriminating methods) and some keyword arguments that include a generic function object, qualifiers, specializers, the method function, and some others that are optional. I agree with this proposal. At the meeting I proposed that the first argument be the generic function object, but I think now that this is better. It provides the right modularity between the class of the generic function and the class of the method. Patrick.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 14:41:40 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Apr 88 11:32:15 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381489; Wed 13-Apr-88 14:31:48 EDT Date: Wed, 13 Apr 88 14:31 EDT From: David A. Moon Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD To: kempf@Sun.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8804131720.AA07908@suntana.sun.com> Message-ID: <19880413183155.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 13 Apr 88 10:20:48 -0700 From: kempf@Sun.COM .... In order for this to work, none of the functions from the metaobject protocol can be generic, otherwise the metacircularity doesn't terminate. So Gregor is correct in this point, and Chapter 3 is incorrect, since compute-effective-method can't be generic. But compute-effective-method has to be generic! That's the whole basis of the meta-objectification of method combination. If this is another non-terminating circularity, then it's another defect in the meta-circular description of CLOS. In an implementation all these circularities have to be broken by special-casing, as in any meta-circular interpreter. .... Minor niggle: compute-effective-method should probably be called compute-effective-method-function, since what it is returning is a function not a method object. What compute-effective-method returns is neither a function nor a method object. It actually returns a Lisp form. See 88-002 p.1-32. This probably means your example method for compute-discriminator-code is wrong because it returns the Lisp form, whereas the one in the version of chapter 3 that was distributed last month calls the effective method and returns the result. I can't be sure your code is wrong since I have yet to see a satisfactory explanation of what compute-discriminator-code is for. This is probably a digression from the main discussion, but I thought it could be important not to let this mistake go by, since it might affect the result of the main discussion.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 14:34:45 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 11:22:52 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 13 APR 88 11:16:06 PDT Date: 13 Apr 88 11:15 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Reinitialization In-reply-to: David A. Moon 's message of Mon, 11 Apr 88 20:35 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <880413-111606-16288@Xerox> I think Moon's summary was illuminating. Let me try to respond to several of the issues. (5) Do we really need four different updating functions? I think the answer is yes, because user-defined methods could quite plausibly do different things for each one. The only case I'm not sure of is whether class-changed and update-instance-structure really need to be distinguished by user-defined methods. Maybe they are only distinct because they take different arguments now. (6) Why do the four updating functions have such inconsistent interfaces? It makes sense for two of them to take initialization arguments and the other two to take before & after instance states, so the real issue is why don't class-changed and update-instance-structure take similar arguments? I believe that is only an artifact of the way CLOS evolved; when we abandoned the attempt to maintain a complete model of class redefinition history, we also stopped passing a copy of the instance with its old structure to update-instance-structure. That was because we didn't have any class to use for that instance. However, just as class-changed gets a temporary instance with potentially dynamic extent, update-instance-structure could get a temporary instance of a temporary class. That would be good, because the information about what slots were added and removed could be accessed through the normal Chapter 3 class examination functions, instead of through special kludgey property lists, and the values of slots could be accessed the normal way. Although I am reluctant to change Chapters 1 and 2, I think it would be justified to make update-instance-structure take two instances as arguments, the same as class-changed. We should also change the name of update-instance-structure to make it more analogous (e.g. class-redefined). It would probably also be okay to get rid of the distinction between class-changed and update-instance-structure and just have one generic function for both, although I haven't thought out the implications of that. We should be real careful here, as we did think all this stuff out moderately carefully and we may all have forgotten the reasons by now. The forgotten reasons had to do with how one could specify an obsolete class with the appropriate methods for the old instance. To take our old favorite example, suppose we wanted to change the definition of the class point. We start with: (defclass point () ((x :accessor point-x :initarg :x) (y :accessor point-y :initarg :y))) (defmethod point-rho ((p point)) ;;compute rho from x and y) (defmethod (setf point-rho) (new-rho (p point)) ;;compute new x and y) (defmethod point-theta ((p point)) ;;compute theta from x and y) (defmethod (setf point-theta) (new-theta (p point)) ;;compute new x and y) We make a few instances and change it to: (defclass point () ((rho :accessor point-rho) (theta :initarg point-theta))) (defmethod point-x ((p point)) ;;compute x from rho and theta) (defmethod (setf point-x) (new-x (p point)) ;;compute new rho and theta) (defmethod point-y ((p point)) ;;compute y from rho and theta) (defmethod (setf point-y) (new-y (p point)) ;;compute new rho and theta) (defmethod initialize-instance :after ((p point)) &key :x :y) ;; if x and y are provided, use (setf point-x) (setf point-y) ;; to compute the appropriate values for rho and theta ) Now, what methods remain on the class for old-point. We discussed copying (using) the old methods. But we bogged down in trying to understand how many other methods had to be copied in order to keep the original contract for point-rho and point-theta. If point-rho called the generic function (distance x y) and we later decided to change the name of this function to (euclidian-distance x y), what would have to happen for update-instance-structure to work on the old methods. We decided that there was no reasonable way to specify what it meant to keep around a copy of an obsolete-class and its methods, and therefore we had to use the list descriptions of the old instance. On the other hand, for class-changed, the methods and classes are current. Hence it is reasonable to leave in the users hands the problem of keeping the method for class-changed current. --- (2) What should be shared among the four updating functions? There are actually three different things: (a) the code to fill slots from initialization arguments (b) the code to fill slots from values of initialization forms (c) user-defined methods So far the discussion does not seem to have recognized that we are talking about three distinct things that could be shared. The thing we are talking about sharing is -not- simply the primary method for initialize-instance. Now, (a) only makes sense for initialize and reinitialize, since the other two don't have initialization arguments. (b) doesn't make sense for reinitialize in my opinion, and should only be done for newly added slots for class-changed and update-instance-structure, in my opinion (see issue 4). (c) definitely makes sense for all four, except that only initialize and reinitialize would pass initialization arguments to the user-defined methods. By the way, (c) is what Barry Margolin brought up at X3J13, so that's committee input to which we must respond. I want to argue, that under some control, all these make sense for all four updating functions. The control is simply the list-of-slots-to-consider argument that Moon proposed for initialize-slots-from-initforms. I will even be so bold as to suggest some new names, though I would not like to defend them at great cost. The four updating functions are: initialize-new-instance instance &rest initialization-arguments reinitialize-instance instance &rest initialization-arguments update-instance-structure instance added-slots discarded-slots property-list &rest initialization-arguments update-instance-with-new-class previous current &rest initialization-arguments These all call: initialize-instance instance slots-for-initform &rest initialization-arguments The value of slots-for-initform can be a list of slot-names (possibly nil) or T, which is equivalent to specifying all slots of the instance. For each slot on the list, if it is uninitialized, and it has an initfunction, it is initialized with the value of applying the initfunction to NIL. What value does each of each of the updating functions pass to initialize-intance for this argument. The call from initialize-new-instance passes T of course. The call from reinitialize-instance passes NIL The call from update-instance-structure passes added-slots The call from update-instance-with-new-class passes new-slots Gregor and I previously argued that reinitialize-instance should try to reinitialize all the slots that were unititialized. We claimed that this would allow a specialized reinitialization method to call slot-makunbound on just those slots wanted reinitialized. However, achieving this is still easy. The specialized method still makes these slots unbound, and passes along the list of slots that have been made unbound to initialize-instance. All four pass the initialization-arguments to initialize-instance. The call to update-instance-structure from the system of course passes NIL as the initialization-arguments. So does the call to update-instance-with-new-class. However, an :around method on either of these latter can compute some interesting initialization-arguments and do a call-next-method. As an example of the use, consider the following around method for update-instance-structure for point the above example: (defmethod update-instance-structure :around ((p point) ... ;;push :x and :y on the initarg list and call-next-method ) There is an obvious corresponding example for update-instance-with-new-class. The upshot is that there is one shared generic function for all four updaters. Code that is not to be shared is put in the updaters. Code that is to be shared is put in the shared function. Updating from initforms and from initialization-arguments can be controlled by what is passed to the shared code.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 14:04:13 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:54:16 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 13 APR 88 09:54:47 PDT Date: 13 Apr 88 09:54 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: two questions about standard-class In-reply-to: Sonya E. Keene 's message of Tue, 12 Apr 88 11:58 EDT To: skeene@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880413-095447-16103@Xerox> A class is considered initialized if its direct superclasses are known. I don't understand this; how can a class be defined without stating what its direct superclasses are? This is a NON-feature that was removed at the meeting. The old idea was to represent a forward-referenced-class as a class without any direct superclasses. It was to have been defined by using the functional level (add-named-class (symbol-class 'standard-class)) where direct-superclasses were not provided. But we decided to have aforward-referenced-class. CLOS now specifies that direct-superclases be known at creation time for a standard-class. I was also confused about class-default-direct-superclasses. I understand what it is supposed to do (the method for standard-class ensures that standard-object is included in the CPL). The documentation (page 3-14 on my draft) says if there are any supplied superclasses, this method returns the list of supplied superclasses and doesn't add standard-object to that list. If there are no supplied superclasses, this method returns a list containing standard object. The goal of this approach seems to be not to require standard-object to be a direct superclass of each class (otherwise the method would always add standard-object to the list). The assumption seems to be that if there is a supplied superclass, it already has standard-object in its CPL. Does this really work? What if you define a class and specify T to be the only direct superclass? The intention is that this should be made to work. It requires the following not all of which are spelled out explicitly in the writing. 1) Any class in the kernel that is implemented as a standard-class must have standard-object in its class-precedence list. The only exception is the class T, if that class is implemented as a standard-class. 2) It is not legal to specify T as a direct superclass of a standard class. 3) In the kernel, the only legal superclass of a standard-class is a standard-class. Since all existing standard-classes that can be used as a superclass have standard-object in their class-precedence-list, if class-default-direct-superclasses provides standard-object as a direct-supreclass when no direct-superclasses are specified, this invariant continues to hold. Of course, it is possible to program around this restriction using the MOP. [Whatever the answer to the question, if I stated the goal of the approach correctly, it should probably be written down in the documentation.] Right.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 13:42:34 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:32:50 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381401; Wed 13-Apr-88 13:32:32 EDT Date: Wed, 13 Apr 88 13:32 EDT From: Sonya E. Keene Subject: corrections to Chapter 1 To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <19880413173208.7.SKEENE@JUNCO.SCRC.Symbolics.COM> The section "Determining the Class Precedence List" has examples where defclass is used to define classes, and the CPL is computed from those definitions. However, the CPLs shown don't include standard-object (they do include t). We should really fix this. The table in Figure 1-1 has two columns, labelled "Predefined Common Lisp Type" and "Class Precedence List". The first column heading isn't right; actually, it is correct, but it misses the point. They are Common Lisp types, but the important thing is that CLOS has classes corresponding to those types. I think that column heading should be simply "Classes" or "Predefined Classes" (since "Classes Corresponding to Common Lisp Types" is too long). ----------- Also, the section "Standard Meta-objects" says "The class named standard-object is an instance of the class standard-class and is a superclass of every class that is an instance of standard-class except itself." I believe that the MOP (p 3-10) contradicts this statement, since the class structure-object is an instance of the class standard-class, yet it doesn't have standard-object as a superclass. [The previous paragraph seems related to my other message. It seems like there are some exceptions to the general rules that are not clearly spelled out. There is a general rule that for instances of standard-class, all superclasses have to have the same metaclass; but the implied superclass T is an exception. There is a general rule that all instances of standard-class include standard-object as a superclass; but structure-class is an exception.]  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 13:40:39 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:28:59 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA04134; Wed, 13 Apr 88 10:28:19 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA10548; Wed, 13 Apr 88 10:27:30 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA07908; Wed, 13 Apr 88 10:20:50 PDT Message-Id: <8804131720.AA07908@suntana.sun.com> To: common-lisp-object-system@sail.stanford.edu Subject: Re: MAKE-METHOD-FUNCTION and APPLY-METHOD Date: Wed, 13 Apr 88 10:20:48 -0700 From: kempf@Sun.COM I read back over the mail and did some further thinking on this, and I've got some additional thoughts on the subject, and a miniproposal. First to respond to the immediate nature of Gregor's message, I agree with his point that the code for generic dispatch and the method function interface are intertwined. Since the code for generic dispatch has the job of calculating the list of applicable methods and the effective method (according to Chapter 1), it also has the job of arranging where that information appears in the environment of the method function. Some of the possibilities for where to put it are a "hidden" argument to the method function, a "hidden" lexical variable in the method function's environment which the generic dispatch code accesses via some implementation dependent interface, etc. So, for purposes of arranging for changes in control flow such as call-next-method, it is not possible to seperate the code doing the dispatching from the method function interface. I think it might be helpful at this point to briefly review the concepts, functions and macros in Chapters 1, 2, and 3 related to this topic to see how they fit together. First some definitions from Chapter 1: Applicable Methods-Given a generic function invocation, the list of applicable methods are all methods defined on the generic function whose parameter specializers are satisfied by their corresponding arguments. The definition of "satisfy" is given in Chapter 1, pg. 1-28. Effective Method-The effective method is a combination of the applicable methods according to their precedence order. It is the code actually executed during the generic function invocation. Calculating it is the subject of Chapter 1, pp. 1-31-1-35. Note that these definitions make no mention of dispatcher functions (or handlers, as they are called in Flavors) nor of method functions. Generic dispatch is a process, which results in the calculation of the list of applicable methods and the effective method, and the application of the effective method to the arguments. Dispatcher functions, precalculation of the list of applicable methods, etc. are all optimizations, which must preserve the semantics of this model in order to be valid. In practice, a dispatcher function is needed to bundle the control flow associated with generic dispatch into one place, however. Now how does this all fit into the metaobject protocol of Chapter 3? In Chapter 3, pp. 3-59-3-61 list the generic functions. There are three of interest: compute-applicable-methods compute-effective-method These compute the two quantities defined in Chapter 1. compute-discriminator-code What does this do? Well, the description in Chapter 3 isn't very clear. The example uses make-effective-method-function, which isn't documented anywhere else, and in the invocation of compute-effective-method the actual parameter list does not match the formal parameter interface described below the example. Here's my guess as to how the default method should look: (defmethod compute-discriminator-code ((generic-function standard-generic-function)) (let ( (method-combination-object (generic-function-method-combination generic-function) ) ) #'(lambda (&rest args) (let ( (methods (compute-applicable-methods generic-function args) ) ) (check-keyword-arguments generic-function methods args) (apply #'compute-effective-method generic-function method-combination-object methods ) ) ) ;lambda ) ;let ) ; compute-discriminator-code In order for this to work, none of the functions from the metaobject protocol can be generic, otherwise the metacircularity doesn't terminate. So Gregor is correct in this point, and Chapter 3 is incorrect, since compute-effective-method can't be generic. The appropriate place for specializations is in compute-dispatcher-code. Compute-effective-method and compute-applicable-methods bundle whatever implementation dependent mechanism is required to make sure that the environment of method functions has the necessary information for call-next-method to happen correctly. Minor niggle: compute-effective-method should probably be called compute-effective-method-function, since what it is returning is a function not a method object. However, Patrick and Dave also have a point, in that there needs to be some way for creating method functions which installs the special processing needed to implement call-next-method into the user supplied code. Perusing Chapter 1 for a moment, we find two macros which look as if they might help: make-method
call-method From the description, these look like hooks into the innards of compute-effective-method, however, precisely how they might fit in, I can't figure out. So we are, indeed, left with a hole in the metaobject protocol which Patrick's proposed make-method-function would fill. Here is the interface again: make-method-function &optional This should return a perfectly vaild function which is compilable and funcallable, with the exception that it may need to be funcalled by the function returned by compute-discriminator-code to work properly. The fundamental idea here is that compute-discriminator-code and make-method-function scheme together to make sure the right code is generated for unusual changes in control flow like call-next-method. Both are generic functions, with compute-discriminator-code specialized on its first argument and make-method-function specialized on its first and second. Of course, this analysis overlooks one fundamental point. There are no primitives in Common Lisp for arranging the transfer of information needed for things like call-next-method because Common Lisp doesn't have first class environments. I've got some ideas about simulating this, but they're not firm so I won't make this lengthy message even more lengthy by including them. The miniproposal is this: 1) compute-effective-method, compute-applicable-methods, and check-keyword-arguments are all functions. 2) make-method-function is implemented as Dave and Patrick have outlined. 3) We figure out how call-method and make-method from Chapter 1 fits into the metaobject protocol. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 13:18:59 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Apr 88 10:10:12 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381364; Wed 13-Apr-88 13:09:57 EDT Date: Wed, 13 Apr 88 13:09 EDT From: Sonya E. Keene Subject: two questions about standard-class To: skeene@STONY-BROOK.SCRC.Symbolics.COM, common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880412155813.0.SKEENE@JUNCO.SCRC.Symbolics.COM> Message-ID: <19880413170930.6.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: Tue, 12 Apr 88 11:58 EDT From: Sonya E. Keene A class is considered initialized if its direct superclasses are known. I don't understand this; how can a class be defined without stating what its direct superclasses are? I was also confused about class-default-direct-superclasses. I understand what it is supposed to do (the method for standard-class ensures that standard-object is included in the CPL). The documentation (page 3-14 on my draft) says if there are any supplied superclasses, this method returns the list of supplied superclasses and doesn't add standard-object to that list. If there are no supplied superclasses, this method returns a list containing standard object. The goal of this approach seems to be not to require standard-object to be a direct superclass of each class (otherwise the method would always add standard-object to the list). The assumption seems to be that if there is a supplied superclass, it already has standard-object in its CPL. Does this really work? What if you define a class and specify T to be the only direct superclass? Well, you can't do that with defclass, anyway, since Chapter 1 states that you can't use defclass to define subclasses of a built-in class, and t is a built-in class. However, I don't know whether you can do the same thing some other way, using the MOP. (later... the 3rd paragraph below makes me think there is a way) I'm having trouble understanding some of the ramifications of T being a built-in class. It seems strange that you can't specify T as a superclass in the defclass form, yet you get T automatically as a superclass (by virtue of it being a superclass of standard-object). The MOP states that standard-object is a standard-class. This implies that there must be some way to define a standard-class (eg standard-object) and include a built-in class (eg t) as a superclass. This mechanism must be different than the normal make-instance of standard-class, because that calls valid-superclass-p, which signals an error if the metaclass of the superclass is not EQ with the class being defined. Or else the method for valid-superclass-p should make an exception for the class T. [Whatever the answer to the question, if I stated the goal of the approach correctly, it should probably be written down in the documentation.]  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 11:56:52 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Apr 88 08:48:06 PDT Received: by ti.com id AA29239; Wed, 13 Apr 88 10:45:12 CDT Received: from Jenner by tilde id AA03273; Wed, 13 Apr 88 10:23:42 CDT Message-Id: <2785937331-3382088@Jenner> Date: Wed, 13 Apr 88 10:28:51 CDT From: Patrick H Dussud To: Gregor.pa@xerox.com Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: method-lambda and apply-method-lambda In-Reply-To: Msg of Tue, 12 Apr 88 10:21 PDT from Gregor.pa@xerox.com We have to find some way to converge on this soon. My basic point is that the genericity should be at the level of add-method and compute-discriminator-code and that at the level of making method functions and calling method functions the code should not be generic. I don't understand your position here. Here is the issue the way I see it: - The fact that a generic function calls an effective method establishes a contract between these two entities. - This contract has to be abstracted because the implementor should be free to optimize this time critical operation. - We want to give access to this operation, namely one wants to call a method that belongs to a generic function, with its own set of arguments, with his own set of next methods (apply-method-lambda). - We want to give programmers the use of (setf method-function), which is concerned by the above contract (make-method-function). In 88-003 the following pieces are connected to this contract besides apply-method-lambda and make-method-function: - Compute-discriminator-code, whose result is a piece of code,which when executed does the method lookup and the calling of the effective method function object. - Add-method is connected to this protocol because it needs to make sure that the method added to the generic function will fulfill its part of the contract. Add-method and compute-discriminator code are generic. Add-method behavior ( deciding if a method is acceptable to the generic function) is implemented by specialized methods. Compute-discriminator-code will implement its part of the contract with specialized methods. Now you tell me that the other portions of the pieces connected to the contract should be wired in for standard-method and standard-generic-function, and there is no standard way to call a method, compatible with a generic function, if the method is not a standard-method and if the generic function is not a standard-generic-function. I strongly object to this attitude because: One implementation can define a new pair of (generic-function, method) that have their own contract (In theory, you write a method on compute-discriminator-code and add-method), but any portable code that would want to call such a method would fail because they are using the wrong function. Worse, a user has NO WAY of telling if he can use apply-method-lambda on a (generic-function, method) pair, unless: (and (eql (class-of generic-function) (symbol-class 'standard-generic-function)) (eql (class-of method) (symbol-class 'standard-method))) is true. In my opinion, it breaks one of the goals of the metaclass design: One can write some portable tools that can use the introspection capability of MOP. We may as well forbid any specialization of standard-generic-function and standard-method. Patrick.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 13 Apr 88 11:20:28 EDT Received: from Semillon.ms by ArpaGateway.ms ; 13 APR 88 08:12:22 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 13 APR 88 08:09:47 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA01194; Wed, 13 Apr 88 08:08:41 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA05564; Wed, 13 Apr 88 08:08:06 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA07797; Wed, 13 Apr 88 08:01:33 PDT Message-Id: <8804131501.AA07797@suntana.sun.com> To: common-lisp-object-system@sail.stanford.edu, commonloops.pa@Xerox.COM Subject: Announcing New Journal on Object-Oriented Programming Date: Wed, 13 Apr 88 08:01:31 -0700 From: kempf@Sun.COM For those of you who have not yet heard, there is a new journal dedicated to object-oriented programming. The name is the Journal of Object-Oriented Programming and the address is: Journal of Object-Oriented Programming P.O. Box 66338 Woodland Park, CO 80866 303-687-2517 The editor in chief is Dr. Richard Wiener from U. Colorado at Colorado Springs. People who have interesting applications using the PCL implementation of CLOS, New Flavors, or other Lisp object-oriented languages are encouraged to send in manuscripts. You can also send them to me if you want, since I'm the review board representative for Lisp. The first issue is due out in May, and it is targeted for 6 issues a year, in case you care to subscribe. Editorial Comment: I think it is extremely important that people in the object-oriented programming community using Lisp based object-oriented languages become more visible. Many of the more technically innovative uses of object-oriented programming are coming from Lisp users, but the object-oriented community at large often ignores Lisp object-oriented programmers. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Apr 88 11:17:22 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Apr 88 08:09:21 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA01194; Wed, 13 Apr 88 08:08:41 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA05564; Wed, 13 Apr 88 08:08:06 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA07797; Wed, 13 Apr 88 08:01:33 PDT Message-Id: <8804131501.AA07797@suntana.sun.com> To: common-lisp-object-system@sail.stanford.edu, commonloops.pa@xerox.com Subject: Announcing New Journal on Object-Oriented Programming Date: Wed, 13 Apr 88 08:01:31 -0700 From: kempf@Sun.COM For those of you who have not yet heard, there is a new journal dedicated to object-oriented programming. The name is the Journal of Object-Oriented Programming and the address is: Journal of Object-Oriented Programming P.O. Box 66338 Woodland Park, CO 80866 303-687-2517 The editor in chief is Dr. Richard Wiener from U. Colorado at Colorado Springs. People who have interesting applications using the PCL implementation of CLOS, New Flavors, or other Lisp object-oriented languages are encouraged to send in manuscripts. You can also send them to me if you want, since I'm the review board representative for Lisp. The first issue is due out in May, and it is targeted for 6 issues a year, in case you care to subscribe. Editorial Comment: I think it is extremely important that people in the object-oriented programming community using Lisp based object-oriented languages become more visible. Many of the more technically innovative uses of object-oriented programming are coming from Lisp users, but the object-oriented community at large often ignores Lisp object-oriented programmers. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 13 Apr 88 11:12:52 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 13 APR 88 07:53:43 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 13 APR 88 07:52:14 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM, CJoor@WILMA.BBN.COM, MThome@WILMA.BBN.COM, RShapiro@WILMA.BBN.COM, tmitchell@WILMA.BBN.COM, marcos@austin.lockheed.com, treinhardt@labs-n.bbn.com Subject: flavor problem Date: Wed, 13 Apr 88 10:51:10 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880413-075343-15951@Xerox> I tried adding the flavor code in your message and ran into a bug when compiling defmethod allocate-instance (in slots.lisp) does %%allocate-iwmc--class (or something). Anyway, this produces code that tries to dump # which has a locative in its hash-address entry that the dumper can't dump. k  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Apr 88 21:46:16 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Apr 88 18:35:47 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381003; Tue 12-Apr-88 21:33:57 EDT Date: Tue, 12 Apr 88 21:34 EDT From: David A. Moon Subject: Re: Reinitialization To: kanderso@WILMA.BBN.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: The message of 12 Apr 88 20:42 EDT from kanderso@WILMA.BBN.COM Message-ID: <19880413013405.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 12 Apr 88 20:42:08 -0400 From: kanderso@WILMA.BBN.COM Please correct me if i'm wrong, i've been trying to trying to follow this discussion from the outside. Are you talking about a reinitialization protocal in general, or about reinitialization of classes or methods when they change? Maybe I should let Gregor answer, since it was his idea. Both. The immediate goal is to codify how classes and generic functions change (not methods; for some reason method objects are immutable instead of being redefinable like the other two major kinds of meta objects.) However, the idea is to codify this in terms of a generalized reinitialization mechanism that can also be used for other things, by users.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Apr 88 20:58:14 EDT Received: from WILMA.BBN.COM ([128.89.1.216]) by SAIL.Stanford.EDU with TCP; 12 Apr 88 17:48:37 PDT To: "David A. Moon" cc: Common-Lisp-Object-System@sail.stanford.edu Subject: Re: Reinitialization In-reply-to: Your message of Tue, 12 Apr 88 18:20:00 -0400. <19880412222014.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 12 Apr 88 20:42:08 -0400 From: kanderso@WILMA.BBN.COM Please correct me if i'm wrong, i've been trying to trying to follow this discussion from the outside. Are you talking about a reinitialization protocal in general, or about reinitialization of classes or methods when they change? I can think of a lot of different initialization behavior besides those two: after allocation for a resource (i was something else before, now i'm expected to behave like this), when a simulation object is reset to some initial state, etc. Maybe what they have is common is to abstract [vague], so there is very little behavior of value to share, otherwise we would have agreed on something by now. So my question is, should we consider each of these types of initialization as separate? Perhaps, after we fill them out, we'll see the similarities. k  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Apr 88 18:29:39 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Apr 88 15:20:24 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380883; Tue 12-Apr-88 18:20:05 EDT Date: Tue, 12 Apr 88 18:20 EDT From: David A. Moon Subject: Re: Reinitialization To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <8804122152.AA07085@suntana.sun.com> Message-ID: <19880412222014.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 12 Apr 88 14:52:35 -0700 From: kempf@Sun.COM > (a) initialize-slots-from-initargs instance &rest initialization-arguments > (b) initialize-slots-from-initforms instance list-of-slots-to-consider > (c) normalize-instance instance &rest initialization-arguments I like this seperation, except I'm not sure what you have in mind for normalize-instance? This a-b-c was parallel with the other one, so normalize-instance is where the user-defined methods for the shared part of initialization go. The default method would be a no-op.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Apr 88 18:12:17 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 12 Apr 88 15:02:25 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA21618; Tue, 12 Apr 88 15:01:21 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA21712; Tue, 12 Apr 88 14:59:48 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA07085; Tue, 12 Apr 88 14:52:40 PDT Message-Id: <8804122152.AA07085@suntana.sun.com> To: David A. Moon Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: Reinitialization In-Reply-To: Your message of Mon, 11 Apr 88 20:35:00 -0400. <19880412003504.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 12 Apr 88 14:52:35 -0700 From: kempf@Sun.COM Couple responses/questions > (a) initialize-slots-from-initargs instance &rest initialization-arguments > (b) initialize-slots-from-initforms instance list-of-slots-to-consider > (c) normalize-instance instance &rest initialization-arguments I like this seperation, except I'm not sure what you have in mind for normalize-instance? >Another question is whether (a) and (b) should be >generic, and if so whether they should dispatch on the instance or on >the class. Yes, I think they should. Example: a persistance metaclass which wanted to initialize slots in a database. Certainly, this could be done in bulk by specializing initialize, but the programmer might also want it done in the other cases as well. >(4) A subtle semantic change to class-changed and update-instance-structure >has been proposed, specifically that unbound slots that are not new should >be filled from their initforms instead of being left unbound. I'm opposed I don't recall having seen the change, but I agree with your arguments against it. >One is that I'm opposed to making any >changes in the first two chapters unless there is a good reason; I want >that part of the CLOS spec to be over and done with. This is also the best reason for keeping the four updating functions. >(6) Why do the four updating functions have such inconsistent interfaces? >It makes sense for two of them to take initialization arguments and the I agree with your proposed changes, but, again, this would involve changes in Chapters 1 & 2. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 12 Apr 88 15:28:45 EDT Received: from Salvador.ms by ArpaGateway.ms ; 12 APR 88 12:17:37 PDT Return-Path: <@CONGER.bbn.com:kanderson@VAX.BBN.COM> Redistributed: CommonLoops.pa Received: from CONGER.bbn.com by Xerox.COM ; 12 APR 88 12:16:29 PDT Received: from R&B.bbn.com by CONGER.bbn.com via CHAOS with CHAOS-MAIL id 44327; Tue 12-Apr-88 14:53:48 EDT Date: Tue, 12 Apr 88 14:53 EDT From: Kenneth R. Anderson Subject: Symbolics set-funcallable-instance-function bug To: CommonLoops.pa@Xerox.COM Message-ID: <880412145325.1.KANDERSON@R&B.bbn.com> ;;; KRA: CL:LENGTH dies in ENDP as it should, while zl:LENGTH doesn't. (defun set-funcallable-instance-function (fin new-value) (cond ((not (funcallable-instance-p fin)) (error "~S is not a funcallable-instance" fin)) ((not (functionp new-value)) (error "~S is not a function." new-value)) ((and (si:lexical-closure-p new-value) (compiled-function-p (si:lexical-closure-function new-value))) (let* ((fin-env (si:lexical-closure-environment fin)) (new-env (si:lexical-closure-environment new-value)) (new-env-size (zl:length new-env)) ; KRA (fin-env-size #.(- funcallable-instance-closure-size ; KRA: constant. (length funcallable-instance-data)))) (cond ((<= new-env-size fin-env-size) (dotimes (i fin-env-size) (setf (sys:%p-contents-offset fin-env i) (and (< i new-env-size) (sys:%p-contents-offset new-env i)))) (setf (si:lexical-closure-function fin) (si:lexical-closure-function new-value))) (t (set-funcallable-instance-function fin (make-trampoline new-value)))))) (t (set-funcallable-instance-function fin (make-trampoline new-value)))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 12 Apr 88 14:17:25 EDT Received: from Semillon.ms by ArpaGateway.ms ; 12 APR 88 11:06:01 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 12 APR 88 11:02:52 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: 3600 walk-template patch Date: Tue, 12 Apr 88 13:53:33 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880412-110601-14202@Xerox> ;;; From walk.lisp: ;;; RShapiro: On Symbolics (setf (foo bar) baz) macroexpands into ;;; (funcall #'(setf foo) bar baz) when foo is a flavor instance accessor. ;;; the walker would convert this to (funcal #'(setq foo) bar baz). (defun walk-template (form template context env) (if (atom template) (ecase template ((EVAL FUNCTION TEST EFFECT RETURN) (walk-form-internal form :EVAL env)) ((QUOTE NIL) form) (SET (walk-form-internal form :SET env)) ((LAMBDA CALL) (cond ((symbolp form) form) #+symbolics ((and (listp form) (eq (car form) 'setf) (null (cddr form))) form) (t (walk-form-internal form context env))))) (case (car template) (REPEAT (walk-template-handle-repeat form (cdr template) ;; For the case where nothing happens ;; after the repeat optimize out the ;; call to length. (if (null (cddr template)) () (nthcdr (- (length form) (length (cddr template))) form)) context env)) (IF (walk-template form (if (if (listp (cadr template)) (eval (cadr template)) (funcall (cadr template) form)) (caddr template) (cadddr template)) context env)) (REMOTE (walk-template form (cadr template) context env)) (otherwise (cond ((atom form) form) (t (recons form (walk-template (car form) (car template) context env) (walk-template (cdr form) (cdr template) context env))))))))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Apr 88 13:36:29 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 12 Apr 88 10:27:34 PDT Received: from Semillon.ms by ArpaGateway.ms ; 12 APR 88 10:23:05 PDT Date: Tue, 12 Apr 88 10:21 PDT From: Gregor.pa@Xerox.COM Subject: method-lambda and apply-method-lambda To: David A. Moon cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <19880412005526.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <880412102105.6.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: Mon, 11 Apr 88 20:55 EDT From: David A. Moon There's something missing from your message. Isn't the only reason make-method-function and apply-method were proposed (by you originally, Gregor) to allow users to interject code between the method lookup and the method invocation, for instance when tracing? Otherwise there would be no need to standardize these little pieces of the implementation of generic functions when we don't standardize all the rest of it. I believe that I originally proposed method-lambda and apply-method as unspecializable interfaces to the standard kind of method. I still (or once again) believe that all we need is some sort of unspecializable interface to the implementation specific calling sequence for standard methods. This will allow two things: 1) users can generate method functions which can be used by the implementation's own method lookup and invocation code. (method-lambda or make-method-function) 2) users can call the implementations own method functions if they want to (usually for some sort of debugging or tracing purposes). (apply-method-function) While I still like method lambda (for the reasons I stated in a previous message), I am willing to accept your argument that: Right. I agree that the two properties Gregor proposes sound important, but I believe that it is impossible to achieve those properties. I think that the attempt to achieve those properties is why we've been having trouble converging here. Giving up those properties will make the problem much easier, and I don't think it means giving up anything that matters. and am willing to accept your suggestion that the criterion we should shoot for are: I think the -only- assertions guaranteed about the value returned by MAKE-METHOD-FUNCTION should be: - COMPILE works on it - the FUNCTION special form works on it - it and the result of compiling it are members of the type FUNCTION - APPLY-METHOD works on it and on the result of compiling it - it and the result of compiling it can be used as the :method-function when creating or reinitializing a method meta-object Which means I am proposing that have make-standard-method-function as an unspecializable function whose result has the above properties and apply-standard-method-function as an unspecializable function which can be used to apply them. I also think the next methods argument to apply-standard-method-function should be a list since I don't see any real advantage to making an abstraction for it. Remember that in this scheme, it is clear that apply-standard-method-function is not really the mechanism used by standard method lookup. Rather it is a hook which the standard lookup mechanism provides for unpriveledged callers of the method functions. So I think the abstraction barrier isn't between method lookup and method invocation, but rather between those two mechanisms on the one hand and user-written code on the other. But this only says why these two functions should exist, not whether they should be generic or not. Right. I agree that the method lookup mechanism and the method invocation mechanism need to understand each other in detail. What I don't understand is how that has any bearing on whether or not these two functions should be generic, i.e. whether or not there should exist more than one method invocation mechanism. I guess I don't understand PCL's compute-discriminator-code generic function, since I don't understand how specializing that could affect what parameters the compiler makes a method-function accept. The idea is not that specializing compute-discriminator-code can "affect what parameters the compiler makes a method-function accept". Rather, the idea is that for a given method on compute-discriminator-code there is a certain kind of method function (and corresponding calling sequence) which is appropriate. A given class of generic function states (by having an appropriate method on add-method) whether or not it is willing to contract with the calling sequence of a given class of method's functions. If there is such a method on add-method, it is a declaration that the compute-discriminator-code method for that class of generic function can handle that class of method. In conclusion, while I agree with all of your message that I understood, it doesn't seem to me to have any bearing on the issue it was supposed to be about. Obviously I missed something big that you thought was there. We have to find some way to converge on this soon. My basic point is that the genericity should be at the level of add-method and compute-discriminator-code and that at the level of making method functions and calling method functions the code should not be generic. I am afraid I am just restating myself, but perhaps I have clarified some part of what I was trying to say? -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 12 Apr 88 13:07:16 EDT Received: from Semillon.ms by ArpaGateway.ms ; 12 APR 88 09:52:35 PDT Date: Tue, 12 Apr 88 09:47 PDT From: Gregor.pa@Xerox.COM Subject: iwmc-class-p bug again To: kanderso@WILMA.BBN.COM cc: CommonLoops.pa@Xerox.COM, kanderson@WILMA.BBN.COM, rshapiro@WILMA.BBN.COM, pci-people%atc.alcoa.com@relay.cs.net, jmattson@WILMA.BBN.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: The message of 11 Apr 88 17:19 PDT from kanderso@WILMA.BBN.COM Message-ID: <880412094755.5.GREGOR@SPIFF.parc.xerox.com> Line-fold: no For 3600 users only. Date: Mon, 11 Apr 88 20:19:08 -0400 From: kanderso@WILMA.BBN.COM I think we patched this once, and someone else did too, and his patch got accepted: Patch to 3600-low.lisp (scl:defsubst iwmc-class-p (x) (and (arrayp x) (eq (scl:named-structure-p x) 'iwmc-class))) In the next release of PCL, this is going to be changed to use flavor's instances instead of structures as the `header' for PCL instances. This changes resulted in a moderate performance improvement for method lookup on the 3600. Method lookup in the one argument case is now about 5.5 times the time of a corresponding function call. People who would like to try this new, higher performance implementation of instances should replace the defsubst of iwmc-class-p with the following code. Then you will need to recompile pcl with (compile-pcl 'low) to make sure enough stuff gets recompiled. ;from 3600-low.lisp (scl:defflavor iwmc-class ((wrapper nil) (static-slots nil) (dynamic-slots ())) () (:constructor %%allocate-instance--class()) :ordered-instance-variables) (defvar *iwmc-class-flavor* (flavor:find-flavor 'iwmc-class)) (scl::defsubst iwmc-class-p (x) (and (sys:instancep x) (eq (sys:%instance-flavor x) *iwmc-class-flavor*))) (scl:defmethod (:print-self iwmc-class) (stream depth slashify) (declare (ignore depth slashify)) (print-object scl:self stream nil)) (defmacro %iwmc-class-class-wrapper (iwmc-class) `(sys:%instance-ref ,iwmc-class 1)) (defmacro %iwmc-class-static-slots (iwmc-class) `(sys:%instance-ref ,iwmc-class 2)) (defmacro %iwmc-class-dynamic-slots (iwmc-class) `(sys:%instance-ref ,iwmc-class 3)) (scl:compile-flavor-methods iwmc-class) -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Apr 88 12:07:05 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Apr 88 08:58:50 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380543; Tue 12-Apr-88 11:58:34 EDT Date: Tue, 12 Apr 88 11:58 EDT From: Sonya E. Keene Subject: two questions about standard-class To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <19880412155813.0.SKEENE@JUNCO.SCRC.Symbolics.COM> A class is considered initialized if its direct superclasses are known. I don't understand this; how can a class be defined without stating what its direct superclasses are? I was also confused about class-default-direct-superclasses. I understand what it is supposed to do (the method for standard-class ensures that standard-object is included in the CPL). The documentation (page 3-14 on my draft) says if there are any supplied superclasses, this method returns the list of supplied superclasses and doesn't add standard-object to that list. If there are no supplied superclasses, this method returns a list containing standard object. The goal of this approach seems to be not to require standard-object to be a direct superclass of each class (otherwise the method would always add standard-object to the list). The assumption seems to be that if there is a supplied superclass, it already has standard-object in its CPL. Does this really work? What if you define a class and specify T to be the only direct superclass? [Whatever the answer to the question, if I stated the goal of the approach correctly, it should probably be written down in the documentation.]  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Apr 88 22:53:41 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 APR 88 19:40:47 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 11 APR 88 19:37:34 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM, rshapiro@WILMA.BBN.COM, pci-people%atc.alcoa.com@relay.cs.net, jmattson@WILMA.BBN.COM Subject: iwmc-class-p bug again Date: Mon, 11 Apr 88 20:19:08 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880411-194047-13073@Xerox> I think we patched this once, and someone else did too, and his patch got accepted: Patch to 3600-low.lisp #|| Received-from-host: GEFILTE RSHAPIRO@GEFILTE.BBN.COM 4/11/88 13:07:31 There's a serious bug with IWMC-CLASS-P which unfortunately send ZMACS into the debugger in certain circumstances, and thus needs to be fixed more or less immediately. The problem is its call to SCL:NAMED-STRUCTURE-SYMBOL (see file >pcl>new>3600-low). If I have presentation actions on a clos class in context T (that is, they can happen anytime at all), and I'm in ZMACS, and I point the mouse at a string (or presumably any other array) I get thrown into the debugger when SCL:NAMED-STRUCTURE-SYMBOL gets called with the string. If SCL:NAMED-STRUCTURE-SYMBOL is replaced by SCL:NAMED-STRUCTURE-P it should work (this is not a predicate, as the name suggests: it returns the structure name iff the object is indeed a named structure), but unfortunately IWMC-CLASS-P is a subst and so references to it need to be recompiled as well.... ||# (scl:defsubst iwmc-class-p (x) (and (arrayp x) (eq (scl:named-structure-p x) 'iwmc-class)))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Apr 88 22:53:26 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 11 APR 88 19:39:02 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 11 APR 88 19:37:42 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM, pci-people%atc.alcoa.com@relay.cs.net, jmattson@WILMA.BBN.COM Subject: cboundp & symbol-class Date: Mon, 11 Apr 88 20:24:37 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880411-193902-13072@Xerox> ;;; Patch added to the end of high.lisp: ;;; KRA: Obvious extensions to PCL to make it a bit more like CLOS chapter 2. (export 'cboundp 'pcl) (defun cboundp (symbol &optional environment) (declare (ignore environment)) ;; "The function CBOUNDP returns TRUE or FALSE." (if (class-named symbol t) t)) (export 'symbol-class 'pcl) (defun symbol-class (symbol &optional environment) (declare (ignore environment)) (class-named symbol t))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 21:05:29 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 17:55:47 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380320; Mon 11-Apr-88 20:55:19 EDT Date: Mon, 11 Apr 88 20:55 EDT From: David A. Moon Subject: method-lambda and apply-method-lambda To: Gregor.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <880411161708.3.GREGOR@SPIFF.parc.xerox.com> Message-ID: <19880412005526.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No There's something missing from your message. Isn't the only reason make-method-function and apply-method were proposed (by you originally, Gregor) to allow users to interject code between the method lookup and the method invocation, for instance when tracing? Otherwise there would be no need to standardize these little pieces of the implementation of generic functions when we don't standardize all the rest of it. So I think the abstraction barrier isn't between method lookup and method invocation, but rather between those two mechanisms on the one hand and user-written code on the other. But this only says why these two functions should exist, not whether they should be generic or not. I agree that the method lookup mechanism and the method invocation mechanism need to understand each other in detail. What I don't understand is how that has any bearing on whether or not these two functions should be generic, i.e. whether or not there should exist more than one method invocation mechanism. I guess I don't understand PCL's compute-discriminator-code generic function, since I don't understand how specializing that could affect what parameters the compiler makes a method-function accept. In conclusion, while I agree with all of your message that I understood, it doesn't seem to me to have any bearing on the issue it was supposed to be about. Obviously I missed something big that you thought was there.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 20:48:20 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 17:35:07 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380302; Mon 11-Apr-88 20:34:57 EDT Date: Mon, 11 Apr 88 20:35 EDT From: David A. Moon Subject: Reinitialization To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <19880323170326.4.MOON@EUPHRATES.SCRC.Symbolics.COM>, <880405173737.1.GREGOR@SPIFF.parc.xerox.com>, The message of 6 Apr 88 13:43 EDT from Dick Gabriel , <880406125216.9.GREGOR@SPIFF.parc.xerox.com>, <880406194011.3.GREGOR@SPIFF.parc.xerox.com>, <880407-100805-6877@Xerox>, <880407103428.1.GREGOR@SPIFF.parc.xerox.com>, <8804071913.AA01613@suntana.sun.com>, The message of 7 Apr 88 17:51 EDT from Dick Gabriel , <880407191422.6.GREGOR@SPIFF.parc.xerox.com>, <880407191538.7.GREGOR@SPIFF.parc.xerox.com>, <8804081541.AA02698@suntana.sun.com>, <8804081903.AA03057@suntana.sun.com>, <880408-153713-9540@Xerox> Message-ID: <19880412003504.0.MOON@EUPHRATES.SCRC.Symbolics.COM> I've been reading this mail, but I haven't said anything because it's all pretty confusing and I've been thinking. So far I've identified seven different relevant issues that we've been discussing here. I'll list them and offer my own opinion on each one. I almost feel I shouldn't send this, as it's still pretty confusing. However, since it's been a week I'm probably not doing anyone any good by keeping this to myself. When I say "the four updating functions", I mean initialize-instance, reinitialize-instance, class-changed, and update-instance-structure. (1) How much should be shared among the four updating functions? My original complaint was that too much was shared, when reinitialize-instance simply called initialize-instance. Then we noticed that the other two updating functions don't share anything, but could. I agree that all four should share something, but not everything (i.e. none of the four updating functions should call one of the others). This issue doesn't seem to be controversial. However, after you see what's below maybe you'll decide that trying to share anything is hopeless and we'd be better off duplicating some code rather than complexifying the language. (2) What should be shared among the four updating functions? There are actually three different things: (a) the code to fill slots from initialization arguments (b) the code to fill slots from values of initialization forms (c) user-defined methods So far the discussion does not seem to have recognized that we are talking about three distinct things that could be shared. The thing we are talking about sharing is -not- simply the primary method for initialize-instance. Now, (a) only makes sense for initialize and reinitialize, since the other two don't have initialization arguments. (b) doesn't make sense for reinitialize in my opinion, and should only be done for newly added slots for class-changed and update-instance-structure, in my opinion (see issue 4). (c) definitely makes sense for all four, except that only initialize and reinitialize would pass initialization arguments to the user-defined methods. By the way, (c) is what Barry Margolin brought up at X3J13, so that's committee input to which we must respond. The most straightforward thing to do here would be to provide -three- shared functions: (a) initialize-slots-from-initargs instance &rest initialization-arguments (b) initialize-slots-from-initforms instance list-of-slots-to-consider (c) normalize-instance instance &rest initialization-arguments [Never mind the names, that's issue 7] The primary method for initialize-instance would call all three. The primary method for reinitialize-instance would call (a) and (c). The primary methods for class-changed and update-instance-structure would call (b) and (c), but the second argument to (b) would be only the added local slots and (c) would be called with only one argument. Maybe we don't need quite this much mechanism. For instance, (a) and (c) could be combined if the name of (a) didn't contain the word "slots", except that the primary method for initialize-instance ought to call (b) between (a) and (c). Another question is whether (a) and (b) should be generic, and if so whether they should dispatch on the instance or on the class. (c) obviously is generic and dispatches on the instance. If (a) and (b) don't have to be generic, a radical proposal that I think should be considered would be to move them back into the implementation dependent part of the system so that they need not be named in the standard. I don't have a proposal to make on issue (2) at this time. I hope I've clarified what we're talking about, though. (3) We've discussed several clever/kludgey ways to tweak the shared code so it behaves differently for each of the four updating functions. I don't think any of them should be adopted. I only suggested this by analogy with slot-missing and because of the excessive sharing between initialize and reinitialize. If I had thought it out before sending my message I would not have suggested it. Once things are modularized correctly, I don't think this extra hair would be used and I don't think we want to put it into the language. (4) A subtle semantic change to class-changed and update-instance-structure has been proposed, specifically that unbound slots that are not new should be filled from their initforms instead of being left unbound. I'm opposed to this change, for two reasons. One is that I'm opposed to making any changes in the first two chapters unless there is a good reason; I want that part of the CLOS spec to be over and done with. The second is that I think an unbound slot should be treated the same as a slot with a value in it, except when you read it. By that rule, it's as wrong for class-changed to bash unbound slots as it would be for it to bash slots with values in them. As far as I know the only reason for proposing this change was that it appeared to simplify the sharing issue. I don't think that would be a good enough reason for a semantic change even if, after we understand the sharing issue, it turns out to be true. (5) Do we really need four different updating functions? I think the answer is yes, because user-defined methods could quite plausibly do different things for each one. The only case I'm not sure of is whether class-changed and update-instance-structure really need to be distinguished by user-defined methods. Maybe they are only distinct because they take different arguments now. (6) Why do the four updating functions have such inconsistent interfaces? It makes sense for two of them to take initialization arguments and the other two to take before & after instance states, so the real issue is why don't class-changed and update-instance-structure take similar arguments? I believe that is only an artifact of the way CLOS evolved; when we abandoned the attempt to maintain a complete model of class redefinition history, we also stopped passing a copy of the instance with its old structure to update-instance-structure. That was because we didn't have any class to use for that instance. However, just as class-changed gets a temporary instance with potentially dynamic extent, update-instance-structure could get a temporary instance of a temporary class. That would be good, because the information about what slots were added and removed could be accessed through the normal Chapter 3 class examination functions, instead of through special kludgey property lists, and the values of slots could be accessed the normal way. Although I am reluctant to change Chapters 1 and 2, I think it would be justified to make update-instance-structure take two instances as arguments, the same as class-changed. We should also change the name of update-instance-structure to make it more analogous (e.g. class-redefined). It would probably also be okay to get rid of the distinction between class-changed and update-instance-structure and just have one generic function for both, although I haven't thought out the implications of that. We should be real careful here, as we did think all this stuff out moderately carefully and we may all have forgotten the reasons by now. (7) What are good names for these five functions, the four updating ones and the shared one? I spent some time thinking about this without satisfactory results. Possible words for the shared operation could be prepare, normalize, renew, reconcile, settle, adjust, adapt, setup, or tidy. None of those really works. Another idea would be to call the shared operation initialize-instance and rename the function that make-instance calls to initialize-new-instance or instance-made. There is also this incoherence between class-changed ("something happened") and just about all the other names ("do something"). I think we're still waiting for a good idea here, and maybe we should first settle the modularity before we pick the names. The problem is that the existing names color one's ideas about what the modularity should be. We're also rapidly approaching the day when we shouldn't change names because of the programmer retraining problem.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Apr 88 19:57:12 EDT Received: from Semillon.ms by ArpaGateway.ms ; 11 APR 88 16:45:01 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 11 APR 88 16:39:19 PDT To: CommonLoops.pa@Xerox.COM cc: pci-people%atc.alcoa.com@relay.cs.net, jmattson@WILMA.BBN.COM, kanderson@WILMA.BBN.COM Subject: PCL - CLOS differences Date: Mon, 11 Apr 88 19:33:38 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880411-164501-12804@Xerox> Date: Mon, 11 Apr 88 17:38:37 -0400 From: kanderso@WILMA.BBN.COM Here are some differences between PCL and CLOS Chapter 2 that i compiled for our users. k ----- cut here ---- DIFFERENCES BETWEEN PCL AND CLOS CHAPTER 2: See #P"NOTES.TEXT" for a description of the latest changes to PCL. * indicates forms that are not available in 3/17/88 St. Patrick's Day PCL X indicates forms that are not available in PCL, but that an extension is available. ADD-METHOD * CALL-METHOD * CALL-NEXT-METHOD X CBOUNDP ; See also CLASS-NAMED. CHANGE-CLASS * CLASS-CHANGED CLASS-NAME (SETF CLASS-NAME) CLASS-OF * CMAKUNBOUND DEFCLASS * DEFGENERIC ; See MAKE-SPECIALIZABLE * DEFINE-METHOD-COMBINATION ; :BEFORE :AFTER :AROUND combinations only. DEFMETHOD ; Use DEFMETHOD-SETF for setf methods. DESCRIBE DOCUMENTATION (SETF DOCUMENTATION) ENSURE-GENERIC-FUNCTION * GENERIC-FLET * GENERIC-FUNCTION * GENERIC-LABELS GET-METHOD INITIALIZE-INSTANCE * INVALID-METHOD-ERROR MAKE-INSTANCE * MAKE-INSTANCES-OBSOLETE * MAKE-METHOD * METHOD-COMBINATION-ERROR * METHOD-QUALIFIERS * NEXT-METHOD-P * NO-APPLICABLE-METHOD PRINT-OBJECT REMOVE-METHOD SLOT-BOUNDP SLOT-EXISTS-P * SLOT-MAKUNBOUND SLOT-MISSING * SLOT-UNBOUND SLOT-VALUE X SYMBOL-CLASS ; See also CLASS-NAMED. * SYMBOL-MACROLET * UPDATE-INSTANCE-STRUCTURE * WITH-ACCESSORS ; Use WITH-ACCESSORS*, see #P"NOTES.TEXT" * WITH-ADDED-METHODS WITH-SLOTS ; Use WITH-SLOTS*, see #P"NOTES.TEXT" Other useful forms not described in the CLOS spec: TRACE-METHOD UNTRACE-METHOD COMPILE-METHOD UNDEFMETHOD UNDEFMETHOD-SETF On LISPM, EMACS commands "M-X kill definition" and "M-." should work. ------- End of Forwarded Message  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 19:33:25 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 16:23:59 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 APR 88 16:17:46 PDT Date: Mon, 11 Apr 88 16:17 PDT From: Gregor.pa@Xerox.COM Subject: method-lambda and apply-method-lambda To: David A. Moon cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <19880411210955.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <880411161708.3.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: Mon, 11 Apr 88 17:09 EDT From: David A. Moon Patrick wanted the implementation-dependent calling sequence for method functions to be under meta-object control, which is why he proposed make-method-function to be generic. I should have noticed this before, unfortunately it didn't jump out at me till over this weekend though. In thinking about this even further, I have concluded that the basic idea of having make-method-function and apply-method be generic functions is flawed. This message tries to explore the reasoning behind this conclusion. The basic conclusion is that the abstraction which Patrick and David's proposal (the proposal) was trying to provide is inappropriate. It is trying to place an abstraction barrier between the method lookup mechanism and the method invocation mechanism, and it turns out it isn't a good idea to put an abstraction barrier there. Lets start by looking carefully at the abstraction the proposal is trying to provide. It is trying to prevent the generic function's method lookup mechanism from having to know the calling sequence of the actual methods. We might have thought that it was trying to protect the actual generic function from having to know the calling sequence of the method, but the fact that make-method-function takes the generic function as its first argument shows that that isn't true. Now we have to decide whether it makes sense for the actual method calling sequence to be isolated from the generic function's method lookup mechanism. I will argue that it doesn't. The basic reason is that the method lookup mechanism and the method calling sequence `want' to be intimately connected. For example, the method lookup mechanism is supremely qualified to be looking up the next-method-info; but in the abstraction presented by the proposal, the actual method calling sequence must do that lookup itself. It isn't clear how one could implement a high performance method lookup and invocation mechanism which also had to pass special information using this protocol. Now lets look at the case where one wants to have a different kind of method on a generic function, where that different kind of method has a different calling sequence. In the proposal, if the different kind of method has a different calling sequence, the class of the generic function will have to be different (make-method-function takes the generic function as its only specializable argument). Using the mop as written up (sort of) and implemented in PCL, the generic function would also have to have a special class, and the method lookup and invocation code would both be specialized by specializing the single generic function compute-discriminator-code. As mentioned two paragraphs above, this is likely to have higher performance as well. I think that the way to think about this is to acknowledge that generic functions must understand the calling needs of their methods. This seems quite reasonable since they must already understand when to call their methods. In order to have methods which have special calling needs, one must have a special class of generic function which understands their calling needs. Understanding their calling needs can be thought of as part of the contract which the generic function entered into when it agreed to have the method as one of its methods. It could be argued that my argument is based on the existing arguments to make-method-function and apply-method; that by changing the proposal so that those generic functions accepted only the method as arguments, it would be possible to specialize only the method to have a special calling sequence. This may be true, but the real point of my argument is that this isn't a good architecture because it separates the method lookup mechanism from the method invocation mechanism in an unatural way. In addition, the proposal has some other problems which I began to surface in my last message. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 19:13:37 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 16:04:19 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380246; Mon 11-Apr-88 19:03:59 EDT Date: Mon, 11 Apr 88 19:04 EDT From: David A. Moon Subject: Re: method-lambda and apply-method-lambda To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8804112133.AA05721@suntana.sun.com> Message-ID: <19880411230405.9.MOON@EUPHRATES.SCRC.Symbolics.COM> [Sorry about the length of this message. I couldn't find anything to delete without losing the sense of the conversation.] Date: Mon, 11 Apr 88 14:33:03 -0700 From: kempf@Sun.COM > APPLY-METHOD method next-method-info &REST arguments I don't think this generic function is really necessary, since APPLY, being itself implementation dependent, could be modified to do the right thing given a method function. Jim, I think you must have missed the point. The problem isn't that what APPLY does is implementation-dependent, but that the arguments to be passed to APPLY are implementation-dependent. The most obvious case is the next-method-info info; there is no way for APPLY to deduce this from the other arguments, is there? If there is a way, I might change my mind on suggesting a separate APPLY-METHOD primitive, but if there isn't a way, we have to have that primitive so that the caller can supply the information. Why does the next method info have to be passed as arguments to APPLY or an APPLY-like function in the first place? I thought the whole purpose of MAKE-METHOD-FUNCTION was to return a function for which that information has already been installed in the (some) environment, or maybe I'm missing something. And that NEXT-METHOD-INFO gets it. MAKE-METHOD-FUNCTION can only depend on static information, which is the same every time the method is called. That's because MAKE-METHOD-FUNCTION is called once and the result is stored as the method-function conceptual-slot of the method meta-object. MAKE-METHOD-FUNCTION isn't called every time the generic function is called, as I understand it. The NEXT-METHOD-INFO is dynamic information since it depends on what other methods are also applicable, which can vary from one call to the next. Some implementations of APPLY already must differentiate based on whether the function object is a closure or not, since in the former case, the lexical environment must be modified to reflect the lexical environment of the closure, so the additional case of a method function is probably nothing new. However, it might be useful for metaobject programmers who want a hook for a metaclass specific way of applying a method. In that case, I think the NEXT-METHOD-INFO argument could be dropped, since the concept of a next method is specific to STANDARD-METHOD. I disagree. I think CALL-NEXT-METHOD should be available to all classes of methods that want it; I don't think it should be something magic for standard-method. No, I didn't mean to imply that CALL-NEXT-METHOD would be magic. Look, here's my vanillia implementation for MAKE-METHOD-FUNCTION for STANDARD-METHOD: (defmethod make-method-function ((proto-method standard-method) (generic-function standard-generic-function) specializers qualifiers lambda-exp &optional macroexpand-env ) `(flet ( (call-next-method (&rest args) (if (check-args args ',specializers) (apply (get-next-method-function ',proto-method) args) (apply #'no-applicable-method ',generic-function args) ) ) ) ,lambda-exp ) ) The only "magic" here is GET-NEXT-METHOD-FUNCTION, and I can't think of any other way to keep track of the next method function unless the method knows about it's next method itself (though there may be some ways to speed up getting it, but this is a specification). Is there something I'm missing here? Maybe there's something I'm missing, because I can't imagine what the implementation of GET-NEXT-METHOD-FUNCTION could possibly be. I just don't see from where it can figure out what method to call. That depends on the current method's position in the precedence-ordered list of applicable methods with relevant qualifiers, and I don't see how GET-NEXT-METHOD-FUNCTION can find either of those quantities. That's why I think there has to be a "next-method-info" object that gets passed around as an extra argument. One implementation of call-next-method would be to funcall the car of next-method-info, passing the cdr of next-method-info to it. CLOS shouldn't mandate that it be a list, though. The method metaclass method for this generic function would then implement any special processing for changing control flow. I don't think I understand this last sentence; do you have a specific proposal? (defmethod apply-method ((method standard-method) &rest arguments) (apply (method-function method) arguments) ) Other metaclasses might want to control method application via their method metaclass object, but the default would be not to. I still don't understand, but that's probably irrelevant for now. I think I've got a different (and perhaps wrong?) model about what's going on. My model is that MAKE-METHOD-FUNCTION constructs a function in which the metaclass dependent specialized control flow primitives (e.g. CALL-NEXT-METHOD) are part of the lexical environment seen by the user code (LAMBDA-EXP). That's my model too. Any other system dependent information needed to influence control flow (e.g. permutation tables) would also need to be included, but naming access controlled so only system code sees it. Agreed (except permutation tables may be only for data access, not for control flow; that in fact depends on the implementation, and we have tried it both ways. Right now we do some control flow there and other control flow elsewhere.) NEXT-METHOD-INFO, or whatever the accessor function is named, is able to get at that information in some implementation dependent way. Agreed. Thus, the method function should be invokable via APPLY, with APPLY-METHOD more of a utility should a metaobject user happen to have a method and not want to retieve the function. want to use it. No hidden arguments to APPLY needed. Non-sequitur. The fact that CALL-NEXT-METHOD is part of the lexical environment does not mean that the body of CALL-NEXT-METHOD contains no free variables. Indeed, since CALL-NEXT-METHOD in a given method does not do the same thing every time it is called, it must depend in some way on a free variable or the equivalent. A lot of this discussion is about how to model that free variable and how abstract to be about it. For instance, if we wanted to totally constrain implementation techniques, we could do something like setf-functions and say "every method-function takes one extra argument, before the arguments visible in defmethod, and the value of this argument is a list of method functions. The parameter bound to this argument is named CLOS-SYSTEM-INTERNALS::NEXT-METHOD-LIST and CALL-NEXT-METHOD works by funcalling its car, passing its cdr as the first argument." I don't think being so concrete would be wise, and I don't think it's necessary either. We shouldn't say what form that information is represented in (maybe it's an array rather than a list, maybe the entries are method meta-objects, rather than method-functions, or maybe the entries are machine program counter values), and we shouldn't say through what path the information is delivered (maybe it's passed in machine register A5, rather than being passed as a Lisp argument; maybe it's stashed in a special variable). But we do have to recognize that the information exists and if we want to be able to do things like tracing methods we have to provide a way to transmit the information from one function to another. Okay, where does this mysterious "information" come from in the first place? My model is that the generic function dispatch produces not only a method function to be called, but also this extra information to be passed to it. Thus it's a function of the argument classes (or identities) that gets precomputed and stored in the method lookup tables. Just as we don't dictate that any particular form of method lookup tables be used, even though every implementation has to have them in some form, we shouldn't dictate any particular form of this information, nor should we dictate whether it is precomputed or calculated on demand when call-next-method is done (if you were assuming we always calculate it on demand, you have to think about what information is required to calculate it).  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 17:51:33 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 14:41:20 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA05758; Mon, 11 Apr 88 14:40:16 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA23028; Mon, 11 Apr 88 14:39:42 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA05721; Mon, 11 Apr 88 14:33:05 PDT Message-Id: <8804112133.AA05721@suntana.sun.com> To: David A. Moon Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: method-lambda and apply-method-lambda In-Reply-To: Your message of Mon, 11 Apr 88 13:56:00 -0400. <19880411175624.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 11 Apr 88 14:33:03 -0700 From: kempf@Sun.COM > APPLY-METHOD method next-method-info &REST arguments I don't think this generic function is really necessary, since APPLY, being itself implementation dependent, could be modified to do the right thing given a method function. Jim, I think you must have missed the point. The problem isn't that what APPLY does is implementation-dependent, but that the arguments to be passed to APPLY are implementation-dependent. The most obvious case is the next-method-info info; there is no way for APPLY to deduce this from the other arguments, is there? If there is a way, I might change my mind on suggesting a separate APPLY-METHOD primitive, but if there isn't a way, we have to have that primitive so that the caller can supply the information. Why does the next method info have to be passed as arguments to APPLY or an APPLY-like function in the first place? I thought the whole purpose of MAKE-METHOD-FUNCTION was to return a function for which that information has already been installed in the (some) environment, or maybe I'm missing something. And that NEXT-METHOD-INFO gets it. Some implementations of APPLY already must differentiate based on whether the function object is a closure or not, since in the former case, the lexical environment must be modified to reflect the lexical environment of the closure, so the additional case of a method function is probably nothing new. However, it might be useful for metaobject programmers who want a hook for a metaclass specific way of applying a method. In that case, I think the NEXT-METHOD-INFO argument could be dropped, since the concept of a next method is specific to STANDARD-METHOD. I disagree. I think CALL-NEXT-METHOD should be available to all classes of methods that want it; I don't think it should be something magic for standard-method. No, I didn't mean to imply that CALL-NEXT-METHOD would be magic. Look, here's my vanillia implementation for MAKE-METHOD-FUNCTION for STANDARD-METHOD: (defmethod make-method-function ((proto-method standard-method) (generic-function standard-generic-function) specializers qualifiers lambda-exp &optional macroexpand-env ) `(flet ( (call-next-method (&rest args) (if (check-args args ',specializers) (apply (get-next-method-function ',proto-method) args) (apply #'no-applicable-method ',generic-function args) ) ) ) ,lambda-exp ) ) The only "magic" here is GET-NEXT-METHOD-FUNCTION, and I can't think of any other way to keep track of the next method function unless the method knows about it's next method itself (though there may be some ways to speed up getting it, but this is a specification). Is there something I'm missing here? The method metaclass method for this generic function would then implement any special processing for changing control flow. I don't think I understand this last sentence; do you have a specific proposal? (defmethod apply-method ((method standard-method) &rest arguments) (apply (method-function method) arguments) ) Other metaclasses might want to control method application via their method metaclass object, but the default would be not to. I think I've got a different (and perhaps wrong?) model about what's going on. My model is that MAKE-METHOD-FUNCTION constructs a function in which the metaclass dependent specialized control flow primitives (e.g. CALL-NEXT-METHOD) are part of the lexical environment seen by the user code (LAMBDA-EXP). Any other system dependent information needed to influence control flow (e.g. permutation tables) would also need to be included, but naming access controlled so only system code sees it. NEXT-METHOD-INFO, or whatever the accessor function is named, is able to get at that information in some implementation dependent way. Thus, the method function should be invokable via APPLY, with APPLY-METHOD more of a utility should a metaobject user happen to have a method and not want to retieve the function. want to use it. No hidden arguments to APPLY needed. Anyway, let me know if this is making sense, or if it's only a result of allergic reaction to springtime pollen. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 17:16:49 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 14:09:59 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380099; Mon 11-Apr-88 17:09:44 EDT Date: Mon, 11 Apr 88 17:09 EDT From: David A. Moon Subject: method-lambda and apply-method-lambda To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <880411134332.8.GREGOR@SPIFF.parc.xerox.com> Message-ID: <19880411210955.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 11 Apr 88 13:43 PDT From: Gregor.pa@Xerox.COM The major problem I have is with making apply-method be a generic function. It seems to me that doing this will prevent the metacircularity from `bottoming out'. Patrick wanted the implementation-dependent calling sequence for method functions to be under meta-object control, which is why he proposed make-method-function to be generic. If make-method-function can select from among several calling sequences, apply-method has to know which one to use, which is the reason to make it generic too. We should see what Patrick says, but it seems to me that either both of those functions should be generic or neither should be. I have no opinion of my own on whether the implementation-dependent calling sequence for method functions should be under meta-object control. But if apply-method is a generic function, how is it itself implemented? Clearly there is an infinite recursion if the standard method is not special-cased. Since this is a meta-circular system, that's no surprise, is it? Would this be the first place where a standard method had to be special-cased? (That is not a rhetorical question; I don't know the answer and I'm wondering.)  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 16:53:59 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 13:44:10 PDT Received: from Semillon.ms by ArpaGateway.ms ; 11 APR 88 13:44:08 PDT Date: Mon, 11 Apr 88 13:43 PDT From: Gregor.pa@Xerox.COM Subject: method-lambda and apply-method-lambda To: David A. Moon cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <19880408221409.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <880411134332.8.GREGOR@SPIFF.parc.xerox.com> Line-fold: no I have several minor questions with this proposal and one major one. I will start with the major one since I think it addresses an important characteristic of the proposal. The minor ones can be dealt with in a later message. The major problem I have is with making apply-method be a generic function. It seems to me that doing this will prevent the metacircularity from `bottoming out'. This is illustrated by the YES answer to the following question: - Are standard generic functions guaranteed to call apply-method? Yes: But if apply-method is a generic function, how is it itself implemented? No: Then why bother having apply-method be a generic function, what does it really buy me? This is why the proposal include in the draft MOP had apply-method being a function. It seemed to me that the code that called it was `below the level of metacircularity' in the evaluator. One way of seeing this is that the current design of the MOP has no generic function invocations happening during the invocation of a generic function. This simple rule prevents the kind of infinite metacircularity problems that are coming up here. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 16:45:26 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 13:35:52 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 380027; Mon 11-Apr-88 16:35:39 EDT Date: Mon, 11 Apr 88 16:35 EDT From: David A. Moon Subject: Re: lattice of kernel classes To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <880411-131548-12292@Xerox> Message-ID: <19880411203548.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 11 Apr 88 13:15 PDT From: Danny Bobrow The reason for making T be a built-in-class is to ensure that a) no instances of T can be made b) No direct subclasses of T can be made (without significant effort) I think we need some way to ensure this. Either we have to make T an exception to the rule in Chapter 1, or put this information in more directly in Chpater 3. What's wrong with (b)? For (a), if you specifically want an error to be signalled if someone makes an instance of the class named T, give it a make-instance method that signals that error. I don't like errors that get detected by fortunate coincidences, because that tends to result in error messages that mere mortals can't understand.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 16:28:38 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 13:19:57 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 APR 88 13:15:48 PDT Date: 11 Apr 88 13:15 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: lattice of kernel classes In-reply-to: Sonya E. Keene 's message of Mon, 11 Apr 88 15:14 EDT To: skeene@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880411-131548-12292@Xerox> 1. In the diagram, there is a class named "standard-structure". I think it is meant to be "structure-object"; which is what it is called in the previous section. Right. 2. The classes and have angle brackets around them, which indicates that they are used primarily for type determination, like , , and so on. I don't think of those two classes in that way; I think of them as primarily being there to support default behavior of instances of structure-class and standard-class. So, I would recommend getting rid of the angle brackets. I think that these classes serve both purposes. It is appropriate to test if an object is structure using . So given the dual role of these objects, do you think it better not to use <>, since that might indicate their only purpose is for type checking, or is suffcient to amplify the statements about their other roles in the text. 3. This section states that T is an instance of built-in class, but the section "Instances of class, built-in-class, and structure-class" states that an implementation can use standard-class for ANY class associated with a Common Lisp type. This seems contradictory. The reason for making T be a built-in-class is to ensure that a) no instances of T can be made b) No direct subclasses of T can be made (without significant effort) I think we need some way to ensure this. Either we have to make T an exception to the rule in Chapter 1, or put this information in more directly in Chpater 3.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 16:03:08 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 12:50:16 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 379965; Mon 11-Apr-88 15:50:01 EDT Date: Mon, 11 Apr 88 15:50 EDT From: David A. Moon Subject: dependent update protocol To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <880411113858.6.GREGOR@SPIFF.parc.xerox.com> Message-ID: <19880411195010.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 11 Apr 88 11:38 PDT From: Gregor.pa@Xerox.COM Moon has suggested that the dependents protocol stuff should not be part of standard-object; rather it should be defined as a separate mixin since that is what multiple inheritance is for after all. He also mentioned some problems he had with the way the dependent protocol worked. He didn't identify those problems, but we had some problems with it ourselves which we have tried to address. I believe those possible problems were with the next level up: the way the updating of subclasses uses this protocol, not with this protocol itself. I still haven't had time to figure out if those problems are real. However, since your message didn't address that level at all, we can defer that. This message outlines a new dependents updating protcol. This protocol is different from what we had before in several important ways: - there is a separate mixin for the dependents stuff, that mixin is used by standard-class to do dependents updating. Users can use it in their code to particpate in that dependent updating protocol. Good. - There is a mechanism for allowing the modified object to pass information describing the modification to all the dependents. This mechanism is designed to allow subclassing to work. That is, a given class (say standard-class) may use this mechanism to pass information to its dependents. Good. Without specifying the format of that information, a subclass of standard-class can augment that information to pass extra information about how it has been modified. Actually your example shows that it's not really true that the format of the information is unspecified. What is specified is that it is a list with one element for each interested class, in most-specific-first order. What is unspecified is the format of the list elements. Dependents of the subclass which expect to see the augmented information will see it, dependents which do not expect to see augmented information will see the original information. This all seems good except for a couple of minor points: \Defmeth map-dependents ((instance updatable-object-mixin) function args) For all dependents of instance, applies function to instance, the dependent and args. It's usually better not to try to pass extra args through a mapping function; instead the function being mapped can be a closure that knows the extra args. This is more flexible, and is how all eight functions in CLtL whose names start with "map" work. Thus I would make map-dependents take only two arguments. (defmethod reinitialize-instance :around ((object updatable-object-mixin) &rest reinitargs) (let ((before (apply #'before-reinitialization object reinitargs))) (call-next-method) (let ((update-args (apply #'after-reinitialization object before reinitargs))) (map-dependents object #'update-dependent object update-args)))) I don't see how this can work if reinitialize-instance changes the set of dependents. The map-dependents will map over the new dependents, and any old dependents that were removed will never be updated. Maybe you can say that remove-dependent, or by convention each caller of it, calls update-dependent or a variant of it on the dependent being removed. However, I suspect that is not flexible enough. I know some of our analogues to this have to start by collecting all the dependents into a table that is independent of the dependency structure. I don't have an answer here; I think more thought is required. This example shows how this protocol might be used. In particular, it demonstrates how the protocol can be used by a subclass to encapsulate the information the superclas might pass. All use of this protocol should be in this style. If that's true I would prefer to have the style (collecting lists of values returned by each interested method, and taking them apart again) be enforced by method combination, instead of leaving it up to each programmer to get it right. Also, since the style you propose depends on three methods for three different generic functions to be kept in sync, and does something unpredictable without necessarily signalling an error if one of the methods is left out, it doesn't seem very robust. I would prefer to see either a more abstract data structure than a list, so that leaving out a method (or forgetting to call cdr) for one class would not damage the data seen by other class's methods, or else to use one generic function instead of three, so that all the code for one class would be in a single place and hence less likely to be out of sync. In the latter case, this generic function would be called multiple times and one of its arguments would indicate whether state was being collected or distributed. My conclusion is that the registration protocol is okay but the updating protocol needs more thought, although it certainly feels like it's on the right track.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 15:28:12 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 12:15:19 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 379903; Mon 11-Apr-88 15:15:09 EDT Date: Mon, 11 Apr 88 15:14 EDT From: Sonya E. Keene Subject: lattice of kernel classes To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <19880411191450.4.SKEENE@JUNCO.SCRC.Symbolics.COM> Three comments on this section of MOP: 1. In the diagram, there is a class named "standard-structure". I think it is meant to be "structure-object"; which is what it is called in the previous section. 2. The classes and have angle brackets around them, which indicates that they are used primarily for type determination, like , , and so on. I don't think of those two classes in that way; I think of them as primarily being there to support default behavior of instances of structure-class and standard-class. So, I would recommend getting rid of the angle brackets. 3. This section states that T is an instance of built-in class, but the section "Instances of class, built-in-class, and structure-class" states that an implementation can use standard-class for ANY class associated with a Common Lisp type. This seems contradictory.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 14:58:53 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 11:46:29 PDT Received: from Semillon.ms by ArpaGateway.ms ; 11 APR 88 11:39:39 PDT Date: Mon, 11 Apr 88 11:38 PDT From: Gregor.pa@Xerox.COM Subject: dependent update protocol To: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text Message-ID: <880411113858.6.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Moon has suggested that the dependents protocol stuff should not be part of standard-object; rather it should be defined as a separate mixin since that is what multiple inheritance is for after all. He also mentioned some problems he had with the way the dependent protocol worked. He didn't identify those problems, but we had some problems with it ourselves which we have tried to address. This message outlines a new dependents updating protcol. This protocol is different from what we had before in several important ways: - there is a separate mixin for the dependents stuff, that mixin is used by standard-class to do dependents updating. Users can use it in their code to particpate in that dependent updating protocol. - There is a mechanism for allowing the modified object to pass information describing the modification to all the dependents. This mechanism is designed to allow subclassing to work. That is, a given class (say standard-class) may use this mechanism to pass information to its dependents. Without specifying the format of that information, a subclass of standard-class can augment that information to pass extra information about how it has been modified. Dependents of the subclass which expect to see the augmented information will see it, dependents which do not expect to see augmented information will see the original information. CLOS supports a general mechanism for registering dependents of objects, and updating those objects on change. It does this through the medium of a mixin class, updatable-object-mixin, that supports updating of dependents. A dependent of an object O1 is any object that may need to be updated when O1 changes. An object becomes a dependent only by explicitly registering itself as one. The dependent registering protocol allows redundant registering of dependents; this means that code which wants an object to be registered as a dependent of an object should always do so. It should never depend on the particular implementation to do so since specific implementations may use the dependent updating protocol in different ways. Some examples of the use are: 1) A screen view of an object (perhaps a class) needs to update itself when the object (class definition) changes. To do this it registers itself as a dependent of that object, whenever the object changes it will update all its dependents. 2) A subclass of a class wants to recompute its class precedence list when the class changes its direct superclasses. The subclass registers itself as a dependent of the class, whenever the class changes, the subclass is updated and can recompute its class precedence list. 3) Some set of objects needs to be updated when a class changes. This can be handled in one of two ways, all the objects can be registered as dependents, or a single object can be created which encapsulates all the other objects. The single `large' object can be registered as a dependent. (defclass updatable-object-mixin () ()) This class supports two protocols, registration and updating of dependents. The registration protocol is comprised of the generic functions add-dependent, remove-dependent, and map-dependents. The updating protocol is comprised of methods on reinitialize-instance, and the generic functions before-reinitialization, after-reinitialization and update-dependent. The Registration Protocol \Defmeth add-dependent ((object updatable-object-mixin) new-dependent) adds new-dependent as a new dependent of object. Does nothing if new-dependent is already a dependent of object. \Defmeth remove-dependent ((object updatable-object-mixin) dependent) removes dependent as one of the dependents of object. Does nothing if dependent is not already one of the dependents of object. \Defmeth map-dependents ((instance updatable-object-mixin) function args) For all dependents of instance, applies function to instance, the dependent and args. The Updating Protocol The updating protocol has two parts. The first part is an :around method on reinitialize-instance which causes all the dependents of an object to be updated whenever the object is reinitialized. This part of the protocol also provides a mechanism which allows the object to pass information to its dependents describing the change effected by reinitializing the object. This mechanism is provided by having the :around method on reinitialize-instance call the generic-function before-reinitialization before the reinitialization, and the generic-function after-reinitializing after the reinitialization. The value returned by after-reinitialization is passed in the call to update-dependent on each of the dependents. [We are actively soliciting suggestions for better names for before-reinitialization and after-reinitialization.] (defmethod reinitialize-instance :around ((object updatable-object-mixin) &rest reinitargs) (let ((before (apply #'before-reinitialization object reinitargs))) (call-next-method) (let ((update-args (apply #'after-reinitialization object before reinitargs))) (map-dependents object #'update-dependent object update-args)))) The updatable-object-mixin provides implementations of before-reinitialization, after-reinitialization, and update-dependent. (defmethod before-reinitialization ((object updateable-object) &rest ignore) ()) (defmethod after-reinitialization ((object updateable-object) before-reinitialization &rest ignore) ()) (defmethod update-dependent ((dependent updateable-object) (object updateable-object) after-reinitialization) ()) Example: This example shows how this protocol might be used. In particular, it demonstrates how the protocol can be used by a subclass to encapsulate the information the superclas might pass. All use of this protocol should be in this style. The standard methods on before-reinitialization, after-reinitialization and update-dependent are there to support this. Suppose that a specific kind of metaclass wants to propagate special information when used as a submetaclass of itself. When ordinary standard-class is used as a submetaclass, standard-class should see the after-reinitialization information it was expecting to see. (defclass my-class (standard-class) ()) (defmethod before-reinitialization ((c my-class) &rest reinitiargs) (cons () (call-next-method))) (defmethod after-reinitialization ((c my-class) before &rest reinitargs) (cons () (apply #'call-next-method c (cdr before) reinitargs))) (defmethod update-dependent ((dependent standard-class) (object my-class) after-reinitialization) (call-next-method dependent object (cdr after-reinitialization))) (defmethod update-dependent ((dependent my-class) (object my-class) after-reinitialization) () (call-next-method dependent object (cdr after-reinitialization))) -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 14:05:45 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Apr 88 10:56:57 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 379803; Mon 11-Apr-88 13:56:17 EDT Date: Mon, 11 Apr 88 13:56 EDT From: David A. Moon Subject: Re: method-lambda and apply-method-lambda To: kempf@Sun.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8804111558.AA05147@suntana.sun.com> Message-ID: <19880411175624.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 11 Apr 88 08:58:35 -0700 From: kempf@Sun.COM > APPLY-METHOD method next-method-info &REST arguments I don't think this generic function is really necessary, since APPLY, being itself implementation dependent, could be modified to do the right thing given a method function. Jim, I think you must have missed the point. The problem isn't that what APPLY does is implementation-dependent, but that the arguments to be passed to APPLY are implementation-dependent. The most obvious case is the next-method-info info; there is no way for APPLY to deduce this from the other arguments, is there? If there is a way, I might change my mind on suggesting a separate APPLY-METHOD primitive, but if there isn't a way, we have to have that primitive so that the caller can supply the information. Some implementations of APPLY already must differentiate based on whether the function object is a closure or not, since in the former case, the lexical environment must be modified to reflect the lexical environment of the closure, so the additional case of a method function is probably nothing new. However, it might be useful for metaobject programmers who want a hook for a metaclass specific way of applying a method. In that case, I think the NEXT-METHOD-INFO argument could be dropped, since the concept of a next method is specific to STANDARD-METHOD. I disagree. I think CALL-NEXT-METHOD should be available to all classes of methods that want it; I don't think it should be something magic for standard-method. The method metaclass method for this generic function would then implement any special processing for changing control flow. I don't think I understand this last sentence; do you have a specific proposal?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Apr 88 12:36:00 EDT Received: from Semillon.ms by ArpaGateway.ms ; 11 APR 88 09:24:59 PDT Return-Path: <@RELAY.CS.NET:pierce@golfer.dayton.ncr.com> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 11 APR 88 09:21:26 PDT Received: from relay2.cs.net by RELAY.CS.NET id ae29487; 11 Apr 88 11:48 EDT Received: from ncr by RELAY.CS.NET id af21074; 11 Apr 88 11:44 EDT To: commonloops.pa@Xerox.COM Date: Mon, 11 Apr 88 9:47:57 EST Subject: HIGH.bin load time error Cc: gene.pierce%dayton.ncr.com@RELAY.CS.NET X-Mailer: Elm [version 1.5] From: pierce@golfer.dayton.ncr.com Message-ID: <880411-092459-11593@Xerox> The following is a correction to a call for help concerning HIGH.lisp. The problem is during load time not compile time. Sorry for the confusion. While loading HIGH.lisp I am encountering the following error with the march 17th version of pcl. The error occurs on a symbolics running genera 7.1 and on a SUN running 4.2bsd using lucid lisp. NO MATCHING METHOD FOR THE GENERIC-FUNCTION: #. Any and all help will be appreciated. Thanks, Gene Pierce NCR Corp. gene.pierce%dayton.ncr.com@relay.cs.net -- -- --  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Apr 88 12:35:44 EDT Received: from Salvador.ms by ArpaGateway.ms ; 11 APR 88 09:22:44 PDT Return-Path: <@RELAY.CS.NET:pierce@golfer.dayton.ncr.com> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 11 APR 88 09:21:14 PDT Received: from relay2.cs.net by RELAY.CS.NET id ab29487; 11 Apr 88 11:48 EDT Received: from ncr by RELAY.CS.NET id ac21074; 11 Apr 88 11:43 EDT To: commonloops.pa@Xerox.COM Date: Mon, 11 Apr 88 9:24:05 EST Subject: HIGH.lisp Compiling error Cc: gene.pierce%dayton.ncr.com@RELAY.CS.NET X-Mailer: Elm [version 1.5] From: pierce@golfer.dayton.ncr.com Message-ID: <880411-092244-11588@Xerox> --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Apr 88 12:15:49 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 09:06:49 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA00083; Mon, 11 Apr 88 09:05:47 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA10363; Mon, 11 Apr 88 09:05:14 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA05147; Mon, 11 Apr 88 08:58:37 PDT Message-Id: <8804111558.AA05147@suntana.sun.com> To: David A. Moon Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: method-lambda and apply-method-lambda In-Reply-To: Your message of Fri, 08 Apr 88 18:14:00 -0400. <19880408221409.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 11 Apr 88 08:58:35 -0700 From: kempf@Sun.COM Dave's analysis has clarified things somewhat. Here's some additional thoughts: > MAKE-METHOD-FUNCTION proto-method generic-function qualifiers specializers > lambda-exp &OPTIONAL macroexpand-environment Yes, I agree that this is needed to handle CALL-NEXT-METHOD and other metaclass dependent additions to the method function's lexical environment (things like permutation tables are implementation specific details, and therefore not part of the specification). I would have preferred to see a more general function for constructing a function given a lexical environment and a lambda expression, but, given the ambiguity in Common Lisp about such topics, this will have to do. > APPLY-METHOD method next-method-info &REST arguments I don't think this generic function is really necessary, since APPLY, being itself implementation dependent, could be modified to do the right thing given a method function. Some implementations of APPLY already must differentiate based on whether the function object is a closure or not, since in the former case, the lexical environment must be modified to reflect the lexical environment of the closure, so the additional case of a method function is probably nothing new. However, it might be useful for metaobject programmers who want a hook for a metaclass specific way of applying a method. In that case, I think the NEXT-METHOD-INFO argument could be dropped, since the concept of a next method is specific to STANDARD-METHOD. The method metaclass method for this generic function would then implement any special processing for changing control flow. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Apr 88 06:45:10 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Apr 88 03:36:43 PDT Received: by labrea.Stanford.EDU; Sat, 9 Apr 88 02:36:15 PST Received: from bhopal.lucid.com by edsel id AA11444g; Sat, 9 Apr 88 03:13:42 PDT Received: by bhopal id AA08707g; Sat, 9 Apr 88 03:14:32 PDT Date: Sat, 9 Apr 88 03:14:32 PDT From: Jon L White Message-Id: <8804091014.AA08707@bhopal.lucid.com> To: Moon@stony-brook.scrc.symbolics.com Cc: Gregor.pa@xerox.com, common-lisp-object-system@sail.stanford.edu, rwk@ai.ai.mit.com, rg@ai.ai.mit.com, sun!franz!feast!smh@labrea.Stanford.EDU In-Reply-To: David A. Moon's message of Fri, 8 Apr 88 14:52 EDT <19880408185223.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Subject: add-named-xxx re: The way that add-named-method -is- different from add-named-class and add-named-generic-function (ahem) is that add-named-method doesn't have a symbol as a name, instead the conceptual name (something that identifies a prior object to be replaced) is composed of the generic function, the specializers, and the qualifiers. That difference is inherent, but the other differences in your most recent draft are accidental and should be eliminated. . . . I.e., the "name" for a method isn't a symbol but could be a "definition spec" (or "function spec" if you will). Although one might facetiously suggest that (lambda (x y) (list x y)) is a "conceptual" name for the function #'(lambda (x y) (list x y)) I think this is stretching the point. On the other hand, having a name for a method like (documentation (standard-class)) ;for primary methods or (documentation (persistent-class) :before) ;for before methods is a natural expression of "function specs". [I presume that you meant "parameter specializer name" when you said "specializers" above]. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 18:49:23 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:39:43 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 08 APR 88 15:37:13 PDT Date: 8 Apr 88 15:37 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: (re)initialization revisited In-reply-to: kempf@Sun.COM's message of Thu, 07 Apr 88 12:13:45 -0700 To: kempf@Sun.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880408-153713-9540@Xerox> Jim proposes removing some functions in the spec. I sympathize with this as a general goal. But in this case I think it is misguided. There are really four concepts 1) initializate (make a brand new instance have the right state) 2) reinitialize (make an old instance have a "standard" starting state) 3) class-changed (make a change from one form of current instance to another) 4) update-instance-structure (make an appropriate current instance from an outdated instance. Because there are four concepts, there must be four entries so that users can change what is done for each. Collapsing concepts into a commonly named fn just causes confusion. For example, in doing class-changed, one can take advantage of methods on the class-before-change; for example, changing class of p1 from an x-y-point to rho-theta-point, one can use the methods for rho and theta defined on x-y-point. There is no class-before-change for update-instance-structure. Reinititializing must potentially take into account old values on slots. Initialization never has to. We introduced the general concept because we had two examples in CLOS itself that require it: instances of standard-class, and instances of standard-generic-function. Both must take into account previous state of the objects to be changed. --- There is commonality of code in the usual case between these four concepts. We express that common piece as a separate function shared-initialize. Now the question comes up of what happens if one wants to "slightly" change the common part. This ability to make a slight change easily is an advertised feature of object oriented programming. The question comes up, what conditions can you use to determine the slight change. The hypothesis in our original proposal was that it was a reasonable thing to make the slight change depend on who called the common piece. Gregor and I chose to enable this by making the caller name be an argument of the call. This supports two different mechanisms for capturing the differences 1) It allows a single method to test the value of the flag. Or to put it another way, it allows a case statement within the called method to determine which code is run. This is rather like building generic functions by using case statements. However, it is appropriate if most of the code is shared, and the unshared parts are distributed through the code. 2) It supports the definition of individual methods specialized on the caller symbol. This is appropriate if the usual method must be completely shadowed, or if the usual method can be surrounded by the desired special case behavior. RPG suggested passing a functional argument. I mistakenly though that there would be no way of changing the functional argument in the case of class-changed and update-instance-structure. Dick pointed out that the way one does this is to make a special caller that modifies the usual provided initializer functions and calls the next method. This is elegant provided one can easily make changes in provided functions. Dick suggested extending with-added-methods to allow specification of the generic function to be changed, or later by using a special form to mess with the incoming initializer. The comparison seems to be between: RPG code: Consider: (defmethod reinitialize-instance ((instance standard-object) initializer &rest initargs) ... (apply initializer instance initargs) ... ) Now if we want to alter the behavior of shared-initialize when called by reinitialize-instance on some more specific class than standard-object, we do the following: (defmethod reinitialize-instance ((instance some-class) initializer &rest initargs) (with-generic-function-messed-with (initializer (mess-with-generic-function initializer)) (apply #'call-next-method instance initializer initargs))) ---- Code from DGB/Gregor proposal: (defmethod reinitialize-instance ((instance standard-object) &rest initargs) ... (shared-initialize instance 'reinitialize-instance initargs) ... ) (defmethod shared-initialize ((instance some-class) (caller (eql 'reinitialize-instance)) &rest initargs) ... whatever messing you like doing ... some more messing ) And there is no "with-generic-function-messed-with" macro to deal with ---  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 8 Apr 88 18:33:22 EDT Received: from Semillon.ms by ArpaGateway.ms ; 08 APR 88 15:21:39 PDT Return-Path: Redistributed: commonloops.pa Received: from ai.CEL.FMC.COM by Xerox.COM ; 08 APR 88 15:18:02 PDT Received: from unixb.CEL.FMC.COM (unixb.ARPA) by ai.CEL.FMC.COM with Sendmail (4.12/4.7) id AA23316; Fri, 8 Apr 88 15:17:30 pst Received: by unixb.CEL.FMC.COM with Sendmail (4.12/4.7) id AA22871; Fri, 8 Apr 88 15:17:21 pst From: rajd@cel.fmc.com (Rajendra Dodhiawala) Message-Id: <8804082317.AA22871@unixb.CEL.FMC.COM> Date: 08 Apr 88 15:17:19 PST (Fri) To: commonloops.pa@Xerox.COM Subject: Re: PCL compilation error - 3600/Genera 7.1 I should have mentioned in my previous message that I am trying to install PCL dated March 17th (the St. Patrick's Day release). The machine and the system were mentioned in the subject line; that is, Symbolics 3600 and Genera 7.1. I don't have any patches for the PCL mentioned, except the one sent by Ray Hill on *slot-unbound* and named-structure-symbol for the 3600-low.lisp file. - rajendra FMC Central Engineering Labs 1205 Coleman Ave Santa Clara, CA 95052 (408) 289-3303 ARPAnet: rajd@cel.fmc.com  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 18:25:05 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:14:14 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 378864; Fri 8-Apr-88 18:13:57 EDT Date: Fri, 8 Apr 88 18:14 EDT From: David A. Moon Subject: method-lambda and apply-method-lambda To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <880115131101.2.GREGOR@SPIFF.parc.xerox.com>, <2784314289-5590063@Jenner>, <8803252143.AA03557@suntana.sun.com>, <2784566339-4218491@Jenner>, <880328113536.8.GREGOR@SPIFF.parc.xerox.com>, <2785148209-6123016@Jenner> Message-ID: <19880408221409.1.MOON@EUPHRATES.SCRC.Symbolics.COM> I've been thinking about this issue and here's my considered opinion. Date: Fri, 15 Jan 88 13:11 PST From: Gregor.pa@Xerox.COM A problem we have never quite resolved is how to abstract out the information about call-next-method (and slot optimization) that needs to be passed to method functions. I have said on several occaisons that I would like for it to be possible to apply method functions to the 'natural' arguments; I would also like it to be possible to construct method functions. Moon has countered quite rightly that this makes it difficult to implement call-next-method. Briefly I propose that we introduce a constructs called method-lambda and method-apply. I strongly agree with these goals. I think we're still searching for the right constructs to satisfy the goals. I think Patrick is on the right track, though. Date: Fri, 25 Mar 88 14:38:09 CST From: Patrick H Dussud I don't think that method-lambda, as describe in 88-003 is good enough. It captures the contract between a class of generic functions and a class of methods, so it should be metaclass driven. You can imagine several contracts on a single implementation. I propose the following: Make-method-function is a generic function. make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT The generic function make-method-function returns a function suitable for the function slot of a method. Its representation is implementation dependent. I think the -only- assertions guaranteed about the value returned by MAKE-METHOD-FUNCTION should be: - COMPILE works on it - the FUNCTION special form works on it - it and the result of compiling it are members of the type FUNCTION - APPLY-METHOD works on it and on the result of compiling it - it and the result of compiling it can be used as the :method-function when creating or reinitializing a method meta-object A plausible implementation technique is for MAKE-METHOD-FUNCTION to return a list whose car is LAMBDA and whose cdr is implementation-dependent. Other implementation techniques are also possible. apply-method METHOD NEXT-METHOD-LIST &rest ARGUMENTS [ generic function] apply-method is discriminated on METHOD. METHOD is the method that needs to be invoked. Using a method meta-object rather than a method-function is an interesting change. After thinking about it, I agree that this is right. The meta object encapsulates all the static information that might determine what calling sequence to use (generic function, specializers, and qualifiers) while the other arguments to APPLY-METHOD are all the dynamic information that can be needed for calling a method. NEXT-METHOD-LIST is the list of all the methods that can be invoked by calling call-next-method. There is an interesting question here whether this should be explicitly a list of method objects, or should be abstracted as some implementation-dependent object that represents that list. Date: Fri, 25 Mar 88 13:43:43 -0800 From: kempf@Sun.COM Why, precisely, do you think there need be any difference between a method function and any other kind of function? I can understand this for a generic function, since a generic function has slots, but a method function has none. It seems to me that most of how a method function differs is covered by additions to its lexical environment, and that FUNCALL and APPLY should do. Date: Mon, 28 Mar 88 12:38:59 CST From: Patrick H Dussud I agree that in structure, a method function is like any other function. However method functions are getting called with(in) an implementation dependent environment that must be abstracted from the user. This is the motivation for the encapsulation (method-lambda, apply-method-lambda) given in chapter 3. The point of my earlier message is that this encapsulation should be metaclass dependent. The things that may be contained in the environment are(among others): Permutation vector(s), call-next-method list. This environment is distinct from the lexical environment of a closure. That does not prevent some implementation to code it as if it were a lexical environment, but that's an implementation choice. I agree with Patrick's response here. It can be further clarified by understanding the difference between static information (always the same for a given method) and dynamic information. Permutation vector(s) and call-next-method list are dynamic, they depend on the (classes of the) arguments, thus they cannot be supplied by using a lexical closure as the method-function. Date: Mon, 28 Mar 88 11:35 PST From: Gregor.pa@Xerox.COM Since, as you say, the method function captures the contract between a class of generic function and a class of method, I think this generic function should receive the prototype method as an argument as well. Agreed. I am not sure that I want to have to pass the method to apply-method? If I am going to pass the method, why don't I also pass the generic function? No, I think passing the method object is right (see my comment above). However, you could convince me that apply-method should take all three of the method-function, the method, and the generic-function. One way to convince me of this would be to show a case where one wants to call a method-function that is not the current method-function of any method (perhaps when tracing). Also, I am pretty sure we want to make compile work on these Agreed. Perhaps the solution is to have the generic function you say, but specify in addition that the standard method returns (METHOD-LAMBDA (..) ...). No, I think it's important to define the -behavior- of what make-method-function returns, but to leave the -representation- implementation-dependent. I don't think it's a good idea to introduce this new symbol that is like LAMBDA. More about this directly below. Date: Mon, 4 Apr 88 07:16:49 CDT From: Patrick H Dussud Date: Mon, 28 Mar 88 11:35 PST From: Gregor.pa@XEROX.COM The point is that in this case the `method function lambda' appears lexically in the source code. That means that it can capture the lexical variable function. It also means that it is compiled at compile-file time. I think both of these are important properties. I see your point, but the problem is that you can't decide at compile time what will be the implementation of the abstraction without knowing anything about the class of generic function, or the method. Right. I agree that the two properties Gregor proposes sound important, but I believe that it is impossible to achieve those properties. I think that the attempt to achieve those properties is why we've been having trouble converging here. Giving up those properties will make the problem much easier, and I don't think it means giving up anything that matters. Another point I want to make is that both Gregor's and Patrick's versions of advise-1-arg-method [I'll omit repeating the code here] don't work, because they use FUNCALL on the result of METHOD-FUNCTION. You have to use APPLY-METHOD, not APPLY or FUNCALL. I assume this was an accident, not a proposal that FUNCALL should work on these functions. The problem with make-method-function being a function instead of a macro is that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at compile time and constant, we couldn't do the closure you had in mind. If this is seen as a problem, we could make make-method-function be a macro that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then calls the generic function I don't think this is a good idea. If users want to write macros whose expander functions call make-method-function, they can do that. In fact I think that will be done often, and I approve of it. make-method-function itself, as a primitive, should remain a function, not be turned into a macro. I don't think it's useful to provide a built-in macro version of this, because I think any macro that calls make-method-function is going to do other things as well. Note that your example does not work anyway. You call the original method function, but the continuation (a representation of the next-methods list) is lost in the process. -Part- of what I was complaining about with use of FUNCALL. I am sure that we need something, like a local macro defined inside of the expanded method function, that allows someone to get at the continuation, and then pass it to apply-method-function. I'll have to think more about it. Agreed. See my comment above on whether the second argument to APPLY-METHOD should be a list of method objects or something more abstract. Here's what I think we should do: MAKE-METHOD-FUNCTION proto-method generic-function qualifiers specializers lambda-exp &OPTIONAL macroexpand-environment and the return value's behavior is defined as I proposed above. Note that the functions CALL-NEXT-METHOD, NEXT-METHOD-P, and NEXT-METHOD-INFO [see below] have bindings in a scope that includes all forms in lambda-exp. *** Note that I am proposing a change here; 88-002 would make the scope include only the body of lambda-exp, but Flavors users convinced me that that is inconsistent and wrong, and that default-value forms in the lambda-list must be included in the scope. The implementation of this is easy. In earlier discussions I believe it was argued that the implementation is too difficult, but I think the MAKE-METHOD-FUNCTION proposal reveals that no user needs to be concerned with the implementation of this scoping, as it is always done inside of MAKE-METHOD-FUNCTION. APPLY-METHOD method next-method-info &REST arguments This is the only way to call the result of MAKE-METHOD-FUNCTION. method is the meta-object, not the method-function. As noted above, my mind could be changed on the arguments to this. NEXT-METHOD-INFO This is in the same category as CALL-NEXT-METHOD and NEXT-METHOD-P. The only defined operation on its value is to use it as the second argument to APPLY-METHOD. MAKE-NEXT-METHOD-INFO method generic-function list-of-methods This is a primitive that returns the same kind of abstract value that NEXT-METHOD-INFO returns, given a concrete list of methods and the two meta objects that control the method calling sequence. We could find a better name than "next-method-info". My only comments on the name are (a) avoid "continuation", it really means something else, and (b) include the words "next method(s)" in the name to express the relationship of this to CALL-NEXT-METHOD.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 8 Apr 88 17:20:12 EDT Received: from Salvador.ms by ArpaGateway.ms ; 08 APR 88 14:12:04 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 08 APR 88 14:10:58 PDT To: CommonLoops.pa@Xerox.COM cc: tmitchel@WILMA.BBN.COM Subject: [Tom Mitchell: clos in 7.2] Date: Fri, 08 Apr 88 17:09:41 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880408-141204-9352@Xerox> Hopefully, some of these patches aren't necessary anymore. ------- Forwarded Message Date: Fri, 8 Apr 88 16:11:19 EDT From: Tom Mitchell To: kanderson@vax.bbn.com Subject: clos in 7.2 I have been playing with CLOS for the past couple of days, (with moderate sucess) and just tried it on 7.2. There is a problem with loading the current system in 7.2. The file "CLOS:CLOS;REL-7-PATCHES" has two references to the package "L-COMPILER". Apparently Symbolics has changed the name of this package to "COMPILER". (The logical host L-COMPILER still exists though) I have a new version of the file -- Leningrad:>tom>clos>rel-7-patches -- that seems to work. I guess the defsystem needs to be conditionalized somehow to load different files depending on 7.1 or 7.2. Now if i could just get the dumb box to import symbols into package cl-user... cheers, - -tom ------- End of Forwarded Message  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 16:22:09 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 13:14:36 PDT Received: from Semillon.ms by ArpaGateway.ms ; 08 APR 88 13:13:01 PDT Date: Fri, 8 Apr 88 13:12 PDT From: Gregor.pa@Xerox.COM Subject: comments on CLOS draft 88-2 To: "mike@gold-hill.com any day now" cc: common-lisp-object-system@SAIL.STANFORD.EDU, mike@LIVE-OAK.LCS.MIT.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: The message of 8 Apr 88 11:13 PDT from "mike@gold-hill.com any day now" Message-ID: <880408131233.1.GREGOR@SPIFF.parc.xerox.com> Line-fold: no I believe that the philosopy behind the suggestion is a good one, but I don't think this particular instance applies. The reason is that I don't see instance updating as a development environment only issue -- the reason we put updating in was that we didn't see it as a development environment only issue. Imagine a piece of product code which defines a bunch of classes, call it Product1. Now imagine another product which is an extension to the first product, call that Product2. It is reasonable to assume that Product2 will want to modify some aspects of Prodcut1. Specifically, Product2 may want to modify some of Product1's class definitions. The instance update protocol is designed to make this kind of scenario workable. I think having this kind of flexibility is going to be real important to unbundled products which use CLOS. Another important point is that the CLOS committee understands the cost of having this kind of flexibility quite well. It is minimal. I don't think that this feature complicates the implementation of CLOS significantly. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 15:19:29 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 12:11:23 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA25083; Fri, 8 Apr 88 12:10:27 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA24828; Fri, 8 Apr 88 12:09:47 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA03057; Fri, 8 Apr 88 12:03:02 PDT Message-Id: <8804081903.AA03057@suntana.sun.com> To: Dick Gabriel Cc: common-lisp-object-system@SAIL.Stanford.EDU Subject: Re: Reinitialization In-Reply-To: Your message of 07 Apr 88 14:51:00 -0700. <8804072155.AA10716@Sun.COM> Date: Fri, 08 Apr 88 12:03:00 -0700 From: kempf@Sun.COM Yow! That *was* pretty hairy. Well, anywy, my observations on the matter are the following: 1) 99% of the people using CLOS won't be interested in customizing (re)initialization anyway, 2) Of the 1% that are, maybe 80% will need the fine distinctions that the current interface provides. So putting in 4 functions just so .8% of the people who use CLOS don't have to go through extra hair doesn't make much sense to me. Not to speak of the hair in your note. Here's what I had in mind. Let's say Joe MetaObject User wants to specialize in such a way that, indeed, some distinction between an instance changing due to a class redefinition and due to a CHANGE-CLASS call are distinguished. Then the following code should do it: (defmethod change-class ((instance joes-class) new-class) (with-added-methods (reinitialize ((object joes-class) &rest reinit-args) ) ) ) Now, let's say Joe wants to change around how instances are reinitialized when a change is made through redefinition of a class. This is somewhat trickier, but still possible: (defmethod reinitialize ((object joes-class) &rest reinit-args) ) (defmethod change-class ((instance joes-class) new-class (with-added-methods (reinitialize ((object joes-class) &rest reinit-args) ) (apply #'reinitialize instance joes-reinit-args) ) ) Are there any other occasions when reinitialize might be called? One might be that a programmer might want to call it directly. In that case, its incumbent upon Joe to supply his own method which does reinitialization according to a scheme for direct calls, perhaps using a different name or lexically, at the top level. In any event, you get the idea. No flags, special variables, functional arguments, MSG, smoke, or mirrors. Just using the mechanisms which are already in place to do the job. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 8 Apr 88 15:13:00 EDT Received: from Semillon.ms by ArpaGateway.ms ; 08 APR 88 12:02:01 PDT Return-Path: Redistributed: commonloops.pa Received: from ai.CEL.FMC.COM by Xerox.COM ; 08 APR 88 11:59:44 PDT Received: from unixb.CEL.FMC.COM (unixb.ARPA) by ai.CEL.FMC.COM with Sendmail (4.12/4.7) id AA21754; Fri, 8 Apr 88 11:59:15 pst Received: by unixb.CEL.FMC.COM with Sendmail (4.12/4.7) id AA20676; Fri, 8 Apr 88 11:59:07 pst From: rajd@cel.fmc.com (Rajendra Dodhiawala) Message-Id: <8804081959.AA20676@unixb.CEL.FMC.COM> Date: 08 Apr 88 11:59:05 PST (Fri) To: commonloops.pa@Xerox.COM Subject: PCL compilation error - 3600/Genera 7.1 I have gone a little further in trying to install PCL thanx to Ray Hill at Alcoa Labs. However, I haven't been entirely successful. I haven't yet been able to compile the system yet. This time I get an error in the FIXUP file. CLASS-NAMED OBSOLETE-CLASS is not the name of a class. There is no obsolete-class in *class-name-hash-table*. I discovered something going on with obsolete-class in the file std-class. The call to CLASS-NAMED occurs from the first eval-when in FIXUP file. I know little of PCL to go about poking on my own, and I was not anticipating these (compilation!) problems when I volunteered to install the system at or site!! Any pointers in this direction will be appreciated. If further elaboration of the error is required I will do so. - rajendra Raj Dodhiawala FMC Central Engineering Labs 1205 Coleman Ave Santa Clara, CA 95052 (408) 289-3303 ARPAnet: rajd@cel.fmc.com  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 15:00:58 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:52:44 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 378631; Fri 8-Apr-88 14:52:09 EDT Date: Fri, 8 Apr 88 14:52 EDT From: David A. Moon Subject: add-named-xxx To: Gregor.pa@Xerox.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <880404112029.5.GREGOR@SPIFF.parc.xerox.com> Message-ID: <19880408185223.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: Mon, 4 Apr 88 11:20 PDT From: Gregor.pa@Xerox.COM At our last meeting, there was some sentiment for making the behavior of add-named-class, ensure-generic-function and add-named-method more uniform. This message attempts to address those issues. I have spent some time thinking about this, and I still feel that while add-named-class and ensure-generic-function are similar, add-named-method is different. One way to see this is to think about the defining forms which these functions are the analog of. add-named-class is the analog of defclass; ensure-generic-function is the analog of defgeneric; add-named-method is the analog of defmethod. defclass and defgeneric each provide a way to specify the class of the metaobject created.... On the other hand, defmethod provides no mechanism for controlling the class of the generic function or the method it creates. For this reason it doesn't make sense for add-named-method to have that ability. Wait a minute. I thought the only reason defmethod didn't allow one to specify the class of the method is that there is no good place to stick it in the syntax. I could easily imagine someone defining an alternate version of defmethod, with different syntax, that allowed the method class to be specified. They would be chagrined if they could not use add-named-method to implement this macro, but had to make an unmodular copy of the body of add-named-method in order to do it. Are you saying that it is fundamentally wrong to specify the class of the method object when defining a method? I admit that I've only seen one application of this, in a paper from some folks at BBN who were using PCL, and what they were doing was confused (they didn't want meta objects at all, just plain Lisp macros). However I assume that use of method meta object classes does make sense sometimes and that specifying the class when defining a method does make sense sometimes. On the other hand, it is possible to make add-named-method a little more uniform by having it take keyword arguments which get passed on to the make-instance of the method. (defun add-named-method (generic-function-name &rest keys &key qualifiers specializers &allow-other-keys) (let* ((gf (ensure-generic-function (class-prototype (class-named 'standard-generic-function)) :name generic-function-name)) (new-method (apply #'make-instance (generic-function-method-class gf) keys)) (old-method (get-method gf qualifiers specializers))) (when old-method (remove-method gf old-method)) (add-method gf new-method))) An alternate proposal would be to give the caller of add-named-method more control over the arguments passed to ensure-generic-function. My feeling is that it isn't worth cluttering up add-named-method to do that. If someone wants more control over the arguments to ensure-generic-function they can call it directly. After thinking about the above three paragraphs a bit, I think this is wrong modularity, by your own arguments. I think the caller of add-named-method should -always- call ensure-generic-function himself. That is, defmethod really consists of two parts, defining the generic function if not already defined, and defining/replacing the method. These two parts should not be combined in the macro expansion. Thus the arguments to add-named-method should be a prototype method (the usual kludge for class-discriminating methods) and some keyword arguments that include a generic function object, qualifiers, specializers, the method function, and some others that are optional. The way that add-named-method -is- different from add-named-class and add-named-generic-function (ahem) is that add-named-method doesn't have a symbol as a name, instead the conceptual name (something that identifies a prior object to be replaced) is composed of the generic function, the specializers, and the qualifiers. That difference is inherent, but the other differences in your most recent draft are accidental and should be eliminated. I think this is the reasoning behind the sentiment for making these things more uniform. Does this make sense to you?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 14:57:10 EDT Received: from WILMA.BBN.COM ([128.89.1.216]) by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:47:58 PDT To: "mike@gold-hill.com any day now" cc: common-lisp-object-system@sail.stanford.edu, mike@LIVE-OAK.LCS.MIT.EDU Subject: Re: comments on CLOS draft 88-2 In-reply-to: Your message of Fri, 08 Apr 88 13:13:00 -0500. Date: Fri, 08 Apr 88 14:46:28 -0400 From: kanderso@WILMA.BBN.COM >The following are the operations from the "Functions in the Programmer >Interface" that I think should be removed. >UPDATE-INSTANCE-STRUCTURE >MAKE-INSTANCES-OBSOLETE >CHANGE-CLASS, >CLASS-CHANGED I think the first 4 of the above list belong together as they are a protocol for what happens to instances when a class changes. I agree that dynamically changing things should be optional. Since it is a metaclass issue, the metaclass protocols should allow this behavior to be added as an optional meta class mixin wheter it is in CLOS spec or not. >CMAKUNBOUND >CBOUNDP These deal with adding and deleteing classes and i don't see how CLOS could live without them. Some kind of dynamic behvior is very nice. I would hate to have to reboot every time i make a mistake. k  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 14:49:01 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:42:13 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA24564; Fri, 8 Apr 88 11:40:15 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA23681; Fri, 8 Apr 88 11:39:50 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA02977; Fri, 8 Apr 88 11:33:10 PDT Message-Id: <8804081833.AA02977@suntana.sun.com> To: David A. Moon Cc: "mike@gold-hill.com any day now" , common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: comments on CLOS draft 88-2 In-Reply-To: Your message of Fri, 08 Apr 88 14:01:00 -0400. <19880408180143.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 08 Apr 88 11:33:08 -0700 From: kempf@Sun.COM I also agree with Dave and Mike on this issue, except I'm not sure about CHANGE-CLASS. Certainly, some way of getting a minimal subset would make pushing CLOS more deeply into CL implementations more palatable. I'm not sure, however, if it's possible at this late a date to do so. It could probably be factored into a Chapter 2.5, between the Metaobject Protocol and the Programmer Interface, and be called something like "Environment Hooks", though hooks probably isn't the right word. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 14:10:50 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 11:01:56 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 378569; 8 Apr 88 14:01:34 EDT Date: Fri, 8 Apr 88 14:01 EDT From: David A. Moon Subject: comments on CLOS draft 88-2 To: "mike@gold-hill.com any day now" cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 8 Apr 88 14:13 EDT from "mike@gold-hill.com any day now" Message-ID: <19880408180143.1.MOON@EUPHRATES.SCRC.Symbolics.COM> I agree that it would be a good idea to define a standard run-time (i.e. non-development) subset of Common Lisp. I don't think CLOS is the only area where features would be deleted to create this subset. For some reason it's been very difficult to recruit volunteers to propose the details of this. By the way, I'm not sure it's desirable to omit CHANGE-CLASS from a run-time subset. This is not really a development operation, some application programs do it.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 13:52:17 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 10:44:11 PDT Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 8 Apr 88 13:42-EDT Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86604; 8 Apr 88 13:40:59-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98371; Thu 7-Apr-88 13:14:50-EST Date: Fri, 8 Apr 88 13:13 est From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now) COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW To: common-lisp-object-system@sail.stanford.edu Subject: comments on CLOS draft 88-2 cc: mike Our (Gold Hill's) mail link will be disappearing shortly for about two weeks, so I wanted to get out these last comments for your consideration in the next CLOS spec draft. This has nothing to do with instance-variable names by the way. :-) ...Mike Beckerle Gold Hill ------------------------------------------------------------- More (but different) Comments on the CLOS specification 88-02: I am generally pleased with the detail level of the new draft. It nails down the semantics of CLOS much more clearly than CLtL does for most of CL. Nevertheless, there is one aspect of the spec that I think should be changed before adoption as a preliminary standard. This has to do with overspecification of the amount of dynamic redefinition possible in CLOS programs. All material having to do with the behavior of instances when classes are redefined should be omitted. Common Lisp implementations should not be required to update instances when classes are redefined. The spec should separate "language" issues from "environment" issues here and specify only the behavior of whole programs, not of environments that have been subjected to any number of redefinitions and changes. I do not deny that it is convenient when developing a program to have dynamic redefinition of classes; however, the common lisp spec should be for a language first and an environment second. In particular, the material in pages 1-15 through 1-18 of the "Programmer Interface Concepts" part should be deleted. The behavior of instances when classes are redefined should not be specified. Specification of these kind of behaviors in CLtL is very weak, and is frequently the source of significant disagreement on the behavior of otherwise simple language constructs. We should not carry on the tradition in CLtL of specifying how programs behave in the face of redefinition or a dynamically changing execution environment. The following are the operations from the "Functions in the Programmer Interface" that I think should be removed. UPDATE-INSTANCE-STRUCTURE MAKE-INSTANCES-OBSOLETE CHANGE-CLASS, CLASS-CHANGED CMAKUNBOUND CBOUNDP The other alternative is for these symbols to name optional components of CLOS which are not required to work in all implementations, but if they do, they use these standard names and have this standard functionality.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 13:10:48 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 8 Apr 88 10:02:31 PDT Received: by ti.com id AA28671; Fri, 8 Apr 88 12:00:15 CDT Received: from dsg by tilde id AA21572; Fri, 8 Apr 88 11:53:02 CDT Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 5 Apr 88 08:52:50 CDT Message-Id: <2785240766-146050@Jenner> Date: Tue, 5 Apr 88 08:59:26 CDT From: Patrick H Dussud To: Gregor.pa@XEROX.COM Cc: Common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Method-lambda and apply-method-lambda Return-Path: Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Thu, 31 Mar 88 15:46:20 CST Message-Id: <2784836687-3921370@Jenner> Date: Thu, 31 Mar 88 15:44:47 CST From: Patrick H Dussud To: Gregor.pa@XEROX.COM Cc: Common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Method-lambda and apply-method-lambda In-Reply-To: Msg of Mon, 28 Mar 88 11:35 PST from Gregor.pa@XEROX.COM Date: Mon, 28 Mar 88 11:35 PST From: Gregor.pa@XEROX.COM Subject: Method-lambda and apply-method-lambda Date: Fri, 25 Mar 88 14:38:09 CST From: Patrick H Dussud I have two kinds of comments about your proposal. I have some minor comments about the details of the proposal itself as well as some serious questions about whether it can work. I will start with the minor nits. make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT Since, as you say, the method function captures the contract between a class of generic function and a class of method, I think this generic function should receive the prototype method as an argument as well. I am not sure that I want to have to pass the method to apply-method? If I am going to pass the method, why don't I also pass the generic function? Good idea. I didn't put a method in there because I was under the impression that the modularity of the contract is broken. The way compute-effective-method is designed, the contract between the generic function and the method, abstracted by the local macro call-method will not depend on the method. Maybe I didn't look hard enough. Also, I am pretty sure we want to make compile work on these, which brings me to my second point. How does one write the following code in your proposal: (defun advise-1-arg-method (method) (let ((function (method-function method))) (reinitialize-instance method :function #'(method-lambda (a) (format *trace-output* "~&Got arg ~S" a) (funcall function a))))) You can do: (defun advise-1-arg-method (method) (let ((function (method-function method))) (reinitialize-instance method :function (make-method-function (method-generic-function method) (method-qualifiers method) (method-parameter-specializers method) `(lambda (a) (format *trace-output* "~&Got arg ~S" a) (funcall ,function a)))lambda-form ))) The point is that in this case the `method function lambda' appears lexically in the source code. That means that it can capture the lexical variable function. It also means that it is compiled at compile-file time. I see your point, but the problem is that you can't decide at compile time what will be the implementation of the abstraction without knowing anything about the class of generic function, or the method. The problem with make-method-function being a function instead of a macro is that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at compile time and constant, we couldn't do the closure you had in mind. If this is seen as a problem, we could make make-method-function be a macro that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then calls the generic function: Expand-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT which produces something like: (function (lambda ....)). Note that what it produces is implementation dependent and can substitute lambda for something else. Note that your example does not work anyway. You call the original method function, but the continuation (a representation of the next-methods list) is lost in the process. I am sure that we need something, like a local macro defined inside of the expanded method function, that allows someone to get at the continuation, and then pass it to apply-method-function. I'll have to think more about it. Patrick.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 12:59:21 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 8 Apr 88 09:50:23 PDT Received: by ti.com id AA28504; Fri, 8 Apr 88 11:48:07 CDT Received: from dsg by tilde id AA20268; Fri, 8 Apr 88 11:06:23 CDT Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 4 Apr 88 07:13:29 CDT Message-Id: <2785148209-6123016@Jenner> Date: Mon, 4 Apr 88 07:16:49 CDT From: Patrick H Dussud To: Gregor.pa@XEROX.COM Cc: Common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Method-lambda and apply-method-lambda In-Reply-To: Msg of Mon, 28 Mar 88 11:35 PST from Gregor.pa@XEROX.COM Date: Mon, 28 Mar 88 11:35 PST From: Gregor.pa@XEROX.COM Subject: Method-lambda and apply-method-lambda Date: Fri, 25 Mar 88 14:38:09 CST From: Patrick H Dussud I have two kinds of comments about your proposal. I have some minor comments about the details of the proposal itself as well as some serious questions about whether it can work. I will start with the minor nits. make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT Since, as you say, the method function captures the contract between a class of generic function and a class of method, I think this generic function should receive the prototype method as an argument as well. I am not sure that I want to have to pass the method to apply-method? If I am going to pass the method, why don't I also pass the generic function? Good idea. I didn't put a method in there because I was under the impression that the modularity of the contract is broken. The way compute-effective-method is designed, the contract between the generic function and the method, abstracted by the local macro call-method will not depend on the method. Maybe I didn't look hard enough. Also, I am pretty sure we want to make compile work on these, which brings me to my second point. How does one write the following code in your proposal: (defun advise-1-arg-method (method) (let ((function (method-function method))) (reinitialize-instance method :function #'(method-lambda (a) (format *trace-output* "~&Got arg ~S" a) (funcall function a))))) You can do: (defun advise-1-arg-method (method) (let ((function (method-function method))) (reinitialize-instance method :function (make-method-function (method-generic-function method) (method-qualifiers method) (method-parameter-specializers method) `(lambda (a) (format *trace-output* "~&Got arg ~S" a) (funcall ,function a)))lambda-form ))) The point is that in this case the `method function lambda' appears lexically in the source code. That means that it can capture the lexical variable function. It also means that it is compiled at compile-file time. I see your point, but the problem is that you can't decide at compile time what will be the implementation of the abstraction without knowing anything about the class of generic function, or the method. The problem with make-method-function being a function instead of a macro is that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at compile time and constant, we couldn't do the closure you had in mind. If this is seen as a problem, we could make make-method-function be a macro that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then calls the generic function: Expand-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT which produces something like: (function (lambda ....)). Note that what it produces is implementation dependent and can substitute lambda for something else. Note that your example does not work anyway. You call the original method function, but the continuation (a representation of the next-methods list) is lost in the process. I am sure that we need something, like a local macro defined inside of the expanded method function, that allows someone to get at the continuation, and then pass it to apply-method-function. I'll have to think more about it. Patrick.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 8 Apr 88 12:54:10 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 08 APR 88 09:42:56 PDT Return-Path: <@DREA-BALROG.ARPA:Gavin@DREA-BALROG.ARPA> Redistributed: CommonLoops.pa Received: from DREA-BALROG.ARPA by Xerox.COM ; 08 APR 88 09:41:04 PDT Date: Fri, 8 Apr 88 13:29 ADT From: Gavin L. Hemphill Subject: A question To: CommonLoops.pa@Xerox.COM Message-ID: <880408132949.2.GAVIN@DREA-BALROG.ARPA> Phone-Number: (902) 426-3100 x 182 [8:00am to 4:15pm Alantic Time] Template-for-reply: COMPATIBLE-1R-REPLY-TEMPLATE (dumb question of the month :-) ) Is it possible to define a class (say class2) based on an instance of a superior class (class1) in such a way that the value in a slot of an instance of class1 is shared by instances of class2 (i.e., changes to the value of the slot in an instance of class2 are visible to the methods associated with class1 and vice versa). In my reading of the CLOS spec I'm not sure if this is a reasonable thing to expect to be able to do, or if it is, how one goes about defining that behavior. G++ -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 12:32:23 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 09:24:33 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 378468; Fri 8-Apr-88 12:23:32 EDT Date: Fri, 8 Apr 88 12:23 EDT From: David A. Moon Subject: Re: CLOS, and slot hiding. To: "mike@gold-hill.com any day now" cc: Bobrow.pa@Xerox.COM, kempf@Sun.COM, common-lisp-object-system@SAIL.STANFORD.EDU, sidney@LIVE-OAK.LCS.MIT.EDU, ariel@oz.ai.mit.edu In-Reply-To: The message of 8 Apr 88 10:11 EDT from "mike@gold-hill.com any day now" Message-ID: <19880408162339.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: Fri, 8 Apr 88 09:11 est From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now) So much for the "open" philosophy issue. As for it being "hard" to implement, No one said anything it being or not being hard to implement. The issue is that it is hard to design. There are complicated issues which would have to be resolved. A standardization committee is the wrong place to do the research to resolve those issues. My gut feeling is that once there was a design, it would not be especially difficult to implement, but since I don't know what the design is, that's only a feeling.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 11:57:09 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 08:49:43 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA21479; Fri, 8 Apr 88 08:48:49 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA17091; Fri, 8 Apr 88 08:48:19 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA02698; Fri, 8 Apr 88 08:41:38 PDT Message-Id: <8804081541.AA02698@suntana.sun.com> To: Gregor.pa@Xerox.COM Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: (re)initialization revisited In-Reply-To: Your message of Thu, 07 Apr 88 19:14:00 -0700. <880407191422.6.GREGOR@SPIFF.parc.xerox.com> Date: Fri, 08 Apr 88 08:41:36 -0700 From: kempf@Sun.COM >Even though programmers don't call class-changed or >update-instance-structure, it is easy to imagine that a programmer would >want to do a different thing to an instance in these two cases. The >cases really are different and programs will want to be sensitive to >that difference. I'd like to see a specific example. To justify having four functions, two of which have different interfaces but do essentially the same thing and two of which have the same interface but do the same thing except for calling one function (possibly, if that hasn't been dropped) you would want to have them be useful in a large number of cases. The fact that an additional level is being proposed which essentially unifies all four suggests to me that the number of cases probably won't be that large. The difference between changing the instance structure from an old class definition to a new, or from one class to another is slight. In both cases, the common ground is changing the instance structure due to a change in class. Programmers that want to do something different in the latter case can specialize change-class and the reinitialize method to get specialized behavior, including setting flags or special functions around an invocation of call-next-method to get specialized behavior because they are in change-class. Likewise for update-instance-structure. This would throw the burden of dealing with corner cases on the programmer, rather than trying to anticipate what the programmer wants and making it part of the language design. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 09:46:04 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 06:38:13 PDT Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 8 Apr 88 09:31-EDT Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86563; 8 Apr 88 09:28:45-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98350; Thu 7-Apr-88 09:11:40-EST Date: Fri, 8 Apr 88 09:11 est From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now) COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW To: Bobrow.pa@Xerox.COM Subject: Re: CLOS, and slot hiding. Cc: mike%acorn@LIVE-OAK.LCS.MIT.EDU, kempf@Sun.COM, common-lisp-object-system@sail.stanford.edu, sidney@LIVE-OAK.LCS.MIT.EDU, ariel@oz.ai.mit.edu Date: 6 Apr 88 10:40 PDT From: Danny Bobrow >I agree with the comments made by Moon about the design goals of >CLOS. Alan Snyder made a big pitch for having encapsulation be an >important goal for the Common Lisp community, and it was rejected. >One reason is that it was hard (as Moon mentioned) and another is >because it does not fit into the philosophy of Lisp, which has always >prided itself on being an open system (this is the point that Jim >made so well). Frankly, I think we should eliminate lexical scoping then and all go back to using global special vars and functions everywhere. After all, we want an "open" system. Now seriously. Abstraction features that are useful and allow programmers to easily practice useful information hiding are in no way opposed to "open" systems. The two concepts are utterly orthogonal. I don't want to prevent people who want to know how my classes are implemented from finding out. I just dont want them to HAVE to find out in order to use my class as a superclass. I especially don't want them to find out the hard way, by having their methods interact with superclass methods in an obscure manner. So much for the "open" philosophy issue. As for it being "hard" to implement, this may be a legitimate objection; however, lots of things in CLOS are "hard" to implement in both the sense of semantically difficult to achieve correctness, and in terms of required run-time inefficiency. Is there some horrible interaction that a class-specific slot option would have with other aspects of CLOS semantics which I am overlooking? My intuition is that a change to with-slots would provide the necessary semantics, and that it could be implemented via the SYMBOL-MACROLET facility and some gensymming. ...mike beckerle  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 08:56:05 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 05:48:19 PDT Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 8 Apr 88 08:46-EDT Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86556; 8 Apr 88 08:44:59-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98344; Thu 7-Apr-88 08:42:09-EST Date: Fri, 8 Apr 88 08:41 est From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now) COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW To: kempf@Sun.COM Subject: Re: CLOS, and slot hiding. Cc: mike%acorn@oak.lcs.mit.edu, common-lisp-object-system@sail.stanford.edu, sidney@XX.LCS.MIT.EDU, ariel@oz.ai.mit.edu Date: Wed, 06 Apr 88 09:30:08 -0700 From: kempf@Sun.COM >If the package system is really the only way to do this, then there >is really a deep flaw in CLOS. It doesn't support classes for >data-abstraction very well at all. Was this issue every discussed >in the design of CLOS? I think you have this backwards. The flaw (if any) is not in CLOS but in Common Lisp. The charter of the CLOS committee was to design an object-oriented extension to Common Lisp, not to "fix" Common Lisp. Common Lisp deals with modularity using name spaces, packages being one method of establishing a name space. If the extension were to Scheme, then environments would be used for establishing the modularity needed for data abstraction. Extending any language for object-oriented programming requires that the fundamental abstraction principles of the language be used and compatibility extended, otherwise the extension becomes unworkable. I don't think that common lisp has any particular flaw in this area. To separate global objects, like specvars, you have to use packages. Local variables and functions can be separated using lexical closures. My dispute is with the nature of instance variables. In the current CLOS proposal, they get treated in a manner more analogous to CL's special vars than to local variables. You have to use symbol naming at the user level to separate them, i.e., either gensymming or packages. You want to use the same name but have it mean something different? I'm confused, sorry. Do you have an example? Here's a simple one. Everything described here is in the same package. I have a class, MOVING-OBJECT, with two instance vars RHO and THETA, used by the method MOVE, defined for MOVING-OBJECT as an update to the RHO and THETA vars. I tell my associates about the class MOVING-OBJECT, and the method MOVE. He defines a subclass AIRPLANE. He wants to use the method MOVE on instances of AIRPLANE, but he also wants to define methods BANK and TURN, involving tilting and turning of the conceptual airplane with respect to level. He wants to use instance variables RHO and THETA to represent angles of tilt and turn. He cannot use these names because the class MOVING-OBJECT already has these names. Unfortunately, since he didn't need to know the implementation of the MOVE method, he didn't know that there were already instance vars named RHO and THETA. Note that the desired behavior is not like CLOS's "local" slots, but might be called "class specific" slots. These slots exist in all instances of the class and subclass, but their names are available only to methods defined on the specific class that they are created in. ...mike beckerle  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Apr 88 04:43:50 EDT Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 01:35:43 PDT Received: by labrea.Stanford.EDU; Fri, 8 Apr 88 00:35:12 PST Received: from bhopal.lucid.com by edsel id AA05945g; Fri, 8 Apr 88 01:28:52 PDT Received: by bhopal id AA04226g; Fri, 8 Apr 88 01:29:41 PDT Date: Fri, 8 Apr 88 01:29:41 PDT From: Jon L White Message-Id: <8804080829.AA04226@bhopal.lucid.com> To: Gregor.pa@xerox.com Cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: Gregor.pa@Xerox.COM's message of Mon, 4 Apr 88 16:20 PDT <880404162009.9.GREGOR@SPIFF.parc.xerox.com> Subject: update-instance-structure re: In the examples section. I believe the defmethod of update-instance-structure should be at the end of the example. Even though this code might work interpreted (in some implementations) it definitely won't compile. This is because setf of position-rho is used before position-rho is defined. Will this still be the case after the "cleanup" proposal for setf-functions is adopted? I thought one of the two main advantages is that you can assume a particular function name for doing the SETF, regardless of whether or not it or the accessor function is "defined". -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Apr 88 22:25:05 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 19:17:19 PDT Received: from Semillon.ms by ArpaGateway.ms ; 07 APR 88 19:15:59 PDT Date: Thu, 7 Apr 88 19:15 PDT From: Gregor.pa@Xerox.COM Subject: Reinitialization To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: The message of 7 Apr 88 14:51 PDT from Dick Gabriel Message-ID: <880407191538.7.GREGOR@SPIFF.parc.xerox.com> Line-fold: no After talking to Dick about it in person and having my misunderstanding clarified for me, I am now in favor of his modification of the proposal Danny and I originally sent out. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Apr 88 22:24:39 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 19:17:09 PDT Received: from Semillon.ms by ArpaGateway.ms ; 07 APR 88 19:14:43 PDT Date: Thu, 7 Apr 88 19:14 PDT From: Gregor.pa@Xerox.COM Subject: Re: (re)initialization revisited To: kempf@Sun.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <8804071913.AA01613@suntana.sun.com> Message-ID: <880407191422.6.GREGOR@SPIFF.parc.xerox.com> Line-fold: no The problem I have with your proposal is that as I see it, the four concepts are really different concepts. I think it would be a mistake to combine them. Even though programmers don't call class-changed or update-instance-structure, it is easy to imagine that a programmer would want to do a different thing to an instance in these two cases. The cases really are different and programs will want to be sensitive to that difference. There is of course a lot of similarity. The major thrust of the proposal Danny and I mailed out was to point out the similarity in their behavior and isolate it in a common subroutine. All the stuff about the flags and stuff is secondary. I don't think any further collapsing of these concepts will be a good idea though. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Apr 88 17:59:11 EDT Date: 07 Apr 88 1451 PDT From: Dick Gabriel Subject: Reinitialization To: common-lisp-object-system@SAIL.Stanford.EDU Something seems horrendously complicated about this whole affair. There are 4 updaters: initialize-instance reinitialize-instance update-instance-structure class-changed In this message I use reinitialize-instance as the example. These are called from parts unknown. They invoke a shared initializer called shared-initialize. We want to be able write methods to change the shared behavior, the gross behavior of the 4 updaters, and the behavior of some of the behavior of what is otherwise shared initialization bahavior. The modification in the last case depends only on which of the updaters invokes the shared initialization rountine. The point of my proposal was to have the shared initialization GF passed in as an argument to the updaters so that one could write code that only knew the calling protocol for the updater and which could locally modify the initializer routine passed in. This way, even though shared-initialize is always passed in, you can hack with it directly by writing a simple method on reinitialize-instance. Suppose reinitialize-instance were like this: (defmethod reinitialize-instance ((instance standard-object) initializer &rest initargs) ... (apply initializer instance initargs) ... ) Now if we want to alter the behavior of shared-initialize when called by reinitialize-instance on some more specific class than standard-object, we do the following: (defmethod reinitialize-instance ((instance some-class) initializer &rest initargs) (with-generic-function-messed-with (initializer (mess-with-generic-function initializer)) (apply #'call-next-method instance initializer initargs))) Notice we don't have to worry about the hairy mess and weird stuff in the body of reinitialize-instance, *and* we've used an object-oriented programming style to boot! This seems like the most common case to me. Suppose you want to change shared-initialize to take an argument saying why it was called. In this case I guess you can modify shared-initialize to accept an special initargs pair encoding the caller and then modify the 4 updaters as above but to add the initargs pair. Suppose we want to alter the behavior of shared-initialize any time reinitialize-instance is called and there is no more specific class to specialize reinitialize-instance on. Here it's trickier, but doable: (let ((r-i #'reinitialize-instance)) (with-generic-function-messed-with (initializer (mess-with-generic-function #'shared-initialize)) (defmethod reinitialize-instance ((instance some-class) initializer &rest initargs) (apply r-i instance initializer initargs)) (defun fix-this-mess () (setf (symbol-function 'reinitialize-instance) r-i)))) How would you do this with the flag scenario? I thought you would do this: (let ((s-i #'shared-initialize)) (defmethod shared-initialize ((instance standard-object) caller &rest initargs) (if (member caller ) (apply s-i instance caller initargs))) ...)) Looks pretty familiar, eh? Is there a better way? I think there is a simpler way: (defmethod reinitialize-instance ((instance standard-object) &rest initargs) (reinitializeds-shared-initialize instance initargs)) (defmethod reinitializeds-shared-initialize ((instance standard-object) &rest initargs) (apply #'shared-initialize instance initargs)) (defmethod shared-initialize ((instance standard-object) &rest initargs) ...) Now to alter the gross behavior, reinitialize-instance gets changed. To alter the shared behavior, shared-initialize gets changed. To alter some of the shared behavior, leaving the rest alone, reinitializeds-shared-initialize (for example) gets changed. Note that this makes people who don't use strange cases pay some performance penalty. Now, this has to be too much hair for this problem. Maybe Kempf's idea is right. Maybe we don't want to expose all of this for specialization. If I had some idea what piece of code Danny and Gregor wanted to write, I could think about this more clearly. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Apr 88 15:29:20 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 12:21:43 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA07958; Thu, 7 Apr 88 12:20:53 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA27708; Thu, 7 Apr 88 12:20:32 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA01613; Thu, 7 Apr 88 12:13:48 PDT Message-Id: <8804071913.AA01613@suntana.sun.com> To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: (re)initialization revisited In-Reply-To: Your message of Tue, 05 Apr 88 17:37:00 -0700. <880405173737.1.GREGOR@SPIFF.parc.xerox.com> Date: Thu, 07 Apr 88 12:13:45 -0700 From: kempf@Sun.COM I agree in principle with Gregor's initial message, but all the proposed alternatives so far leave me less than enthusiastic. The proposed solutions have involved using flags, function valued arguments, or special variables to pass a function to four different generic functions which ultimately end up doing the same thing. I'm going to argue for a solution which I proposed briefly last fall, namely collapsing the initialization functions into one or two. In particular, note the following: 1) Neither update-instance-structure nor class-changed is meant to be called by the programmer. This means that their interfaces could be rearranged to be the same, by either bundling the added-slots, discarded-slots and property list arguments to update-instance-structure and simply passing the old object, or by unbundling the previous object instance to class-changed and passing that information in the form update-instance-structure currently gets it. The kernel code which calls the merged function would take care of formatting the call correctly. This would allow one of the two functions to be dropped. 2) This leaves initialize-instance and reinitialize-instance. Since these interfaces are the same anyway, what's the point of having two differently named functions? Chapter 3 implies that the only difference is that reinitialize-instance takes care of calling update-dependents, but this seems to have been dropped in the current discussion. Even if it hadn't been, update-dependents could be called upon initialization also, with, of course, no result since no dependents have been registered on object's state yet. This leaves us with two functions: 1) A reinitialization function, which gets passed an assortment of information on the old object in some form and the new object, allowing the user to customize what precisely the initialization arguments are. 2) A raw initialization function, which gets passed the initargs. Since 1) basically needs to call 2), I'd suggest that 1) be named reinitialize-instance, and that 2) be named initialize-instance. There are plenty of refinements one could think of, like how to allow the kind of pairwise generic dispatch which class-changed currently allows, and details to fill in, but rather than take the time to hack out some code, I'd like to see what people think of this idea. The problem with the other solutions proposed so far is that they end up adding yet another function to CLOS, when some judicious subtraction and rearrangement might reduce the bulk somewhat and also provide a more unified solution. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Apr 88 13:47:56 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 10:40:32 PDT Received: from Semillon.ms by ArpaGateway.ms ; 07 APR 88 10:35:20 PDT Date: Thu, 7 Apr 88 10:34 PDT From: Gregor.pa@Xerox.COM Subject: Re: Reinitialization To: Danny Bobrow cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <880407-100805-6877@Xerox> Message-ID: <880407103428.1.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: 7 Apr 88 10:07 PDT From: Danny Bobrow I liked Dick's variation on our proposal; that is, I like using a function rather than a flag for variation. I also support his proposed addition to with-added-methods of an option to specify the generic function. However, there is a bug in the proposal. Since users never call class-changed or update-instance-structure (only the system does), there is no way to change the call, and shared-initialize will always be used (so why have an argument). Here are two proposals to fix the bug, neither of which I like a lot, though I prefer the first. Unfortunately, I don't think either of these can work. The first reduces directly to a stripped down version of the original proposal, the second doesn't work for other reasons. 1) Have a generic function compute-initialization-function which returns a function to use: (defmethod compute-initialization-function ((instance standard-object)) #'shared-initialize) (defmethod initialize-instance ((instance standard-object) &rest initargs) (apply (compute-initialization-function instance) instance initargs)) . . The problem here is that because compute-intialization-function doesn't accept an argument saying who the caller is, it will return the same value when called by initialize-instance, update-instance-structure etc. This in effect reduces this to the original proposal where initialize-instance, class-changed etc. all call the same generic function. The only difference is that the function isn't called with an argument that says who its caller is. 2) Have a special variable *initializer* with the a default value #'shared-initialize, and use that. For some additonal flexibility, one could allow initialize-instance and reinitialize-instance to have keyword argument :initializer whose default value is *initializer*. The problem with this is that the user can never know when update-instance-structure is going to be called. This means it is impossible to control the binding of *intializer* around calls to update-instance-structure. Given this I see two alternatives: Modify proposal 1 above so that there are three generic functions, initialize-instance-initializer, update-instance-structure-initializer, and class-changed-intiailizer. The standard method on each of these would return #'shared-initialize. Users could define their own methods on these generic function to control what shared initializer got used. This is essentially Dick's proposal debugged. Go back to the proposal Danny and I had originally. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 7 Apr 88 13:19:26 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 7 Apr 88 10:11:22 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 07 APR 88 10:08:05 PDT Date: 7 Apr 88 10:07 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Reinitialization In-reply-to: Dick Gabriel 's message of 06 Apr 88 10:43 PDT To: RPG@SAIL.Stanford.EDU cc: common-lisp-object-system@SAIL.Stanford.EDU Message-ID: <880407-100805-6877@Xerox> I liked Dick's variation on our proposal; that is, I like using a function rather than a flag for variation. I also support his proposed addition to with-added-methods of an option to specify the generic function. However, there is a bug in the proposal. Since users never call class-changed or update-instance-structure (only the system does), there is no way to change the call, and shared-initialize will always be used (so why have an argument). Here are two proposals to fix the bug, neither of which I like a lot, though I prefer the first. 1) Have a generic function compute-initialization-function which returns a function to use: (defmethod compute-initialization-function ((instance standard-object)) #'shared-initialize) (defmethod initialize-instance ((instance standard-object) &rest initargs) (apply (compute-initialization-function instance) instance initargs)) (defmethod update-instance-structure ((instance standard-object) added-slots discarded-slots property-list) (funcall (compute-initialization-function instance) instance)) etc. 2) Have a special variable *initializer* with the a default value #'shared-initialize, and use that. For some additonal flexibility, one could allow initialize-instance and reinitialize-instance to have keyword argument :initializer whose default value is *initializer*. (defmethod update-instance-structure ((instance standard-object) added-slots discarded-slots property-list) (funcall *initializer* instance)) (defmethod initialize-instance ((instance standard-object) &key (initializer *initializer*) &rest initargs) (apply initializer instance initargs))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 22:48:01 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 19:40:38 PDT Received: from Semillon.ms by ArpaGateway.ms ; 06 APR 88 19:40:27 PDT Date: Wed, 6 Apr 88 19:40 PDT From: Gregor.pa@Xerox.COM Subject: Reinitialization To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <880406125216.9.GREGOR@SPIFF.parc.xerox.com> Message-ID: <880406194011.3.GREGOR@SPIFF.parc.xerox.com> Line-fold: no After further consideration, I am pretty happy with Dicks amended version of the proposal Danny and I mailed out. What do other people think? -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 16:01:15 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 12:53:07 PDT Received: from Semillon.ms by ArpaGateway.ms ; 06 APR 88 12:52:38 PDT Date: Wed, 6 Apr 88 12:52 PDT From: Gregor.pa@Xerox.COM Subject: Reinitialization To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: The message of 6 Apr 88 10:43 PDT from Dick Gabriel Message-ID: <880406125216.9.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: 06 Apr 88 10:43 PDT From: Dick Gabriel I agree with Gregor's analysis and with the general outline of his solution. However, I usually have bad reactions to the use of flags to signify flow of control, so I would prefer to have some other means of implementing the solution. I think the solution you propose doesn't address one of the problems we were trying to address. Looking back over our message, it seems we didn't make that goal clear at all. This message tries to show why we decided to use a flag to communicate the caller of shared-initialize. Moon may also want to comment on this since his message originally suggested the use of this kind of flag. The basic idea is that while it might be nice in practise so separate out the code into the part which is specific to each of the three pseudo-initialization functions and the part which is common, this kind of separation may be difficult to do in practise. For this reason it is convenient to have the shared code know who its caller was. That way the shared code can make decisions about what to do based on who its caller is. As you point out this can be done by passing in a function which will be called, but this just reduces it to having to separate any code which is partly shared and partly initializer-specific. The intuition is that this would prove to be a pain in practise. Each of the update functions would take an extra argument, which is the initializer function. The code that invokes the updaters would pass in the current function binding for shared-initialize. If a user wanted to alter the shared initialization behavior he would define a method on shared-initialize, as in Gregor's scheme. If he wanted to define radical new update behavior, he would define methods on initialize-instance, reinitialize-instance, update-instance-structure, or class-changed, as in Gregor's scheme. As I mentioned, the problem isn't when you want to define radically new behavior its when you want to define behavior which is a complex blend, Suppose he wanted to change the initialization behavior for, let's say, reinitialize-instance. In Gregor's scheme he would write a method on shared-initialize which discriminated on the identity of the second argument. In my proposal he would write a method on reinitialize-instance and supply a new initializer function: I never intended for anyone to write methods which discriminated on the identity of the caller argument. I would certainly think it was a bad idea to do that. My idea was that the caller argument would be used as a flag inside the method itself. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 13:55:32 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 10:47:06 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 06 APR 88 10:41:01 PDT Date: 6 Apr 88 10:40 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: CLOS, and slot hiding. In-reply-to: mike%acorn@LIVE-OAK.LCS.MIT.EDU (mike@gold-hill.com any day now)'s message of Tue, 5 Apr 88 15:05 est To: mike%acorn@LIVE-OAK.LCS.MIT.EDU cc: kempf@Sun.COM, common-lisp-object-system@sail.stanford.edu, sidney@LIVE-OAK.LCS.MIT.EDU, ariel@oz.ai.mit.edu Message-ID: <880406-104101-5261@Xerox> I agree with the comments made by Moon about the design goals of CLOS. Alan Snyder made a big pitch for having encapsulation be an important goal for the Common Lisp community, and it was rejected. One reason is that it was hard (as Moon mentioned) and another is because it does not fit into the philosophy of Lisp, which has always prided itself on being an open system (this is the point that Jim made so well). The metaobject protocol (Chapter 3) is designed to allow people to experiment with additions and variations on the language. Jim Kempf put Common Objects on top of CLOS using the MOP, and Common Objects has some of the properties you are talking about (if I understand you properly). Do you have a real example in mind? danny  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 13:54:43 EDT Date: 06 Apr 88 1043 PDT From: Dick Gabriel Subject: Reinitialization To: common-lisp-object-system@SAIL.Stanford.EDU I agree with Gregor's analysis and with the general outline of his solution. However, I usually have bad reactions to the use of flags to signify flow of control, so I would prefer to have some other means of implementing the solution. Here is a possibility, which has its own drawbacks, but which I believe is better. Sample code: (defmethod make-instance ((class standard-class) &rest initargs) (let ((defaulted-initargs (default-initargs class initargs))) (check-initargs class defaulted-initargs) (let ((instance (apply #'allocate-instance class defaulted-initargs))) (apply #'initialize-instance class #'shared-initialize defaulted-initargs) instance))) (defmethod initialize-instance ((instance standard-object) initializer &rest initargs) (apply initializer instance initargs)) (defmethod reinitialize-instance ((instance standard-object) initializer &rest initargs) (apply initializer instance initargs)) (defmethod update-instance-structure ((instance standard-object) initializer added-slots discarded-slots property-list) (funcall initializer instance)) (defmethod class-changed ((previous standard-object) (current standard-object) initializer) (funcall initializer current)) (defmethod shared-initialize ((instance standard-object) &rest initargs) .. initialize the slots from the initargs in the order .. .. specified in chapter 1 .. .. .. for any slots which are still unbound, initialize .. .. them from their initforms .. ) Each of the update functions would take an extra argument, which is the initializer function. The code that invokes the updaters would pass in the current function binding for shared-initialize. If a user wanted to alter the shared initialization behavior he would define a method on shared-initialize, as in Gregor's scheme. If he wanted to define radical new update behavior, he would define methods on initialize-instance, reinitialize-instance, update-instance-structure, or class-changed, as in Gregor's scheme. Suppose he wanted to change the initialization behavior for, let's say, reinitialize-instance. In Gregor's scheme he would write a method on shared-initialize which discriminated on the identity of the second argument. In my proposal he would write a method on reinitialize-instance and supply a new initializer function: (defmethod reinitialize-instance ((instance my-class) initializer &rest initargs) (generic-labels ((shared-initialize ...)) (apply #'call-next-method instance shared-initialize initargs))) [Note that due to the 2 namespace problem I cannot use with-added-methods to easily alter initializer. Maybe we should change with-added-methods to add an option that says here is the generic function to use? (defmethod reinitialize-instance ((instance my-class) initializer &rest initargs) (with-added-methods (initializer (instance &rest initargs) (:generic-function initializer) (:method ((instance my-class) &rest initargs) ...)) (apply #'call-next-method instance initializer initargs)))] -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 13:22:49 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Apr 88 10:15:08 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 376857; Wed 6-Apr-88 13:14:28 EDT Date: Wed, 6 Apr 88 13:14 EDT From: David A. Moon Subject: Re: CLOS, and slot hiding. To: kempf@Sun.COM cc: "mike@gold-hill.com any day now" , common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8804061630.AA01292@suntana.sun.com> Message-ID: <19880406171441.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Jim, I agree with your very clear message and wish I had said the same things in mine, in addition to what I did say.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 12:47:13 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:39:47 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA16269; Wed, 6 Apr 88 09:38:03 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA28297; Wed, 6 Apr 88 09:37:38 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA01292; Wed, 6 Apr 88 09:30:52 PDT Message-Id: <8804061630.AA01292@suntana.sun.com> To: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now) Cc: kempf@Sun.COM, common-lisp-object-system@sail.stanford.edu, sidney@XX.LCS.MIT.EDU, ariel@oz.ai.mit.edu Subject: Re: CLOS, and slot hiding. In-Reply-To: Your message of Tue, 05 Apr 88 15:05:00 -0500. <8804061603.AA15672@Sun.COM> Date: Wed, 06 Apr 88 09:30:08 -0700 From: kempf@Sun.COM >I would like to be able to define a class that has certain advertised >behavior that I can advertise to users who will use it as a superclass >of their own defined classes, as a mixin. All I need to advertise are >the names, calling sequences and effects of some methods. As far as I >can tell, CLOS requires me to also advertise the names of the instance >variables that the methods use internally to contain state, so that >users can avoid name collisions when they define their own instance >variables. There are a couple of considerations here. Slots with no declared accessors will not be accessable to the outside world via access generic functions. One way to achieve encapsulation is to not declare accessors. This still leaves WITH-SLOTS, but if you don't want the slots to be accessable through WITH-SLOTS, just don't export their names from the package in which the class is defined. >If the package system is really the only way to do this, then there >is really a deep flaw in CLOS. It doesn't support classes for >data-abstraction very well at all. Was this issue every discussed >in the design of CLOS? I think you have this backwards. The flaw (if any) is not in CLOS but in Common Lisp. The charter of the CLOS committee was to design an object-oriented extension to Common Lisp, not to "fix" Common Lisp. Common Lisp deals with modularity using name spaces, packages being one method of establishing a name space. If the extension were to Scheme, then environments would be used for establishing the modularity needed for data abstraction. Extending any language for object-oriented programming requires that the fundamental abstraction principles of the language be used and compatibility extended, otherwise the extension becomes unworkable. If you subclass, it should not matter what you name the slots as long as the names are in a different package. When resolution of slot names occurs, you will, of course, get slots with names that are the same except for the package, but since putting something in a different package is usually an indication that it is functionally distinct, this should not matter to the structure of the program. In this manner, you should not have to use gensym's or other tricks to be sure that no name collisions occur. >I want to use the SAME name, i.e. identical package, etc. >Using a separate package is unacceptable, as the package namespace in >common lisp is a GLOBAL space. Gensymming symbols and gensymming packages >seem like the same solution to me, both equally "tricky". You want to use the same name but have it mean something different? I'm confused, sorry. Do you have an example? jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 12:45:36 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:38:07 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 376793; Wed 6-Apr-88 12:37:45 EDT Date: Wed, 6 Apr 88 12:37 EDT From: David A. Moon Subject: Re: CLOS, and slot hiding. To: "mike@gold-hill.com any day now" cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 5 Apr 88 16:05 EDT from "mike@gold-hill.com any day now" Message-ID: <19880406163752.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 5 Apr 88 15:05 est From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now) >I would like to be able to define a class that has certain advertised >behavior that I can advertise to users who will use it as a superclass >of their own defined classes, as a mixin. All I need to advertise are >the names, calling sequences and effects of some methods. As far as I >can tell, CLOS requires me to also advertise the names of the instance >variables that the methods use internally to contain state, so that >users can avoid name collisions when they define their own instance >variables. If the package system is really the only way to do this, then there is really a deep flaw in CLOS. It doesn't support classes for data-abstraction very well at all. Was this issue every discussed in the design of CLOS? Yes, it was discussed quite a bit. Providing more information-hiding than the package system provides was decided to be not a goal of CLOS, basically because it's difficult. Since the goals of CLOS have never been published, this is my personal judgement, but I think the other members of the CLOS working group would agree that this is a reasonably accurate statement of the history. Note that I am not claiming that CLOS provides excellent data abstraction and I am not claiming that it would be useless to have explicit modularity boundaries between subclasses and superclasses. What I am claiming, and there is plenty of support for this claim, is that standardization efforts that do too much innovation beyond current practice generally fail. CLOS is a standardization effort, not primarily a research effort, and there is no expectation that researchers won't develop a better language a few years from now. The purpose of CLOS is to satisfy the people who need a standard, portable, efficient, well-documented object-oriented programming language right now and can't afford to wait a few years. I in fact think that CLOS as it is went too far in the research direction and that is why it's taken longer than expected and come out a little more incoherent than we would like. I would like to submit this as an official comment on the draft CLOS spec (88-002) for x3j13. Fine. I'm not sure if we've yet appointed anyone to be responsible for collecting the official comments and making sure we have responses to them, but this exchange of messages should be saved as part of that. The class abstraction should support this kind of information hiding. The names of the instance variables should not be automatically inherited by the subclasses in every case. One must at least be able to override this default behavior and specify that certain instance variables are specific to the class and thereby avoid the name conflict problem with instance variables of subclasses. I imagine that chapter 3 will provide the ability to extend the system in this direction, if you define your own methods to replace enough of the standard programmer interface. Since chapter 3 is barely started at this point, it's hard to make a definitive statement about that.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Apr 88 12:12:05 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:04:57 PDT Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 5 Apr 88 15:28-EDT Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM (DIAL|DIAL|6210575) by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86206; 5 Apr 88 15:25:28-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98107; Tue 5-Apr-88 15:06:08-EST Date: Tue, 5 Apr 88 15:05 est From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now) COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW To: kempf@Sun.COM Subject: Re: CLOS, and slot hiding. Cc: mike%acorn@oak.lcs.mit.edu, common-lisp-object-system@sail.stanford.edu, sidney, ariel@oz.ai.mit.edu Date: Mon, 04 Apr 88 08:34:59 -0700 From: kempf@Sun.COM >I would like to be able to define a class that has certain advertised >behavior that I can advertise to users who will use it as a superclass >of their own defined classes, as a mixin. All I need to advertise are >the names, calling sequences and effects of some methods. As far as I >can tell, CLOS requires me to also advertise the names of the instance >variables that the methods use internally to contain state, so that >users can avoid name collisions when they define their own instance >variables. There are a couple of considerations here. Slots with no declared accessors will not be accessable to the outside world via access generic functions. One way to achieve encapsulation is to not declare accessors. This still leaves WITH-SLOTS, but if you don't want the slots to be accessable through WITH-SLOTS, just don't export their names from the package in which the class is defined. If the package system is really the only way to do this, then there is really a deep flaw in CLOS. It doesn't support classes for data-abstraction very well at all. Was this issue every discussed in the design of CLOS? I would like to submit this as an official comment on the draft CLOS spec (88-002) for x3j13. The class abstraction should support this kind of information hiding. The names of the instance variables should not be automatically inherited by the subclasses in every case. One must at least be able to override this default behavior and specify that certain instance variables are specific to the class and thereby avoid the name conflict problem with instance variables of subclasses. If you subclass, it should not matter what you name the slots as long as the names are in a different package. When resolution of slot names occurs, you will, of course, get slots with names that are the same except for the package, but since putting something in a different package is usually an indication that it is functionally distinct, this should not matter to the structure of the program. In this manner, you should not have to use gensym's or other tricks to be sure that no name collisions occur. I want to use the SAME name, i.e. identical package, etc. Using a separate package is unacceptable, as the package namespace in common lisp is a GLOBAL space. Gensymming symbols and gensymming packages seem like the same solution to me, both equally "tricky". >What I really want to be able >to do is define instance variables whose names are local to the >specific superclass. ...mike beckerle Gold Hill P.S., I really should give credit to marty hiller (ariel@oz) for this observation about CLOS instance variables. She passed it on to sidney who passed it on to me.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Apr 88 23:04:39 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 Apr 88 19:54:21 PDT Received: from Semillon.ms by ArpaGateway.ms ; 05 APR 88 19:52:00 PDT Date: Tue, 5 Apr 88 19:51 PDT From: Gregor.pa@Xerox.COM Subject: comments from Kathy Chapman To: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text Message-ID: <880405195147.4.GREGOR@SPIFF.parc.xerox.com> Line-fold: no In this morning's mail, I received handwritten comments from Kathy Chapman on Chapters 1 and 2. She seems to have marked up almost all the pages, so typing her comments in isn't practical. Mostly she seems to have homed in on places in the specification where the language was confusing to her. Given that, I think the best thing to do is for me to give this marked up copy to Dick and Linda so that they can address her comments by going through the draft. If they find comments that require we look into some of our past design decisions then we can do that on the mailing list in the usual way. (Editors note, I wanted to say "that require us to reassess some of our design decisions", but it seems that `reassess' is not a real word.) If someone else really wants a copy of her comments I could make one and send it to you, but I don't plan to make any copies unless someone asks me to. P.S. Has anyone else received comments from people? -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Apr 88 20:54:38 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 Apr 88 17:46:28 PDT Received: from Semillon.ms by ArpaGateway.ms ; 05 APR 88 17:37:58 PDT Date: Tue, 5 Apr 88 17:37 PDT From: Gregor.PA@Xerox.COM, Bobrow.PA@Xerox.COM Sender: Gregor.pa@GRAPEVINE.parc.xerox.com Subject: (re)initialization revisited To: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text Message-ID: <880405173737.1.GREGOR@SPIFF.parc.xerox.com> Line-fold: no This message addresses some important issues which we would like to get feedback on as soon as possible. Please send at least some sort of comment as soon as time permits. This message attempts to address some of the problems Moon brought up with reinitialize-instance. In thinking about this we came to the some of the same conclusions he did, namely that we really needed to integrate initialize-instance, update-instance-structure and class-changed a little more. Having done that, we were able to fit reinitialize-instance in quite easily. This message is in 3 parts. The first part introduces the observations we made when we went back to think about this. The second part outlines change to existing parts of chapter 1 and 2. The third part starts from that change, modularizes it better and introduces reinitialize-instance. Part 1. First lets look at the existing generic functions initialize-instance, update-instance-structure and class-changed. In looking at the specification of these functions, we can see that the each one's primary method is doing something very close to identical. They could almost be calling a common subroutine. The most interesting thing is that except for some very special cases, they could in fact call a common subroutine. We believe, that while we were designing these sections, we (all of us) must have intended for them to "call" that common subroutine. Part 2. So, we would like to modify the primary methods for initialize-instance, update-instance-structure and class-changed to have a common behavior. This common behavior could be defined by a shared subroutine. (defun subroutine (instance &rest initargs) .. initialize the slots from the initargs in the order .. .. specified in chapter 1 .. .. .. for any slots which are still unbound, initialize .. .. them from their initforms .. ) In order to understand this change fully, lets look carefully at cases where this would actually cause different behavior: INITIALIZE-INSTANCE This is actually not a change for initialize instance. There may be some problems with some of the mentioned optimizations, but lets come back to that in another message. UPDATE-INSTANCE-STRUCTURE (Note that update-instance-structure would not call the subroutine with any initargs, so only the part which sets unbound slots to the result of evaluating their initforms would apply.) The difference is when a slot appears in both the old and new versions of the class, has an initform in the new version of the class, and is unbound in an instance at the time of class redefinition. Under the old definition, update-instance-structure would do nothing to the slot. Under the new definition, update-instance-structure would set the slot to the result of evaluating its initform. CLASS-CHANGED Class-changed is exactly analogous to update-instance-structure. If there is a slot which appears in both the old and new classes, and that slot is unbound at the time of change-class, the new definition of class-changed will set its value to the result of evaluating the initform. The old definition wouldn't have touched the slot at all. Part 3. The proposal we would like to make is to have the subroutine which does the setting of slots described above moved to the standard method of a new generic function called shared-initialize (all names here could be improved upon). Initialize-instance, update-instance-structure and class-changed would each call shared-initialize. Users who wanted to add code to one of the specific update functions would define a method on it. Users who want to add initialization code common to all the ways an instance is initialize would define a method on shared-initialize. In order for user defined methods on shared-initialize to know why they were being called, shared-initialize takes an argument which is the name of the generic function which called it. Given this structure, reinitialize-instance would be a generic-function just like the other three, its standard method would call shared-initialize with 'reinitialize-instance as the second argument. Here is some sample code: (defmethod make-instance ((class standard-class) &rest initargs) (let ((defaulted-initargs (default-initargs class initargs))) (check-initargs class defaulted-initargs) (let ((instance (apply #'allocate-instance class defaulted-initargs))) (apply #'initialize-instance class defaulted-initargs) instance))) (defmethod initialize-instance ((instance standard-object) &rest initargs) (apply #'shared-initialize instance 'initialize-instance initargs)) (defmethod reinitialize-instance ((instance standard-object) &rest initargs) (apply #'shared-initialize instance 'reinitialize-instance initargs)) (defmethod update-instance-structure ((instance standard-object) added-slots discarded-slots property-list) (shared-initialize instance 'update-instance-structure)) (defmethod class-changed ((previous standard-object) (current standard-object)) (shared-initialize current 'class-changed)) (defmethod shared-initialize ((instance standard-object) caller &rest initargs) .. initialize the slots from the initargs in the order .. .. specified in chapter 1 .. .. .. for any slots which are still unbound, initialize .. .. them from their initforms .. ) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 4 Apr 88 20:54:35 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 04 APR 88 17:48:34 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 04 APR 88 17:47:15 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA19021; Mon, 4 Apr 88 17:46:35 PDT Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2) id AA18131; Mon, 4 Apr 88 17:46:22 PDT Received: by clam.sun.com (3.2/SMI-3.2) id AA18117; Mon, 4 Apr 88 17:48:21 PDT Date: Mon, 4 Apr 88 17:48:21 PDT From: cperdue@Sun.COM (Cris Perdue) Message-Id: <8804050048.AA18117@clam.sun.com> To: commonloops.pa@Xerox.COM Subject: Portable macroexpansions again Here is another portable macroexpander, one that has been working well for me on both the Lucid and Franz products. Perhaps it can be of use to portability of the PCL code walker or others. Please respond with comments, rotten fruit, etc.: In alternate-macroexpand-1, "env" is the code walker's own variety of environment data structure. Macro-env-spec is something this code calls that returns a list of local macro definitions in the same form as in a macrolet. I compute and retain this every time the local macroexpansion environment changes due to flet or macrolet, stacking and unstacking it along with other environmental information. ;;; Call this like macroexpand-1, but only in cases where the ;;; form is determined to be a macro call. Only the first returned value is ;;; useful. (defun alternate-macroexpand-1 (form &optional env) (let ((spec (macro-env-spec env))) (if spec (eval `(macrolet ,spec () (expansion ,form))) (macroexpand-1 form)))) ;;; Expands into a form that evaluates to the macroexpansion of FORM in the ;;; current macro environment. (defmacro expansion (form &environment env) (list 'quote (macroexpand-1 form env)))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Apr 88 19:38:33 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 16:31:46 PDT Received: from Semillon.ms by ArpaGateway.ms ; 04 APR 88 15:42:15 PDT Date: Mon, 4 Apr 88 15:41 PDT From: Gregor.pa@Xerox.COM Subject: Some early comments on 88-003 (accessor methods) To: David A. Moon , Bobrow.PA@Xerox.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <19880323170326.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <880404154147.8.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: Wed, 23 Mar 88 12:03 EST From: David A. Moon I don't understand why accessor methods are said to be created by an update-dependent method through a special deferred creation mechanism, rather than being created in the normal fashion as part of the macro expansion of defclass. Earlier we said that there is no real difference between an automatically created accessor method and one that the user writes himself, and that both should run at the same speed. Page 24 gives a reason (the class may not be fully defined) for delaying creating accessor methods, but this reason does not make any sense. There is no such restriction for ordinary methods. Right, accessor methods want to be added and removed by initialize-instance and reinitialize-instance respectively. The specific bit of illogic which is responsible for this is the third complete paragraph of page 24 which says: "These are generated by the update-dependent method on standard-class. It cannot be generated by initialize-instance since the class may not be fully defined when initialize-instance is called." As you point out, a class does not need to be fully defined to define methods on it. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Apr 88 19:38:18 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 16:31:53 PDT Received: from Semillon.ms by ArpaGateway.ms ; 04 APR 88 16:20:26 PDT Date: Mon, 4 Apr 88 16:20 PDT From: Gregor.pa@Xerox.COM Subject: update-instance-structure To: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text Message-ID: <880404162009.9.GREGOR@SPIFF.parc.xerox.com> Line-fold: no There are a couple of minor problems with the update-instance-structure section in chapter 2. In the arguments section, the first sentence where it says "When make-instances-obsolete is invoked..". It probably means something more like "After make-instances-obsolete is invoked, of after a class has been redefined, all the instances must be updated. When an instance is being updated ...". In the examples section. I believe the defmethod of update-instance-structure should be at the end of the example. Even though this code might work interpreted (in some implementations) it definitely won't compile. This is because setf of position-rho is used before position-rho is defined. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Apr 88 18:29:31 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 15:22:01 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 04 APR 88 14:42:31 PDT Date: Mon, 4 Apr 88 11:20 PDT From: Gregor.pa@Xerox.COM Subject: add-named-xxx To: common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text Message-ID: <880404112029.5.GREGOR@SPIFF.parc.xerox.com> Line-fold: no At our last meeting, there was some sentiment for making the behavior of add-named-class, ensure-generic-function and add-named-method more uniform. This message attempts to address those issues. I have spent some time thinking about this, and I still feel that while add-named-class and ensure-generic-function are similar, add-named-method is different. One way to see this is to think about the defining forms which these functions are the analog of. add-named-class is the analog of defclass; ensure-generic-function is the analog of defgeneric; add-named-method is the analog of defmethod. defclass and defgeneric each provide a way to specify the class of the metaobject created. One could imagine wanting to specialize the code that created and installed that metaobject based on its class. As an example, one could imagine wanting to have special code for creating a installing instances of a particular metaclass, say my-standard-class. One way to provide this kind of functionality is to have add-named-class and ensure-generic-functions each be generic-functions which specialize on their first argument. The first argument is the prototype instance of the class of metaobject being created. This leads us to define these generic functions as: (defmethod add-named-class ((proto standard-class) &key name superclass-names slot-specifications options environment) ;; This method implements the behavior specified for defclass ;; with (:metaclass standard-class). ) (defmethod ensure-generic-function ((proto standard-generic-function) &key name lambda-list argument-precedence-order . (rest of options from pg 2-49) . ) ;; This method implements the behavior specified for defgeneric ;; with (:generic-function-class standard-class). ) On the other hand, defmethod provides no mechanism for controlling the class of the generic function or the method it creates. For this reason it doesn't make sense for add-named-method to have that ability. On the other hand, it is possible to make add-named-method a little more uniform by having it take keyword arguments which get passed on to the make-instance of the method. (defun add-named-method (generic-function-name &rest keys &key qualifiers specializers &allow-other-keys) (let* ((gf (ensure-generic-function (class-prototype (class-named 'standard-generic-function)) :name generic-function-name)) (new-method (apply #'make-instance (generic-function-method-class gf) keys)) (old-method (get-method gf qualifiers specializers))) (when old-method (remove-method gf old-method)) (add-method gf new-method))) An alternate proposal would be to give the caller of add-named-method more control over the arguments passed to ensure-generic-function. My feeling is that it isn't worth cluttering up add-named-method to do that. If someone wants more control over the arguments to ensure-generic-function they can call it directly. ------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Apr 88 12:24:11 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 4 Apr 88 09:16:10 PDT Received: by ti.com id AA04225; Mon, 4 Apr 88 11:14:15 CDT Message-Id: <8804041614.AA04225@ti.com> Received: by tilde id AA18273; Mon, 4 Apr 88 11:03:35 CDT Date: Mon, 4 Apr 88 11:03:35 CDT From: dussud@ausome.csc.ti.com To: common-lisp-object-system@sail.stanford.edu Subject: Method-lambda and apply-method-lambda From: Patrick H Dussud To: Gregor.pa@XEROX.COM Cc: Common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Method-lambda and apply-method-lambda In-Reply-To: Msg of Mon, 28 Mar 88 11:35 PST from Gregor.pa@XEROX.COM Date: Mon, 28 Mar 88 11:35 PST From: Gregor.pa@XEROX.COM Subject: Method-lambda and apply-method-lambda Date: Fri, 25 Mar 88 14:38:09 CST From: Patrick H Dussud I have two kinds of comments about your proposal. I have some minor comments about the details of the proposal itself as well as some serious questions about whether it can work. I will start with the minor nits. make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT Since, as you say, the method function captures the contract between a class of generic function and a class of method, I think this generic function should receive the prototype method as an argument as well. I am not sure that I want to have to pass the method to apply-method? If I am going to pass the method, why don't I also pass the generic function? Good idea. I didn't put a method in there because I was under the impression that the modularity of the contract is broken. The way compute-effective-method is designed, the contract between the generic function and the method, abstracted by the local macro call-method will not depend on the method. Maybe I didn't look hard enough. Also, I am pretty sure we want to make compile work on these, which brings me to my second point. How does one write the following code in your proposal: (defun advise-1-arg-method (method) (let ((function (method-function method))) (reinitialize-instance method :function #'(method-lambda (a) (format *trace-output* "~&Got arg ~S" a) (funcall function a))))) You can do: (defun advise-1-arg-method (method) (let ((function (method-function method))) (reinitialize-instance method :function (make-method-function (method-generic-function method) (method-qualifiers method) (method-parameter-specializers method) `(lambda (a) (format *trace-output* "~&Got arg ~S" a) (funcall ,function a)))lambda-form ))) The point is that in this case the `method function lambda' appears lexically in the source code. That means that it can capture the lexical variable function. It also means that it is compiled at compile-file time. I see your point, but the problem is that you can't decide at compile time what will be the implementation of the abstraction without knowing anything about the class of generic function, or the method. The problem with make-method-function being a function instead of a macro is that even if all of[ GENERIC-FUNCTION QUALIFIERS SPECIALIZERS ] were known at compile time and constant, we couldn't do the closure you had in mind. If this is seen as a problem, we could make make-method-function be a macro that evaluates GENERIC-FUNCTION QUALIFIERS SPECIALIZERS at macroexpand time then calls the generic function: Expand-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT which produces something like: (function (lambda ....)). Note that what it produces is implementation dependent and can substitute lambda for something else. Note that your example does not work anyway. You call the original method function, but the continuation (a representation of the next-methods list) is lost in the process. I am sure that we need something, like a local macro defined inside of the expanded method function, that allows someone to get at the continuation, and then pass it to apply-method-function. I'll have to think more about it. Patrick.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Apr 88 11:49:43 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 08:42:56 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA09986; Mon, 4 Apr 88 08:42:01 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA29447; Mon, 4 Apr 88 08:41:48 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA04490; Mon, 4 Apr 88 08:35:01 PDT Message-Id: <8804041535.AA04490@suntana.sun.com> To: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88) Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: CLOS, and slot hiding. In-Reply-To: Your message of Mon, 04 Apr 88 06:48:00 -0500. <8804041243.AA08554@Sun.COM> Date: Mon, 04 Apr 88 08:34:59 -0700 From: kempf@Sun.COM >I would like to be able to define a class that has certain advertised >behavior that I can advertise to users who will use it as a superclass >of their own defined classes, as a mixin. All I need to advertise are >the names, calling sequences and effects of some methods. As far as I >can tell, CLOS requires me to also advertise the names of the instance >variables that the methods use internally to contain state, so that >users can avoid name collisions when they define their own instance >variables. There are a couple of considerations here. Slots with no declared accessors will not be accessable to the outside world via access generic functions. One way to achieve encapsulation is to not declare accessors. This still leaves WITH-SLOTS, but if you don't want the slots to be accessable through WITH-SLOTS, just don't export their names from the package in which the class is defined. If you subclass, it should not matter what you name the slots as long as the names are in a different package. When resolution of slot names occurs, you will, of course, get slots with names that are the same except for the package, but since putting something in a different package is usually an indication that it is functionally distinct, this should not matter to the structure of the program. In this manner, you should not have to use gensym's or other tricks to be sure that no name collisions occur. >What I really want to be able >to do is define instance variables whose names are local to the >specific superclass. In summary, by not making slots accessable through access functions and using the package system to isolate the names in the package where the superclass is defined, you can achieve this. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Apr 88 08:47:15 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 4 Apr 88 05:41:13 PDT Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 4 Apr 88 08:41-EDT Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86087; 4 Apr 88 08:38:51-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 97959; Sun 3-Apr-88 13:30:54-EST Date: Mon, 4 Apr 88 06:48 est From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88) COMMENTS: NOTE %acorn@oak... CHANGES TO @GOLD-HILL.COM ON 1-April-88 To: common-lisp-object-system@sail.stanford.edu Subject: CLOS, and slot hiding. This query came in from sidney marcowitz in our GOLDWORKS development group re: CLOS. I think it raises an important issue. Defstruct has the exact same problem, and I had hoped that CLOS would improve upon it in this area. The only discussion I find of this is page 1-13 of the new spec (88-002) which indicates that slots can be shadowed, but it seems to imply that if not shadowed they cannot be hidden. ...mike beckerle Gold Hill Computers ---------------------------------------------------------------------- I would like to be able to define a class that has certain advertised behavior that I can advertise to users who will use it as a superclass of their own defined classes, as a mixin. All I need to advertise are the names, calling sequences and effects of some methods. As far as I can tell, CLOS requires me to also advertise the names of the instance variables that the methods use internally to contain state, so that users can avoid name collisions when they define their own instance variables. For example, say I define a moving-object class that when included as a superclass provides methods for things like update-velocity. It should be transparent whether the internal representation uses cartesian or radial coordinates. But people who define classes that inherit from the moving-object class will have to know not to name any instance variables X and Y, or RAD and THETA, or whatever. Even worse, I can't change the internal representation of my moving-object class without the danger of creating collisions with names that my users have happened to choose. Using macros that create gensyms for the instance variables, or defining a new package for each such superclass, or choosing long ugly names that nobody will ever think of, all seem like unaesthetic solutions. What I really want to be able to do is define instance variables whose names are local to the specific superclass. This is a problem with the specification's support of data abstraction, modularity, and information hiding. What I would like to know is if CLOS addresses the problem, and if not, are there specific reasons that the CLOS committee has for leaving it out of the spec. Thanks, -- sidney  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Apr 88 21:23:53 EDT Received: from Salvador.ms by ArpaGateway.ms ; 03 APR 88 18:14:18 PDT Return-Path: <@CUNYVM.CUNY.EDU:VICTOR@carmen.uu.se> Redistributed: CommonLoops.pa Received: from CUNYVM.CUNY.EDU ([128.228.1.2]) by Xerox.COM ; 03 APR 88 18:10:54 PDT Received: from max.uu.se by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 5201; Sun, 03 Apr 88 12:31:41 EST Received: from bmc1.uu.se by max.uu.se; Sat, 2 Apr 88 23:48 MET Received: from TCP-DAEMON by bmc1.UU.SE; Sat, 2 Apr 88 11:38 MET Date: Sat, 2 Apr 88 11:38:20 From: Bj|rn Victor Subject: Re: built-in-class-of To: kanderso@wilma.bbn.COM Cc: CommonLoops.pa@Xerox.COM, kanderson@wilma.bbn.COM, Victor@carmen.uu.se In-Reply-To: <880329-192042-2161@Xerox> Message-ID: <880402113820.22.VICTOR@CARMEN> That code breaks XCL too, so I did the same but #+/-Xerox. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Apr 88 14:28:51 EST Received: from Salvador.ms by ArpaGateway.ms ; 01 APR 88 11:20:33 PST Return-Path: Redistributed: commonloops.PA Received: from NMFECC.ARPA by Xerox.COM ; 01 APR 88 11:19:40 PST Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ; Fri, 1 Apr 88 11:16:49 PST Date: Fri, 1 Apr 88 11:16:49 PST From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA Message-Id: <880401111649.2100021d@NMFECC.ARPA> To: commonloops.PA@Xerox.COM Subject: Where can I get CLOS? Date: Fri, 1-APR-1988 11:23 MST X-VMS-Mail-To: ARPA%"commonloops%xerox.com@nmfecc.arpa" Where can I get the latest CLOS and documentation?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Mar 88 17:02:39 EST Date: 31 Mar 88 1355 PST From: Dick Gabriel Subject: Error Terminology To: common-lisp-object-system@SAIL.Stanford.EDU RPG writes: ``\item{\bull} The type of a slot will always be {\tt (and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are the values of the {\bf :type} slot options contained in all of the slot specifiers. If no slot specifier contains the {\bf :type} slot option, the type of the slot will always be {\bf t}. No implementation is required to check that the value stored in a slot satisfies the type of the slot, but implementations are allowed to extend the \OS\ to check such values and to use the type of a slot during compilation.'' Actually, the part about compilation is intended to imply that an a slot may be implemented in a type-specific manner, but maybe using the term ``compilation'' might confuse people whose implementations don't have compilers. No implementation is required to check that the value stored in a slot satisfies the type of the slot, but implementations are allowed to extend the \OS\ to check such values, to use the type of a slot to determine its representation, and to use the type of a slot during compilation. The distinction I was trying to get at with the new formulation is to separate the type of a slot from the uses of the type of a slot. The original stated that meaning of the type of a slot was that the contents of a slot would always be of the type determined by the inherited slot type. This leads to the embarassing explanation that the contents don't have to obey this constraint. We wouldn't have to make the embarassing explanation if we defined what the type of a slot was without referring to the contents of the slot and left it as an extension that an implementation could use the type in various ways. The source of the embarassment is that we say that the meaning of the type of a slot is that the contents of the slot will always be of that type, except when it isn't. It struck me as being better to say that the type of a slot is computed in some manner and that implementations could respect that type if they wish, which is a less bizarre formulation. I suppose there is nothing wrong with the original. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Mar 88 00:01:20 EST Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 30 Mar 88 20:54:57 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 373331; Wed 30-Mar-88 23:54:38 EST Date: Wed, 30 Mar 88 23:54 EST From: David A. Moon Subject: Error Terminology To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 25 Mar 88 00:55 EST from Dick Gabriel Message-ID: <19880331045444.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 24 Mar 88 2155 PST From: Dick Gabriel .... On a related note, I think that one of the uses of the term ``undefined'' is suspect, though it is not on Moon's list of suspect uses: ``\item{\bull} The contents of a slot will always be of type {\tt (and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are the values of the {\bf :type} slot options contained in all of the slot specifiers. If no slot specifier contains the {\bf :type} slot option, the contents of the slot will always be of type {\bf t}. The result of attempting to store in a slot a value that does not satisfy the type of the slot is undefined.'' The suspicion is that this ought to be described some other, less sinister way: ``\item{\bull} The type of a slot will always be {\tt (and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are the values of the {\bf :type} slot options contained in all of the slot specifiers. If no slot specifier contains the {\bf :type} slot option, the type of the slot will always be {\bf t}. No implementation is required to check that the value stored in a slot satisfies the type of the slot, but implementations are allowed to extend the \OS\ to check such values and to use the type of a slot during compilation.'' If I understand what you're saying, the difference is that with the first description, and implementation is allowed to halt and catch fire if you store a bignum into a slot that is declared :type fixnum, while with the second description the implementation is not; it's required either to ignore the type declaration or to signal an error. Personally, I don't have strong feelings about type declarations, other than that they should be removed from Common Lisp entirely, so I'm not really in a position to choose between those two alternatives. However, if the purpose of type declarations is to allow optimization through specialized implementation techniques, I would think that you would not want to deny the implementation the freedom that the first description allows. Well, that wasn't very clear. What I mean is, the first description allows a slot to be implemented in a special type-specific way, as one might implement a local variable. The second description requires slots to be implemented in the general way that can hold all objects, but allows the type declaration to be used only for two purposes: to propagate that type through code that reads the slot, thereby doing type-specific optimization on that code, and to add a type check to code that writes the slot, signalling an error if the declaration is violated.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Mar 88 22:24:37 EST Received: from Cabernet.ms by ArpaGateway.ms ; 29 MAR 88 19:20:42 PST Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 29 MAR 88 19:18:59 PST To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: built-in-class-of Date: Tue, 29 Mar 88 22:12:23 -0500 From: kanderso@WILMA.BBN.COM Message-ID: <880329-192042-2161@Xerox> The code below does break KCL because of recursive compile. So i conditionalized it. From high.lisp: (defmacro define-built-in-classes (classes-and-supers &optional reset-p) `(eval-when (compile load eval) (when ,reset-p (setq *built-in-class-lattice* ())) (dolist (bic ,classes-and-supers) (pushnew bic *built-in-class-lattice* :test #'equal)) (define-built-in-classes-1) #-kcl (compile 'built-in-class-of (make-built-in-class-of)) ; ; This code was commented out and replaced with the above line ; but I think that might break KCL or Golden. ; #+kcl (setf (symbol-function 'built-in-class-of) #'(lambda (x) (declare (notinline built-in-class-of)) (compile 'built-in-class-of (make-built-in-class-of)) (built-in-class-of x))) ))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Mar 88 14:52:33 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 28 Mar 88 11:42:48 PST Received: from Semillon.ms by ArpaGateway.ms ; 28 MAR 88 11:38:48 PST Date: Mon, 28 Mar 88 11:35 PST From: Gregor.pa@Xerox.COM Subject: Method-lambda and apply-method-lambda To: Patrick H Dussud cc: Common-lisp-object-system@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <2784314289-5590063@Jenner> Message-ID: <880328113536.8.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: Fri, 25 Mar 88 14:38:09 CST From: Patrick H Dussud I have two kinds of comments about your proposal. I have some minor comments about the details of the proposal itself as well as some serious questions about whether it can work. I will start with the minor nits. make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT Since, as you say, the method function captures the contract between a class of generic function and a class of method, I think this generic function should receive the prototype method as an argument as well. I am not sure that I want to have to pass the method to apply-method? If I am going to pass the method, why don't I also pass the generic function? Also, I am pretty sure we want to make compile work on these, which brings me to my second point. How does one write the following code in your proposal: (defun advise-1-arg-method (method) (let ((function (method-function method))) (reinitialize-instance method :function #'(method-lambda (a) (format *trace-output* "~&Got arg ~S" a) (funcall function a))))) The point is that in this case the `method function lambda' appears lexically in the source code. That means that it can capture the lexical variable function. It also means that it is compiled at compile-file time. I think both of these are important properties. Perhaps the solution is to have the generic function you say, but specify in addition that the standard method returns (METHOD-LAMBDA (..) ...). -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Mar 88 13:53:50 EST Received: from ti.com by SAIL.Stanford.EDU with TCP; 28 Mar 88 10:44:49 PST Received: by ti.com id AA23660; Mon, 28 Mar 88 12:43:57 CST Received: from Jenner by tilde id AA07959; Mon, 28 Mar 88 12:41:54 CST Message-Id: <2784566339-4218491@Jenner> Date: Mon, 28 Mar 88 12:38:59 CST From: Patrick H Dussud To: kempf@sun.com Cc: Common-lisp-object-system@sail.stanford.edu Subject: Re: Method-lambda and apply-method-lambda In-Reply-To: Msg of Fri, 25 Mar 88 13:43:43 -0800 from kempf@sun.com >>I don't think that method-lambda, as describe in 88-003 is good enough. It >>captures the contract between a class of generic functions and a class of methods, >>so it should be metaclass driven. You can imagine several contracts on a single >>implementation. Why, precisely, do you think there need be any difference between a method function and any other kind of function? I can understand this for a generic function, since a generic function has slots, but a method function has none. It seems to me that most of how a method function differs is covered by additions to its lexical environment, and that FUNCALL and APPLY should do. I agree that in structure, a method function is like any other function. However method functions are getting called with(in) an implementation dependent environment that must be abstracted from the user. This is the motivation for the encapsulation (method-lambda, apply-method-lambda) given in chapter 3. The point of my earlier message is that this encapsulation should be metaclass dependent. The things that may be contained in the environment are(among others): Permutation vector(s), call-next-method list. This environment is distinct from the lexical environment of a closure. That does not prevent some implementation to code it as if it were a lexical environment, but that's an implementation choice. Patrick.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Mar 88 21:17:10 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 25 Mar 88 18:10:31 PST Received: from Cabernet.ms by ArpaGateway.ms ; 25 MAR 88 18:06:16 PST Date: 25 Mar 88 18:06 PST From: Masinter.pa@Xerox.COM Subject: Re: Error Terminology In-reply-to: Dick Gabriel 's message of 24 Mar 88 21:55 PST To: RPG@SAIL.Stanford.EDU cc: common-lisp-object-system@SAIL.Stanford.EDU Message-ID: <880325-180616-1599@Xerox> You'll have to define "harmless". I think you'll find it difficult.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Mar 88 21:00:45 EST Received: from Salvador.ms by ArpaGateway.ms ; 25 MAR 88 17:49:34 PST Return-Path: Redistributed: CommonLoops.PA Received: from SUMEX-AIM.Stanford.EDU by Xerox.COM ; 25 MAR 88 17:46:56 PST Date: Fri, 25 Mar 88 17:47:30 PST From: James Rice Subject: PCL on TI Explorers To: CommonLoops.PA@Xerox.COM Message-ID: <12385274995.58.RICE@SUMEX-AIM.Stanford.EDU> I sent out a message about this a while ago but it looks like the wheel is being re,reinvented. We have fixes here which interface PCL to the TI inspector, flavor inspector (making it a class inspector as well), Zmacs and such, including a function spec handler... If you'd like any of these please drop me a line and I'll point you at the sources. Rice. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Mar 88 16:58:42 EST Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 25 Mar 88 13:51:49 PST Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA21629; Fri, 25 Mar 88 13:50:37 PST Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA16532; Fri, 25 Mar 88 13:50:48 PST Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA03557; Fri, 25 Mar 88 13:43:46 PST Message-Id: <8803252143.AA03557@suntana.sun.com> To: Patrick H Dussud Cc: Common-lisp-object-system@sail.stanford.edu Subject: Re: Method-lambda and apply-method-lambda In-Reply-To: Your message of Fri, 25 Mar 88 14:38:09 -0600. <2784314289-5590063@Jenner> Date: Fri, 25 Mar 88 13:43:43 -0800 From: kempf@Sun.COM >>I don't think that method-lambda, as describe in 88-003 is good enough. It >>captures the contract between a class of generic functions and a class of methods, >>so it should be metaclass driven. You can imagine several contracts on a single >>implementation. Why, precisely, do you think there need be any difference between a method function and any other kind of function? I can understand this for a generic function, since a generic function has slots, but a method function has none. It seems to me that most of how a method function differs is covered by additions to its lexical environment, and that FUNCALL and APPLY should do. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Mar 88 16:44:59 EST Received: from ti.com by SAIL.Stanford.EDU with TCP; 25 Mar 88 13:37:52 PST Received: by ti.com id AA07168; Fri, 25 Mar 88 15:37:05 CST Received: from Jenner by tilde id AA19733; Fri, 25 Mar 88 14:40:27 CST Message-Id: <2784314289-5590063@Jenner> Date: Fri, 25 Mar 88 14:38:09 CST From: Patrick H Dussud To: Common-lisp-object-system@sail.stanford.edu Subject: Method-lambda and apply-method-lambda I don't think that method-lambda, as describe in 88-003 is good enough. It captures the contract between a class of generic functions and a class of methods, so it should be metaclass driven. You can imagine several contracts on a single implementation. I propose the following: Make-method-function is a generic function. make-method-function GENERIC-FUNCTION QUALIFIERS SPECIALIZERS LAMBDA-FORM &optional MACROEXPAND-ENVIRONMENT Generic-function is the generic-function object. Note that it can be gotten at compile-file time and is not expected to change incompatibly between compile-file time and load time. QUALIFIERS, SPECIALIZERS, LAMBDA-FORM are the "natural" arguments MACROEXPAND-ENVIRONMENT is necessary in order to capture the lexical context. It default to the null macroexpand environment. The generic function make-method-function returns a function suitable for the function slot of a method. Its representation is implementation dependent. The example given in 88-003 would be changed to: (defun trace-gf (gf) (let ((nargs (generic-function-required-arguments gf)) (lambda-list (generic-function-lambda-list gf)) (specializers (make-list nargs :initial-element (symbol-class 't))) (qualifiers '(:around)) (function (compile () (make-method-function gf qualifiers specializers `(lambda ,lambda-list (format *trace-output* "~&Hi there.") (call-next-method)))))) (add-method gf (make-instance 'standard-method :lambda-list lambda-list :specializers specializers :qualifiers qualifiers :function function)))) I am not sure that compile should or would work on the result of make-method-function. This must be decided. (defmethod (setf foo) :before ((x c1) y &rest z) (do-foo ...)) would expand into (let ((gf (ensure-generic-function '(setf foo)))) (add-named-method gf '(:before) '((x c1) y &rest z) (make-method-function gf '(:before) '(c1 t) '(lambda (x y &rest z) (do-foo ...))) environment)) --------- apply-method-lambda must be changed for the same reasons. I propose the following: apply-method METHOD NEXT-METHOD-LIST &rest ARGUMENTS [ generic function] apply-method is discriminated on METHOD. METHOD is the method that needs to be invoked. NEXT-METHOD-LIST is the list of all the methods that can be invoked by calling call-next-method. ARGUMENTS are the "external" arguments to the method. The last one should be a list of remaining arguments. Implementations are free to optimize this to internal function calling primitives. Patrick.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Mar 88 11:04:48 EST Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 25 Mar 88 07:57:51 PST Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA16688; Fri, 25 Mar 88 07:58:04 PST Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA04958; Fri, 25 Mar 88 07:58:16 PST Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA03308; Fri, 25 Mar 88 07:51:14 PST Message-Id: <8803251551.AA03308@suntana.sun.com> To: common-lisp-object-system@sail.stanford.edu Subject: Ch3 Date: Fri, 25 Mar 88 07:51:12 -0800 From: kempf@Sun.COM I haven't had time to review it yet, but will in a couple weeks. I basically agree with Moon's comments posted several days ago. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Mar 88 01:04:21 EST Date: 24 Mar 88 2155 PST From: Dick Gabriel Subject: Error Terminology To: common-lisp-object-system@SAIL.Stanford.EDU Earlier I mentioned that I had changed the wording surrounding the order of evaluation of initforms to use the term ``unspecified.'' I suspect that ``unspecified'' needs a definition, so here's an attempt. I think it is different from ``undefined.'' ``When situation $S$ occurs, the results are unspecified.'' This terminology has the following meaning: \beginlist \item{\bull} The effects of this situation are not specified in the \OS, but the effects are harmless. \item{\bull} Implementations are allowed to specify the effects of this situation. \item{\bull} No portable program can depend on the effects of this situation, and all portable programs are required to treat the situation as unpredictable but harmless. \endlist ******************************************************************** On a related note, I think that one of the uses of the term ``undefined'' is suspect, though it is not on Moon's list of suspect uses: ``\item{\bull} The contents of a slot will always be of type {\tt (and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are the values of the {\bf :type} slot options contained in all of the slot specifiers. If no slot specifier contains the {\bf :type} slot option, the contents of the slot will always be of type {\bf t}. The result of attempting to store in a slot a value that does not satisfy the type of the slot is undefined.'' The suspicion is that this ought to be described some other, less sinister way: ``\item{\bull} The type of a slot will always be {\tt (and} $T\sub 1$ $\ldots$ $T\sub n${\tt )} where $T\sub 1 \ldots T\sub n$ are the values of the {\bf :type} slot options contained in all of the slot specifiers. If no slot specifier contains the {\bf :type} slot option, the type of the slot will always be {\bf t}. No implementation is required to check that the value stored in a slot satisfies the type of the slot, but implementations are allowed to extend the \OS\ to check such values and to use the type of a slot during compilation.'' -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Mar 88 22:31:16 EST Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 24 Mar 88 18:55:19 PST Received: by labrea.Stanford.EDU; Thu, 24 Mar 88 17:55:55 PST Received: from bhopal.lucid.com by edsel id AA19705g; Thu, 24 Mar 88 17:47:27 PST Received: by bhopal id AA08754g; Thu, 24 Mar 88 17:47:18 PST Date: Thu, 24 Mar 88 17:47:18 PST From: Jon L White Message-Id: <8803250147.AA08754@bhopal.lucid.com> To: Moon@stony-brook.scrc.symbolics.com Cc: RPG@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu In-Reply-To: David A. Moon's message of Wed, 23 Mar 88 15:04 EST <19880323200429.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Subject: Error Terminology re: I'm not concerned about enforceability here, since this is a statement about programs rather than about implementations, Well, this is in a proposed part of a "spec"; and if that document makes its specifications by reference to what "valid programs" do, and if those specifications are inherently unenforceable, then no user will be able to determine whether or not his code is a valid program. E.g., it might be "invalid" only because he presumed that the undefined situation wouldn't delete all the files in his file system; yet that is not such an unreasonable requirement to expect even of "undefined" situations. That's why I think some of this murky area should be handled as "design notes" or "implemention notes" focusing on intent, rather than as "specifications". -- JonL --  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Mar 88 16:57:38 EST Received: from Cabernet.ms by ArpaGateway.ms ; 24 MAR 88 13:52:03 PST Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 24 MAR 88 13:47:53 PST Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA24650; Thu, 24 Mar 88 16:47:38 EST Received: by bigburd.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA20984; Thu, 24 Mar 88 16:47:33 EST From: fritzson@PRC.Unisys.COM (Richard Fritzson) Message-Id: <8803242147.AA20984@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd.PRC.Unisys.COM with PUP; Thu, 24 Mar 88 16:47 EST To: commonloops.pa@Xerox.COM Date: 24 Mar 88 16:47 EST (Thursday) To: commonloops.pa@Xerox.COM Subject: Latest PCL on Xerox and Sun/Allegro Cc: fritzson@bigburd.PRC.Unisys.COM Apologies to anyone who gets this twice. I mailed it out a couple of days ago and never received it so I suspect it was lost. The current version of PCL on parcvax does apparently run on the Xerox workstations under Lyric. I've succesfully compiled it and run a medium size PCL application with it. To compile the current version on a SUN 3 using Franz Allegro 2.2 I had to be sure that my *features* included :SUN3 (not just the usual :SUN) in order to properly compile fin.lisp. Other than that, it seems to work fine.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Mar 88 16:53:00 EST Received: from Semillon.ms by ArpaGateway.ms ; 24 MAR 88 13:45:48 PST Return-Path: <@CUNYVM.CUNY.EDU:VICTOR@carmen.uu.se> Redistributed: commonloops.pa Received: from CUNYVM.CUNY.EDU by Xerox.COM ; 24 MAR 88 13:43:07 PST Received: from max.uu.se by CUNYVM.CUNY.EDU ; Thu, 24 Mar 88 16:42:57 EST Received: from bmc1.uu.se by max.uu.se; Thu, 24 Mar 88 22:40 MET Received: from TCP-DAEMON by bmc1.UU.SE; Thu, 24 Mar 88 22:39 MET Date: Thu, 24 Mar 88 22:38:14 From: Bj|rn Victor Subject: Re: PCL on TI Explorers To: Cerys@XX.LCS.MIT.EDU Cc: commonloops.pa@Xerox.COM, Victor@carmen.uu.se In-Reply-To: <2784127840-3732781@RTS-12> Message-ID: <880324223814.16.VICTOR@CARMEN> I noticed the same thing, but used the Symbolics version in 3600-LOW and replaced "si:define-function-spec-handler" with "defun (:property method sys:function-spec-handler)". At some point I had to add a case for SYS:DWIMIFY, which just returns the original spec. Someday I'll patch up ZMACS to handle PCL, too. --Bjorn Victor Victor@Carmen.UU.SE Dept. of Computer Systems or Uppsala University, SWEDEN Victor%Carmen.UU.SE@uunet.UU.NET -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Mar 88 18:05:04 EST Date: 23 Mar 88 1454 PST From: Dick Gabriel Subject: Undefined To: common-lisp-object-system@SAIL.Stanford.EDU I have no problems with revisiting all the uses of the term ``undefined'' and changing some or all of them. Moon's instance 2, though, mistakenly uses the term ``undefined'' when it should say ``unspecified.'' I have already fixed it (several days ago) in the files: 2. The order of evaluation of default value forms and the order of evaluation of {\bf :initform} forms are unspecified. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Mar 88 17:26:59 EST Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 14:19:07 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368955; Wed 23-Mar-88 17:19:11 EST Date: Wed, 23 Mar 88 17:18 EST From: David A. Moon Subject: D'4 Example To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 23 Mar 88 16:14 EST from Dick Gabriel Supersedes: <19880323215912.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Comments: Added commentary on all 88-002 usages of the terminology being discussed Message-ID: <19880323221851.1.MOON@EUPHRATES.SCRC.Symbolics.COM> The text in question didn't say radical changes of class, it said any change of class. Maybe what this really shows is that no matter what you define to be undefined, a sufficiently clever implementor can come up with a subset of that that clearly should have been specified to be valid for extension rather than forever undefined. I suppose in a way you said the same thing by defining the set D'4 as the negation of another set. So what does this mean? I'm happy with your latest words for describing things that are specified to be forever undefined, but I'm probably not happy with some of the things that are specified that way. Actually, there are very few of them; ignoring duplicates, only six things are forever undefined in 88-002 (found by searching for all occurrences of the word "undefined"): 1. The result of attempting to store in a slot a value that does not satisfy the type of the slot is undefined. 2. The order of evaluation of default value forms and the order of evaluation of {\bf :initform} forms are undefined. 3. This implies that a programmer must not use {\bf change-class} inside a method if any methods for that generic function access any slots, or the results are undefined. 4. This argument has dynamic extent within {\bf change-class}; if it is referenced in any way once {\bf class-changed} returns, the results are undefined. 5. If these [print-object] rules are not obeyed, the results are undefined. 6. The results are undefined if the user attempts to change the class associated with a symbol that is defined as a type specifier by {\it Common Lisp: The Language.} I think 3, 5, and 6 are questionable. I can see reasons why implementation dependent extensions might make sense for each of these. If you read the rules referred to, #5 is particularly questionable. Are the results undefined if a print-object method does not look at *print-escape*? 1, 2, and 4 are noncontroversial, I think.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Mar 88 17:06:36 EST Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 13:59:28 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368943; Wed 23-Mar-88 16:59:14 EST Date: Wed, 23 Mar 88 16:59 EST From: David A. Moon Subject: D'4 Example To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 23 Mar 88 16:14 EST from Dick Gabriel Message-ID: <19880323215912.0.MOON@EUPHRATES.SCRC.Symbolics.COM> The text in question didn't say radical changes of class, it said any change of class. Maybe what this really shows is that no matter what you define to be undefined, a sufficiently clever implementor can come up with a subset of that that clearly should have been specified to be valid for extension rather than forever undefined. I suppose in a way you said the same thing by defining the set D'4 as the negation of another set. So what does this mean? I'm happy with your latest words for describing things that are specified to be forever undefined, but I'm probably not happy with some of the things that are specified that way.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Mar 88 16:22:10 EST Date: 23 Mar 88 1314 PST From: Dick Gabriel Subject: D'4 Example To: common-lisp-object-system@SAIL.Stanford.EDU Moon writes: ``Is this really a good example of an element of D'4?'' I think it is, but I'm probably thinking of a different situation than Dave is. If the two classes are similar somehow, such as making the class of some instance be HONDA-ACCORD when it used to be HONDA-PRELUDE, then it makes sense to extend CLOS to ``make it work.'' But there is nothing to prevent someone from changing the class of some instance from BALLISTIC-TRANSISTOR to MOJO-HAND. In this case what does it mean to be in a method selected on the basis of the inherent characteristics of an instance of BALLISTIC-TRANSISTOR when those characteristics all change? If there are two inheritance chains whose only common superclass is T, it is not unreasonable to find that the slot names defined by a pair of classes, one in each chain, could be the same. An implementor could ``make it work'' that slot accesses to same-named slots could not suffer a conniption, but what would such accesses mean? It is reasonable to require that when execution is lexically within some method, that the author of the method can count on the basic identity of the instances on the basis of which it was selected to not change. Those characteristics *might* change, so we do not want to detect such changes, but for the implementor to mandate some behavior in this bizarre case is beyond the reasonable scope of his work. Thus even the statement of what it would mean to extend CLOS to this situation is senseless. If the class of some instance radically changes (according to the author's ontology), the meaning of a method that continues while such a change happens is as stable or sensible as if the names of the slots in that instance were instantly permutted while the actual offsets used by the method remained the same. Thus, you could make it work, but you couldn't make it make sense. The new wording solves this problem by letting implementors go to extremes to make it work, while we've told the users to ignore the work done by the implementors. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Mar 88 15:12:50 EST Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 12:04:35 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368822; Wed 23-Mar-88 15:04:32 EST Date: Wed, 23 Mar 88 15:04 EST From: David A. Moon Subject: Error Terminology To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 22 Mar 88 11:11 EST from Dick Gabriel Message-ID: <19880323200429.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 22 Mar 88 0811 PST From: Dick Gabriel ``When situation $S$ occurs, the results are undefined.'' \item{\bull} No valid program may depend on the effects of this situation, and all valid programs are required to treat the effects of this situation as unpredictable. Agreed. I'm not concerned about enforceability here, since this is a statement about programs rather than about implementations, and although it has been proposed to validate implementations, no one has proposed to validate all the programs in existence. Is D'4 empty? No. Here is an example: ``This implies that a programmer must not use {\bf change-class} inside a method if any methods for that generic function access any slots, or the results are undefined.'' We don't want to make implementations detect uses of change-class within a method that accesses slots that might change as a result of the change-class. It's ok if an implementation detects it, though. But it's not ok for any implementor to try to extend CLOS to mean something in this case. An implementor might specify that when this situation happens the system has a conniption, but no reasonable programmer would depend on that. Is this really a good example of an element of D'4? I fail to understand why we want to forbid implementors from making this work. After all, the only problem with implementing this is that some optimizations of slot-value, which some people have in mind to use, can't handle it.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 Mar 88 14:09:43 EST Received: from Semillon.ms by ArpaGateway.ms ; 23 MAR 88 11:03:41 PST Date: Wed, 23 Mar 88 10:56 PST From: Gregor.pa@Xerox.COM Subject: bug with defmethod documentation strings To: CommonLoops.PA@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text Supersedes: <880323105612.6.GREGOR@SPIFF.parc.xerox.com> Message-ID: <880323105622.7.GREGOR@SPIFF.parc.xerox.com> Line-fold: no There is a bug in the current version of PCL which affects defmethod's whose body is just a single string. The bug is apparent in the following example: (defmethod type-string ((x symbol)) "a symbol") (type-string 'foo) ==> NIL instead of "a symbol" The following patch fixes this bug. Anyone who has run into this problem should install this patch in their macros.lisp file. ; from macros.lisp (eval-when (compile load eval) (defun extract-declarations (body &optional environment) (declare (ignore environment) (values documentation declarations body)) (let (documentation declarations form) (when (and (stringp (car body)) (cdr body)) (setq documentation (pop body))) (loop (when (null body) (return)) (setq form (car body)) (cond ((and (listp form) (eq (car form) 'declare)) (dolist (declaration (cdr (pop body))) (push declaration declarations))) (t (return)))) (values documentation `((declare ,.declarations)) body))) ) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 Mar 88 14:09:20 EST Received: from Semillon.ms by ArpaGateway.ms ; 23 MAR 88 10:58:15 PST Date: Wed, 23 Mar 88 10:51 PST From: Gregor.pa@Xerox.COM Subject: bug in 3-17-88 pcl, compute-effective-slotd To: John Alan McDonald cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: <8803230131.AA03430@entropy.ms.washington.edu> Message-ID: <880323105135.4.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: Tue, 22 Mar 88 17:31:08 PST From: jam@entropy.ms.washington.edu (John Alan McDonald) ;;; -*- Package: PCL; Mode: Lisp; Syntax: Common-Lisp; -*- ;;; In PCL version 3-17-88, Symbolics Genera 7.1, ;;; apparant bug in compute-effective-slotd ;; the following bombs: (defclass class1 () (x)) (defclass class2 (class1) ((x :type number))) The following patch fixes this problem. Everyone should install this patch in their std-class.lisp file. It replaces the existing definition of compute-effective-slotd. ; from std-class.lisp (defmethod COMPUTE-EFFECTIVE-SLOTD ((class standard-class) slotds) (let* ((unsupplied *slotd-unsupplied*) (name unsupplied) (keyword unsupplied) (initfunction unsupplied) (initform unsupplied) (initargs nil) (allocation unsupplied) (type unsupplied) (accessors (and (car slotds) (slotd-accessors (car slotds)))) (readers (and (car slotds) (slotd-readers (car slotds))))) (dolist (slotd slotds) (when slotd (when (eq name unsupplied) (setq name (slotd-name slotd) keyword (slotd-keyword slotd))) (when (eq initform unsupplied) (setq initform (slotd-initform slotd)) (setq initfunction (slotd-initfunction slotd))) (when (eq allocation unsupplied) (setq allocation (slotd-allocation slotd))) (setq initargs (append (slotd-initargs slotd) initargs)) (let ((slotd-type (slotd-type slotd))) (setq type (cond ((eq type unsupplied) slotd-type) ((eq slotd-type unsupplied) type) ((subtypep type slotd-type) type) (t `(and ,type ,slotd-type))))))) (when (eq initform unsupplied) (setq initfunction nil)) (when (eq type unsupplied) (setq type 't)) (when (eq allocation unsupplied) (setq allocation :instance)) (make-slotd class :name name :keyword keyword :initform initform :initfunction initfunction :initargs initargs :allocation allocation :type type :accessors accessors :readers readers))) -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Mar 88 13:15:27 EST Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 88 10:06:00 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 368620; Wed 23-Mar-88 12:03:23 EST Date: Wed, 23 Mar 88 12:03 EST From: David A. Moon Subject: Some early comments on 88-003 To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <19880323170326.4.MOON@EUPHRATES.SCRC.Symbolics.COM> I'm holding most of my comments until the next revision of chapter 3 comes out, since Gregor said a lot of things addressed at our meeting last week will be fixed, and the draft will be coming out within a couple of weeks. However, here are a couple of points that were not touched on in that meeting. Introduction: I'd like to see a one-page description of each protocol, instead of the present one or two sentence decriptions. This should cover what the protocol is for, who uses it, who implements it, what its limitations are, etc. By "who" I mean the CLOS system itself, a programmer working within that system, or a programmer extending the system. I'd also like to see a much clearer exposition of contracts for any generic functions that the user is intended to write methods for, clarifying constraints on the user's method and constraints on the caller. Right now the document doesn't even say which generic functions the user is supposed to be able to write methods for. I think the naming layer is a little too separate. I don't see why metaobject classes shouldn't accept the name as an initialization argument, instead of requiring it to be setf'ed separately. This name is just documentation: supplying the initialization argument doesn't cause setf of symbol-class or setf of symbol-function to be called of course. I don't understand why accessor methods are said to be created by an update-dependent method through a special deferred creation mechanism, rather than being created in the normal fashion as part of the macro expansion of defclass. Earlier we said that there is no real difference between an automatically created accessor method and one that the user writes himself, and that both should run at the same speed. Page 24 gives a reason (the class may not be fully defined) for delaying creating accessor methods, but this reason does not make any sense. There is no such restriction for ordinary methods. The return value of method-applicable-keywords (by the way, a confusing name), in the case where any keyword argument is valid because some method specifies &allow-other-keys, can't work. Page 27 says the symbol &allow-other-keys is a member of the list to signal this. But that's ambiguous with the tasteless but valid practice of using the symbol &allow-other-keys as a keyword argument name. Also representing the infinite list of all possible acceptable keywords with a finite list is a poor idea, because anyone who doesn't check for this case and just does MEMBER is bound to find some symbol that is not a member of the finite list, even though it is a member of the conceptual infinite list. This should be changed back to what I proposed originally, which is that the symbol &allow-other-keys is returned in place of the whole list. The way reinitialize-instance is specified can't work. The basic problem is that reinitialize-instance is specified to call initialize-instance, but an initialize-instance method has no way to find out whether it was called from reinitialize-instance or from make-instance. This makes it impossible to implement the specification (page 30) that "only those arguments explicitly given will affect the object." First, a user-written initialize-instance :after method that takes keyword arguments and defaults them is supposed to use the defaults if called from make-instance, but ignore the defaults if called from reinitialize-instance; there is no reasonable way to program that. Second, page 2-59 specifies some permissible optimizations for the default primary method for initialize-instance, and these optimizations are incompatible with what reinitialize-instance is doing. The use of :allow-other-keys in the default primary method for reinitialize-instance given on page 30 is also a dead giveaway that the modularity is wrong. In any case, make-instance and reinitialize-instance aren't the only two functions that need to put an instance into a consistent "initialized" state. Class-changed and update-instance-structure have similar needs (as Barmar pointed out during the plenary meeting). The general outline of the solution to this is obvious: there should be a generic function that acts as a common subroutine of all four of those functions, plus any others that are discovered. Initialization/update code that needs to be shared should be in methods for this new generic function, code that does not need to be shared should be in methods for the other generic functions. The arguments to this new generic function should probably be an instance, the name of the function that was originally called, and initargs. Reinitialize-instance should have its own method for dealing with the slots, instead of reusing the initialize-instance one. I don't have a full proposal yet, but it would be along these lines. It's also worth thinking about a more radical idea, in which initialize-instance would be broken into two parts, to get the modularity right. More work is needed here but I hope you can see why what's in the document today won't fly. Still in the reinitialization section, this update-dependents mechanism isn't quite right. The problem is the claim that all standard-objects support update-dependents, which then requires you to say that there are actually two different mechanisms for recording dependents, the general one that works for all standard-objects and the efficient one which is the one that you're really supposed to use. It doesn't make sense to stick every feature that sounds at all general into standard-object; that's pre-multiple-inheritance thinking. The update-dependents mechanism should be provided by a mixin with a documented name, which is a superclass of every class that needs the feature. I also have some minor comments about the interface to update-dependents, but they should wait a bit. The modularity of update-dependent for classes might be wrong, which probably means just that I think the keyword arguments it takes aren't the right ones. I'm not sure of my thinking here yet, but I thought I ought to mention it now in case it stimulates anyone else to think about this. When I get time I will do a detailed comparison of this with the way Flavors does it, which I believe to be both correct and fairly efficient. Don't forget that the document never says what the "access key instance access" protocol is for, how it's used, and what the keys are -- Gregor had to explain that in person. It needs to be in the document. Issues not covered at all (not a complete list, probably): - lexical generic functions, relation to class-direct-generic-functions - compile-time versus run-time environment issues  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 Mar 88 12:38:36 EST Received: from Semillon.ms by ArpaGateway.ms ; 23 MAR 88 09:24:37 PST Return-Path: Redistributed: commonloops.pa Received: from XX.LCS.MIT.EDU by Xerox.COM ; 23 MAR 88 09:19:43 PST Received: from RTS-12.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 23 Mar 88 11:52-EST Message-Id: <2784127840-3732781@RTS-12> Sender: cerys@RTS-12.ARPA Date: Wed, 23 Mar 88 11:50:40 EST From: "Daniel L. Cerys" To: commonloops.pa@Xerox.COM Subject: PCL on TI Explorers I just attempted to compile PCL on a TI Explorer but failed since there was no function-spec handler for pcl:method's. The following simple handler definition makes PCL usable on Explorers. This should probably go in TI-LOW.LISP. ;;;Added by Dan Cerys 22 Mar 88 (ticl:defprop method method-function-spec-handler sys:function-spec-handler) (defun method-function-spec-handler (function function-spec &optional arg1 arg2) (let ((symbol (second function-spec))) (case function (sys:validate-function-spec t) (otherwise (sys:function-spec-default-handler function function-spec arg1 arg2))))) [At some point, this handler should be augmented to handle other operations.] Dan  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Mar 88 18:11:04 EST Received: from Cabernet.ms by ArpaGateway.ms ; 22 MAR 88 14:54:04 PST Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 22 MAR 88 14:49:08 PST To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM, cjoor@WILMA.BBN.COM Subject: 3600 improvements, and specialized describe. Date: Tue, 22 Mar 88 17:47:14 -0500 From: kanderso@WILMA.BBN.COM Message-ID: <880322-145404-2599@Xerox> In 3/17 PCL: ;;; From 3600-low.lisp for M-x Kill definition (si:define-function-spec-handler method (op spec &optional arg1 arg2) (if (eq op 'sys:validate-function-spec) (and (let ((gspec (cadr spec))) (or (symbolp gspec) (and (listp gspec) (eq (car gspec) 'setf) (symbolp (cadr gspec)) (null (cddr gspec))))) (let ((tail (cddr spec))) (loop (cond ((null tail) (return nil)) ((listp (car tail)) (return t)) ((symbolp (pop tail))) (t (return nil)))))) (let ((table (if (listp (cadr spec)) *method-setf-fdefs* *method-fdefs*)) (key (if (listp (cadr spec)) (cons (cadadr spec) (cddr spec)) (cdr spec)))) (case op ((si:fdefinedp si:fdefinition) (gethash key table nil)) (si:fundefine ; KRA: For M-X Kill definition (multiple-value-bind (gf method nil) (parse-method-or-spec (cdr spec)) (remove-method gf method))) (si:fdefine (setf (gethash key table) arg1)) (otherwise (si:function-spec-default-handler op spec arg1 arg2)))))) ;;; Added to 3600-low.lisp to provide a proceed option for ;;; ENSURE-GENERIC-FUNCTION. (zl:defflavor generic-clobbers-function (name) (si:error) :initable-instance-variables) (zl:defmethod (dbg:report generic-clobbers-function) (stream) (format stream "~S aready names a ~a" name (if (and (symbolp name) (macro-function name)) "macro" "function"))) (zl:defmethod (sys:proceed generic-clobbers-function :specialize-it) () "Make it specializable anyway?" (make-specializable name)) ;;; From boot.lisp (defun ensure-generic-function (spec &rest keys &key lambda-list argument-precedence-order declarations documentation method-combination generic-function-class method-class) (declare (ignore lambda-list argument-precedence-order declarations documentation method-combination generic-function-class method-class)) (let ((existing (and (gboundp spec) (gdefinition spec)))) (cond ((null existing) (let ((new (apply #'ensure-gf-internal spec keys))) (setq new (set-function-name new spec)) (setf (gdefinition spec) new))) ((funcallable-instance-p existing) existing) (existing #+lispm (zl:signal 'generic-clobbers-function :name spec) #-lispm (error "~S already names an ordinary function or a macro,~%~ it can't be converted to a generic function." spec))))) ;;; Added to high.lisp ;;; KRA: I'm not sure why this isn't done in PCL. Should it be? (make-specializable 'describe) (defmethod describe ((anything object)) (declare (ignore no-complaints)) (describe-instance anything))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Mar 88 16:29:07 EST Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 22 Mar 88 13:23:09 PST Received: by labrea.Stanford.EDU; Tue, 22 Mar 88 13:23:47 PST Received: from bhopal.lucid.com by edsel id AA08496g; Tue, 22 Mar 88 13:21:42 PST Received: by bhopal id AA03932g; Tue, 22 Mar 88 13:21:26 PST Date: Tue, 22 Mar 88 13:21:26 PST From: Jon L White Message-Id: <8803222121.AA03932@bhopal.lucid.com> To: RPG@sail.stanford.edu Cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: Dick Gabriel's message of 22 Mar 88 0811 PST <8803221617.AA07359@edsel.lucid.com> Subject: Error Terminology re: \item{\bull} No valid program may depend on the effects of this situation, and all valid programs are required to treat the effects of this situation as unpredictable. Granting the complaint about "must not extend" being an un-enforceable clause, then I think this substitute for it is also un-enforceable (i.e. how can you determine whether a program treats some result as unpredictable). But the example you have found is brilliant; it cleary shows that the design cannot be silent about the situations you call D'4. That seems to be precisely the bug in CLtL -- that silence in this situation implicitly means "is an error", which for other reasons was defined to cover the "extensible" case too. Actually, I didn't think the original wording was all that bad -- "an implementation must not extend ...". Maybe what was bad about it was that it wasn't identified as a "designer's note" or "implementation note". -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Mar 88 11:17:08 EST Date: 22 Mar 88 0811 PST From: Dick Gabriel Subject: Error Terminology To: common-lisp-object-system@SAIL.Stanford.EDU Here is the concept behind the terminology. Let D be the domain of expressions and A a domain of answers. Let E be a function E: D x Env1 x ... x Envn => A. The meaning is that E takes some expressions in D plus some number of environments and produces an answer. E is the meaning of expressions. Let's restrict D to expressions described in CLOS. We consider projections of the domain of E to D. E is normally a partial function, being defined for only a subset of D, called D'. The error terminology has to do with describing the various elements in D-D'. There are 4 subsets of D' of interest; call them D'1, D'2, D'3, and D'4. D'1 is the subset such that attempting to apply E to its elements results in an error being signaled in all cases and implementations. D'2 is the subset such that attempting to apply E to its elements results in an error being signaled in the interpreter and under the safest compiler safety setting in all implementations. D'3 is the subset on which implementations are free to define new meanings - that is, an implementation is free to extend the domain of well-definedness to subsets of D'3. Note that D'1 and D'2 are pairwise disjoint with D'3. Let D'4 be D'4 = (D-D')-(D'1+D'2+D'3) We are talking about D'1 when we say ``When situation $S$ occurs, an error is signaled.'' We are talking about D'2 when we say ``When situation $S$ occurs, an error should be signaled.'' We are talking about D'3 when we say ``The \CLOS\ may be extended to cover situation $S$.'' And we are talking about D'4 when we say ``When situation $S$ occurs, the results are undefined.'' Notice that D'4 has an odd definition: It's not part of the required well-defined portion of D, we don't want to specify that all implementations try to detect elements of D'4 even in simple cases, and the authors of CLOS don't want anyone to extend CLOS to mean anything on those elements (sometimes because there is no reasonable meaning). Is D'4 empty? No. Here is an example: ``This implies that a programmer must not use {\bf change-class} inside a method if any methods for that generic function access any slots, or the results are undefined.'' We don't want to make implementations detect uses of change-class within a method that accesses slots that might change as a result of the change-class. It's ok if an implementation detects it, though. But it's not ok for any implementor to try to extend CLOS to mean something in this case. An implementor might specify that when this situation happens the system has a conniption, but no reasonable programmer would depend on that. Since we don't seem to want to tell implementors to keep their paws off of D'4, and since I assume we don't want some mathematical treatment like this message, how about telling users to keep their hands off of D'4, thus rendering the attempts of implementors fruitless? Note that we talk about valid programs, not portable ones. Thus someone living in one implementation has to think twice about venturing into D'4 land. ************************************************************************** ``When situation $S$ occurs, the results are undefined.'' This terminology has the following meaning: \beginlist \item{\bull} If this situation occurs, the results are unpredictable. The results may range from harmless to fatal. \item{\bull} Implementations are allowed to detect this situation and signal an error, but no implementation is required to detect the situation. \item{\bull} No valid program may depend on the effects of this situation, and all valid programs are required to treat the effects of this situation as unpredictable. \endlist **************************************************************************** -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Mar 88 03:23:35 EST Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 22 Mar 88 00:18:02 PST Received: by labrea.Stanford.EDU; Tue, 22 Mar 88 00:18:40 PST Received: from bhopal.lucid.com by edsel id AA05815g; Tue, 22 Mar 88 00:14:32 PST Received: by bhopal id AA02884g; Tue, 22 Mar 88 00:14:13 PST Date: Tue, 22 Mar 88 00:14:13 PST From: Jon L White Message-Id: <8803220814.AA02884@bhopal.lucid.com> To: Moon@stony-brook.scrc.symbolics.com Cc: RPG@sail.stanford.edu, common-lisp-object-system@sail.stanford.edu In-Reply-To: David A. Moon's message of Mon, 21 Mar 88 17:36 EST <19880321223621.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Subject: Proposed Wording Change to the Error Terminology (II) re: [... meaning of "it is undefined" ...] I suppose we could always ask X3J13 to appoint a separate committee for this, and then use whatever terminology they come up with in the CLOS document. That way I wouldn't have to feel any responsibility to try to help. It's indeed unfortunate that between the "Error" subcommittee and the "Cleanup" subcommittee, no one dared tackle the "it is an error" bug. I sincerely hope, if there is any real action on the matter, that you will feel the same professional responsibility to offer constructive comments as you have already done in so many other areas. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 19:34:46 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Mar 88 16:28:22 PST Received: from Semillon.ms by ArpaGateway.ms ; 21 MAR 88 15:57:53 PST Date: Mon, 21 Mar 88 15:04 PST From: Gregor.pa@Xerox.COM Subject: Proposed Wording Change to the Error Terminology (II) To: Dick Gabriel cc: common-lisp-object-system@SAIL.Stanford.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text In-Reply-To: The message of 21 Mar 88 13:29 PST from Dick Gabriel Message-ID: <880321150455.7.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: 21 Mar 88 13:29 PST From: Dick Gabriel \item{\bull} No implementation is allowed to extend the semantics of the \OS\ to this situation. Well this just solves the problem by being silent on the crucial issue. Its hard, but I think we can do better. What it we said something like: No implementation is allowed to extend the semantics of the \OS\ to this situation. This means that while a given implementation may document its behavior under the situation, no valid program should count on that behavior. During the X3J13 meeting, people were trying to draw a distinction between documenting what happened in the unspecified situation and featurizing that situation. I am trying to do something similar here without resorting to saying anything as gross as `featurize'. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 17:42:10 EST Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 88 14:35:54 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 367417; Mon 21-Mar-88 17:36:18 EST Date: Mon, 21 Mar 88 17:36 EST From: David A. Moon Subject: Proposed Wording Change to the Error Terminology (II) To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 21 Mar 88 16:29 EST from Dick Gabriel Message-ID: <19880321223621.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 21 Mar 88 1329 PST From: Dick Gabriel When you read this, take out your chapter 1 and read the rest of the section on error terminology. The suggestions about using the term ``portable'' as part of the definition of ``undefined'' seem to have been made under the influence of amnesia regarding the rest of the section. Not so. I put that suggestion there specifically to get you to articulate more clearly the difference between this "undefined" situation and the "may be extended" situation that follows it in chapter 1. \item{\bull} No implementation is allowed to extend the semantics of the \OS\ to this situation. This new wording is the vaguest yet, which I assume was your intention. Maybe that's best, I don't know. It doesn't seem to put to rest the objections that arose in the X3J13 meeting. I suppose we could always ask X3J13 to appoint a separate committee for this, and then use whatever terminology they come up with in the CLOS document. That way I wouldn't have to feel any responsibility to try to help. Maybe Sonya will have a good suggestion for how to word this, in two weeks when she gets back from vacation.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 16:36:15 EST Date: 21 Mar 88 1329 PST From: Dick Gabriel Subject: Proposed Wording Change to the Error Terminology (II) To: common-lisp-object-system@SAIL.Stanford.EDU When you read this, take out your chapter 1 and read the rest of the section on error terminology. The suggestions about using the term ``portable'' as part of the definition of ``undefined'' seem to have been made under the influence of amnesia regarding the rest of the section. **************************************************************************** ``When situation $S$ occurs, the results are undefined.'' This terminology has the following meaning: \beginlist \item{\bull} If this situation occurs, the results are unpredictable. The results may range from harmless to fatal. \item{\bull} No valid program should cause this situation to happen. \item{\bull} Implementations are allowed to detect this situation and signal an error, but no implementation is required to detect the situation. \item{\bull} No implementation is allowed to extend the semantics of the \OS\ to this situation. \endlist **************************************************************************** -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 16:09:07 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Mar 88 13:03:24 PST Received: from Cabernet.ms by ArpaGateway.ms ; 21 MAR 88 12:58:12 PST Date: Mon, 21 Mar 88 12:58:07 PST From: Pavel.pa@Xerox.COM Subject: Re: Proposed Wording Change to the Error Terminology In-reply-to: <19880321204529.4.MOON@EUPHRATES.SCRC.Symbolics.COM> To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880321-125812-3974@Xerox> In both of Moon's proposed rewordings, I would much rather see the word ``should'' instead of the word ``must''. It seems ludicrous to me for the conformance status of an implementation to depend upon its documentation. Pavel  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 15:51:27 EST Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 88 12:45:07 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 367268; Mon 21-Mar-88 15:45:31 EST Date: Mon, 21 Mar 88 15:45 EST From: David A. Moon Subject: Proposed Wording Change to the Error Terminology To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 18 Mar 88 20:46 EST from Dick Gabriel Message-ID: <19880321204529.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 18 Mar 88 1746 PST From: Dick Gabriel \item{\bull} No implementation is allowed to extend the semantics of the \OS\ to this situation; the effects of the situation may be described or specified by the implementors, but the effects may not be described as an extension to the \OS\. I must confess that I cannot figure out what this means. Do you mean simply that the word "extension" may not appear in the implementation's description? The previous text "the effects of the situation may be harmless, but they must remain undefined" seemed a little clearer to me, although still pretty obscure. With both wordings, I would find it very difficult to decide whether an implementation did or did not conform to the specification in this respect, unless the test is simply whether the word "extension" appears in the documentation (and the documentation is in English). To try to help clarify this, let me offer two proposed rewordings to choose from: (1) the effects of the situation may be described or specified by the implementors, but the description must warn that portable programs cannot depend on this behavior. (2) the effects of the situation may be described or specified by the implementors, but the description must warn that no properly written program, portable or not, should depend on this behavior.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 14:22:48 EST Date: 21 Mar 88 1115 PST From: Dick Gabriel Subject: Proposed Wording PicoChange to the Error Terminology To: common-lisp-object-system@SAIL.Stanford.EDU Dan Weinreb's proposed wording change is accepted. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 12:34:48 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Mar 88 08:10:16 PST Received: from Riesling.ms by ArpaGateway.ms ; 21 MAR 88 08:08:22 PST Sender: "James_L_Mayer.WBST128"@Xerox.COM Date: 21 Mar 88 08:07:13 PST (Monday) Subject: CLOS Status From: "James_L_Mayer.WBST128"@Xerox.COM To: Common-Lisp@SAIL.STANFORD.EDU cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Reply-to: "James_L_Mayer.WBST128"@Xerox.COM Message-ID: <880321-080822-3332@Xerox> Some questions about the Common Lisp Object System: (1) What is the status of the standard? When was the last draft spec released and how can I get a copy? (2) What is the implementation status? Is PCL still the best approximation available? (3) I will be running in Sun Common Lisp. What CLOS options are/will be open to me? Thank you. -- Jim Mayer  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Mar 88 12:34:06 EST Received: from Cabernet.ms by ArpaGateway.ms ; 21 MAR 88 09:26:09 PST Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 21 MAR 88 09:23:24 PST Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA05772; Mon, 21 Mar 88 12:23:02 EST Received: by bigburd.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA12386; Mon, 21 Mar 88 12:22:59 EST From: fritzson@PRC.Unisys.COM (Richard Fritzson) Message-Id: <8803211722.AA12386@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd.PRC.Unisys.COM with PUP; Mon, 21 Mar 88 12:22 EST To: commonloops.pa@Xerox.COM Date: 21 Mar 88 12:22 EST (Monday) To: commonloops.pa@Xerox.COM Subject: Franz SUN 3 compile of 3/17/88 pcl In order to compile the current "St. Patricks Day" release of PCL using ExCL on the SUN3, it is necessary to get :SUN3 into your *features* list. Otherwise not all of the essentail parts of FIN.LISP will be compiled. Inserting #+excl (push :sun3 *features*) into the list of "various hacks" near the top of defsys.lisp worked for me. I'm not certain offhand what the "correct" way to do this is.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Mar 88 12:11:26 EST Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 21 Mar 88 09:05:15 PST Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 179921; Mon 21-Mar-88 12:05:42 EST Date: Mon, 21 Mar 88 12:06 EST From: Daniel L. Weinreb Subject: Proposed Wording PicoChange to the Error Terminology To: RPG@SAIL.Stanford.EDU, common-lisp-object-system@SAIL.Stanford.EDU In-Reply-To: The message of 18 Mar 88 20:46 EST from Dick Gabriel Message-ID: <19880321170608.6.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: 18 Mar 88 1746 PST From: Dick Gabriel \item{\bull} If this situation occurs, the results are unpredictable. The results may range from harmless to fatal to the running system. Pico-nit: the second sentence reads as if the speaker were using the locution "From X to Y to Z", as in "We carry all brands of cameras, from Minoltas to Nikons to Canons". (As you might guess, I can't stand this construct, particularly when the speaker isn't even talking about a continuous range at all.) I'm not sure how to best fix this, but "The results may range from harmless to fatal" would be fine with me.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Mar 88 20:54:23 EST Date: 18 Mar 88 1746 PST From: Dick Gabriel Subject: Proposed Wording Change to the Error Terminology To: common-lisp-object-system@SAIL.Stanford.EDU At the x3j13 meeting this week there was some negative comments about the definition of ``undefined.'' The following is an attempt to address those criticisms. The last bullet is the part in question: **************************************************************************** ``When situation $S$ occurs, the results are undefined.'' This terminology has the following meaning: \beginlist \item{\bull} If this situation occurs, the results are unpredictable. The results may range from harmless to fatal to the running system. \item{\bull} No valid program should cause this situation to happen. \item{\bull} Implementations are allowed to detect this situation and signal an error, but no implementation is required to detect the situation. \item{\bull} No implementation is allowed to extend the semantics of the \OS\ to this situation; the effects of the situation may be described or specified by the implementors, but the effects may not be described as an extension to the \OS\. \endlist **************************************************************************** -rpg-  Received: from Xerox.COM (TCP 1500262350) by AI.AI.MIT.EDU 18 Mar 88 09:27:31 EST Received: from Chardonnay.ms by ArpaGateway.ms ; 18 MAR 88 06:21:38 PST Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 18 MAR 88 06:19:22 PST To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: change-class-internal bug Date: Fri, 18 Mar 88 09:11:19 -0500 From: kanderso@WILMA.BBN.COM Message-ID: <880318-062138-1202@Xerox> ;;; -*- Package: PCL -*- Bug using SLOT-VALUE of an instance of class obsolete-class. You get into infinte recursion as i've indicated in the code below. Basically CHANGE-CLASS-INTERNAL cannot use the normal ALL-SLOTS mechanism because that winds up using SLOT-VALUE again. I remeber this in the old PCL we must have patched it locally. k (defun slot-value (object slot-name) (SLOT-VALUE-USING-CLASS (CLASS-OF OBJECT) OBJECT SLOT-NAME)) ; <- (defmethod slot-value-using-class ((class obsolete-class) object slot-name &optional dont-call-slot-missing-p default) (CHANGE-CLASS OBJECT ; <- (CADR (SLOT-VALUE CLASS 'CLASS-PRECEDENCE-LIST))) (slot-value-using-class (class-of object) object slot-name dont-call-slot-missing-p default)) (defun change-class (object new-class) (or (classp new-class) (setq new-class (class-named new-class))) (let ((new-object (make-instance new-class))) ;; Call change-class-internal so that a user-defined method ;; (or the default method) can copy the information from the ;; old instance to the dummy instance of the new class. (CHANGE-CLASS-INTERNAL OBJECT NEW-OBJECT) ; <- ;; Now that the dummy new-object has the right information, ;; move all that stuff into the old-instance. (setf (iwmc-class-class-wrapper object) (wrapper-of new-class)) (setf (iwmc-class-static-slots object) (iwmc-class-static-slots new-object)) (setf (iwmc-class-dynamic-slots object) (iwmc-class-dynamic-slots new-object)) object)) (defmethod change-class-internal ((old object) (new object)) (let ((all-slots (ALL-SLOTS OLD))) ; <- (iterate ((name in all-slots by cddr) (value in (cdr all-slots) by cddr)) (put-slot-always new name value)))) (defun all-slots (object) (ALL-SLOTS-USING-CLASS (CLASS-OF OBJECT) OBJECT)) ; <- (defmethod all-slots-using-class ((class standard-class) object) (append (iterate ((slotd in (class-instance-slots class))) (collect (slotd-name slotd)) (collect (SLOT-VALUE OBJECT (SLOTD-NAME SLOTD)))) ; <- OOPS! (iwmc-class-dynamic-slots object)))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 17 Mar 88 18:20:47 EST Received: from Semillon.ms by ArpaGateway.ms ; 17 MAR 88 15:07:52 PST Date: Thu, 17 Mar 88 15:04 PST From: Gregor.pa@Xerox.COM Subject: new version of PCL To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text Message-ID: <880317150425.7.GREGOR@SPIFF.parc.xerox.com> Line-fold: no There is a new version of PCL on parcvax.xerox.com. This version fixes the bug with (*slot-unsupplied*) that prevented PCL from booting in all lisps. I don't know how many version of Franz Lisp this version will work in. I will come back to that as soon as I get some special code from Franz. This version fixes the bugs that prevented PCL from working on the 3600. This version does not fix the problems with Lyric. I will come back to those shortly. In all, this version should run in the following lisps: Symbolics, Lucid, Coral, Ibuki (01/01), and TI Common Lisps. It may run run in Franz Lisp on the SUN3. It won't run in other Franz Lisps yet. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 16 Mar 88 18:47:01 EST Received: from Chardonnay.ms by ArpaGateway.ms ; 16 MAR 88 15:40:11 PST Return-Path: <@CUNYVM.CUNY.EDU:MAILER@ICINECA2.BITNET> Redistributed: COMMONLOOPS.PA Received: from CUNYVM.CUNY.EDU ([128.228.1.2]) by Xerox.COM ; 16 MAR 88 15:38:06 PST Received: from ICINECA2.BITNET by CUNYVM.CUNY.EDU ; Wed, 16 Mar 88 18:37:54 EST Date: Wed, 16 Mar 88 18:38 N From: Reply-To: Subject: Please remove my address from the list..... To: COMMONLOOPS.PA@Xerox.COM X-Original-To: "COMMONLOOPS.PA@XEROX.COM" Message-ID: <880316-154011-1148@Xerox> Message-id: <3033> Date: WED, 16-MAR-88 18:38 N From: Reply-To: (alternate reply) Subject: Please remove my address from the list..... To: X-Original-To: commonloops.PA@xerox.com, GUERRIERI Thanks, guerrier@ic.berkeley.edu  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 16 Mar 88 11:28:05 EST Received: from Salvador.ms by ArpaGateway.ms ; 16 MAR 88 08:23:14 PST Return-Path: Redistributed: commonloops.pa Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by Xerox.COM ; 16 MAR 88 08:21:40 PST Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 178883; Wed 16-Mar-88 11:20:54 EST Date: Wed, 16 Mar 88 11:21 EST From: Daniel L. Weinreb Subject: Persistent Objects To: edsel!zach@labrea.stanford.edu cc: commonloops.pa@Xerox.COM In-Reply-To: <8803152023.AA17969@bhopal.lucid.com> Message-ID: <19880316162143.0.DLW@CHICOPEE.SCRC.Symbolics.COM> Line-fold: No I and my colleagues have been working for a few years on an object-oriented database system called Statice. It provides objects that are persistent, and shared between workstations. It uses database techniques to provide concurrency control (using two-phase locking), recovery (using a log), and high-speed associative lookup (using several kinds of indexes including B-trees). It's integrated with Common Lisp; it currently is built on New Flavors but will be changed to CLOS when the latter is available (the changes needed will be very slight). It's currently in alpha-test and will become a product later this year. I've written an overview paper about Statice, entitled "An Object-Oriented Database System to support an Integrated Programming Environment", and I've submitted it to OOPSLA-88 for publicatation. If you sent me your U.S. mail address, I'll be happy to mail you a copy.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 16 Mar 88 05:24:42 EST Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 88 02:19:35 PST Return-Path: Redistributed: commonloops.pa Received: from EDDIE.MIT.EDU by Xerox.COM ; 16 MAR 88 02:17:51 PST Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id ; Wed, 16 Mar 88 05:15:19 EST Received: by spt.entity.com (smail2.5); 16 Mar 88 05:00:41 EST (Wed) To: cherry@vallecito.scrc.symbolics.com Cc: commonloops.pa@Xerox.COM In-Reply-To: James J. Cherry's message of Sun, 13 Mar 88 23:45 EST <19880314044516.2.CHERRY@MERCED.SCRC.Symbolics.COM> Subject: Can't compile fcl in coral lisp Message-Id: <8803160500.AA09508@spt.entity.com> Date: 16 Mar 88 05:00:41 EST (Wed) From: gz@spt.entity.com (Gail Zacharias) The problem seems to be that the class-options slot of early defclasses is left uninitialized. Adding the following line to the function bootstrap-initialize in braid1.lisp fixes it: (bootstrap-set-slot 'class c 'options nil)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 21:42:33 EST Received: from Chardonnay.ms by ArpaGateway.ms ; 15 MAR 88 18:40:59 PST Return-Path: Redistributed: commonloops.PA Received: from vax2.nlm.nih.gov ([192.5.52.2]) by Xerox.COM ; 15 MAR 88 18:39:02 PST Received: by vax2.nlm.nih.gov (5.54/1.14) id AA03326; Tue, 15 Mar 88 21:34:35 EST Date: Tue, 15 Mar 88 21:34:35 EST From: lef@vax2.nlm.nih.gov (Larry Fitzpatrick) Message-Id: <8803160234.AA03326@vax2.nlm.nih.gov> To: commonloops.PA@Xerox.COM Subject: Please remove me from the list... Thanks,lef@nlm.nih.gov  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 21:24:08 EST Received: from Salvador.ms by ArpaGateway.ms ; 15 MAR 88 18:07:56 PST Return-Path: Redistributed: commonloops.pa@XEROX.ARPA Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by Xerox.COM ; 15 MAR 88 18:06:25 PST Received: from MERCED.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 213614; Tue 15-Mar-88 21:05:59 EST Date: Mon, 14 Mar 88 00:58 EST From: James J. Cherry Subject: that's cli::generic-function-p, not pcl:generic-function-p To: commonloops.pa@Xerox.COM cc: hornig@VALLECITO.SCRC.Symbolics.COM Supersedes: <19880314055636.6.CHERRY@MERCED.SCRC.Symbolics.COM> Message-ID: <19880314055847.7.CHERRY@MERCED.SCRC.Symbolics.COM> From 3600-low.lisp, the call to generic-function-p in setup-function-specs-to-edit-advice-1 is missing the cli:: package. This breaks the c-e debugger cmd on smbx systems. (sorry for the last bug - it is sys: in 7.2, but cli:: in 7.1) (defun setup-function-specs-to-edit-advice-1 (spec) (and (or (symbolp spec) (and (listp spec) (eq (car spec) 'setf))) (gboundp spec) (cli::generic-function-p (gdefinition spec)) ;; ^^^^ (mapcar #'(lambda (m) (make-method-spec spec (method-options m) (unparse-specializers (method-type-specifiers m)))) (generic-function-methods (gdefinition spec)))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 21:23:53 EST Received: from Chardonnay.ms by ArpaGateway.ms ; 15 MAR 88 18:06:14 PST Return-Path: <@VALLECITO.SCRC.Symbolics.COM,@MERCED.SCRC.Symbolics.COM:cherry@VALLECITO.SCRC.Symbolics.COM> Redistributed: commonloops.pa@XEROX.ARPA Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by Xerox.COM ; 15 MAR 88 18:04:12 PST Received: from MERCED.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via INTERNET with SMTP id 213613; 15 Mar 88 21:03:49 EST Date: Mon, 14 Mar 88 00:56 EST From: James J. Cherry Subject: that's sys:generic-function-p, not pcl:generic-function-p To: commonloops.pa@Xerox.COM cc: hornig@VALLECITO.SCRC.Symbolics.COM Message-ID: <19880314055636.6.CHERRY@MERCED.SCRC.Symbolics.COM> From 3600-low.lisp, the call to generic-function-p in setup-function-specs-to-edit-advice-1 is missing the sys: package. This breaks the c-e debugger cmd on smbx systems. (defun setup-function-specs-to-edit-advice-1 (spec) (and (or (symbolp spec) (and (listp spec) (eq (car spec) 'setf))) (gboundp spec) (sys:generic-function-p (gdefinition spec)) ;; ^^^^ (mapcar #'(lambda (m) (make-method-spec spec (method-options m) (unparse-specializers (method-type-specifiers m)))) (generic-function-methods (gdefinition spec)))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 21:06:49 EST Received: from Salvador.ms by ArpaGateway.ms ; 15 MAR 88 18:01:51 PST Return-Path: Redistributed: commonloops.pa@XEROX.ARPA Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by Xerox.COM ; 15 MAR 88 18:00:26 PST Received: from MERCED.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 213612; Tue 15-Mar-88 20:59:55 EST Date: Mon, 14 Mar 88 00:52 EST From: James J. Cherry Subject: named-structure-symbol missing scl: in 3600-low To: commonloops.pa@Xerox.COM Supersedes: <19880314051756.4.CHERRY@MERCED.SCRC.Symbolics.COM> Message-ID: <19880314055243.5.CHERRY@MERCED.SCRC.Symbolics.COM> The call to named-structure-symbol in iwmc-class-p (from 3600-low) is missing the scl: pkg. The other bug is that iwmc-class-p gets called with a symbol as its arg, which scl:named-structure-symbol barfs about. It needs to arrayp the arg first: (scl:defsubst iwmc-class-p (x) (and (arrayp x) (eq (scl:named-structure-symbol x) 'iwmc-class)))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 20:51:02 EST Received: from Salvador.ms by ArpaGateway.ms ; 15 MAR 88 17:28:58 PST Return-Path: Redistributed: commonloops.pa@XEROX.ARPA Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by Xerox.COM ; 15 MAR 88 17:25:33 PST Received: from MERCED.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 213606; Tue 15-Mar-88 20:25:08 EST Date: Mon, 14 Mar 88 00:17 EST From: James J. Cherry Subject: named-structure-symbol missing scl: in 3600-low To: commonloops.pa@Xerox.COM Message-ID: <19880314051756.4.CHERRY@MERCED.SCRC.Symbolics.COM> The call to named-structure-symbol in iwmc-class-p (from 3600-low) is missing the scl: pck. (scl:defsubst iwmc-class-p (x) (eq (scl:named-structure-symbol x) 'iwmc-class))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 20:07:52 EST Received: from Salvador.ms by ArpaGateway.ms ; 15 MAR 88 16:54:27 PST Return-Path: Redistributed: commonloops.pa@XEROX.ARPA Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by Xerox.COM ; 15 MAR 88 16:52:55 PST Received: from MERCED.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 213599; Tue 15-Mar-88 19:52:31 EST Date: Sun, 13 Mar 88 23:45 EST From: James J. Cherry Subject: Can't compile fcl in coral lisp To: commonloops.pa@Xerox.COM Message-ID: <19880314044516.2.CHERRY@MERCED.SCRC.Symbolics.COM> I can't get the latest (copied today) version of PCL to compile under coral common lisp. It barf trying to compile the top level form (eval-when (compile load eval) (mapcar #'eval *fsc-defclass-forms*)) Compiling FSC... > Error: (*SLOT-UNBOUND*) is not a valid argument to CCL:ASSQ . > While executing: CCL:ASSQ I'd say more, but the debugger in coral sucks pretty hard. [I added the change to canonicalize-slot-specification from the bug reports today and it didn't seem to help.]  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 18:30:26 EST Received: from Semillon.ms by ArpaGateway.ms ; 15 MAR 88 15:27:45 PST Return-Path: Redistributed: CommonLoops.pa Received: from june.cs.washington.edu by Xerox.COM ; 15 MAR 88 15:21:25 PST Received: by june.cs.washington.edu (5.52.1/6.13) id AA01753; Tue, 15 Mar 88 15:16:14 PST Date: Tue, 15 Mar 88 15:16:14 PST From: witold@june.cs.washington.edu (Witold Paluszynski) Return-Path: Message-Id: <8803152316.AA01753@june.cs.washington.edu> To: CommonLoops.pa@Xerox.COM Subject: problems installing PCL in Vax Lisp Hi, I am just beginning to use PCL and I have some problems with installing it. I first installed it on an 1108 according to the instructions in defsys.lisp. It compiled, loaded, and ran test.lisp fine despite some warnings. However, I also need to have it on a Vax and this did not work as smoothly. The farthest I got was with the version released on parcvax:/pub/pcl on March 10 (the previous version crashed during compilation). I am getting some fatal compilation errors, of which one contains the message "No class named: STANDARD-GENERIC-CLASS" (this happens while compiling fixup.lisp). Still, all files get compiled but when I get a fresh lisp, load pcl and then try to load the test file it crashes and I get the above error message (the first few tests run successfully and this happens in: "Testing Class Wrapper Caching..."). Because this is the first time I do it I suspect there might be some things about installing pcl I don't know about. I simply copy all files from parcvax, then rename *.lisp to *.lsp and follow the instructions in defsys.lisp (after modifying it for the local VMS directory which I specify as "PCL:"). I would appreciate very much any help I could get to get this thing to run. I am not on this list so please answer directly to me. Thanks, Witold  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 18:06:35 EST Received: from Salvador.ms by ArpaGateway.ms ; 15 MAR 88 15:03:20 PST Return-Path: Redistributed: commonloops.pa Received: from postgres.Berkeley.EDU by Xerox.COM ; 15 MAR 88 14:58:44 PST Received: by postgres.Berkeley.EDU (5.57/1.26) id AA09208; Tue, 15 Mar 88 14:58:57 PST Message-Id: <8803152258.AA09208@postgres.Berkeley.EDU> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: Zachary Smith Cc: edsel!lgd@labrea.stanford.edu, commonloops.pa@Xerox.COM, edsel!rpg@labrea.stanford.edu Precedence: special-delivery In-Reply-To: Your message of Tue, 15 Mar 88 12:23:28 PST <8803152023.AA17969@bhopal.lucid.com> Subject: Re: Persistent Objects Date: Tue, 15 Mar 88 14:58:52 PST Sender: dcmartin%postgres.Berkeley.EDU@Berkeley.EDU We (the Object FADS - for lack of a better name) group have been using the POSTGRES database to do exactly what you are talking about. One of the graduate students (ywang@postgres) has written a shared object hierarchy which allows some of these features. I am working on version control and storing sexp's to recreate arbitrary CLOS objects (ie. objects which are not shared, but must be recreated when loading a shared object). As for storing aribitrary lisp in a database, you should look at Margaret Butler's PhD thesis: _Persistant LISP: Storing Interobject References in a Database_, UCB/CSD 88/401. Hope this helps. dcm -------- Your message: I am real interested in whatever is currently available on the persistent objects concept. Has anyone written any papers about this? In particular, I am proposing a system where large bodies of structured text (usually but not necessarily programs) are represented in the running image by CLOS objects. These objects also have to be organised into a database with locking, version control, read-write access control and the like. I understand that someone is planning on extending CLOS to include some or all of this kind of thing and I'd dearly like to know about it. Thanks, --------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 16:46:31 EST Received: from Semillon.ms by ArpaGateway.ms ; 15 MAR 88 13:43:02 PST Date: Tue, 15 Mar 88 13:40 PST From: Gregor.pa@Xerox.COM Subject: operate-on-system To: Richard Fritzson cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-1.text In-Reply-To: <8803151116.AA10588@bigburd.PRC.Unisys.COM> Message-ID: <880315134000.1.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: 15 Mar 88 06:15 EST (Tuesday) From: fritzson@PRC.Unisys.COM (Richard Fritzson) The only occurence of yes-or-no-p in the definition of operate-on-system (in defsys.lisp) asks its question in such a way that the answer "yes" is treated as "no" and "no" is treated as "yes". That is, if the user says "yes, load the existing binary", the source is loaded, and if the user says "no, don't load the existing binary", the binary is loaded. I fixed this so it will do the right thing when you answer yes in future releases. This is, of course, no big deal to fix. But I noticed it right after I began trying to use pcl::precompile-random-code-segments. Whenever I recompile, I am always asked this particular question about loading the binary of the file which contains the call to pcl::precompile-random-code-segments. Am I supposed to be getting this question every time, or have I organized the files in the defsystem incorrectly? Yes, unfortunately the current version of defsys will ask this question everytime. It doesn't know better not to. I hope to fix this one day when I have some free time. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 16:42:55 EST Received: from Semillon.ms by ArpaGateway.ms ; 15 MAR 88 13:39:15 PST Date: Tue, 15 Mar 88 13:35 PST From: Gregor.pa@Xerox.COM Subject: Re: new version of PCL To: stanonik@nprdc.arpa cc: CommonLoops.pa@Xerox.COM In-Reply-To: <8803142259.AA11644@pacific.ARPA> Message-ID: <880315133506.8.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: 14 Mar 88 14:59 PST (Monday) From: stanonik@nprdc.arpa (Ron Stanonik) I just ftp'ed pcl from parcvax and it wouldn't compile until I fiddled with canonicalize-slot-specification in defclass. I changed this to use LIST and LIST* instead of doubly nested backquotes. (I didn't want to try to figure out whether I was right about how doubly nested ,@ works or KCL was right). Try the following, it should work just as well for you. The reason why I have to use list like this, and the reason the backquotes were doubly nested is to make the hack that reduces the number of initfunctions work. Specifically, if you do something like: (defclass foo () ((x *init*) (y *init*))) it will expand into: (let ((#:g1 #'(lambda () *init*))) (load-defclass . . (list (list :name 'x :initfunction #:g1 :initform '*init*) (list :name 'y :initfunction #:g1 :initform '*init*)) . .)) The point is that it uses the same initfunction over if possible. ;from defclass.lisp (defun canonicalize-slot-specification (class-name spec) (cond ((symbolp spec) `'(:name ,spec)) ((null (cdr spec)) `'(:name ,(car spec))) ((null (cddr spec)) (warn "In DEFCLASS ~S, the slot specification ~S is obsolete.~%~ Convert it to ~S" class-name spec (list (car spec) :initform (cadr spec))) `(list :name ',(car spec) :initform ',(cadr spec) :initfunction ,(make-initfunction (cadr spec)))) (t (let* ((name (pop spec)) (unsupplied (list nil)) (initform (getf spec :initform unsupplied))) (if (eq initform unsupplied) `(list* :name ',name ',spec) `(list* :name ',name :initfunction ,(make-initfunction initform) ',spec)))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 16:26:33 EST Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 88 13:23:14 PST Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 15 MAR 88 13:21:38 PST To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: Bug in canonicalize-slot-specification Date: Tue, 15 Mar 88 14:15:04 -0500 From: kanderso@WILMA.BBN.COM Message-ID: <880315-132314-2153@Xerox> It looks like there is an extra quote in canonicalize-slot-specification of defclass.lisp. Here is a patched version: (defun canonicalize-slot-specification (class-name spec) (cond ((symbolp spec) `'(:name ,spec)) ((null (cdr spec)) `'(:name ,(car spec))) ((null (cddr spec)) (warn "In DEFCLASS ~S, the slot specification ~S is obsolete.~%~ Convert it to ~S" class-name spec (list (car spec) :initform (cadr spec))) `'(:name ,(car spec) :initform ,(cadr spec) :initfunction ,(make-initfunction (cadr spec)))) (t (let* ((name (pop spec)) (unsupplied (list nil)) (initform (getf spec :initform unsupplied))) (if (eq initform unsupplied) ``(:name ,',name ,',@spec) ``(:name ,',name :initfunction ,,(make-initfunction initform) ,,@spec)))))) ;; KRA ,',@spec))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 16:14:26 EST Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 88 13:11:30 PST Return-Path: Redistributed: commonloops.pa Received: from labrea.Stanford.EDU by Xerox.COM ; 15 MAR 88 13:07:58 PST Received: by labrea.Stanford.EDU; Tue, 15 Mar 88 13:07:45 PST Received: from bhopal.lucid.com by edsel id AA17702g; Tue, 15 Mar 88 12:16:27 PST Received: by bhopal id AA17969g; Tue, 15 Mar 88 12:23:28 PST Date: Tue, 15 Mar 88 12:23:28 PST From: Zachary Smith Message-Id: <8803152023.AA17969@bhopal.lucid.com> To: edsel!lgd@labrea.Stanford.EDU Subject: Persistent Objects Cc: commonloops.pa@Xerox.COM, edsel!rpg@labrea.Stanford.EDU I am real interested in whatever is currently available on the persistent objects concept. Has anyone written any papers about this? In particular, I am proposing a system where large bodies of structured text (usually but not necessarily programs) are represented in the running image by CLOS objects. These objects also have to be organised into a database with locking, version control, read-write access control and the like. I understand that someone is planning on extending CLOS to include some or all of this kind of thing and I'd dearly like to know about it. Thanks,  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 14:54:26 EST Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 88 11:40:09 PST Return-Path: Redistributed: commonloops.pa Received: from nprdc.arpa by Xerox.COM ; 15 MAR 88 11:37:01 PST Received: by nprdc.arpa (5.54/ 1.1) id AA29681; Tue, 15 Mar 88 11:36:12 PST Received: by pacific.ARPA (5.54/4.7) id AA20015; Tue, 15 Mar 88 11:37:11 PST From: stanonik@nprdc.arpa (Ron Stanonik) Message-Id: <8803151937.AA20015@pacific.ARPA> Date: 15 Mar 88 11:37 PST (Tuesday) To: kanderso@WILMA.BBN.COM Subject: Re: Re: new version of PCL Reply-To: stanonik@nprdc.arpa Cc: commonloops.pa@Xerox.COM PCL seems to be okay after my fix, but I'm only running small, simple programs through it. Frankly I don't understand why the code isn't something more like `(:name ,name ,@spec), rather than the double backquote. Ron stanonik@nprdc.arpa  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 08:37:33 EST Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 88 05:33:39 PST Return-Path: Redistributed: CommonLoops.pa Received: from cpswh.cps.msu.edu ([35.8.56.10]) by Xerox.COM ; 15 MAR 88 05:30:44 PST Received: from cps45x (cps45x.cps.msu.edu) by cpswh.cps.msu.edu (3.2/2.2); id AA06906; Tue, 15 Mar 88 08:30:19 EST Return-Path: Received: by cps45x (3.2/SMI-2.0) id AA09280; Tue, 15 Mar 88 08:28:06 EST Date: Tue, 15 Mar 88 08:28:06 EST From: rang%cps45x@cpswh.cps.msu.EDU (Anton Rang) Message-Id: <8803151328.AA09280@cps45x> To: Gregor.pa@Xerox.COM Subject: Newest version of PCL & Xerox Lisp (Lyric) on 1186 Cc: CommonLoops.pa@Xerox.COM When I try to compile the newest version of PCL (March 8 beta test) under Lyric, I get the following error message while compiling 'high.lisp': The literal value # would not be dumpable in a FASL file. It's a continuable error; I've been selecting the continuation option "Use ... anyway and hope for the best". Will this work? I looked at the code, but didn't see anything obviously incompatible with what I know of the compiler. Also, compilation is *SLOW*! I don't know if this is due to anything in PCL or not, but it's been compiling since 5:00 last night and it was going until 2:30 in the morning before it hit the error. The first few modules compiled quickly, then it hit DCODE and everything slowed down. Maybe this is just a slow compiler. Anton Rang  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Mar 88 06:23:36 EST Received: from Salvador.ms by ArpaGateway.ms ; 15 MAR 88 03:19:38 PST Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 15 MAR 88 03:16:55 PST Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA01015; Tue, 15 Mar 88 06:16:46 EST Received: by bigburd.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA10588; Tue, 15 Mar 88 06:16:41 EST From: fritzson@PRC.Unisys.COM (Richard Fritzson) Message-Id: <8803151116.AA10588@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd.PRC.Unisys.COM with PUP; Tue, 15 Mar 88 06:16 EST To: commonloops.pa@Xerox.COM Date: 15 Mar 88 06:15 EST (Tuesday) To: commonloops.pa@Xerox.COM Subject: operate-on-system The only occurence of yes-or-no-p in the definition of operate-on-system (in defsys.lisp) asks its question in such a way that the answer "yes" is treated as "no" and "no" is treated as "yes". That is, if the user says "yes, load the existing binary", the source is loaded, and if the user says "no, don't load the existing binary", the binary is loaded. This is, of course, no big deal to fix. But I noticed it right after I began trying to use pcl::precompile-random-code-segments. Whenever I recompile, I am always asked this particular question about loading the binary of the file which contains the call to pcl::precompile-random-code-segments. Am I supposed to be getting this question every time, or have I organized the files in the defsystem incorrectly? Can someone who is successfully using pcl::precompile-random-code-segments clue me in? If the question is normal, what is the right answer? Thanks.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Mar 88 21:54:11 EST Received: from Cabernet.ms by ArpaGateway.ms ; 14 MAR 88 15:04:13 PST Return-Path: Redistributed: CommonLoops.pa Received: from nprdc.arpa by Xerox.COM ; 14 MAR 88 14:59:26 PST Received: by nprdc.arpa (5.54/ 1.1) id AA15568; Mon, 14 Mar 88 14:58:36 PST Received: by pacific.ARPA (5.54/4.7) id AA11644; Mon, 14 Mar 88 14:59:35 PST From: stanonik@nprdc.arpa (Ron Stanonik) Message-Id: <8803142259.AA11644@pacific.ARPA> Date: 14 Mar 88 14:59 PST (Monday) To: Gregor.pa@Xerox.COM Subject: Re: new version of PCL Reply-To: stanonik@nprdc.arpa Cc: CommonLoops.pa@Xerox.COM I just ftp'ed pcl from parcvax and it wouldn't compile until I fiddled with canonicalize-slot-specification in defclass. The complaint was KCl (Kyoto Common Lisp) June 3, 1987 Compiling METHODS... Compiling methods.lsp. Error: Too many arguments. Error signalled by QUOTE. Backtrace: > eval > mapcar > eval > progn > eval-when > progn > let > QUOTE ; (MAPCAR #'EVAL ...) is being compiled. ;;; The form (MAPCAR #'EVAL *METHODS-DEFCLASS-FORMS*) was not evaluated successfully. ;;; You are recommended to compile again. No FASL generated. canonicalize-slot-specification was returning any slot options as (quote ); eg, ((arf :accessor arf))) became (list (list :name 'arf (quote :accessor arf))). Maybe I missed a fix? At any rate, the following fix(?) allows methods to compile; eg, the example becomes (list (list* :name 'arf (quote :accessor arf))). Ron Stanonik stanonik@nprdc.arpa *** odefclass.lsp Mon Mar 14 14:06:30 1988 --- defclass.lsp Mon Mar 14 14:06:34 1988 *************** *** 230,239 **** (unsupplied (list nil)) (initform (getf spec :initform unsupplied))) (if (eq initform unsupplied) ! ``(:name ,',name ,',@spec) ``(:name ,',name :initfunction ,,(make-initfunction initform) ! ,',@spec)))))) (defun canonicalize-defclass-option (class-name option) (declare (ignore class-name)) --- 230,239 ---- (unsupplied (list nil)) (initform (getf spec :initform unsupplied))) (if (eq initform unsupplied) ! ``(:name ,',name ,@',spec) ``(:name ,',name :initfunction ,,(make-initfunction initform) ! ,@',spec)))))) (defun canonicalize-defclass-option (class-name option) (declare (ignore class-name))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Mar 88 15:53:37 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Mar 88 12:15:28 PST Received: from Semillon.ms by ArpaGateway.ms ; 11 MAR 88 11:32:04 PST Date: Fri, 11 Mar 88 11:27 PST From: Gregor.pa@Xerox.COM Subject: new version of mopc To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-1.text Message-ID: <880311112713.4.GREGOR@SPIFF.parc.xerox.com> Line-fold: no There is a new version of the MOP on sail. This one is called mopc.tex so there should be no problems with sail filenames. As a reminder, the directory is [CLS,LSP]. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Mar 88 22:36:41 EST Received: from Semillon.ms by ArpaGateway.ms ; 10 MAR 88 19:06:57 PST Date: Thu, 10 Mar 88 19:00 PST From: Gregor.pa@Xerox.COM Subject: new new version of PCL To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-1.text Message-ID: <880310190031.8.GREGOR@SPIFF.parc.xerox.com> Line-fold: no For some people the Super Tuesday version of PCL was a bust. This is true for people using older versions of Franz Lisp, and people using VaxLisp. So, there is a new version of PCL on parcvax.xerox.com. It should behave better for you all. Gregor -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Mar 88 17:35:11 EST Received: from Salvador.ms by ArpaGateway.ms ; 10 MAR 88 14:31:47 PST Return-Path: Redistributed: commonloops.pa Received: from VAX.BBN.COM by Xerox.COM ; 10 MAR 88 14:30:01 PST To: Gregor.pa@Xerox.COM cc: commonloops.pa@Xerox.COM Subject: Re: IWMC-Class-p bug & make-specializable In-reply-to: Your message of Thu, 10 Mar 88 10:46:00 -0800. <880310104656.2.GREGOR@SPIFF.parc.xerox.com> Date: Thu, 10 Mar 88 17:23:26 -0500 From: Mike Thome Message-ID: <880310-143147-2447@Xerox> The example that blew up in my face: (IWMC-Class-p #) The original code: (scl:defsubst iwmc-class-p (x) (and (si:arrayp x) (not (zerop (si:array-named-structure-bit x))) (eq (aref x 0) 'iwmc-class))) I Gather that fonts are arrays (multi-dimensional), are named structures (unsuprisingly) and have an array leader - in which case the named-structure-symbol is stored in element 1 of the LEADER rather than in element 0 of the array itself... a normal multi-d array gets caught before the aref happens, and a regular structure is single-dimensional. Our fix (which works) was: (scl:defsubst iwmc-class-p (x) (and (si:arrayp x) (not (zerop (si:array-named-structure-bit x))) (eq (array-dimensions x) 1) (eq (aref x 0) 'iwmc-class))) But the following should (?) also work, and possibly faster: (scl:defsubst iwmc-class-p (x) (and (named-structure-p x) (eq (named-structure-symbol x) 'iwmc-class))) As to my comment about FINs - again, another case of inaccuracy in my original message... Attempting to print the environment of a *FIN* (as in describe-ing a FIN) results in an infinite printed representation, since the tail of the env list is a pair whose first element is the whole list whose tail is a pair whose first element is the whole list whose tail... Solution? Disconnect the env from the closure (can the system be tricked into thinking that the list is shorted than it actually is?)? cheers, mike (mthome@bbn.com)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Mar 88 14:09:56 EST Received: from Semillon.ms by ArpaGateway.ms ; 10 MAR 88 11:02:51 PST Date: Thu, 10 Mar 88 10:55 PST From: Gregor.pa@Xerox.COM Subject: new version of PCL To: CommonLoops.PA@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-1.text Message-ID: <880310105545.3.GREGOR@SPIFF.parc.xerox.com> Line-fold: no There is a new version of PCL on parcvax.xerox.com. This version works on the TI Explorer. This version also supports a prototype implementation of the make-instance behavior specified in the CLOS specification. This prototype version goes by the name mki for the time being. See the notes.text file for more details. Gregor -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Mar 88 14:00:21 EST Received: from Semillon.ms by ArpaGateway.ms ; 10 MAR 88 10:55:06 PST Date: Thu, 10 Mar 88 10:46 PST From: Gregor.pa@Xerox.COM Subject: IWMC-Class-p bug & make-specializable To: Mike Thome cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-1.text In-Reply-To: The message of 10 Mar 88 05:21 PST from Mike Thome Message-ID: <880310104656.2.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: Thu, 10 Mar 88 08:21:25 -0500 From: Mike Thome Just ran across this bug yesterday: In the 3600 version of PCL, the provided definition for IWMC-CLASS-P (in 3600-low.lisp, NOT the defstruct-generated one in low.lisp) breaks when the function is passed any sort of multidimensional array. It assumes all arrays are vectors. We've fixed it here by just adding an ARRAY-DIMENSIONS check, but we haven't tested (or looked) to see if the resulting code is still faster than that generated by the defstruct in low.lisp. Hmm, could you send a test case? When I do the following on my 3600 it returns NIL just as it should: (iwmc-class-p (make-array '(10 10 10))) While I'm on the subject of wishes - how 'bout a way to make 3600 FINs printable (i.e. non-recursive print-form) that is nicer than setting *print-circle* (or whatever it is)??? I don't know what you mean by this. Generic functions print out nicely as shown in this interaction: #'print-object # Could you please clarify what printing behavior you would like to get. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Mar 88 08:32:14 EST Received: from Semillon.ms by ArpaGateway.ms ; 10 MAR 88 05:28:38 PST Return-Path: Redistributed: commonloops.pa Received: from VAX.BBN.COM by Xerox.COM ; 10 MAR 88 05:26:58 PST To: commonloops.pa@Xerox.COM Subject: IWMC-Class-p bug & make-specializable Date: Thu, 10 Mar 88 08:21:25 -0500 From: Mike Thome Message-ID: <880310-052838-1459@Xerox> Just ran across this bug yesterday: In the 3600 version of PCL, the provided definition for IWMC-CLASS-P (in 3600-low.lisp, NOT the defstruct-generated one in low.lisp) breaks when the function is passed any sort of multidimensional array. It assumes all arrays are vectors. We've fixed it here by just adding an ARRAY-DIMENSIONS check, but we haven't tested (or looked) to see if the resulting code is still faster than that generated by the defstruct in low.lisp. Also, does anyone have a good way to do the equivalent of a MAKE-SPECIALIZABLE on a setf-method? I've hacked up some functions that usually work, but if anyone already has a more robust (possibly to be included in PCL distributions?) I'd prefer to use something that'll be more standard. Any idea how long it'll be until MAKE-SPECIALIZABLE disappears/turns into a CLOS-defined function? While I'm on the subject of wishes - how 'bout a way to make 3600 FINs printable (i.e. non-recursive print-form) that is nicer than setting *print-circle* (or whatever it is)??? thanks, -mike thome (mthome@bbn.com)  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Mar 88 21:48:26 EST Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Mar 88 18:43:13 PST Received: by labrea.Stanford.EDU; Wed, 9 Mar 88 18:43:58 PST Received: from bhopal.lucid.com by edsel id AA14794g; Wed, 9 Mar 88 18:28:38 PST Received: by bhopal id AA09672g; Wed, 9 Mar 88 18:35:03 PST Date: Wed, 9 Mar 88 18:35:03 PST From: Linda G. DeMichiel Message-Id: <8803100235.AA09672@bhopal.lucid.com> To: common-lisp-object-system@sail.Stanford.EDU, common-lisp@sail.Stanford.EDU Subject: CLOS Consortium Cc: gregor@xerox.com, lgd@sail.Stanford.EDU, rpg@sail.Stanford.EDU CLOS Consortium Lucid is currently pursuing the establishment of a consortium to do a high-performance implementation of the Common Lisp Object System. The suggested organization for this consortium is the following: Each member company is to supply either programmers or money, and the consortium will select a group of individuals to do the implementation (in the case that more programmers are offered than needed). It is likely that the current PCL will become the seed for this implementation. No restrictions will exist as to which companies may become members of the consortium, and we expect that the implementors would be from various companies. The result will be a set of sources either in the public domain or owned by the member companies. Lucid offers to contribute at least one highly-talented programmer and the organization for the program. A mechanism should also be established to handle companies who want to join the consortium at a later date. We will be holding an organizational meeting during X3J13 next week for anyone who may be interested in participating. This meeting is scheduled for Tuesday, March 15, 8:00p.m., at Hyatt Rickeys, 4219 El Camino Real, Palo Alto. If you are interested in joining and cannot make the meeting, please let me know. Linda DeMichiel Lucid, Inc. 415-329-8400  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Mar 88 13:11:02 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 Mar 88 10:06:19 PST Received: from Semillon.ms by ArpaGateway.ms ; 09 MAR 88 09:45:50 PST Date: Wed, 9 Mar 88 09:40 PST From: Gregor.pa@Xerox.COM Subject: Small omission in Chap 2 To: Richard Fritzson cc: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-1.text In-Reply-To: <8803091703.AA28687@bigburd.PRC.Unisys.COM> Message-ID: <880309094045.9.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: 9 Mar 88 12:01 EST (Wednesday) From: fritzson@PRC.Unisys.COM (Richard Fritzson) The description of the standard-generic-function SLOT-MISSING indicates that it is called when an attempt is made to access a non-existent slot of an object, if the object's metaclass is standard-class. This is a reasonable restriction (although I hate what happens when I mistakenly apply an accessor function to NIL). However, the description of the function SLOT-VALUE doesn't include the restriction to objects whose metaclasses are standard-class. It seems to say that slot-missing will always be called (even for objects whose metaclass is built-in-class). I expect that the former was the intended meaning, but they should both say the same thing. Thanks for catching this and sending us a message. I believe the reason this bug happened in the document is that we tried to finesse the issue that slot-value actually called the generic-function slot-value-using-class. This means that we tried to put too much of the description of the effect of calling slot-value in the actual section on slot-value and got tripped up. I suppose this will be easier to fix now that we actually have chapter three and can feel free to reference it from chapter 2. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 9 Mar 88 13:05:43 EST Received: from Semillon.ms by ArpaGateway.ms ; 09 MAR 88 09:45:03 PST Date: Wed, 9 Mar 88 09:35 PST From: Gregor.pa@Xerox.COM Subject: Handling of "no applicable method" To: Richard Fritzson cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-1.text In-Reply-To: <8803091703.AA28649@bigburd.PRC.Unisys.COM> Message-ID: <880309093552.8.GREGOR@SPIFF.parc.xerox.com> Line-fold: no Date: 9 Mar 88 12:00 EST (Wednesday) From: fritzson@PRC.Unisys.COM (Richard Fritzson) When I mistakenly apply a slot accessor on an entirely inappropriate object (such as NIL), I would expect to see something like "No applicable method". Instead the method for "slot-value-using-class (standard-class)" is invoked on the object producing very bad results. This bug will be fixed in the version of PCL I hope to release later today. In the meantime, you can fix it for yourself by replacing the following two definitions from dcode.lisp. You will then have to recompile the file dcode.lisp and the file dcode-pre1.lisp. You can then load those two files into an exisiting PCL. Note that you will have to reload all of your code for this change to take effect though. ;from dcode.lisp (define-function-template all-std-class-readers-dcode () '(.GENERIC-FUNCTION. .CACHE.) (let ((mask (make-generic-function-cache-mask 1))) `(function (lambda (arg) (locally (declare (optimize (speed 3) (safety 0))) (let* ((wrapper (and (iwmc-class-p arg) (iwmc-class-class-wrapper arg))) (offset (wrapper-cache-no wrapper ,mask)) (method nil) (class nil)) (cond ((null wrapper) (no-matching-method .GENERIC-FUNCTION.)) ((eq (r/w-cache-key) wrapper) (get-static-slot--class arg (r/w-cache-val))) ((setq class (class-wrapper-class wrapper) method (lookup-method-1 .GENERIC-FUNCTION. arg)) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (slotd-position slot-name (class-instance-slots class)))) (cond ((not (null slot-pos)) ;Got an instance slot! (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (get-static-slot--class arg slot-pos)) (t (slot-value-using-class--class-internal class arg slot-name nil nil))))) (t (no-matching-method .GENERIC-FUNCTION.))))))))) (define-function-template all-std-class-writers-dcode () '(.GENERIC-FUNCTION. .CACHE.) (let ((mask (make-generic-function-cache-mask 1))) `(function (lambda (arg new-value) (locally (declare (optimize (speed 3) (safety 0))) (let* ((wrapper (and (iwmc-class-p arg) (iwmc-class-class-wrapper arg))) (offset (wrapper-cache-no wrapper ,mask)) (method nil) (class nil)) (cond ((null wrapper) (no-matching-method .GENERIC-FUNCTION.)) ((eq (r/w-cache-key) wrapper) (setf (get-static-slot--class arg (r/w-cache-val)) new-value)) ((setq class (class-wrapper-class wrapper) method (lookup-method-1 .GENERIC-FUNCTION. arg)) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (slotd-position slot-name (class-instance-slots class)))) (cond ((not (null slot-pos)) ;Got an instance slot! (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (setf (get-static-slot--class arg slot-pos) new-value)) (t (put-slot-using-class--class-internal class arg slot-name new-value nil))))) (t (no-matching-method .GENERIC-FUNCTION.))))))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 9 Mar 88 12:15:04 EST Received: from Salvador.ms by ArpaGateway.ms ; 09 MAR 88 09:05:34 PST Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 09 MAR 88 09:03:40 PST Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA06435; Wed, 9 Mar 88 12:03:12 EST Received: by bigburd.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA28649; Wed, 9 Mar 88 12:03:15 EST From: fritzson@PRC.Unisys.COM (Richard Fritzson) Message-Id: <8803091703.AA28649@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd.PRC.Unisys.COM with PUP; Wed, 9 Mar 88 12:03 EST To: commonloops.pa@Xerox.COM Date: 9 Mar 88 12:00 EST (Wednesday) To: commonloops.pa@Xerox.COM Subject: Handling of "no applicable method" When I mistakenly apply a slot accessor on an entirely inappropriate object (such as NIL), I would expect to see something like "No applicable method". Instead the method for "slot-value-using-class (standard-class)" is invoked on the object producing very bad results. (On the Xerox machines a lower level error,"ARG NOT IWMC-CLASS", is produced; on some unix lisps, including kcl and franz, you get a segmentation fault.) I can see a use of slot-value being optimized into this situation, but why do accessors produce it too?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Mar 88 12:08:50 EST Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by SAIL.Stanford.EDU with TCP; 9 Mar 88 09:03:36 PST Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA06441; Wed, 9 Mar 88 12:03:54 EST Received: by bigburd.PRC.Unisys.COM (5.54/Domain/jpb/2.9) id AA28687; Wed, 9 Mar 88 12:03:57 EST From: fritzson@PRC.Unisys.COM (Richard Fritzson) Message-Id: <8803091703.AA28687@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd.PRC.Unisys.COM with PUP; Wed, 9 Mar 88 12:03 EST To: common-lisp-object-system@sail.stanford.edu Date: 9 Mar 88 12:01 EST (Wednesday) To: common-lisp-object-system@sail.stanford.edu Subject: Small omission in Chap 2 Cc: fritzson@bigburd.PRC.Unisys.COM The description of the standard-generic-function SLOT-MISSING indicates that it is called when an attempt is made to access a non-existent slot of an object, if the object's metaclass is standard-class. This is a reasonable restriction (although I hate what happens when I mistakenly apply an accessor function to NIL). However, the description of the function SLOT-VALUE doesn't include the restriction to objects whose metaclasses are standard-class. It seems to say that slot-missing will always be called (even for objects whose metaclass is built-in-class). I expect that the former was the intended meaning, but they should both say the same thing. -Rich Fritzson Unisys - Paoli Research Center P.O. Box 517 Paoli, PA 19301 (215) 648-7606  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Mar 88 07:39:53 EST Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 9 Mar 88 04:35:51 PST Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP id AA05653; Wed, 9 Mar 88 07:36:14 EST Received: by mcvax.cwi.nl; Wed, 9 Mar 88 13:26:23 +0100 (MET) Received: by inria.inria.fr; Wed, 9 Mar 88 12:16:32 +0100 (MET) Date: Wed, 9 Mar 88 12:16:32 +0100 From: mcvax!inria.inria.fr!cointe@uunet.UU.NET (Pierre Cointe) Message-Id: <8803091116.AA27957@inria.inria.fr> To: Gregor.pa@xerox.com, common-lisp-object-system@sail.stanford.edu Subject: Re: new version of mop Lease could you mail me the files also? AMities, Pierre  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Mar 88 18:16:27 EST Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Mar 88 15:10:41 PST Received: from Semillon.ms by ArpaGateway.ms ; 08 MAR 88 14:28:17 PST Date: Tue, 8 Mar 88 14:23 PST From: Gregor.pa@Xerox.COM Subject: new version of mop To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-1.text Message-ID: <880308142336.7.GREGOR@SPIFF.parc.xerox.com> Line-fold: no There is a new version of the mop on sail. It is called new-mopc.tex. You will also need to get a new version of the macros file. Danny says that at one point you have to type a return at TeX to make it happy but other than that it TeX's fine. We will try to fix that bug soon. Pages 1-30 of this version are in pretty solid shape. The remaining pages are OK, but not as solid. We will work on getting those better in the next day or so. Patrick, I will mail you the files as soon as I send this message. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 7 Mar 88 22:14:59 EST Received: from Cabernet.ms by ArpaGateway.ms ; 07 MAR 88 19:09:49 PST Return-Path: <@cadre.dsl.pittsburgh.edu:jas@dsl.pittsburgh.edu> Redistributed: CommonLoops.pa Received: from cadre.dsl.pittsburgh.edu by Xerox.COM ; 07 MAR 88 19:07:29 PST Received: by cadre.dsl.pittsburgh.edu id AA06920; Mon, 7 Mar 88 22:05:23 EST Date: Mon, 7 Mar 88 22:05:23 EST From: jas@cadre.dsl.pittsburgh.edu (Jeffrey A. Sullivan) Message-Id: <8803080305.AA06920@cadre.dsl.pittsburgh.edu> To: CommonLoops.pa@Xerox.COM Subject: PCL Compile warnings in Coral CL In case you are interested, the following warnings are issued when (pcl::compile- pcl) is run in Allegro CL on a mac II. Compiler warnings for file "HD60:Programming:Lisp:clos:walk.lisp" : In function WALKER::WITH-AUGMENTED-ENVIRONMENT : Unused lexical variable (#:G181 ) Compiler warnings for file "HD60:Programming:Lisp:clos:macros.lisp" : In function PCL::DEFINE-METHOD-BODY-MACRO : Unused lexical variable (#:G785) Compiler warnings for file "HD60:Programming:Lisp:clos:boot.lisp" : In function PCL::EXPAND-DEFMETHOD-INTERNAL : Unused lexical variables (PCL::SETF P PCL::QUALIFIERS PCL::METHOD) In function PCL::ENSURE-GENERIC-FUNCTION : Unused lexical variable (PCL::GENERIC -FUNCTION-CLASS) In function PCL::REAL-ENSURE-GF-INTERNAL : Unused lexical variables (PCL::METHOD -COMBINATION DOCUMENTATION PCL::DECLARATIONS PCL::ARGUMENT-PRECEDENCE-ORDER PCL:: LAMBDA-LIST) In function PCL::MAKE-TOP-LEVEL-FORM : Unused lexical variable (PCL::NAME) Compiler warnings for file "HD60:Programming:Lisp:clos:methods.lisp" : In function PCL::LOOKUP-METHOD-INTERNAL : Unused lexical variable (PCL::GENERIC- FUNCTION) Compiler warnings for file "HD60:Programming:Lisp:clos:combin.lisp" : In function PCL::MAKE-EFFECTIVE-METHOD-