Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Sep 87 16:01:37 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 10 Sep 87 12:50:19 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 10 SEP 87 12:50:44 PDT Date: 10 Sep 87 12:50 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Meeting on Sept. 17-18 In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Thu, 10 Sep 87 09:48:11 MST To: kempf%hplabsz@hplabs.HP.COM cc: common-lisp-object-system@sail.stanford.edu Message-ID: <870910-125044-16719@Xerox> Jim, The meeting will be at Xerox, starting at 9AM on Sept 17. Come to the visitors entrance, and ask for me or Gregor. We will have some coffee, juice and pastries in the room, as well as a recording whiteboard. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Sep 87 14:10:28 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Sep 87 11:01:20 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 10 Sep 87 10:57:15 pdt Received: from hplabsz.hpl.hp.com by hplms2; Thu, 10 Sep 87 08:44:19 pdt Return-Path: Received: from hplabsz by hplabsz; Thu, 10 Sep 87 09:48:14 pdt To: common-lisp-object-system@sail.stanford.edu Subject: Meeting on Sept. 17-18 X-Mailer: mh6.5 Date: Thu, 10 Sep 87 09:48:11 MST Message-Id: <4135.558287291@hplabsz> From: kempf%hplabsz@hplabs.HP.COM Has the location of the meeting next week been resolved? If so, could someone post the place and time? Thanks. jak PS: Our phone connection in Andover was down for about a week, so apologies if this information has already been posted.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Sep 87 00:24:11 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Sep 87 21:14:10 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 230758; Wed 9-Sep-87 22:43:07 EDT Date: Wed, 9 Sep 87 22:42 EDT From: David A. Moon Subject: User control of the CPL To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870909224238.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Should we adopt the :component-order class-option from Flavors, as a simple way for the user to have control of the CPL without making him write his own algorithm? Gregor doesn't like the ability to specify constraints on the ordering of classes that only apply conditionally, i.e. if those classes are actually present among the superclasses. He considers this bad style. Moon volunteered to write a proposal with some examples, and we agreed to resolve this over the mail. PROPOSAL: The :precedence option to defclass is written (:precedence C1 C2 C3 ...) where the C's are class names. This specifies that C1 must precede C2 in the CPL, C2 must precede C3, etc. This defclass option may appear any number of times. The default if no :precedence option is specified for a class C with direct superclasses C1, C2, ..., Cn is (:precedence C C1 C2 ... Cn). To completely eliminate all precedence constraints, specify (:precedence C). In the notation used on page 1-14 of 87-002, the :precedence option allows direct control over Rc. Each ordered pair (C1,C2) in Rc is specified by writing (:precedence C1 C2). :precedence with more than two class names is simply a convenient abbreviation for multiple :precedence options. OPTIONS: Optionally we could add an additional requirement that each Ci in a :precedence option in the defclass for C must be either C or one of C's direct superclasses. I am opposed to this, for reasons which should become clear from the examples. It doesn't hurt to have extra ordered pairs in Rc that do not affect the CPL. Another way of saying this is that the :precedence option is useful both for relaxing the precedence constraints, compared with the default, and for adding additional constraints to the default constraints. Optionally we could add an additional stipulation that regardless of the use of :precedence options, a class always precedes its direct superclasses. Specifically, in (defclass C (C1 C2 C3) () ...), the effect of (:precedence C C1), (:precedence C C2), and (:precedence C C3) is always present; in addition, if the user does not specify a :precedence option, defclass supplies (:precedence C1 C2 C3). This would slightly simplify the following section, but it seems like a kludgey restriction on how much control over the precedence relations the user is permitted. I have found applications that would not work with this restriction, so I oppose adding this restriction. Optionally we could add a restriction that a :precedence option in the defclass for C may not specify that another class precedes C. Flavors has such a restriction, however I believe it to be unnecessary and I oppose making this restriction in CLOS. EFFECT ON CPL ALGORITHM: The first and third paragraphs on page 1-15 of 87-002 would need to be changed. The statement "there can be only one such candidate class" is no longer true once the user can relax the constraints using the :precedence option. A more complex disambiguation rule is necessarily required. I suggest replacing the first paragraph on 1-15 with: Sometimes there are several classes from Sc with no predecessors. In this case, we select one of these candidate classes according to the following rule: Traverse the superclasses of each member of the CPL found so far, associating the number (d*n*n)-(i*n)+b with the class at depth d and breadth b in the tree rooted at the ith element of the CPL found so far (make it a tree by considering only the first occurrence in breadth-first order of each class). n is the number of classes involved (the initial length of Sc). Choose the candidate with the smallest associated number, considering the minimum if several numbers are associated with one class. This algorithm selects a unique candidate because no two associated numbers are equal. A class is always the first element of its own CPL. Thus the CPL computed so far, used in the above rule, can never be empty. This implies an additional check: when computing the CPL of C, if (C',C) is an element of R, signal an error reporting that it is invalid for C' to precede C. The above rule is the simplest rule I could find that is compatible with the 87-002 rule. Other rules I considered were not compatible with the 87-002 rule and had additional undesirable properties. Note that in all cases when the :precedence option is not used this rule produces the same answer as the one in 87-002, and produces it in essentially the same way. In this case d=1 for the winning candidate. There are more efficient implementations than computing all the numbers and then finding the minimum number, however that's the easiest way I could find to explain it. An actual implementation could traverse all the trees in parallel, in a suitable order, and take the first candidate it encounters. Note that the last sentence in the first paragraph on 1-15 is irrelevant to the paragraph and repeats what was already said in the last paragraph on 1-14, so I would simply remove it. The third paragraph on 1-15 could be replaced with a more precise specification of the rule quoted above, if desired. EXAMPLES: For brevity I have omitted from R all pairs involving the class t. ;Two superclasses and we don't care about their order ;CPL=(example2 example super-2 super-1 t) ;R={(example-2,example),(example,super-1),(example,super-2),(super-2,super-1)} (defclass example (super-1 super-2) () (:precedence example super-1) (:precedence example super-2)) (defclass example-2 (example super-2 super-1) ()) ;Two mixins that can be used separately but they interact and therefore ;if they are used together, they must be used in a certain order to work. ;Specifically, mixin-2 must be before mixin-1. (defclass base-class () ()) (defclass use-1 (mixin-1 base-class) ()) (defclass use-2 (mixin-2 base-class) ()) (defclass use-both (mixin-1 mixin-2 base-class) ()) (defclass use-both-2 (use-1 use-2) ()) (defclass mixin-1 (base-class) () (:precedence mixin-2 mixin-1 base-class)) (defclass mixin-2 (base-class) () (:precedence mixin-2 mixin-1 base-class)) ;use-1 and use-2 will not accidentally include the other mixin ;use-both will get an error for inconsistent precedence constraints ;use-both-2 will get a CPL of (use-both-2 use-1 use-2 mixin-2 mixin-1 base-class t) ;R={(use-both-2,use-1),(use-1,use-2),(use-1,mixin-1),(mixin-1,base-class), ; (use-2,mixin-2),(mixin-2,base-class),(mixin-2,mixin-1)} ;"Gross example" that helped me shoot down various other rules for ;resolving topological sort ambiguities ;CPL is (a c b e d t) ;R is {(a,b),(b,d),(c,b),(e,d)}. (defclass a (b d) ()) (defclass b (c) () (:precedence b)) (defclass c () () (:precedence c b)) (defclass d (e) () (:precedence d)) (defclass e () () (:precedence e d)) ;Two examples taken from actual (ugh, bletch) window code: ;This one shows two mixins that have an ordering constraint among them, ;but are not always used together. Rather than rely on any class that ;includes both to specify the constraint correctly, we specify it here. ;The user is adding more constraints to the default constraints. (DEFCLASS DONT-SELECT-WITH-MOUSE-MIXIN (ESSENTIAL-WINDOW) () ;; If TV:SELECT-MIXIN is present, we must ;; override its :NAME-FOR-SELECTION method (:PRECEDENCE TV:DONT-SELECT-WITH-MOUSE-MIXIN TV:SELECT-MIXIN TV:ESSENTIAL-WINDOW)) ;This one shows a class that is just a bundle of useful mixins, but doesn't ;want to constrain the order of those mixins. ;The user is specifying fewer than the default constraints (DEFCLASS WINDOW (STREAM-MIXIN BORDERS-MIXIN LABEL-MIXIN SELECT-MIXIN GRAPHICS-MIXIN MINIMUM-WINDOW) () ;; The mixins already come with almost all necessary constraints. ;; Relax the constraints that would normally be implied by the above list ;; of components, so that subclasses of WINDOW can rearrange things. ;; Put the label inside the border. (:PRECEDENCE BORDERS-MIXIN LABEL-MIXIN) ;; For esthetics, force WINDOW to precede MINIMUM-WINDOW (:PRECEDENCE WINDOW MINIMUM-WINDOW))  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Sep 87 19:39:36 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Sep 87 16:30:24 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 09 SEP 87 16:30:51 PDT Date: 9 Sep 87 16:30 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: proposed syntactic cleanups in defmethod In-reply-to: David A. Moon 's message of Thu, 20 Aug 87 12:29 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870909-163051-15667@Xerox> I propose that the DEFMETHOD macro be specified to "refer to" (in the sense of CLtL p.160) each specialized parameter. I think this is a fine idea. One of the most common mistakes of beginning Lisp programmers is omitting quote marks or putting them in the wrong place. Actually, it's not only beginning programmers who do this. I still do it myself sometimes, and I believe I have seen Danny Bobrow do it. I never do 'that'', do I?? The other problem with methods on individuals is that the current syntax [for defmethod] is awkward when the individual is anything other than a symbol or a number The intent was that for other cases, one would use the add-method form which evaluates its arguments. However, I don't at all mind seeing a change that makes defmethod easier to use for this case. And I agree that evaluating the argument is useful, and using single quote may be a more error prone as a syntax than a fully spelled keyword. Of EQL and MEMBER, I prefer EQL since the form (MEMBER X) looks too easy to extend with a Y and Z. But I would prefer not to suggest extensions unless we are prepared to follow through on them soon. For this reason some other word might be better. How about (THIS x) as being mnemonic and short. I think that adding QUOTE as a type-specifier to Common Lisp is both unnecessary and confusing. (Yes, I know I suggested it. I was wrong.) Instead, the parameter-specializer for a method on an individual should be (MEMBER object), the type-specifier that Common Lisp already defines for this purpose. Note that there is no particular reason why the parameter-specializer should be the same as the parameter-specializer-name; they're already not the same for methods on classes. A problem with this may be that the type specifier is used in the specializers argument of add-method, and again this could lead to unwarranted extrapolation. On the other hand, if you are using add-method perhaps you are immune to unwarranted speculation.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Sep 87 14:34:51 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Sep 87 11:24:45 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 09 SEP 87 11:20:17 PDT Date: 9 Sep 87 11:20 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Updating Obsolete Instances To: common-lisp-object-system@SAIL.STANFORD.EDU cc: Bobrow.pa@Xerox.COM Message-ID: <870909-112017-15101@Xerox> One of the open questions we should resolve next week is what the protocol should be for updating obsolete instances (instances of obsolete classes). I present here a radically simpler proposal than the ones we were most recently considering, though it bears strong resemblance to some that were discussed earlier. Proposal: A class becomes obsolete when it is redefined (directly or indirectly), the instance slots it specifies changes, AND it has one or more instances. For classes that are instances of standard-class, we support a protocol to update instances whose structure becomes obsolete. If a class becomes obsolete, then we say its instances are obsolete instances. Let c-new be the class specified by the new class definition. Let obsolete-slots be the names of those slots that are not included in the new definition, added-slots be the names of the new slots added, and common-slots be the rest. Effectively what happens is that all the obsolete instances become a subclass of a newly defined class that has as direct-superclasses (obsolete-class c-new). Hence, all methods applicable to instances of the new class are applicable to the old instances. However, the first time an attempt is made to access a slot-value of the obsolete instance, the structure of the instance is updated to the current structure before the slot-value completes. The updating is done (effectively) as follows: 1) Values of all slots in the old instance are saved 2) The structure of the instance is made to correspond to the structure specified by the current class definition (and it is an instance of class c-new) 3) Values of all common-slots are inserted in the new instance structure in the same named slot 4) The generic function obsolete-instance-updated is called. Its arguments are the instance (now with the new structure) and a property list containing the names and values of the obsolete-slots. There is a method on standard-object for obsolete-instance-updated (defmethod obsolete-instance-updated ((updated-instance standard-object) obsolete-slot-values) ...) This method initializes (from initform) any slot in the new structure that is not already bound. Slots without initforms are not touched. Note that by specializing obsolete-instance-updated, one can do work before or after, or instead of the initialization of unbound slots. To enable users to cause instances to be updated without having to add a phony slot, or some other abomination, we provide a generic-function: (make-class-obsolete class) with a method for standard-class that has the appropriate effect. DISADVANTAGES 1) This proposal specifies that updating will not happen until a slot is accessed. Perhaps this is too restrictive on implementations. 2) Methods applicable to the old class, but no longer current are not usable. 3) This proposal does not support sequential updating of a chain of obsolete structures. The only information it provides is the set of obsolete-slots and values. We could make it possible to determine which version of the obsolete class was involved in the update by passing the obsolete-class as a second argument to updating-obsolete-instance. But I don't think this is worth it. ADVANTAGES 1) It specifies exactly when the update will happen, and hence is guaranteed to minimize the work done; that is, no instance is updated until it needs to be. It is possible to test if an instance is obsolete by checing its type (seeing if its class is a subclass of obsolete-class). 2) It ameliorates a problem we were discussing about how long what methods must be kept around etc. No old versions of methods are kept. 3) It is simple to explain. Only one instance and class is involved in updating-obsolete-instance, and the obsolete-slot information is passed explicitly. The default behavior is what I claim is usually wanted.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Sep 87 15:32:18 EDT Date: 08 Sep 87 1221 PDT From: Dick Gabriel Subject: WITH-ADDED-METHODS To: common-lisp-object-system@SAIL.STANFORD.EDU There is, I think, a better syntax for WITH-ADDED-METHODS than what Danny sent out. That syntax was one we discussed in the context of a slightly different semantics. (with-added-methods ((foo (...)...) (bar (...) ...) (bar (...) ...) (foo (...)...) ) This takes the possibly already existing generic functions, FOO and BAR, copies them, adds the new methods to them as specified, and then executes . If no generic function exists, it is created. Previously defined generic functions are not altered by the action of this construct. The bindings of FOO and BAR have indefinite extent. -rpg-  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 4 Sep 87 16:47:47 EDT Received: from Catawba.ms by ArpaGateway.ms ; 04 SEP 87 13:37:36 PDT Return-Path: Redistributed: commonloops.pa Received: from hplabs.HP.COM ([15.255.16.7]) by Xerox.COM ; 04 SEP 87 13:34:14 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Fri, 4 Sep 87 13:31:59 pdt Received: from hplrds (hplrds) by hplms2; Fri, 4 Sep 87 13:31:41 pdt Return-Path: Received: by hplrds ; Fri, 4 Sep 87 13:27:52 pdt Date: Fri, 4 Sep 87 13:27:52 pdt From: dsouza%hplrds@hplabs.HP.COM Message-Id: <8709042027.AA00225@hplrds> To: commonloops.pa@Xerox.COM Subject: *early-generic-functions* in file boot.l In PCL 8-27-87, file boot.l : The following code attempts to do a (setf (symbol-function ...) NIL). Commenting out the line and replacing by the subsequent line appears to fix the problem: (eval-when (eval load) ;; To try and make it possible to load PCL into an environment in which ;; it has already been loaded, be sure to get rid of any generic function ;; objects we are likely to encounter during bootstrapping. (dolist (x *early-generic-functions*) (cond ((and x (symbolp x)) (fmakunbound x)) ((and (listp x) (eq (car x) 'setf)) ;;;(setf (get-setf-generic-function (cadr x)) nil) ;COMMENT OUT (fmakunbound (get-setf-generic-function-name (cadr x)))) ;REPLACE WITH (t (error "What the hell is ~S doing on *early-generic-functions*?" x))))) Roy D'Souza dsouza@hplabs.hp.com (415) 857-7557  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Sep 87 14:21:08 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Sep 87 11:12:21 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 87 11:10:36 PDT Date: 4 Sep 87 11:10 PDT Sender: Lanning.pa@Xerox.COM From: Stanley's Tool Works Subject: WITH-SLOTS, "virtual" slots, and the meta-object protocol To: Common-Lisp-Object-System@Sail.Stanford.edu Message-ID: <870904-111036-11421@Xerox> Start with the standard x/y v rho/theta example: (defclass position () (x y)) (defmethod rho ((p position)) ...) (defmethod theta ((p position)) ...) (defmethod-setf rho ((p position)) (value) ...) (defmethod-setf theta ((p position)) (value) ...) What if a user of the POSITION class writes the following method: (defmethod zoom ((p position) n) (with-slots (p) (setf rho (* n rho)))) How is this going to work? Presumably the WITH-SLOTS macro consults the class to find out what vars should be treated as slot references, but the notion that RHO and THETA are slots has not been made explicit. How does the writer of the POSITION class tell the class about these "virtual" slots? Perhaps there should be macros that let you write (defaccessor rho ((p position)) ...) (defaccessor-setf rho ((p position)) ...) or maybe a new method-qualifier so you could write (defmethod rho :accessor ((p position)) ...) (defmethod-setf rho :accessor ((p position)) ...) I guess there could also be another class-option added to DEFCLASS, but even if there were, something like these macros would be needed. ----- smL  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Sep 87 14:07:14 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Sep 87 10:58:23 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 87 08:56:41 PDT Date: 4 Sep 87 08:56 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Anonymous Generic Function Proposal (Draft 2) In-reply-to: Dick Gabriel 's message of 01 Sep 87 23:17 PDT To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870904-085641-11164@Xerox> Dick and I had a discussion about with-added-methods. We came to the following conclusion about handling Case 3. (with-added-methods (*) . ) This takes a generic function and a list of methods specified as lambda-expressions, creates a copy of the generic function and extends it by adding the given methods. Within the lexical scope of the form, (in ) appearances of refer to the extended generic-function. with-added-methods does not affect the original definition of . This answers my question -- (defmethod fie (x) 0) (defun foo (x) (with-added-methods fie ((lambda ((x P1)) 17)) (cons (fie x) (fum x))) (defun fum (y) (fie y)) (foo (make-instance 'P1)) ==> (17 . 0) And it answers Pavel's query: During the time that WITH-ADDED-METHODS is active, should the other processes see the added methods or not? I would hope not! Correct. To obtain a special version of print with added methods, one uses (with-added-methods #'print ((lambda (...)...) (lambda (...)...)) #'print) and passes the returned generic function as an argument. Note that since the generic function is copied on entry, this specialized print is not affected by later global changes to the print generic function.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 4 Sep 87 11:11:23 EDT Received: from Concord.ms by ArpaGateway.ms ; 04 SEP 87 08:00:03 PDT Return-Path: Redistributed: commonloops.pa Received: from hplabs.HP.COM ([15.255.16.7]) by Xerox.COM ; 04 SEP 87 07:57:14 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Fri, 4 Sep 87 07:56:31 pdt Received: from hplabsz.hpl.hp.com by hplms2; Fri, 4 Sep 87 07:56:15 pdt Return-Path: Received: from hplabsz by hplabsz; Fri, 4 Sep 87 08:57:02 pdt To: gregor.pa@Xerox.COM Cc: commonloops.pa@Xerox.COM Subject: Next Release? X-Mailer: mh6.5 Date: Fri, 04 Sep 87 08:56:59 MST Message-Id: <27104.557765819@hplabsz> From: kempf%hplabsz@hplabs.HP.COM Will there be a release available anytime soon? If so, will method combination be supported?  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 4 Sep 87 10:19:18 EDT Received: from Semillon.ms by ArpaGateway.ms ; 04 SEP 87 07:08:11 PDT Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 04 SEP 87 07:06:02 PDT Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (burdvax) [5.54/1.0] id AA04655; Fri, 4 Sep 87 10:05:33 EDT Received: by bigburd.PRC.Unisys.COM (bigburd) [5.54/1.0] id AA16596; Fri, 4 Sep 87 10:05:27 EDT From: fritzson@bigburd.PRC.Unisys.COM (Richard Fritzson) Message-Id: <8709041405.AA16596@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd with PUP; Fri, 4 Sep 87 10:05 EDT Date: 4 Sep 87 10:05 EDT (Friday) To: commonloops.pa@Xerox.COM Subject: trace-method Cc: fritzson@bigburd.prc.unisys.com I've been trying out trace-method and untrace-method. What I find is that even though (trace-method '(distance (position position))) actually does put a traced version of the code in the method-function slot of the appropriate method object, I still don't get a trace when I invoke the generic function which executes the method. To be specific, after executing the above form, (distance posa posb) returns the correct result with no trace printed, but if I try this: (setf (symbol-function 'temporary) (method-function (get-method (symbol-function 'distance) () (list (class-named 'position) (class-named 'position))))) (temporary posa posb) I get the correct result and a trace. How does the system manage to skip using the method-function of the method object?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Sep 87 21:45:41 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Sep 87 18:37:57 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 227853; Thu 3-Sep-87 21:39:00 EDT Date: Thu, 3 Sep 87 21:38 EDT From: David A. Moon Subject: Re: Another try on object creation To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870903-141438-10242@Xerox> Message-ID: <870903213846.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 3 Sep 87 14:14 PDT From: Danny Bobrow .... Another question. What happens if a method is invoked with a named argument that it is not prepared to receive? Is it a run-time error? It is easy to construct examples where this could happen. I'll answer the rest of your message later, because I want to think a bit, but the answer to this question is that functions defined with defmethod receive their arguments in exactly the same way as functions defined with defun. So it does whatever CLtL says and the implementation implements.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Sep 87 20:13:38 EDT Received: from [15.255.16.7] by SAIL.STANFORD.EDU with TCP; 3 Sep 87 17:04:47 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 1 Sep 87 16:00:08 pdt Received: from hplabsz.hpl.hp.com by hplms2; Tue, 1 Sep 87 15:59:35 pdt Return-Path: Received: from hplabsz by hplabsz; Tue, 1 Sep 87 17:00:18 pdt To: Patrick H Dussud Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Solutions to Name/Object Mapping for Generic Functions In-Reply-To: Your message of Thu, 27 Aug 87 15:05:47 -0500. <2766081947-606167@Jenner> Date: Tue, 01 Sep 87 17:00:15 MST Message-Id: <3994.557535615@hplabsz> From: kempf%hplabsz@hplabs.HP.COM > > THE PROBLEM AND PROPERTIES OF A GOOD SOLUTION > > > The following are some possible solutions: > > 1) The symbol function cell could be eliminated as a global object and > the name to funcallable object mapping could be maintained within the > environment, as is the case in Scheme. > > 2) The generic function slot accessor functions could take an > environment argument and return information accordingly. This > was the solution I believe Patrick proposed. > 3) We could simply leave it up to implementors to supply these > hooks, if they so choose. > If you are talking about name-to-generic-function mapping, 2 is not what > I have proposed. Yes, you are right. What I should have said is that it is *similar* to what you proposed. The original proposal mentioned modifying ADD-METHOD, GET-METHOD, REMOVE-METHOD, FIND-APPLICABLE-METHODS, and ENSURE-GENERIC-FUNCTION to take environment arguments, which are all part of the metaclass protocol, in addition to SYMBOL-FUNCTION: > 2- CLOS functions that must have an environment argument: > > CLASS-NAMED and its SETF form, > ADD-METHOD, > GET-METHOD, > REMOVE-METHOD, > FIND-APPLICABLE-METHODS, > ENSURE-GENERIC-FUNCTION. I believe the intention was, however, that they should pass the environment on to SYMBOL-FUNCTION or use it in some implementation dependent manner. What 2 is proposing is to decouple modification of SYMBOL-FUNCTION to take an environment parameter, which I believe will have serious reprecussions for Common Lisp semantics, from the metaclass protocol modifications. Modification of SYMBOL-FUNCTION would be the essense of 1. > Name-to-generic-function mapping shouldn't depend on > the metaclass protocol since it should behave the same as > name-to-regular-function. If SYMBOL-FUNCTION is modified to take an environment argument, then the name-to-regular-function mapping is going to change too. A metacircular definition of the Common Lisp interpreter might look like; (cond ( (fboundp (first form)) (apply (symbol-function (first form)) argument-list) ) ) Changing SYMBOL-FUNCTION means this becomes; (cond ( (fboundp (first form)) (apply (symbol-function (first form) ) argument-list) ) ) But what environment? The current one? The base one? Modification of SYMBOL-FUNCTION means that semantics of function application in Common Lisp must be changed, becoming more like Scheme. Now, I have no objection to this (in fact, I think it would be an improvement) but some compiler writers and application developers might. Note that this semantic change is very different from the one generic functions introduce, because it involves global (environment) rather than local (parameter classes) information, and hence could require larger modifications to existing code. > Not being affected by the metaclass protocol, > it can be left to the implementation. The hook should be specified > though. If some implementations decide to ignore the environment, > that's fine. Since the environment is going to be passed explicitly (see > Moon's reponse to my proposal), we either need a new primitive for that, > or change SYMBOL-FUNCTION to accept an environment argument. A new > primitive for metaclass programmers is probably the best thing to do. I'm not quite sure what the "or" is here. I understand the proposal for primitives to access the environment, but I don't understand where the hook could be, other than through the metaclass method lambda lists. A way to work around this difficulty might be the following. Instead of modifying the name to generic function mapping to be sensitive to the environment, we modify the generic function object to slot value mapping to use the environment. This was supposed to be the essence of 2. Thus information on methods being compiled can be stored in the generic function object, but invocation of the generic function would get definitions in the compiler's run time environment. This complicates the object to slot value mapping somewhat, but avoids the problem with changing the semantics of SYMBOL-FUNCTION. The idea is that the generic function remembers the environment in which it was defined for funcalling purposes, and otherwise uses the current environment for maintaining information about definitions being compiled. Admittedly, this is a halfway solution, but would involve less drastic modifications to Common Lisp, I think. > However I object to 3 since it will make serious metaclass programming > non portable. It will restrict the class of object-object oriented languages which can be portably implemented using the metaclass protocol to those which don't require information on methods being compiled to be portably available in the compile time environment. Note that CommonObjects is in this class, and we have gotten around the problems by some monumental kludges and some portable importabilities, ie., things which each implementor of PCL needed to customize to their system. That particular part of CommonObjects on CommonLoops was the most difficult to do, and the one which breaks most often. The tradeoff for CLOS is that the metaclass protocol would be simpler, and no modification of the base Common Lisp semantics would be needed, meaning we could probably converge on a solution more quickly.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Sep 87 17:22:52 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Sep 87 14:14:21 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 03 SEP 87 14:14:38 PDT Date: 3 Sep 87 14:14 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Another try on object creation In-reply-to: David A. Moon 's message of Wed, 2 Sep 87 23:13 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870903-141438-10242@Xerox> Patrick Asked Why don't you use a class prototype to call default-initargs and check-initargs? Moon had two arguments for this One is that this was the only use of prototypes, so by changing this we can eliminate the need to expose that concept; it makes the standard simpler. The concept of class-prototype must be introduced for other reasons in the metaobject protocol, so I don't buy this reason. The second reason is ... functions generic on the class are part of the metaclass protocol and you only write methods for them if you are doing over part of the implementation. My intuition (expressed in our initial propposal) was that default-initargs, check-initargs etc were really user (instance) business. However, I now agree with Moon that these mechanisms for initialization (except for user-defined :after methods) are more closely associated with the implementation of a class and hence are metaclass methods. Ordinary users would rarely want to change them -- especially if these methods are not guaranteed to be called each time (i.e. optimized away) except at some great cost. Since I think these optimizations are important in the standard case, I am happy to leave default-initargs and check-initargs specialized on the metaclass. I do have another question on the initialization proposal though. Why do we need &method-key? Why not make the congruence rules for generic functions be those Moon described for &method-key i.e. the acceptable named arguments for a generic function are the union of the named arguments of the methods, or &allow-other-keys. The one feature this eliminates is the ability to define a generic function for which all methods must have exactly the same named arguments. This seems a small loss, and we gain by not having to add another lambda-keyword. Another question. What happens if a method is invoked with a named argument that it is not prepared to receive? Is it a run-time error? It is easy to construct examples where this could happen.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Sep 87 23:20:31 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 2 Sep 87 20:13:02 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 226977; Wed 2-Sep-87 23:13:58 EDT Date: Wed, 2 Sep 87 23:13 EDT From: David A. Moon Subject: Re: Another try on object creation To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <2766605837-15560752@Jenner> Message-ID: <870902231340.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 2 Sep 87 16:37:17 CDT From: Patrick H Dussud (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (check-initargs class initargs) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance)) I have a question: Why don't you use a class prototype to call default-initargs and check-initargs? That's the way the notes from the meeting had it, but in my proposal I changed that for two reasons. One is that this was the only use of prototypes, so by changing this we can eliminate the need to expose that concept; it makes the standard simpler. The second reason is a little more complex: in trying to figure out why there was such apparent randomness, with some functions generic on the instance and others generic on the class, I decided it must be that functions generic on the instance can have methods defined by ordinary users, and can have those methods combined with inheritance, while functions generic on the class are part of the metaclass protocol and you only write methods for them if you are doing over part of the implementation. At the meeting we said that it was "hard to make default-initargs and check-initargs generic" and left it at that. If you think about check-initargs, all the checking has to be in one place; there is no way to do it by combining inherited methods, each of which checks one class's initargs. In fact there is one method for check-initargs which looks at the slot-initargs and the lambda-lists of the applicable methods and decides what to do. Therefore, I decided check-initargs must be a metaclass method. The alternative would have been to have a check-initarg generic function that checks one argument at a time, which seemed unduly complex. Less clear is defaulting, but what decided me there was that at the meeting there was a move to combine default-initargs and check-initargs into a single operation, in which case they would have to be generic on the same thing. I don't really see much usefulness in users defining their own default-initargs methods, when they are not working at the metaclass level, so to keep things simple I made that generic on the class. It's true that in this formulation you can't do certain customized defaulting and checking operations except by programming at the metaclass level. However, making those two functions generic on the instance still wouldn't make those operations simple and easy to explain (see mail discussion of the past few months), and I think at some point we have to limit the ambitions of CLOS and say that it doesn't replace all forms of programming. That's why I proposed it the way I did. This is not to say that no one should propose that it work a different way, if they can refute the arguments above. For this purpose, default-initargs and check-initargs should be discussed separately.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Sep 87 18:42:11 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 2 Sep 87 15:34:34 PDT Received: from relay2.cs.net by RELAY.CS.NET id ab03266; 2 Sep 87 17:59 EDT Received: from ti-csl by RELAY.CS.NET id af13392; 2 Sep 87 17:48 EDT Received: from Jenner by tilde id AA19802; Wed, 2 Sep 87 16:39:20 CDT Message-Id: <2766605837-15560752@Jenner> Date: Wed, 2 Sep 87 16:37:17 CDT From: Patrick H Dussud To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: Another try on object creation In-Reply-To: Msg of Fri, 28 Aug 87 22:13 EDT from "David A. Moon" (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (check-initargs class initargs) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance)) (defmethod make-instance ((class-name symbol) &rest initargs) (apply #'make-instance (symbol-class class-name) initargs)) I have a question: Why don't you use a class prototype to call default-initargs and check-initargs? Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Sep 87 15:30:13 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Sep 87 12:24:04 PDT Received: from Semillon.ms by ArpaGateway.ms ; 02 SEP 87 12:10:50 PDT Date: Wed, 2 Sep 87 12:10:46 PDT From: Pavel.pa@Xerox.COM Subject: Re: Anonymous Generic Function Proposal (Draft 2) In-reply-to: <870902-114927-8581@Xerox> To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870902-121050-8628@Xerox> Another question about the proposal: What is the intent with respect to multi-process environments? During the time that WITH-ADDED-METHODS is active, should the other processes see the added methhods or not? I would hope not;; this should have the same sort of behaviour as special variables. Pavel  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 2 Sep 87 15:08:04 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 87 11:55:26 PDT Date: 2 Sep 87 11:54 PDT From: Gregor.pa@Xerox.COM Subject: test message 2 To: CommonLoops.pa@Xerox.COM Message-ID: <870902-115526-8603@Xerox> This message is just a test, please delete it. Sorry for the inconvenience. Gregor  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Sep 87 14:55:50 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Sep 87 11:49:10 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 87 11:49:27 PDT Date: 2 Sep 87 11:49 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Anonymous Generic Function Proposal (Draft 2) In-reply-to: Dick Gabriel 's message of 01 Sep 87 23:17 PDT To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870902-114927-8581@Xerox> When WITH-ADDED-METHODS exits, the added methods are removed. Any flow of control out of the WITH-ADDED-METHODS causes the methods to be removed. I still find this ambiguous. Consider (defmethod fie (x) 0) (defun foo (x) (with-added-methods fie ((lambda ((x P1)) 17)) (cons (fie x) (fum x))) (defun fum (y) (fie y)) (foo (make-instance 'P1)) ==> (17 . 17) or ==> (17 . 0)  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Sep 87 02:24:26 EDT Date: 01 Sep 87 2317 PDT From: Dick Gabriel Subject: Anonymous Generic Function Proposal (Draft 2) To: common-lisp-object-system@SAIL.STANFORD.EDU Draft 1 is amended to take into account Danny's comment. There are 3 cases to consider: 1. Purely anonymous generic functions, corresponding to (function (lambda ...)) in Common Lisp. 2. A set of named generic functions to be used within a particular body, corresponding to (labels ...) in Common Lisp. An analog to FLET might be appropriate also. 3. A means of extending a generic function currently defined on a symbol (name) or lexically. This corresponds to nothing in Common Lisp. Here is a proposal, inspired by Guy Steele, which covers case 1: (generic (lambda ...) (lambda ...) (lambda ...) ...)) This special form produces a generic function with the lambda-expressions as the methods. This is about as similar to the FUNCTION syntax as can be rationally gotten. To cover case 2 we define an analog to Common Lisp LABELS, but instead of functions the user defines methods: (generic-labels ((foo (...)...) (bar (...) ...) (bar (...) ...) (foo (...)...) ) This form produces 2 new generic functions, FOO and BAR. At this point it is easy to extend FLET similarly: (generic-flet ((foo (...)...) (bar (...) ...) (bar (...) ...) (foo (...)...) ) The simplest means of producing an anonymous recursive generic function is: (generic-labels ((self (...)...(self...)...) (self (...)...(self...)...) ...) #'self) Both GENERIC-LABELS and GENERIC-FLET produce new generic functions. The fact that a generic function is already bound to a variable of the same name or to a symbol is irrelevant to the operation of these forms. Notice that the special form FUNCTION will need to be amended in CLtL to be able to produce a generic function, but this should be a natural fallout of making a generic function a subtype of FUNCTION. Handling case 3 is more difficult, because there is no corresponding Common Lisp form to do a similar thing for functions. A danger is to inadvertently design a form that will also accomplish the dynamic binding of a function associated with a symbol. (with-added-methods (*) . ) This takes a generic function and a list of methods specified as lambda-expressions, extends the generic function by adding the appropriate methods, and then executes the forms in as if they were in a PROGN. When WITH-ADDED-METHODS exits, the added methods are removed. Any flow of control out of the WITH-ADDED-METHODS causes the methods to be removed. Notice that this handles both anonymous and named generic functions. For example: (generic-flet ((foo (...)...) (foo (...)...)) (with-added-methods #'print ((lambda (...)...) (lambda (...)...)) (with-added-methods #'foo ((lambda (...)...)) ))) -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 1 Sep 87 21:30:23 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 1 Sep 87 18:23:50 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 SEP 87 18:19:05 PDT Date: 1 Sep 87 18:18 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Anonymous Generic Function Proposal (Draft 1) In-reply-to: Dick Gabriel 's message of 01 Sep 87 13:00 PDT To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870901-181905-7824@Xerox> (with-added-methods ((print (...)...) (print (...)...) (read (...)...) (read (...)...) (read (...)...)) ) Is this strictly lexical (only calls within the have the added methods), or is it dynamic (calls from any called function see the methods, but the methods are removed when the fom is exited). Both are useful I think. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 1 Sep 87 16:09:12 EDT Date: 01 Sep 87 1300 PDT From: Dick Gabriel Subject: Anonymous Generic Function Proposal (Draft 1) To: common-lisp-object-system@SAIL.STANFORD.EDU There are 3 cases to consider: 1. Purely anonymous generic functions, corresponding to (function (lambda ...)) in Common Lisp. 2. A set of named generic functions to be used within a particular body, corresponding to (labels ...) in Common Lisp. An analog to FLET might be appropriate also. 3. A means of extending a generic function currently defined on a symbol (name). This corresponds to nothing in Common Lisp. Here is a proposal, inspired by Guy Steele, which covers case 1: (generic (lambda ...) (lambda ...) (lambda ...) ...)) This special form produces a generic function with the lambda-expressions as the methods. This is about as similar to the FUNCTION syntax as can be rationally gotten. To cover case 2 we define an analog to Common Lisp LABELS, but instead of functions the user defines methods: (generic-labels ((foo (...)...) (bar (...) ...) (bar (...) ...) (foo (...)...) ) At this point it is easy to extend FLET similarly: (generic-flet ((foo (...)...) (bar (...) ...) (bar (...) ...) (foo (...)...) ) The simplest means of producing an anonymous recursive generic function is: (generic-labels ((self (...)...(self...)...) (self (...)...(self...)...) ...) #'self) Notice that the special form FUNCTION will need to be amended in CLtL to be able to produce a generic function, but this should be a natural fallout of making a generic function a subtype of FUNCTION. Handling case 3 is more difficult, because there is no corresponding Common Lisp form to do a similar thing for functions. A danger is to inadvertently design a form that will also accomplish the dynamic binding of a function associated with a symbol. (with-added-methods ((print (...)...) (print (...)...) (read (...)...) (read (...)...) (read (...)...)) ) Among the things that could have been included in this proposal is the ability to have the method functions be able to call each other without going through the generic function object. However, this obscure case can be hacked together using add-method etc, and I don't believe it deserves a special syntax. (It might be so obscure you cannot understand this description, but that only reinforces my argument.) -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 1 Sep 87 16:04:23 EDT Date: 01 Sep 87 1258 PDT From: Dick Gabriel Subject: Name That Class! To: common-lisp-object-system@SAIL.STANFORD.EDU It would be nice if it turned out that the relationship between a class and its name could be as clean as the relationship between a symbol and its value, but this is not the case: We can already ask of a class its name. When I wrote these examples I thought of two parallel activities going on in two CLOS's right next to each other - one in which a user was using DEFCLASS to build up a hierarchy and one in which a user was using anonymous classes to build up the same hierarchy. My assumption about the equivalence of DEFCLASS and the LET-expression was derived from a belief that simplicity of model was desirable. I don't, now, believe that the behaviors I listed in my message are alarming (though I did originally) because one can imagine a Common Lisp in which (defun f (...)...) and (setf (symbol-function 'f) (function (lambda (...)...))) are equivalent and similar behaviors hold to the ones in that message (that is, SETF of SYMBOL-FUNCTION is smart). We also run into the problem that Common Lisp already treats types as a sort-of subclass of SYMBOL, and so the tight name-to-object mapping described in my message is not altogether out of line with an attempt to integrate classes with types. We haven't really talked about what DEFCLASS is equivalent to yet, so I suppose there are now two proposals as to what that might be on the table. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 1 Sep 87 14:57:37 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 1 Sep 87 11:49:53 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 SEP 87 10:11:53 PDT Date: 1 Sep 87 10:11 PDT From: Gregor.pa@Xerox.COM Subject: Re: Name That Class! In-reply-to: Dick Gabriel 's message of 30 Aug 87 20:24 PDT To: RPG@SAIL.STANFORD.EDU cc: Common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870901-101153-7058@Xerox> Your first example is right. But there is a mistaken assumption in your second example that throws all the others off. Specifically, you say that: It seems that (DEFLCASS FOO ...) is equivalent to (let ((c (make-instance 'standard-class))) (setf ( c) ) (setf (class-named 'foo) c) c) But this isn't right. (defclass foo ...) is equivalent to: (let* ((existing (class-named 'foo t)) (new (if existing (class-for-redefinition existing) (make-instance 'standard-class)))) (setf (class-named 'foo) new) (update-class new ..) new) Given this clarification, its clear that (for instances of standard-class) the rest of your examples should return: 2. T 3. T 4. T The point is that class-named has no smarts (remember that as much as possible we don't want to do things that just couldn't map into a Lisp-1, and certainly set! has no smarts). class-for-redefinition is where all the smarts is.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 1 Sep 87 12:58:06 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 SEP 87 09:24:52 PDT Date: 1 Sep 87 09:22 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: COPY-INSTANCE ? In-reply-to: Sean.Engelson@SPICE.CS.CMU.EDU's message of 1 Sep 87 11:45 EDT To: Sean.Engelson@SPICE.CS.CMU.EDU cc: commonloops.pa@Xerox.COM Message-ID: <870901-092452-6976@Xerox> Because it is unclear what to do with respect to recursion (they are many "right choices") no standard facility for copying is available in PCL. The important issues are: Should values be copied or shared? If copied, should ciruclarities be maintained? If not, should their be a depth limit. danny  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 1 Sep 87 12:57:50 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 SEP 87 08:47:54 PDT Return-Path: Redistributed: commonloops.pa Received: from SPICE.CS.CMU.EDU by Xerox.COM ; 01 SEP 87 08:46:16 PDT Date: 1 Sep 87 11:45 EDT From: Sean.Engelson@SPICE.CS.CMU.EDU To: commonloops.pa@Xerox.COM Subject: COPY-INSTANCE ? Message-Id: <557509557/spe@SPICE.CS.CMU.EDU> Is there a way to copy instances in PCL? Something similar to the COPY- facility would be really useful and should be a part of PCL if it isn't already. -Sean-  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 1 Sep 87 11:51:00 EDT Received: from Burger.ms by ArpaGateway.ms ; 01 SEP 87 08:40:55 PDT Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 01 SEP 87 08:38:43 PDT Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (burdvax) [5.54/1.0] id AA15178; Tue, 1 Sep 87 11:38:13 EDT Received: by bigburd.PRC.Unisys.COM (bigburd) [5.54/1.0] id AA07019; Tue, 1 Sep 87 11:38:10 EDT From: fritzson@bigburd.PRC.Unisys.COM (Richard Fritzson) Message-Id: <8709011538.AA07019@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd with PUP; Tue, 1 Sep 87 11:38 EDT Date: 1 Sep 87 11:37 EDT (Tuesday) To: gregor.pa@Xerox.COM Subject: PCL-ENV glitch Cc: fritzson@bigburd.prc.unisys.com, commonloops.pa@Xerox.COM Thanks for posting a new version of PCL-ENV. In the file PCL-ENV, there is a minor bug. In the function frame-instance: The call to pcl::fnheader-debugging-info ought to be a call to xcl::fnheader-debugging-info. (Otherwise, you will get interrogated by DWIM everytime you break.)  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Aug 87 22:20:56 EDT Received: from AI.AI.MIT.EDU by SAIL.STANFORD.EDU with TCP; 31 Aug 87 19:14:25 PDT Date: Mon, 31 Aug 87 22:18:06 EDT From: Richard Mlynarik Subject: RPG's recent typo. To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <248781.870831.MLY@AI.AI.MIT.EDU> Perhaps DEFCLASS could be renamed DEFTSTRUCT.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Aug 87 11:09:32 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 31 Aug 87 08:02:20 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 31 Aug 87 08:00:47 pdt Received: from hplabsz.hpl.hp.com by hplms2; Mon, 31 Aug 87 08:00:25 pdt Return-Path: Received: from hplabsz by hplabsz; Mon, 31 Aug 87 09:01:03 pdt Message-Id: <8708311501.AA16453@hplabsz.hpl.hp.com> To: "Sonya E. Keene" Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Agenda for September meeting In-Reply-To: Your message of Fri, 21 Aug 87 10:17:00 -0400. <870821101706.9.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: Mon, 31 Aug 87 09:01:00 MST From: kempf%hplabsz@hplabs.HP.COM > Date: Thu, 20 Aug 87 14:23:16 MST > From: kempf%hplabsz@hplabs.HP.COM > With regard to the spec documentation> , I'd like to put in a vote for an ASCII > version to go on parcvax, along with the portable source, so people don't > have to be working in the dark with it. The ASCII version doesn't > necessarily have to be up to the current level of discussion and > decision within the committee (indeed, it probably shouldn't) but should > reflect approximately what is implemented. > Please don't confuse the spec documentation with documentation for an > implementation. These are two very different things! I hope I'm not. My concern is that, if the process of finalizing the spec and the portable implementation continue in tandem, as seems to be happening, people will want to have a more accessable copy of the spec. Of course, there will be differences between the spec and the implementation, and these should probably be documented. Additionally, should a decision be made not to pursue the portable implementation (which would be tragic, in my opinion) then there would be little need. There are lots of people using the current PCL/half CLOS at universities and such, and I think they'd like to have a copy. But I most whole-heartedly agree that the spec and any particular implementation of it are seperate.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Aug 87 00:00:10 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 30 Aug 87 20:53:31 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 224284; Sun 30-Aug-87 23:54:35 EDT Date: Sun, 30 Aug 87 23:54 EDT From: David A. Moon Subject: Class Precedence List To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 30 Aug 87 22:46 EDT from Dick Gabriel Message-ID: <870830235432.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 30 Aug 87 1946 PDT From: Dick Gabriel By the way, have we thought about various means of making the CPL more accessible, such as what New Flavors does? Yes, I signed up to write a proposal that would try to satisfy Gregor's objections to the proposal I presented previously, as best as I could understand them. I haven't done it yet, though. I've been putting my time into make-instance instead.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Aug 87 23:31:38 EDT Date: 30 Aug 87 2024 PDT From: Dick Gabriel Subject: Name That Class! To: Common-lisp-object-system@SAIL.STANFORD.EDU Before I left on my ill-fated trip to Europe (where I confronted face-to-face, once more, my muse) I wrote out some examples of how class objects and their names interacted. The idea was to explore what it meant to build a hierarchy with names (using DEFLCASS) and with class objects (blasting fields). I think these examples are right (I could be wrong) and they might strike some as odd, they are generally in accord with acceptable behavior of functions and the symbols that name them (and DEFSTRUCT names and types as well). I send them in hopes they might help stimulate thought on the issues: 1. (defclass foo ...) (let ((a (class-named 'foo))) (defclass foo ...) (eq a (class-named 'foo))) => T This has been agreed to be the best sufficient way to achieve the old-methods-still-work behavior. 2. (defclass foo ...) (let ((c (make-instance 'standard-class))) (setf ( c) ) (setf (class-named 'foo) c) (eq (class-named 'foo) c)) => ? MAKE-INSTANCE is not psychic, so it must cons. It seems that (DEFLCASS FOO ...) is equivalent to (let ((c (make-instance 'standard-class))) (setf ( c) ) (setf (class-named 'foo) c) c) Note that there is no similar expression in CLtL to which DEFTSRUCT is equivalent. Therefore the EQ must return NIL. This implies that (setf (class-named ...) ...) is smart and worries about the EQness between the previous class, if it exists, and the new one. 3. (let ((c (make-instance 'standard-class))) (setf ( c) ) (setf (class-named 'foo) c) ;foo otherwise undefined (eq (class-named 'foo) c)) => ? Why should (setf (class-named ...) ...) unnecessarily cons? Therefore the EQ should return T. 4. (defclass foo ...) (defclass baz ...) (let ((c1 (class-named 'foo)) (c2 (class-named 'baz))) (setf (class-named 'baz) (class-named 'foo)) ;;; (eq c1 c2) => NIL (eq (class-named 'foo) (class-named 'baz))) => ? Because (eq c1 (class-named 'foo)) => T, (eq c1 c2) => NIL, and (eq c2 (class-named 'baz)) => T, this must return NIL. 5. (defclass foo ...) (defmethod f ((x foo)) ...) ;no other methods (defclass baz ...) (defmethod g ((x baz)) ...) ;no other methods (setq instance1 (make-instance 'foo)) (setq instance2 (make-instance 'baz)) (rotatef (class-named 'foo) (class-named 'baz)) (f instance1) => well-defined? (f instance2) => well-defined? (g instance1) => well-defined? (g instance2) => well-defined? The first generic function invocation is well-defined; the second is an error of some sort; the third is an error of some sort; the fourth is well-defined. 6. (defclass c1 (c2 c3) ...) (defclass c2 ...) (defclass c3 ...) (defmethod f ((x c2)) ...) ;no other methods (setq instance1 (make-instance 'c1)) ;;; Flush the superclass link from C1 to C2 (setf (class-super-classes (class-named 'c1)) `(,(class-named 'c3))) (f instance1) => well-defined? I don't know what this should do, but I suspect the expression (f instance1) is not well-defined because the SETF alters the topology of the graph. It seems that once a name is given to a class, the symbol that is the name and the storage for that class are linked forever unless something like (setf (class-named 'foo) nil) is defined to work. It is also clear that the the applicability of methods within a class graph depends on the topology of the graph and not on the substance of the classes in that graph. If a user were to mistakenly exchange the names of two classes in a graph at the outset, he would not be able to correct that naming error using CLASS-NAMED and (SETF (CLASS-NAMED ...) ...) - example 4 shows this. He would have to alter the superclass slots in the classes surrounding the ones he wishes to switch, according to the technique in example 6, assuming that would even work. Enjoy! -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Aug 87 23:22:38 EDT Date: 30 Aug 87 2017 PDT From: Dick Gabriel Subject: Agenda To: common-lisp-object-system@SAIL.STANFORD.EDU The agenda seems fine to me. The key to making the meeting work is for people to dedicate time to studying the proposals and doing what they have volunteered to do. I, for example, will get to work on the anonymous generic function progosal tomorrow, and you will all have it within a week. Because I just returned from Europe, I don't even know what arrangements Linda has made. But, again, there is no territorialness in what they are, it is a matter of someone volunteering to do the work and then doing it. Danny was also in Europe, and no one else had stepped forward. On the document: I earlier promised to produce a minimal TEX macro file so that people could roll their own. It was a lack of time on my part that prevented that rather than some sinister plot. I hope I can get that done in a day and put it out on SAIL along with the TEX sources. The problem with the current macro file is that it is many dozens of pages long and contains the book layout definition for all of Lucid's manuals. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Aug 87 23:16:05 EDT Date: 30 Aug 87 2009 PDT From: Dick Gabriel Subject: Miscellaneous decisions taken or to be taken To: common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: The document says it has dynamic extent; we need to be sure that we really mean that. In July we said "implementation flexibility, not really a language thing", but I'm damned if I can figure out what that means (optimizing calculation of the effective method?). The document says ``the binding for the local variable CALL-NEXT-METHOD has lexical scope and dynamic extent.'' The idea is that a user would not even be allowed to create a closure that refered to CALL-NEXT-METHOD. I suppose he could, but he'd get some global defintion for CALL-NEXT-METHOD. We intend to not provide a poor man's continuation mechanism. I didn't think we even had anything as sophisticated as hierarchy redefinition in mind when we wrote this. The description needs to be clearer. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Aug 87 22:52:41 EDT Date: 30 Aug 87 1946 PDT From: Dick Gabriel Subject: Class Precedence List To: common-lisp-object-system@SAIL.STANFORD.EDU On July 27 Kempf mailed a note about the description of the class precedence list algorithm. Because I was away until yesterday, I was not able to respond: Kempf writes: 1) The use of the term "partial order" on pg. 1-15, paragraph 1 implies a relation on R which is reflexive, antisymmetric, and transitive. From the text of the paragraph, this relation is presumably the "is a subclass of" relation. However, earlier in the document, reflexivity is explicitly excluded from the "is a subclass of" relation (pg. 1-4, paragraph 3), since a class is defined to be neither a superclass nor a subclass of itself. Either the partial order needs to be replaced with a different order not requiring reflexivity (semiorder, etc.) or the "is a subclass of" relation needs to be redefined so that it is reflexive. Note that the latter solution is used in more technical treatments of typing systems (e.g. Cardelli and Wegner, Computing Surveys, 17, 1985, pp. 471-522). Knuth points out that one can define partial orderings using ``less than or equal'' and so does not require the antisymmetric condition. We should be more explicit here about it and define the partial ordering on a true reflexive, antisymmetric, and transitive relation. Kempf writes: 4) The formal description of class precedence list calculation on pg. 1-15, paragraph 3 is lacking a condition. In the third line, it is not sufficient just to require the existence of an index i, but also its minimality. As a counterexample, consider R := {(c1,c2) (c2,c3) (c3 c5) (c2 c4) (c4 c6)} The inheritance graph for this is.... Well, this is the result of a misreading of the algorithm. However, this is sufficient to require a rewrite of the description. As an aside to JAK, let me point out the following: his example was: c5 c6 | | c3 c4 | | \ / \ / c2 | c1 The relations used to define the partial ordering are: {(c1 c2)(c2 c3)(c2 c4)(c3 c4)(c3 c5)(c4 c6)} The key one is that c3 precedes c4. When the CPL is [c1 c2], there is only one class with no predecessors - C3. I believe the description of the algorithm to be correct, but I stand accused of and confess to it being a difficult description. I will volunteer to try to fix it up. By the way, have we thought about various means of making the CPL more accessible, such as what New Flavors does?  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 30 Aug 87 22:10:50 EDT Received: from Semillon.ms by ArpaGateway.ms ; 30 AUG 87 19:00:00 PDT Return-Path: Redistributed: commonloops.pa Received: from THEORY.CS.CMU.EDU by Xerox.COM ; 30 AUG 87 18:57:18 PDT Date: Sun, 30 Aug 87 16:51:46 EDT From: Timothy.Freeman@theory.cs.cmu.edu To: commonloops.pa@Xerox.COM Subject: Multiple keywords in make-instance Message-ID: <1987.8.30.20.31.35.Timothy.Freeman@THEORY.CS.CMU.EDU> If I do (make-instance 'foo :x 3 :x 4), and x is a slot in instances of the class foo, should the slot be given the value 3 or 4? For the version of PCL that I'm using now (4/29/87 prime), the slot gets 4. Is this also the case for more recent versions of PCL? According to CLtL, if make-instance were a function that takes a keyword argument X, the X parameter to make-instance would be 3. (Page 62, "If more than one such argument pair matches, it is not an error; the leftmost argument pair is used.") I think that PCL should deal with the keyword arguments to make-instance the same way that lisp deals with keyword arguments to functions. That way, if I want to write a piece of code that looks at keyword lists, I can use the same code for both the keyword lists passed to make-instance and the keyword lists passed to other functions.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 28 Aug 87 23:03:31 EDT Received: from Semillon.ms by ArpaGateway.ms ; 28 AUG 87 19:50:01 PDT Date: Fri, 28 Aug 87 19:47 PDT From: Gregor.pa@Xerox.COM Subject: new version of PCL To: CommonLoops.PA@Xerox.COM Message-ID: <870828194702.9.GREGOR@SPIFF.isl.parc.xerox.com> Line-fold: no There is a new version of PCL on parcvax.xerox.com. The notes are in the notes.text file. The only real difference between this version and last weeks is that this version runs in Pyramid Lisp. Otherwise, there were just a couple of bug fixes. Gregor -------  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Aug 87 22:19:07 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Aug 87 19:12:23 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 223738; Fri 28-Aug-87 22:13:25 EDT Date: Fri, 28 Aug 87 22:13 EDT From: David A. Moon Subject: Another try on object creation To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870828221318.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Draft of a new object creation proposal based on CLOS subcommittee discussions July 2, 1987. -foo- means the word foo in italics. FOO means the word foo in boldface. ONE NEW IDEA YOU HAVEN'T SEEN BEFORE There is a new lambda-list-keyword, &METHOD-KEY, which is only valid in DEFGENERIC-OPTIONS and DEFGENERIC-OPTIONS-SETF. The syntax of the lambda-list in these macros becomes ({-var-}+ [&optional {-var-}*] [&rest -var-] { [&key {-var- | ((-keyword- -var-))}* [&allow-other-keys]] | [&method-key [&allow-other-keys]] }) The meaning of &METHOD-KEY is that the specific set of named arguments accepted by the generic function varies depending on the positional arguments. The named arguments accepted by the generic function for a particular call are the union of the named arguments accepted by the applicable methods. There is no attempt to exclude methods that are applicable but are not actually called. Note that in standard method combination, all applicable methods are potentially callable, if CALL-NEXT-METHOD is used. A method that has &REST, but not &KEY, does not affect the set of acceptable named arguments. If the lambda-list of any applicable method or of the DEFGENERIC-OPTIONS has &ALLOW-OTHER-KEYS, all named arguments are accepted by the generic function. The implementation of &METHOD-KEY is in two parts: The macro expansion of DEFMETHOD, when the generic function uses &METHOD-KEY, is altered to save a list of the acceptable named-argument names in a slot of the method object and to put &ALLOW-OTHER-KEYS into the lambda-list of the function. If the lambda-list already contains &ALLOW-OTHER-KEYS, then that symbol is stored in place of the list of acceptable named-argument names (which would be infinite). The function METHOD-NAMED-ARGUMENTS retrieves this list or symbol. Secondly, the generic-function-to-method dispatching mechanism must check the validity of the argument list when the generic function uses &METHOD-KEY and does not use &ALLOW-OTHER-KEYS. This is accomplished by collecting the acceptable named-argument names from the applicable methods and checking the arguments against the union of those lists. If for any applicable method METHOD-NAMED-ARGUMENTS returns &ALLOW-OTHER-KEYS, the whole check is skipped. CONCEPTS TO BE ADDED TO 87-002 -named argument-. We use the term "named argument" instead of "keyword argument" (as in CLtL) for &key arguments, because CL-Cleanup issue KEYWORD-ARGUMENT-NAME-PACKAGE has stated that the names of &key arguments do not have to be keyword symbols. -named argument name-. The symbol that identifies a named argument in an argument list. This is typically a keyword, but is not required to be. The named-argument name should not be confused with the variable name of the parameter variable. These two symbols typically have the same name and are typically in different packages, but that is not required. -initarg-. An initarg (initialization argument) is a named argument that can be used to control object creation and initialization. The &key arguments to MAKE-INSTANCE are initargs. Each initarg has a name, which is a symbol, and may have a value, which is any Lisp object. It is often convenient to use keyword symbols to name initargs, but the name of an initarg can be any symbol, including NIL. -initarg list-. An initarg list (initialization argument list) is a list of alternating initarg names and values. Its structure is identical to a property list and also identical to an &key argument list. As in those lists, if an initarg name appears more than once in an initarg list, the leftmost occurrence supplies the value and the remaining occurrences are ignored. The arguments to MAKE-INSTANCE, after the first, are an initarg list. As in an &key argument list, :ALLOW-OTHER-KEYS can appear in an initarg list, and if its value is non-NIL, error-checking of initarg names is disabled. -slot-filling initarg-. An initarg associated with a slot. If the initarg has a value, the value is stored into the slot of the newly-created object, overriding any initform associated with the slot. -(What about shared slots?)- A single initarg can fill more than one slot. -method-implemented initarg-. An initarg associated with a method. When an object is created, the method is called with the initarg's value as an argument and the method uses the value in any way it likes. If the initarg has no value, the method's lambda-list supplies a default value. A single initarg can be implemented by more than one method. An initarg can be both slot-filling and method-implemented. CHANGES TO 87-002 FEATURES DEFCLASS gets a new :INITARG slot option, which is followed by a symbol. The symbol becomes the name of a slot-filling initarg for this class. DEFCLASS gets a new :DEFAULT-INITARGS option, which is followed by an initarg list. Each value in this list is a form that is evaluated by MAKE-INSTANCE if the initarg does not already have a value. The forms are evaluated in the lexical environment in which the DEFCLASS form was evaluated. Method-implemented initargs are defined simply by defining a method for INITIALIZE-INSTANCE or ALLOCATE-INSTANCE; each named-argument name in the method's lambda-list becomes a method-implemented initarg for all classes for which this method is applicable. Initarg inheritance: The effective set of slot-filling initargs for a class C is the union of the slot-filling initargs defined by C and its superclasses. The effective set of method-implemented initargs for a class C is determined by method inheritance. Default-initargs inheritance: [same as for the :INITFORM slot option] Changes to Lambda-list Congruence Rules (p.1-20): Rules 1, 2, and 6 remain the same, except for wording problems, while rules 3-5 need to be replaced to implement &METHOD-KEY and to fix the interaction among &KEY, &REST, and &ALLOW-OTHER-KEYS. The new rules for congruence are the following: These rules define the congruence of a set of lambda-lists, including the lambda-list of each method for a given generic function and the lambda-list specified with DEFGENERIC-OPTIONS, if present. For -SETF methods, these rules apply to the effective lambda-list produced by combining the two specified lambda-lists according to the rules on page nnn. 1. Each lambda-list must have the same number of required parameters. 2. Each lambda-list must have the same number of optional parameters. Each method can supply a different default for an optional parameter. 3. If any lambda-list uses &REST, &KEY, or &METHOD-KEY, each lambda-list must use one or more of these. Note that &METHOD-KEY is only valid in DEFGENERIC-OPTIONS. 4. If the DEFGENERIC-OPTIONS does not use &METHOD-KEY, or there is no DEFGENERIC-OPTIONS, each method that uses &KEY and does not use &ALLOW-OTHER-KEYS must specify the same named-argument names. 5. The use of &ALLOW-OTHER-KEYS need not be consistent across lambda-lists. 6. The use of &AUX need not be consistent across methods. Rules when initargs are duplicated: The :INITARG slot-option may be specified more than once for a given slot. A single initarg can initialize more than one slot if the same initarg name appears in more than one :INITARG slot-option. If two initargs that initialize the same slot, with the same or different names, are given in the arguments to MAKE-INSTANCE, the leftmost of these initargs in the initarg list prevails. If two different initargs that initialize the same slot have default values, the initarg that appears in a :INITARG slot-option in the most specific class prevails, or if they appeared in the same class, the one leftmost in the slot-options list prevails. It is valid for a given initarg name to be defined more than once as a slot-filling initarg, as a method-implemented initarg, or both. NEW FUNCTIONS TO BE ADDED In this section, I have only sketched each function, for the sake of brevity. Full writeups can be constructed once the overall framework has been agreed upon. Functions are in alphabetical order. By coincidence, all functions listed are generic and expected to specialize on their first argument. (ALLOCATE-INSTANCE class &method-key &allow-other-keys) => instance Metausers can replace the system-supplied, implementation-dependent method for this. (CHECK-INITARGS class initarg-list) Metausers could replace the system-supplied method that implements the normal rules for initarg validity. (CLASS-ALL-INITARGS class) => list of initarg names (includes inherited) (CLASS-DIRECT-INITARGS class) => list of initarg names (CLASS-ALL-INITARG-DEFAULTS class) => ((initarg-name default-value-function)...) (CLASS-DIRECT-INITARG-DEFAULTS class) => ((initarg-name default-value-function)...) (CLASS-ALL-SLOT-INITARGS class) => ((initarg-name slot-name...)...) (CLASS-DIRECT-SLOT-INITARGS class) => ((initarg-name slot-name...)...) (COMPUTE-APPLICABLE-METHODS generic argument-list) => list of methods (DEFAULT-INITARGS class initarg-list) => initarg-list The system-supplied method implements the :DEFAULT-INITARGS class option. [This could specialize on instance instead of class, but I don't see any point to that.] (ENCACHE-INITARG-INHERITANCE class) This is called by the system at least once before a class is instantiated, and is called again whenever anything relevant changes. System-supplied methods for this conspire with methods for CHECK-INITARGS, etc., to make MAKE-INSTANCE faster. Users with their own caching needs can add methods for this generic function. (ENCACHE-METHOD-INHERITANCE class) (ENCACHE-SLOT-INHERITANCE class) (INITIALIZE-INSTANCE instance &method-key &allow-other-keys) Users define :AFTER methods for this to create method-implemented initargs. The primary method for this is system-supplied and takes care of the slot-filling initargs. (MAKE-INSTANCE class &key -initargs-...) => instance (METHOD-NAMED-ARGUMENTS method) => list of symbols or &ALLOW-OTHER-KEYS (SLOT-BOUNDP instance slot-name) => boolean Allows writing INITIALIZE-INSTANCE methods that only initialize slots if they haven't been initialized already. (SLOT-MAKUNBOUND instance slot-name) => NIL PROCEDURAL DEFINITION OF MAKE-INSTANCE MAKE-INSTANCE behaves as if it was defined as follows, except that certain optimizations are permitted, as detailed below. (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (check-initargs class initargs) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance)) (defmethod make-instance ((class-name symbol) &rest initargs) (apply #'make-instance (symbol-class class-name) initargs)) Optimization is possible, including inlining and constant-folding of method lookup and method bodies, provided that the programming environment either prohibits redefining these methods or updates everything when they are redefined. A possible example implementation would be that MAKE-INSTANCE has a separate method for every class, which is automatically written and compiled by the system. This optimization relies on the ENCACHE-INITARG-INHERITANCE generic function and some unpublished slots of STANDARD-CLASS. Because of optimization, methods for the generic functions listed may not actually be called on every call to MAKE-INSTANCE, or may not receive exactly the arguments that would be expected. For example, CHECK-INITARGS may actually be called before DEFAULT-INITARGS rather than after, if it has already been determined that the default initargs will pass CHECK-INITARGS. Additional explicit details of permissible optimization will need to be set forth. MEETING OF STATED DESIGN GOALS Lexical proximity of concepts--the declaration of an initarg as valid, the specification of what it does, and the default if it is not supplied are all together, in a slot specifier or in a method lambda-list. Simple ways to do simple things--slot-filling initargs don't require the user to write any code. Method-implemented initargs work just like ordinary function arguments as far as the user is concerned. Minimal number of new languages--the only addition to Common Lisp is &METHOD-KEY. Ability to do everything at some level--the underlying procedural level is available. Functions to access all the direct and inherited information are documented. Underlying mechanism is exposed so user can use it for other things, rather than abusing instance creation as the only way to access the mechanism--the combination of &method-key, method-named-arguments, compute-applicable-methods, and encache-initarg-inheritance provides everything the user needs.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Aug 87 04:55:32 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Aug 87 01:50:47 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 217984; Fri 21-Aug-87 10:17:46 EDT Date: Fri, 21 Aug 87 10:17 EDT From: Sonya E. Keene Subject: Re: Agenda for September meeting To: kempf%hplabsz@hplabs.HP.COM cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8708202023.AA19448@hplabsz.hpl.hp.com> Message-ID: <870821101706.9.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: Thu, 20 Aug 87 14:23:16 MST From: kempf%hplabsz@hplabs.HP.COM With regard to the spec documentation, I'd like to put in a vote for an ASCII version to go on parcvax, along with the portable source, so people don't have to be working in the dark with it. The ASCII version doesn't necessarily have to be up to the current level of discussion and decision within the committee (indeed, it probably shouldn't) but should reflect approximately what is implemented. Please don't confuse the spec documentation with documentation for an implementation. These are two very different things!  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Aug 87 22:17:50 EDT Received: from [15.255.16.7] by SAIL.STANFORD.EDU with TCP; 27 Aug 87 19:06:56 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Wed, 26 Aug 87 10:31:57 pdt Received: from hplabsz.hpl.hp.com by hplms2; Wed, 26 Aug 87 10:30:39 pdt Return-Path: Received: from hplabsz by hplabsz; Wed, 26 Aug 87 11:28:25 pdt Message-Id: <8708261728.AA27357@hplabsz.hpl.hp.com> To: Patrick H Dussud Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Names to Objects and Compiler-environment In-Reply-To: Your message of Wed, 19 Aug 87 15:21:01 -0500. <2765391661-13139657@Jenner> Date: Wed, 26 Aug 87 11:28:22 MST From: kempf%hplabsz@hplabs.HP.COM THE PROBLEM The fundamental problem I think we are trying to address with this proposal is the transfer of information about class definitions and potentially method definitions from form to form during a file compilation. Such a transfer will necessary be implementation dependent, but we would like to design an interface to the metaclass protocol which is portable. The information on these definitions should either not be a "real" definition or it should be a seperate and shadowing definition from the definition in compiler's run time environment (if any). The alternatives are to either replace the definition in the compiler's run time environment, or to not propagate any information on class and method definitions being compiled between forms. If we chose the former solution (replacing the definition in the compiler's run time environment) we face a bootstrapping problem, since a method or class necessary for the compilation of a file may get redefined while the file is being compiled, breaking the compiler (admittedly, this may not occur very often, but, if it does, it could be very disabling). The latter solution (not propagating any information) would place an unreasonable burden on programmers using CLOS, since they would be required to place class definitions and definitions of methods working on those classes into seperate files. Usual practice in object-oriented programming is to group class definitions and method definitions into the same file, for easy reference. THE PROPOSED SOLUTION A solution has been proposed in which certain metaclass protocol functions (generic and otherwise) take parameters which are "environments". The exact nature of these environment parameters is unspecified, but in order for them to be accessable to the top level macros DEFCLASS and DEFMETHOD without adding alot of additional machinery to Common Lisp, the most logical choice, as Moon has pointed out, is the macro &ENVIRONMENT parameter. The metaclass functions which Patrick has identified as being involved in name to object mapping are: CLASS-NAMED (aka SYMBOL-CLASS) - maps a symbol to a class object having that name. SYMBOL-FUNCTION - maps a symbol naming a (potentially generic) function to the (potentially generic) function object. GET-METHOD - ? according to pg. 2-39 of 87-002, this takes a generic function object, list of method qualifiers, and a list of parameter specializers (which, presumably, are also objects) and produces the method. Sonya has added: GET-SETF-GENERIC-FUNCTION - maps a name for a generic function into the generic function for doing the SETF. I would argue that, of these, CLASS-NAMED and SYMBOL-FUNCTION are at the right primitive level to discuss. My reasoning is as follows. As the spec for GET-METHOD indicates, it is not doing a name to object mapping but rather an object to object mapping. Thus the more primitive operations CLASS-NAMED and SYMBOL-FUNCTION can be used to find the objects, CLASS-NAMED to find the specializer list, and SYMBOL-FUNCTION to find the generic function. As far as GET-SETF-GENERIC-FUNCTION goes, it is doing a name to object mapping, but the mapping is slightly bogus, since the name for a SETF generic function is created, and the operation could just as well be done by passing the generic function object for which the SETF generic function was desired. The generic function object might have to keep around information about it's SETF, however. Alternatively, the algorithm for generating the SETF name could be published (a user can find it simply enough anyway by macroexpanding a SETF form) and we are back in the case where SYMBOL-FUNCTION is the correct primitive for finding the generic function. Naturally, along with the functions for doing the name to object mapping, the functions for doing a SETF will require an environment argument as well. These would be the SETF functions for CLASS-NAMED and for SYMBOL-FUNCTION. Additional CLOS functions which Patrick has identified as possibly requiring an environment argument are: ADD-METHOD, REMOVE-METHOD, FIND-APPLICABLE-METHODS (presumably for use with CALL-NEXT-METHOD), and ENSURE-GENERIC-FUNCTION. While these do not explicitly do name to object mapping, I believe the logic here is the following: ADD-METHOD, REMOVE-METHOD - addition and removal of a method from a generic function is dependent on the environment, since a different method definition may be desired on a generic function in the compile time environment from what is available in the compiler's run time environment (the "outside" or "top" environment). FIND-APPLICABLE-METHODS - the compilation of a CALL-NEXT-METHOD form will require access to methods as they are "defined" or, at the very least, to the definitions compiled during a file compilation, so the "current" definition is used for arranging the method call, rather than the definition in the compiler's run time environment. ENSURE-GENERIC-FUNCTION-This does an implicit name to generic function mapping, setting up any existing function (generic also?) as a default method. Since it will probably use SYMBOL-FUNCTION to retreive the function object bound to the symbol's function cell, an environment parameter might be needed to indicate which particular generic function is required. Of these, only ENSURE-GENERIC-FUNCTION takes a function name as an an argument, the others all take generic function and other objects. Hence, sensitivity to the processing environment need only be included in ENSURE-GENERIC-FUNCTION, since only it will have to internally resolve a name to object mapping. One group of functions Patrick missed in his list is the metaclass functions on pg. 3-25 of the metaobjec protocol specification. They are all defined to take a name for the appropriate metaclass. With the exception of DEFINE-METACLASS (which can be a macro anyway, and thus use its &ENVIRONMENT parameter), the others could as well be defined to operate on a class object which was a metaclass, rather than directly on a metaclass name. WHY CLASS DEFINITIONS NEED TO BE ENVIRONMENT SENSITIVE I believe that an excellent case can be made for an environment argument to CLASS-NAMED, and, correspondingly, that class definitions need to be made both in the compile time environment (but *not* in the compiler's run time environment) and at load time, as usual. The arguments presented in the first section indicated why some way of maintaining information on classes being defined needs to be propagated between forms during a file compilation, independently of any definitions in the compiler's run time environment. An alternative for doing the definition "for real" is to maintain information about definitions being compiled, then have the relevent metaclass protocol functions distinguish whether the information about a particular definition comes from the "for real" definition or from the partial definition. I do not like this solution because it introduces an additional element of complexity into the metaclass protocol which somehow seems unnecessary, and sets up a more sharp distinction between compiling a definition and evaluating it than simply switching environments. CommonObjects did things this way, and it slowed down compilation and made for some nasty case analysis. For example, handling the distinction between the following two cases would be nontrivial (in each case, the class FOO is also defined in the compiler's run time environment): Case 1: (defclass foo () () ) (setf *global-var* (make-instance 'foo)) Case 2: (defclass foo () () ) (eval-when (compile) (setf *global-var* (make-instance 'foo))) Though it could be disputed, I think the intent of Case 1 is to have MAKE-INSTANCE use the FOO defined immediately above it, and that the compiler, running in *not-compile-time-mode* (CLtL 69), should defer instance creation and execution of the SETF until load time, while, in the second case, instance creation and SETF should get done at compile time using the definition in the compiler's run time environment (*compile-time-too* mode) rather than the immediately preceeding defintion, (except for KCL, which runs in *compile-time-too* mode at the top level, but it is definitely in the minority). If a compile time environment is used, then the EVAL-WHEN (COMPILE) can simply be viewed as "popping" back to the compiler's run time environment within the dynamic scope of the form, and returning to the compile-time environment when the form ends. The required behavior from DEFCLASS would be that the establishment of a name to class object mapping is made via the &ENVIRONMENT parameter, at compile time, and in the top level environment, at load time. This suggests some way of obtaining the top level environment for inserting the class name to object mapping. Following Patrick's suggestion, a function GET-CURRENT-ENVIRONMENT could be used. Another possibility is a special variable, *ENVIRONMENT*, which would be bound to the current environment, similarly to how *PACKAGE* is bound to the current package. I'd be interested in hearing if this would have problems, as Moon's comments about GET-CURRENT-ENVIRONMENT seem to indicate: >If GET-CURRENT-ENVIRONMENT takes no arguments, then what you have is >some form of dynamic scoping, rather than lexical scoping, and you can >get scoping problems. Symbolics' implementation, and I believe TI's as >well, currently works this way, using the special variable >SYS:UNDO-DECLARATIONS-FLAG to inform macro expanders on behalf of which >environment they are working. The genesis of this is historical and >predates lexical scoping. This causes a number of subtle problems. >CLOS should not make this mistake. though I'm not quite sure what sorts of arguments GET-CURRENT-ENVIRONMENT should have or how this relates to dynamic scoping. The idea with *ENVIRONMENT* is that it would be bound to the current macroexpansion environment, which may or may not be EQL to the &ENVIRONMENT parameter of a macro (*MACROEXPAND-HOOK* could be used to modify whether this is true or not) but they would, in any event, be the same "kind" of environment. Exactly how the name to object binding is inserted into the environment would, of course, be implementation dependent (but this could be hidden within CLASS-NAMED). In addition, DEFCLASS would naturally have to use definitions within the &ENVIRONMENT parameter for things like determining inheritance information necessary at compile time. What kinds of information would be necessary? For the moment, let's ignore optimization information, since things get a bit more complicated when it is taken into account. Given this, we can rule out slot layout and number information, since WITH-SLOTS :USE-ACCESSORS NIL (the only place it would potentially be needed) should go through SLOT-VALUE. Possibly the slot :INITFORM (and any additional initialization information) would need to be compiled, but they would not have to be accessed by anyone else. The only really important piece of information needed would be the SETF generic function names for inherited slots, since these would be required for expanding SETF forms at compile time. Most other aspects of inheritance (modulo optimizations) could be handled at load time or run time. In order to make things more convenient for the user, we may want to define an interface function called CLASS-NAMED, which takes the class out of the current environment, and a metaclass function, called SYMBOL-CLASS, which requires an environment argument. Corresponding SETFs would also be required. But this seems as if it should be the only modification needed for dealing with the name to class mapping. As a side note, I did an experimental implementation of something similar using the CommonObjects on CommonLoops implementation this spring. The part modifying CLASS-NAMED to be sensitive to the compilation environment worked very well, which leads me to believe that implementation should be possible. WHY SYMBOL-FUNCTION DOESN'T NEED AN ENVIRONMENT PARAMETER FOR THE DEFAULT CLOS LANGUAGE The other part of the initial proposal involved shadowing generic functions and methods in the compile time environment by making the name to function mapping dependent on the environment. The effect would be to require SYMBOL-FUNCTION to have an environment parameter, since SYMBOL-FUNCTION and its SETF are the means whereby a name to (possibly generic) function mapping is established. Note that any attempt to make the name to function mapping dependent on the environment will inevitably have some serious reprecussions for Common Lisp. In particular, the design of Common Lisp assumes functions are named by symbols in a global name space, partitioned through packages. These symbols have a globally accessable function cell, which SYMBOL-FUNCTION, FBOUNDP, MAKFUNBOUND, and other accessor function access. Thus function names are kind of like special variables except they can't be dynamically bound, or, more precisely, like global variables in other languages (Pascal, for example), where dynamic binding is not available. The name to function mappings established by FLET and LABELS are not available via. SYMBOL-FUNCTION. Referring back to the initial motivation for including environment sensitivity, namely information propagated from form to form, there is only one case where one method might need to know something about another 's definition during compilation: CALL-NEXT-METHOD. However, ignoring optimizations for the moment, the characterization of CALL-NEXT-METHOD as lexical in scope and dynamic in extend suggests lookup of the next method could be done, at the latest, at run time exactly as method dispatch is done. Knowledge about the classes of the caller's parameters at compile time could be used to limit the run time method search. Various further optimizations are possible, but the most obvious require only the ability to do method lookup and linking at load time. WHY SYMBOL-FUNCTION MAY REQUIRE ENVIRONMENT DEPENDENCY IN THE METACLASS PROTOCOL Unfortunately, some object oriented languages resolve method inheritance fully at compile time. CommonObjects is an example. CommonObjects has a form similar to CALL-NEXT-METHOD (called CALL-METHOD) which allows the programmer to specify a particular method on the direct super (or on itself), and a function call to the method (via. a special method symbol) is compiled in at compile time. Thus the CALL-METHOD macro must have access to the symbol at compile time, and the fasl loader must maintain a compile time to load time mapping of the symbol. This is all implementation dependent, of course, and this particular feature has given us much trouble in developing the Portable CommonObjects implementation. The point is, however, that compiling a file of CommonObjects methods requires information on the methods previously compiled to be propagated between forms. As mentioned in the previous section, addition of an environment parameter to SYMBOL-FUNCTION (and its SETF) would involve a major change to the semantics of function symbols in Common Lisp. Since the function cell is a globally accessable place, would redefining a function in a particular environment still cause the global definition to change? If so, then bootstrapping problems could easily occur, since a definition which has just been compiled should not be used in the compilation process. If not, then the nature of the function cell as a globally accessable place is compromised, since function invocations in the compiler's run time environment will get one definition, while another definition will be operative in the compilation environment.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Aug 87 20:02:18 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 27 Aug 87 16:55:33 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa09283; 27 Aug 87 19:42 EDT Received: from ti-csl by RELAY.CS.NET id aa05932; 27 Aug 87 19:31 EDT Received: from dsg by tilde id AA00730; Thu, 27 Aug 87 16:33:04 CDT Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Thu, 27 Aug 87 15:06:36 CDT Message-Id: <2766081947-606167@Jenner> Date: Thu, 27 Aug 87 15:05:47 CDT From: Patrick H Dussud To: kempf%hplabsz@hplabs.hp.com Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Solutions to Name/Object Mapping for Generic Functions In-Reply-To: Msg of Thu, 27 Aug 87 10:51:21 MST from kempf%hplabsz@hplabs.hp.com THE PROBLEM AND PROPERTIES OF A GOOD SOLUTION The following are some possible solutions: 1) The symbol function cell could be eliminated as a global object and the name to funcallable object mapping could be maintained within the environment, as is the case in Scheme. 2) The generic function slot accessor functions could take an environment argument and return information accordingly. This was the solution I believe Patrick proposed. 3) We could simply leave it up to implementors to supply these hooks, if they so choose. If you are talking about name-to-generic-function mapping, 2 is not what I have proposed. Name-to-generic-function mapping shouldn't depend on the metaclass protocol since it should behave the same as name-to-regular-function. Not being affected by the metaclass protocol, it can be left to the implementation. The hook should be specified though. If some implementations decide to ignore the environment, that's fine. Since the environment is going to be passed explicitly(see Moon's reponse to my proposal), we either need a new primitive for that, or change SYMBOL-FUNCTION to accept an environment argument. A new primitive for metaclass programmers is probably the best thing to do. However I object to 3 since it will make serious metaclass programming non portable. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Aug 87 12:57:49 EDT Received: from [15.255.16.7] by SAIL.STANFORD.EDU with TCP; 27 Aug 87 09:52:00 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 27 Aug 87 09:51:04 pdt Received: from hplabsz.hpl.hp.com by hplms2; Thu, 27 Aug 87 09:50:38 pdt Return-Path: Received: from hplabsz by hplabsz; Thu, 27 Aug 87 10:51:23 pdt Message-Id: <8708271651.AA07090@hplabsz.hpl.hp.com> To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Solutions to Name/Object Mapping for Generic Functions X-Mailer: mh6.5 Date: Thu, 27 Aug 87 10:51:21 MST From: kempf%hplabsz@hplabs.HP.COM Sorry this note has dragged on so long, but the name to object mapping is a difficult enough problem that I think it requires some thought. THE PROBLEM AND PROPERTIES OF A GOOD SOLUTION As my previous note outlined, the problem with making SYMBOL-FUNCTION sensitive to the environment is that it directly conflicts with the Common Lisp notion of the symbol's function cell as a global place. On the other hand, the consequences for CLOS of not somehow making the metaclass protocol for generic functions sensitive to the environment are that support for resolving method inheritance at compile time will not be available in a portable way (it may and probably will be available in an implementation dependent way, since optimizations will require it). A good solution should somehow avoid either of these extremes. In addition, the solution should not be such that compilation of a method causes redefinition of anything funcallable in the compiler's run time environment, since this could cause bootstrapping to fail. This particular property rules out, for example, allowing the symbol's function cell to become like a dynamically bound function variable. SOME POSSIBLE SOLUTIONS The following are some possible solutions: 1) The symbol function cell could be eliminated as a global object and the name to funcallable object mapping could be maintained within the environment, as is the case in Scheme. 2) The generic function slot accessor functions could take an environment argument and return information accordingly. This was the solution I believe Patrick proposed. 3) We could simply leave it up to implementors to supply these hooks, if they so choose. Nice properties of each solution are: 1) The existence proof of Scheme and T shows that this solution can be implemented. It also has a certain elegence. 2) No radical changes in existing Common Lisp implementations would be needed. 3) No radical changes in the current spec for CLOS would be needed. Nasty properties of each solution are: 1) Radical changes in existing Common Lisp compilers would be needed. The issue of a single function/value cell is controversial, this could be even more so. 2) This would complicate the metaclass protocol for generic functions considerably. In particular, generic function slot accessors would need to maintain data structures for mapping environments to methods, and the dispatch function would need to do the "right" parameter specializer to method function mapping, namely the one established when the method was interpreted or loaded. 3) Implementation of object-oriented languages on the metaclass kernel which resolve method inheritance at run time would have no support. Optimizations of method lookup would be largely implementation dependent. I don't like 2 is because it adds additional complexity to the generic function protocol which I would rather avoid. I actually like 1 best, but doubt we could ever get it implemented. In the interests of wrapping up the loose ends of CLOS as expediently as possible, I'd like to weigh in in favor of 3. While I think that the metaclass kernel is an important part of CLOS, most people who want to use it are more interested in the language for application implementation. As I hope my previous posting has shown, the CLOS language (or programmer interface) has no need for maintaining a seperate definition of generic functions and methods in the compile time environment, since there is no information about methods and generic functions previously compiled in a file which needs to be portably transferred from form to form. In addition, although the lack of this capability made implementation difficult, the implementation of CommonObjects on the PCL kernel has shown that a language which resolves most of method inheritance at compile time can be done.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Aug 87 23:38:34 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 Aug 87 20:33:36 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 221804; Wed 26-Aug-87 23:34:54 EDT Date: Wed, 26 Aug 87 23:34 EDT From: David A. Moon Subject: Re: proposed syntactic cleanups in defmethod To: Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870826-191544-1414@Xerox> Message-ID: <870826233424.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 26 Aug 87 19:15 PDT From: Gregor.pa@Xerox.COM I would like there to be a simple, clean story which can be used to correspondence between any given defmethod form, and a call to add-method, make-instance and ensure-generic-function. Thats what makes defmethod nice syntax for add-method the same way defun is nice syntax for setf of symbol-function. I agree that this is desirable. I don't think the changes I proposed make the story more or less complicated than it was before. For example, evaluating the specification of an individual rather than quoting it only shows up as evaluating or quoting a particular position in the form resulting from expansion of defmethod, I would expect. Since I'm not sure I understand how these meta-level functions are intended to be used, and since I have never seen the simple clean story written down, I don't think I am competent to write out the details of how the expansion of defmethod would be affected by my proposed changes. Gregor, perhaps you could take a crack at it?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Aug 87 22:20:59 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 26 Aug 87 19:16:01 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 26 AUG 87 19:15:44 PDT Date: 26 Aug 87 19:15 PDT From: Gregor.pa@Xerox.COM Subject: Re: proposed syntactic cleanups in defmethod In-reply-to: David A. Moon 's message of Thu, 20 Aug 87 12:29 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870826-191544-1414@Xerox> I have certainly been bothered by the same problems with defmethod syntax you address, but I am not sure about all of these solutions. What is bothering me is that while they all provide convenience, they make the defmethod form itself more complicated. I haven't yet made my mind up, but I thought I would send out a message to at least say something, since you said you hoped it could be resolved quickly. The proposal to make defmethod forms, which actually name specializers for arguments, refer to those arguments certainly would be convenient. There are a lot of cases in PCL code where I could remove declare ignores. But it makes the defmethod story more complicated. Particularly, if arguments which are not specialized are also refered to. I am not sure this is worth the tradeoff? But I am not sure it isn't either. The second proposal (to evaluate the argument to an EQL or ' specializer at load time) addresses a much more real problem. In paricular, without this, its not possible to use call-next-method inside of methods on individuals. That probably makes this worth doing, even it it makes the defmethod story more complex. I have no particular opinion on the third proposal. I would like there to be a simple, clean story which can be used to correspondence between any given defmethod form, and a call to add-method, make-instance and ensure-generic-function. Thats what makes defmethod nice syntax for add-method the same way defun is nice syntax for setf of symbol-function.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Aug 87 20:07:13 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Aug 87 17:01:33 PDT Received: from relay2.cs.net by RELAY.CS.NET id aj02900; 24 Aug 87 19:46 EDT Received: from ti-csl by RELAY.CS.NET id ao16441; 24 Aug 87 19:36 EDT Received: from Jenner by tilde id AA28861; Mon, 24 Aug 87 16:18:11 CDT Message-Id: <2765827013-1804390@Jenner> Date: Mon, 24 Aug 87 16:16:53 CDT From: Patrick H Dussud To: "David A. Moon" Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: short form of define-method-combination In-Reply-To: Msg of Wed, 19 Aug 87 13:20 EDT from "David A. Moon" Date: Wed, 19 Aug 87 13:20 EDT From: "David A. Moon" Subject: short form of define-method-combination Date: Tue, 18 Aug 87 19:06 EDT From: Daniel L. Weinreb I am not enthusiastic about this proposal. I have always liked having the qualifier in the defmethod form explicitly, because it enhances readability. Requiring the qualifier would satisfy my stated wants, provided that the qualifier wasn't optional (so there was only one way to write a primary method) and wasn't re-interned in the keyword package (so we aren't inventing symbols). However, I don't understand why you think the method-combination type of a generic function needs to be repeated in the defmethod, while the rest of the contract of the generic function does not need to be repeated. It seems to me that the command provided by the programming environment to remind one of the arguments expected, values returned, and documentation of the generic function can also remind one of the method-combination type. If you convince me that the method-combination type deserves special treatment, then I'll change my proposal to make the qualifier mandatory instead of prohibited. The fact that we have two ways of defining primary methods for flavors is a major source of confusion. I got lots of questions about it. I am glad that David Proposes to rectify things. I would be in favor of omitting the qualifier, but if Dan objects to it, then requiring the qualifier is OK too. To me, the important thing is that the primary methods have all the same syntax and that we don't end up with two primary methods for one set of specializers. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Aug 87 19:49:56 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Aug 87 16:44:29 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa02900; 24 Aug 87 19:45 EDT Received: from ti-csl by RELAY.CS.NET id ag16441; 24 Aug 87 19:34 EDT Received: from Jenner by tilde id AA27526; Mon, 24 Aug 87 15:17:23 CDT Message-Id: <2765823344-1583937@Jenner> Date: Mon, 24 Aug 87 15:15:44 CDT From: Patrick H Dussud To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: proposed syntactic cleanups in defmethod In-Reply-To: Msg of Thu, 20 Aug 87 12:29 EDT from "David A. Moon" I propose that the DEFMETHOD macro be specified to "refer to" (in the sense of CLtL p.160) each specialized parameter. This means that a compiler warning will not occur regardless of whether the body of the method does or does not refer to the parameter, and the declare ignore in the above examples must be removed. This makes sense intuitively if one regards the type check of the argument against the parameter specializer as being part of the method; thus any specialized parameter is referred to by the type check. Sounds good. So I'd like to see the syntax of an individual parameter-specializer-name changed to use a different word instead of QUOTE, and to use a form that evaluates to the object, instead of the object itself. The form is evaluated at the time the method is defined; it is not evaluated each time the generic function is called. I think it is a very good idea. I mildly prefer EQL over MEMBER, but I thought I'd open up both suggestions for discussion. Each of these suggests an obvious generalization, EQL to other predicates and MEMBER to multiple individuals, and the choice might be based on which generalization we want people to think about, even if we don't propose to implement the generalization. I don't like MEMBER because it looks too much like the CLtL type specifier and lots of people will think that they can discriminate on multiple individuals. I am neutral on EQL versus another name as Kempf suggested. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Aug 87 16:11:05 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 24 Aug 87 13:04:27 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 24 Aug 87 13:04:04 pdt Received: from hplabsz.hpl.hp.com by hplms2; Mon, 24 Aug 87 13:03:41 pdt Return-Path: Received: from hplabsz by hplabsz; Mon, 24 Aug 87 14:04:22 pdt Message-Id: <8708242004.AA12343@hplabsz.hpl.hp.com> To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: ECOOP Reaction to CLOS In-Reply-To: Your message of Mon, 24 Aug 87 12:42:03 -0700. <8708241842.AA11723@hplabsz.hpl.hp.com> Date: Mon, 24 Aug 87 14:04:19 MST From: kempf%hplabsz@hplabs.HP.COM > Define a join class as a superclass which contributes > two or more subclasses to a CPL calculation. Define > the base class as the class for which the CPL calculation > is being made. To calculate the CPL, the inheritance graph > is searched depth first, left to right, up to joins, starting > with the base class. Join superclasses are placed in the class > precedence list at the last occurance, rather than the first, > since such superclasses are usually more general than their > subclasses (from the base class's point of view), > and classes at the end of the class precedence list should be more > general than those at the beginning. After a join class has > been inserted, the local precedence ordering for the join ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > class is used to start the left to right search again above ^^^^^ > the join. The qualitative effect is to achieve a linearization > of the inheritance graph, with more specialized classes at the head of > the class precedence list and more general classes at > the tail, keeping together groups of classes which occur > together in the inheritance graph (i.e. maintaining local > precedence). After I mailed this I realized that the ^ underscored section should read: the local precedence ordering for the join class's leftmost occuring subclass So integrating, and making a couple of other minor changes, gives: Define a join class as a superclass which contributes two or more subclasses to a CPL calculation. Define the base class as the class for which the CPL calculation is being made. To calculate the CPL, the inheritance graph is searched depth first, left to right, up to joins, starting with the base class. Join superclasses are placed in the class precedence list at the last (rightmost) occurance, rather than the first (leftmost), since such superclasses are usually more general than their subclasses (from the base class's point of view), and classes at the end of the class precedence list should be more general than those at the beginning. After a join class has been inserted, the local precedence ordering from the first (leftmost) subclass of the join class is used to start the left to right search again above the join. The qualitative effect is to achieve a linearization of the inheritance graph, with more specialized classes at the head of the class precedence list and more general classes at the tail, keeping together groups of classes which occur together in the inheritance graph (i.e. maintaining local precedence).  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Aug 87 15:59:20 EDT Date: 24 Aug 87 1254 PDT From: Linda DeMichiel Subject: updated spec on SAIL To: common-lisp-object-system@SAIL.STANFORD.EDU I have made a few minor edits to the drafts of the concepts and functions chapters that Sonya put out on SAIL last month. The only changes of note here are some corrections to the new standard-type-class/superclasses table in the section "Integrating Types and Classes." I also tweaked the macros file so that it now prints "Draft" and the date, so that we can keep our hardcopy drafts straight while we work. There are also new .dvi files available. --lgd  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Aug 87 14:53:19 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 24 Aug 87 11:46:12 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 24 Aug 87 11:41:54 pdt Received: from hplabsz.hpl.hp.com by hplms2; Mon, 24 Aug 87 11:41:21 pdt Return-Path: Received: from hplabsz by hplabsz; Mon, 24 Aug 87 12:42:06 pdt Message-Id: <8708241842.AA11723@hplabsz.hpl.hp.com> To: "David A. Moon" Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: ECOOP Reaction to CLOS In-Reply-To: Your message of Tue, 18 Aug 87 20:06:00 -0400. <870818200622.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 24 Aug 87 12:42:03 MST From: kempf%hplabsz@hplabs.HP.COM In <870818-153317-1383@Xerox> kirk writes: >At any rate, presenting the effects of the proposed inheritance >algorithm for CLOS would be more understandable if in conjunction with >presenting the class ordering algorithm, violations of the "implicit >inheritance - explicit override" rule are clearly marked as such. Yes, the description in Part 1 of the spec should contain proper documentation of how slot and class options are default inherited. In <870818200622.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Moon writes: > Some comments on characterizing the class precedence list algorithm. > In my comments I will refer to this set of classes (slots omitted): > (defclass a (b c w)) w x w y w x > (defclass aa (b c d w)) \ / \ / \/ > (defclass b (w x)) b c d w > (defclass c (w y)) \ | / / > (defclass d (w x)) \ | / / > (defclass w ()) \ |/ / > (defclass x ()) aa > (defclass y ()) The class a seems to be missing from the diagram, but I'll refrain from trying to include it, since the result is more confusing that enlightening. > We've seen these classes before. By the rules in 87-002, > the CPL of a is (a b c w y x) and of aa is (aa b c d w x y). > Date: Thu, 9 Jul 87 13:24:38 pdt > From: Jim Kempf > The inheritance graph is searched depth first, left to > right, up to joins. Superclasses at joins are placed > in the class precedence list at the last occurance, > rather than the first, since such superclasses are > usually more general than their subclasses, and classes > at the end of the class precedence list should be more > general than those at the beginning. The qualitative > effect is to achieve a linearization of the inheritance > graph, with more specialized classes at the head of > the class precedence list and more general classes at > the tail, keeping together groups of classes which occur > together in the inheritance graph. > I like this informal way of explaining it, except that I never figured > out precisely what "up to joins" means, and depending on the > interpretation of that phrase, this explanation could be incorrect. > When the depth first walk of the graph for aa above encounters w above > c, that's a join. If it goes on to y, I don't think y is a join, > nevertheless y is not next in the CPL, x is. w is, indeed, a join class, since there is more than one line of inheritance coming out of it. The definition of a join I had in mind is a class which contributes two or more subclasses to the CPL calculation. y is not a join, because there is only one line of inheritance coming from it (namely y->c->aa). x is also a join, because there are two lines of inheritance coming from it (namely x->b->aa and x->d->aa). If we follow the explanation, then, after including w, we use the local precedence ordering to select x as the next class to include. In this case, the local precedence ordering takes priority over other rules and x is included. y is then included after x. So a more accurate statement would be: Define a join class as a superclass which contributes two or more subclasses to a CPL calculation. Define the base class as the class for which the CPL calculation is being made. To calculate the CPL, the inheritance graph is searched depth first, left to right, up to joins, starting with the base class. Join superclasses are placed in the class precedence list at the last occurance, rather than the first, since such superclasses are usually more general than their subclasses (from the base class's point of view), and classes at the end of the class precedence list should be more general than those at the beginning. After a join class has been inserted, the local precedence ordering for the join class is used to start the left to right search again above the join. The qualitative effect is to achieve a linearization of the inheritance graph, with more specialized classes at the head of the class precedence list and more general classes at the tail, keeping together groups of classes which occur together in the inheritance graph (i.e. maintaining local precedence). This a a bit more complicated than the original, but more accurate, I think. Some words about failures to linearize and an example would also be helpful.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Aug 87 21:41:32 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Aug 87 18:37:38 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 218771; Sat 22-Aug-87 21:38:25 EDT Date: Sat, 22 Aug 87 21:37 EDT From: David A. Moon Subject: Re: proposed syntactic cleanups in defmethod To: Masinter.pa@Xerox.COM cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870822-000447-6288@Xerox> Message-ID: <870822213731.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: 22 Aug 87 00:04 PDT From: Masinter.pa@Xerox.COM To clarify, are you proposing that: (dolist (x *broken-mail-hosts*) (defmethod additional-mail-headers ((host (singleton (parse-host x)))) '(:line-fold "No"))) be a reasonable way to assign individual methods to, say, a large number of individuals? Yes. Implementations will have to be careful to allow objects which have individual methods to be GCd, won't they? Not my department. Any form of individual methods has this problem.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Aug 87 03:37:31 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Aug 87 00:33:20 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 22 AUG 87 00:32:02 PDT Date: 22 Aug 87 00:31 PDT From: Masinter.pa@Xerox.COM Subject: Re: TRACE Proposal (Version 1) In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Mon, 10 Aug 87 11:45:31 MST To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870822-003202-6311@Xerox> I've managed to convince myself that definition types (which are primarily for the use of DOCUMENTATION, and a general, programmatic way of "undoing" a DEFmumble), are pretty much independent of "function specs", which are handles on ways of getting at things which might have breakpoints or tracepoints associated with them. What I'm saying is that you should go ahead with your proposal for function-specs in trace/break without worrying about any conflict from the definition-type proposal which I have not finished writing.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Aug 87 03:08:41 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Aug 87 00:04:41 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 22 AUG 87 00:04:47 PDT Date: 22 Aug 87 00:04 PDT From: Masinter.pa@Xerox.COM Subject: Re: proposed syntactic cleanups in defmethod In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Fri, 21 Aug 87 09:21:19 MST To: kempf%hplabsz@hplabs.HP.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870822-000447-6288@Xerox> To clarify, are you proposing that: (dolist (x *broken-mail-hosts*) (defmethod additional-mail-headers ((host (singleton (parse-host x))) '(:line-fold "No"))) be a reasonable way to assign individual methods to, say, a large number of individuals? Implementations will have to be careful to allow objects which have individual methods to be GCd, won't they?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 Aug 87 11:35:06 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 21 Aug 87 08:25:55 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Fri, 21 Aug 87 08:21:12 pdt Received: from hplabsz.hpl.hp.com by hplms2; Fri, 21 Aug 87 08:20:38 pdt Return-Path: Received: from hplabsz by hplabsz; Fri, 21 Aug 87 09:21:22 pdt Message-Id: <8708211521.AA25991@hplabsz.hpl.hp.com> To: "David A. Moon" Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: proposed syntactic cleanups in defmethod In-Reply-To: Your message of Thu, 20 Aug 87 12:29:00 -0400. <870820122915.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 21 Aug 87 09:21:19 MST From: kempf%hplabsz@hplabs.HP.COM Proposal 1: > I propose that the DEFMETHOD macro be specified to "refer to" (in the > sense of CLtL p.160) each specialized parameter. This means that a > compiler warning will not occur regardless of whether the body of the > method does or does not refer to the parameter, I support this proposal. I think a good case was made for it. Proposal 2: > So I'd like to see the syntax of an individual > parameter-specializer-name changed to use a different word instead of > QUOTE, and to use a form that evaluates to the object, instead of the > object itself. The form is evaluated at the time the method is defined; > it is not evaluated each time the generic function is called. I have > two suggestions for what word to use, one based on what test is being > performed and the second based on the Common Lisp type system: I feel vaguely uneasy about this proposal. Part of the reason is because, as rpg more forcefully stated somewhat earlier, I do not much like the idea of having quoted objects as specializers in the first place. The reason for this is as follows. One could view quoted objects as being a kind of restricted subrange type. Allowing quoted objects means that users can define methods which discriminate on individual FIXNUMs or arrays, but disallowing subranges means they can't define methods which discriminate on all FIXNUMs or arrays of a particular size. One could argue that this is rather an argument for allowing subranges than for disallowing quoted objects, but I believe that subranges are a distinctly different kind of thing. In fact, subranges are a kind of type parameterization, since certain parameters must be supplied at the time the type is instantiated (as opposed to when an instance is created) and these parameters are usually of a nature which constrain instances in some manner. Following through on the FIXNUM example, FIXNUMs can be viewed as an instance of a more general type, RESTRICTED-INTEGER, which requires a parameter indicating upper and lower bounds on the size of instances. Similarly, an individual FIXNUM can be viewed as a member of the type (EQL x). That said, I think Moon's ADDITIONAL-MAIL-HEADER example: > (defmethod additional-mail-headers ((host 'xerox.com)) > '(:line-fold "No")) indicates how quoted objects as specifiers might be useful. But one could just as well write: (defmethod additional-mail-headers ((host symbol)) (case host .... ;;various other possibilites ( 'xerox.com '(:line-fold "No") ))) Embedded CASE statements suffer the disadvantage that, when changes are made (for example, adding a new host), then an additional branch must be added or deleted everywhere. But, with quoted objects as parameter specifiers, adding an additional case requires adding new method definitions anyway, so I have trouble seeing any gain as opposed to the loss of consistency cited above. Classes could be used to generalize the mail example: (defclass host-name () ( (name :type symbol :accessor NIL :initform NIL ) ) (:reader-prefix NIL)) (defmethod print-object ((object host-name) stream) (print (name object) stream)) ;;;Various other methods for dealing with host names (defmethod additional-mail-headers ((host host-name)) (case (name host) .... ;;various other possibilites ( 'xerox.com '(:line-fold "No") ))) Modifications to the host tables would still require adding another branch to all CASEs, but methods operating on instances of HOST-NAME are likely to be grouped together, and thus the difference between modifying a CASE and adding an additional method is not large. After all, I don't think the point of CLOS was to completely eliminate the need for CASE statements, but rather to provide users a way of constructing code with generalizes behaviors and structures. So I'd actually prefer to eliminate quoted objects entirely. > I mildly prefer EQL over MEMBER, but I thought I'd open up both > suggestions for discussion. Each of these suggests an obvious > generalization, EQL to other predicates and MEMBER to multiple > individuals, and the choice might be based on which generalization we > want people to think about, even if we don't propose to implement the > generalization. If the above arguments don't sound convincing, or people just don't have the energy and want to stick with what we already have, then I'd prefer introducing some kind of new symbol, rather than using either of these. The reason is because I'd rather avoid having people generalize, since either of the generalizations lead in directions which I don't think we're prepared to address. Something like SINGELTON would be a possibility: (defmethod additional-mail-headers ((host (singleton (parse-host "xerox.com")))) '(:line-fold "No")) Proposal 3: > The final issue has to do with parameter-specializers rather than > parameter-specializer-names, using the terminology of 87-002 page 1-18. > I think that adding QUOTE as a type-specifier to Common Lisp is both > unnecessary and confusing. (Yes, I know I suggested it. I was wrong.) I agree with this (modulo my misgivings about quoted objects as specializers in the first place); however, again I think that some specific other symbol (like SINGLETON) would be more appropriate.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Aug 87 18:30:06 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 20 Aug 87 15:18:52 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 20 Aug 87 13:23:58 pdt Received: from hplabsz.hpl.hp.com by hplms2; Thu, 20 Aug 87 13:22:33 pdt Return-Path: Received: from hplabsz by hplabsz; Thu, 20 Aug 87 14:23:19 pdt Message-Id: <8708202023.AA19448@hplabsz.hpl.hp.com> To: "David A. Moon" Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Agenda for September meeting In-Reply-To: Your message of Tue, 18 Aug 87 14:46:00 -0400. <870818144639.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 20 Aug 87 14:23:16 MST From: kempf%hplabsz@hplabs.HP.COM > Earlier I said that I wanted to leave by Friday noon, but in putting > together the agenda it became clear that 1 1/2 days wasn't enough time. > Hence we've written the agenda for two full days. Is that okay with > everyone? Yes, this is fine. > Discuss written proposals on major areas, circulated over the network > before the meeting and brought to the meeting in hardcopy. Spend no > more than 45 minutes on each proposal, determining yes, no, or needs > further discussion. Expected areas for proposals: object creation, new > draft of metaclass chapter, change-class, 1 or 2 others. I'd like to put in debugging support under the "1 or 2 others" if nobody has any strong objections. I'll rewrite the proposal based on the comments Dave sent and resubmit to the network within the next week. The reason is, our developers seem to need it. > Mail out hardcopies of the latest version of the 87-002 document > immediately (no further editing is planned, right?). Yes, this is very definitely needed, as soon as possible. ------------------------------------------------------------------------------- The rest of the agenda looks good to me. I have no particular preference about where the meeting is held, just as long as the location is mailed out ahead of time, so I can get there on time. With regard to the spec documentation, I'd like to put in a vote for an ASCII version to go on parcvax, along with the portable source, so people don't have to be working in the dark with it. The ASCII version doesn't necessarily have to be up to the current level of discussion and decision within the committee (indeed, it probably shouldn't) but should reflect approximately what is implemented. If there is some problem with deTeXing it, we have some OCR software here which I'd be willing to give a try at scanning it in with. Alternatively, Linda and Dick's paper from ECOOP would be a possible source, although it's more of an overview (and looks like it would probably be easier to scan in). jak  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Aug 87 13:18:55 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 20 Aug 87 10:09:44 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 217266; Thu 20-Aug-87 13:10:51 EDT Date: Thu, 20 Aug 87 13:10 EDT From: David A. Moon Subject: Miscellaneous decisions taken or to be taken To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870820131023.5.MOON@EUPHRATES.SCRC.Symbolics.COM> I have updated my file of miscellaneous decisions taken or to be taken, based on mail received in response to the last time I mailed this out (two weeks ago). If anyone doesn't see their response included, or thinks their favorite issue is missing, please let me know and I will apologize for my error and add it. I hope that we can use this file as part of the agenda for the September meeting. Let's try to resolve any of these issues that can be resolved through the mail before that meeting. Also, if I've marked an issue as agreed but you disagree, please speak up now. The rest of this message is the file. Page separator characters don't seem to go through, so I have replaced each with 16 equal signs. This file reflects Moon's understanding of the status of various CLOS issues, concentrating on the more minor issues. The goal is to make sure that nothing is overlooked, and especially to make sure that issues that have been brought up and resolved are not forgotten before they get into the document. I've removed most comments that were purely editorial comments on the document. I also haven't tried to keep track of all the purely meta-object issues. I've edited things to be as brief as possible. All page references are to the 87-002 version of the CLOS document. The file is divided into pages as follows: 0. This page of general outline 1. Documented holes in chapters 1 and 2 of 87-002 2. Things that have been already decided (but may not be in the document yet) 3. Issues with no apparent remaining disagreement 4. Small issues needing discussion 5. Issues whose status is unclear, maybe to be tabled 6. Big issues needing discussion, each on its own page ================ DOCUMENTED HOLES IN CHAPTERS 1 AND 2 OF 87-002 We publicly promised X3J13 that we would finish these holes and also have a new draft of 87-003 by the next meeting (October). 1-5, 2-44 The initialization protocol for make-instance is not yet specified. 1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes is still under discussion. Document has been updated in draft. Need Cleanup Committee proposals for fixes to the type system. 2-7, 2-46 [The proposed extension to call-next-method has been accepted.] This may not have been put into the document yet. 2-41, 2-48 [Perhaps we can adopt the condition signalling system now.] ================ THINGS THAT HAVE BEEN ALREADY DECIDED (BUT MAY NOT BE IN THE DOCUMENT YET) 27 May 87 call-next-method is allowed to take arguments, however it is an error to give it arguments that would change the set of applicable methods. I think we're saying this signals an error, and mentioning that in some simple cases the lack of need for an error check can be proved at compile time, but in general a run-time check is required. Specify precisely the type of error signalling. 10 June 87 The document has been updated with a discussion of how the standard type classes are organized. 8/9/87 Gregor promised to draw a picture. 2-16 (slot-name form) is not allowed as an abbreviation for (slot-name :initform form). People have been assuming this, we have to document explicitly that it is not allowed. The decision to reject (slot-name form) was made at the July meeting. 2-19 uninitialized slots should be an error to reference, not be defined to return an unstandardized value with no error. I'm willing not to require that it signals an error if people feel that would be an undue burden, otherwise I prefer that reading an uninitialized slot signals an error. In July we decided that signalling an error here should depend on the declared safety level. Dick has proposed terminology for this. p2-19 Values: I thought we agreed that all top level forms should return the object. It says here defclass "returns the name of the class" p2-22 Same comment as 2-19, for defgeneric-options 2-24 ditto for defgeneric-options-setf In July we decided to return the object for all CLOS defxxx functions (being inconsistent with Common Lisp, but consistent within CLOS). The document file has been updated. p2-39 Arguments: "list of t's" should be replaced by "list whose elements are the class named t" since get-method only takes specializers, not names of specializers. Agreed. 2-42 make-generic-function should be deleted, redocumented as a class that can be given to make-instance July: Agreed 2-45 make-method should be deleted, redocumented as a class that can be given to make-instance July: Agreed 2-54 in the Amendments: Clarify that because class names and classes are type-specifiers, they can be validly be used in THE special forms and in TYPE declarations. We forgot this when we clarified that class objects can be used with TYPEP and SUBTYPEP. July: agreed ================ ISSUES WITH NO APPARENT REMAINING DISAGREEMENT 1-12 Should defclass be allowed to change the metaclass of an existing class? Under what conditions should a subclass of standard-class have the same properties wrt instance updating as standard class? Gregor says the metaclass protocol includes a predicate function that controls whether the metaclass can be changed, which depends on whether the representations differ and existing instances might not be transformable. Some cross-reference to this should be added to the documentation of DEFCLASS. 1-15 to 1-22 Several errors in the formal description of class precedence and method combination, pointed out by Jim Kempf on 4 August and 27 July, need to be corrected. These are editorial changes only, that is, they make what the document says conform to what I believe our intent to have been. 2-35 The argument order of the setf method ought to be documented here. In July we suggested making the new-value argument a required argument that comes after all the other required arguments, and before the optional, rest, and keyword arguments. It's important that this depends only on the two lambda-lists, and not on any context such as the generic function object. We still have defmethod-setf so that most users don't have to think about it (only users making setf methods "directly"). The rule, carefully worded so as to work in the face of implementations with non-standard lambda-list-keywords, is that the setf-lambda-list is inserted into the normal lambda-list immediately after the last parameter-specifier that precedes &optional, &rest, &key, or &aux. This is implemented by the following function (should it be standardized as part of CLOS?): (defun combine-setf-lambda-lists (lambda-list setf-lambda-list) (do ((ll lambda-list (cdr ll)) (tail lambda-list)) ((or (null ll) (member (car ll) '(&optional &rest &key &aux))) (when (null ll) (setq tail nil)) (append (ldiff lambda-list tail) setf-lambda-list tail)) (unless (member (car ll) lambda-list-keywords) (setq tail (cdr ll))))) What about the setf of values extension that Common Lisp provides syntactic space for but does not currently prescribe? We're not going to allow that for setf of generic functions. 2-50 Should we flush multiple-value-prog2, as leading to more discussion than is warranted by its simplification of the presentation of define-method-combination? Kempf: Yes. 2-51 It has been suggested that print-object should take a depth argument. Moon strongly disagrees and points to the fourth bullet. I believe this issue was discussed to death on the Common Lisp mailing list a few months or a year ago. The point is that every single method for print-object should not have to deal with *print-level*; that's unmodular. Kempf raised a consistency argument (with defstruct?) but we decided not to change print-object. 2-54 slot-missing should be documented in chapter 2 Gregor: slot-missing is a generic function which takes three required arguments and an optional fourth argument. The three required arguments are the class of the object, the object and the name of the slot. The fourth argument is the new value for the slot if slot-missing is being called by setf of slot-value. This set of arguments allows people to define methods on the metaclass for handling slot-missing. For example, a low performance implementation of dynamic slots could work this way. (defmethod slot-missing ((class dynamic-class) obj slot &optional (nv nvp)) (if nvp (set-dynamic-slot obj slot nv) (get-dynamic-slot obj slot))) The default method on slot-missing signals an error of the same name. Symbol-function (the user callable primitive) needs to be split from the subprimitive for implementors that gets and sets the "real" function definition of a symbol. This is so when a symbol's function definition is a generic function object, the "real" definition can be something that is easier for the implementation to call. July: We need to say explicitly somewhere that calling symbol-function of the name of a generic function is required to return the generic function object, not the "real" definition. Kempf: I don't see splitting SYMBOL-FUNCTION as an issue for the standard, though it may be for certain implementations. Moon: Right, the only standardization issue is making sure SYMBOL-FUNCTION returns the generic function object, not something internal. See earlier discussion of class-names (2-13), which affects symbol-function. Not all of the "corrections and amendments" handed out at the March 1987 X3J13 meeting in Palo Alto have been put into the document yet. The corrections are in but the amendments and the revised explanation of slot inheritance are awaiting review by the group. ================ SMALL ISSUES NEEDING DISCUSSION 1-19 "... Common Lisp be modified to include the following semantics for quote in a type specifier: (deftype quote (object) '(member ,object)))" Has any proposal for this been given to the cleanup committee? Yes: ISSUE: TYPE-MEMBER-SINGLETON, Proposal TYPE-MEMBER-SINGLETON:QUOTE It hasn't really gone through the mill yet, though. In July Moon volunteered to make sure this happens, but in August Moon said he didn't like it and we should use MEMBER in parameter specializers instead. 1-24 Should we have a call-next-method? which calls such a next method if it exists, else returns nil (rather than signalling an error?). This seems useful rather than having to define many base methods on object. Common Lisp reserves question mark for the user; this could be named CALL-NEXT-METHOD-OR-NIL, or something like that. Kempf: signalling an error is sufficient, this probably isn't needed. In July we wondered whether there should be a way to get a list of the remaining methods. What operations on that list should be permitted? - checking whether it's nil gives the desired feature - checking its length - doing something with list elements (presumably method objects) - modifying the list is clearly out - does the list have dynamic or indefinite extent? This may be expensive enough that it can't substitute for CALL-NEXT-METHOD-OR-NIL. I think we're awaiting proposals on these two issues, as well as a concensus on whether we need these features. 2-30: Note the third paragraph on p.2-30 of 87-002, speaking of signalling an error when the arbitrary order of two methods affects the result. I suggest that this error be mandatory instead of optional. 2-38 need a way to recover documentation of a method-combination type July: do this by adding a new value for the second argument to DOCUMENTATION. But the whole writeup on DOCUMENTATION is screwy, and we need a new proposal. When the CL-Cleanup subcommittee finishes cleaning up the concept of "definition" (I think it's waiting for Masinter to propose something) then DOCUMENTATION should follow. 2-57 What does with-slots do for slots that exist in the class but don't have accessors, when :use-accessors t is specified (or defaulted)? July: it shadows any outer bindings of the slot name, and if you actually access that pseudo-variable, it signals an error. Gregor: What if by the time you actually run the body of the method, the slot has an accessor? It all hinges on exactly when macro-expansion time is and that is not specified. There are two issues here: (1) Exactly when is the set of names scoped with with-slots determined? (2) Exactly when is the presence or absence of an accessor for a name determined? What can be done with method objects, e.g. can one method be added to more than one generic function? Kempf: There may be a problem if the method invokes CALL-NEXT-METHOD. [I wasn't able to understand his description of the problem -- Moon] Gregor: I believe it should signal an error to attempt to put a method on more than one generic function. My model of this is that if you want to do something like that, you can take one function, use it as the method function of multiple methods, each of which would be on a different generic function. I'm not sure if we said anywhere what happens when you call a generic function and there is no applicable method; I think it ought to signal an error. Gregor: This is a generic function like slot-missing. There is a generic function NO-MATCHING-METHOD which is called with the generic function as the first argument and the arguments to the generic function as the remaining arguments. This allows people to define a method to handle the no matching method case either on the class of the generic function or on the individual generic function. The default method for no-matching-method signals an error of the same type. The error message should give some information about the classes of the parameters, to help debugging. CALL-NEXT-METHOD with no more methods should do something similar, but not identical. funcallable-standard-class should be documented. It is a metaclass. This is what makes generic function objects funcallable. There is a slot that is the actual function that gets called. I think Gregor volunteered to propose details. We need to decide whether class-name of an anonymous class is nil or signals an error. The concensus seems to be to return nil. What does type-of return when applied to an instance of an anonymous class? Returning NIL is not valid by CLtL's definition of TYPE-OF. The choices are either to return the class object itself or the name of some superclass that has a name, T if necessary. ================ ISSUES WHOSE STATUS IS UNCLEAR, MAYBE TO BE TABLED 1-17 "It is currently under discussion whether to provide constructs for giving generic functions local names." Do we want to have this discussion, or to punt on this syntax. I recall we did come up with some reasonable semantics for a GFLET and GFLABELS. In July we decided to defer this. 2 Aug 87 RPG offered to write a proposal. 2-26 I believe that short form method combination ought to be a macro in the standard library, and documented there, not in the basic principles. I think the standard combinations :append, :and, :or, ... should also be put in the standard library too. Kempf agrees. Moon can't have an opinion until he knows what this library is and whether it's going to be as much of a joke as the Common Lisp Yellow Pages. 2-46 Last line: If call-next method is extended ..." I see no reason for additional keyword arguments. Moon doesn't remember the issue. It may have been consistency; if call-next-method can specify the arguments, then so can make-method-call. You need one keyword argument to specify the methods and another to specify funcall versus apply. It could also have been that call-next-method would be implemented in terms of make-method-call, and therefore would need to be able to specify the arguments. 2-6 call-next-method dynamic versus indefinite extent The document says it has dynamic extent; we need to be sure that we really mean that. In July we said "implementation flexibility, not really a language thing", but I'm damned if I can figure out what that means (optimizing calculation of the effective method?). Gregor: I am pretty sure what we meant was we didn't want to have to worry about the case where someone returns a closure that includes a call to call-next-method, and then redefines the class or method structure so that the closure would have to call different 'next methods'. Moon: Oh, so this is different from extent, because they could do that redefinition before the method returns. So either we should say it captures the set of next methods at a particular instant, or it's undefined what happens if you redefine. 2-9 semantic difficulties discussion was shortened for the document so much that much of the point was lost. At some point we need to decide how much we want to standardize about this and where we want to say it; in the main standard or in some kind of implementation guide. [no response to this so far, Moon should propose I guess] 2-16 boa-arglist should support &key and &allow-other-keys. 2-18 default boa-arglist to be specified Status depends on whether object-creation proposal includes constructors. Moon: method arglist congruence still doesn't satisfy me. I have some ideas about this but unfortunately have not managed to pull them together. To be resolved as part of the initialization protocol discussion. Which symbols defined by the standard go in what package? July: I think we said some will go in LISP: and some will go in CLOS: and we don't know yet where to draw the line. The top level macros and functions should be part of LISP. The internal functions specified for the sake of metaclass programming can reside in CLOS. If CLOS is an optional part of CL, are the symbols in the LISP package even when the option is not present? Probably. Should we adopt the :component-order class-option from Flavors, as a simple way for the user to have control of the CPL without making him write his own algorithm? Gregor doesn't like the ability to specify constraints on the ordering of classes that only apply conditionally, i.e. if those classes are actually present among the superclasses. He considers this bad style. Moon volunteered to write a proposal with some examples, and we agreed to resolve this over the mail. ================ PREFIXED SYMBOL NAMES These two issues appear to be related. 2-18 (:accessor-prefix nil) is not a good way to say "use the slot names as the accessor names". We need to fix this. We could add another option, or remove the whole prefix feature, and require accessor names always to be listed explicitly. In July we agreed to discuss this in the mail. 2-57 with-slots :prefix package problem; This was discussed in the mail and then the ball was dropped. What's in the document is unworkable because it depends on the dynamic value of *package* at macro-expansion time, but Common Lisp doesn't guarantee anything about when macro-expansion occurs. Moon would prefer to flush the :prefix option. An alternative that was discussed was to use symbol-package of the prefix, both here and in defclass accessor construction, as the package, relying on the likelihood of prefixes always ending in delimiter characters and exported symbols never ending in delimiter characters. July: We agreed to resolve this in the mail. Kempf, Moon: Flush :prefix. Gregor: I like the prefix option, although I agree that this is a serious problem. ================ ENSURE-GENERIC-FUNCTION A constellation of issues surrounding the mapping from generic function names to generic function objects. This seems to be awaiting a proposal to pull it all together. 1-18, 2-40 It is not specified whether get-setf-generic-function is setf-able. Gregor: make it setf'able, it's just like symbol-function. Maybe rename it to symbol-setf-generic-function? Moon thinks this would be okay provided it is understood as setting the mapping from a name to a generic function, not side-effecting the generic function. See class-name discussion below (2-13). Good reason to rename it to symbol-setf-generic-function. This set off a discussion of how TRACE should work that maybe doesn't bear directly on CLOS. Kempf is working on a proposal. 2-40 get-setf-generic-function needs an errorp, but it and get-generic-function should be subsumed by ensure-generic-function which would do all the right things. Gregor: I propose that we keep get-setf-generic-function, but that we rename it to symbol-setf-generic-function. In addition, I propose that we do the following: ensure-generic-function, add-named-method and any other CLOS function that takes the name of a generic function as an argument can also take a list like (SETF ) which means the setf-generic function for that argument. I propose that ensure-generic-function do basically what defgeneric-options and defgeneric-options-setf used to do except that ensure-generic-function would be a function (that is it would evaluate its arguments). This isn't a problem since defgeneric-options didn't take any &body arguments anyways. The real thing that needs to be worked out here is what happens if the generic function already exists, but is different in some ways than the description in the arguments to ensure-generic-function. The relevant options (referring to 2-42) seem to be: :lambda-list -- method congruence issue :generic-function-class -- covered below :method-class -- are existing methods mutated? Moon doesn't see any problem with changing these options: :argument-precedence-order :declare :documentation :method-combination Gregor's e-g-f proposal, recovered from mail sent back in February, and edited only slightly: ensure-generic-function &key (generic-function-class (class-named 'standard-generic-function)) (make-existing-function-default-p nil) If symbol is fboundp to a generic-function of the same class as generic-function-class then this function does nothing, and returns the generic function object. If symbol is fboundp to a generic-function of some other class, the generic-function class changing protocol is followed, see chapter 3. Use (class-named 'generic-function) to prevent changing the class (is this right? does "of class" here mean typep or eq type-of?) If symbol not foundp a generic function of generic-function-class is created and put in symbol's function cell. There was some contention over whether there should be a create-p argument to control this, or the caller should do an fboundp test first. If symbol is fboundp to a function, and make-existing-function-default-p is not nil, a generic-function is created, put in the function cell, a default method is added to the generic-function and the symbol's previous function cell value is used as the function for the default method. If symbol is fboundp to a function and make-existing-function-default-p is nil an error is signalled. If symbol names a macro or a special form, an error is signalled. Thus if this does not signal an error, it returns a generic function object that is now the function definition of the symbol. can also be (setf ), as proposed later. How does the caller do an fboundp test of this? Feel free to change the names of the arguments. Note that this is a function not a generic-function. This needs to take additional arguments corresponding to all of the arguments of defgeneric-options; see make-generic-function on 2-42. ================ CLASS NAMING ISSUE [I have not yet summarized all the mail on this topic] ================ CLASS REDEFINITION [I have not yet summarized all the mail on this topic] ================ COMPILER OPTIMIZATION Kempf 29 Jul 87: There was no mention made of compile time optimization, which I believe I made some initial proposals on in late April or early May. I've been meaning to revisit them.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Aug 87 12:34:04 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 20 Aug 87 09:28:29 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 217224; Thu 20-Aug-87 12:29:36 EDT Date: Thu, 20 Aug 87 12:29 EDT From: David A. Moon Subject: proposed syntactic cleanups in defmethod To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870820122915.2.MOON@EUPHRATES.SCRC.Symbolics.COM> We've noticed some problems with the CLOS syntax for defmethod, especially when using methods on individuals, and in response I'd like to propose three cleanups. Note that all of these changes are purely syntactic; that is, they only affect the readability of programs, they don't add or remove capabilities of the language. I hope this is a minor issue that can be dealt with quickly. The first problem has to do with the suggested compiler warnings mentioned on CLtL p. 160 under the IGNORE declaration. Methods often don't use some of their parameters for anything other than making the method applicable for certain arguments to the generic function. Consider this example (defmethod additional-mail-headers ((host 'xerox.com)) (declare (ignore host)) '(:line-fold "No")) One would prefer not to have to write the (declare (ignore host)). This almost always happens with methods on individuals, but it can also happen with methods on classes. Consider (defmethod color ((e elephant)) (declare (ignore e)) 'grey) I propose that the DEFMETHOD macro be specified to "refer to" (in the sense of CLtL p.160) each specialized parameter. This means that a compiler warning will not occur regardless of whether the body of the method does or does not refer to the parameter, and the declare ignore in the above examples must be removed. This makes sense intuitively if one regards the type check of the argument against the parameter specializer as being part of the method; thus any specialized parameter is referred to by the type check. An interesting effect of this is that (defmethod part-color ((e elephant) part) 'grey) and (defmethod part-color ((e elephant) (part t)) 'grey) are no longer synonymous, since the first gives a compiler warning and the second does not. I think this is a feature, not a bug. ================ The second problem relates to the use of the single quote syntax (') for methods on individuals. There are actually two problems here. One is that that single character is easy to overlook. One of the most common mistakes of beginning Lisp programmers is omitting quote marks or putting them in the wrong place. Actually, it's not only beginning programmers who do this. I still do it myself sometimes, and I believe I have seen Danny Bobrow do it. I believe the programmer who intended to write (defmethod color ((e elephant)) 'grey) but accidentally wrote (defmethod color ((e 'elephant)) 'grey) instead is going to have a lot of trouble figuring out what happened. It would be better to make the latter form a syntactic error, so that we can give a clear error message. We should use a different syntax for methods on individuals. The quote mark is a cute hack, but I think we can afford to use something slightly more verbose. Suggestion below. The other problem with methods on individuals is that the current syntax is awkward when the individual is anything other than a symbol or a number, just because defmethod is using a special magic syntax instead of a normal Lisp form. Returning to my first example, suppose hosts are to be represented by CLOS objects rather than symbols. Instead of writing (defmethod additional-mail-headers ((host 'xerox.com)) '(:line-fold "No")) I now have to write (defmethod additional-mail-headers ((host '(parse-host "xerox.com"))) '(:line-fold "No")) but this doesn't work, because the form (parse-host "xerox.com") is not in a position to be evaluated. I can write (eval `(defmethod additional-mail-headers ((host ',(parse-host "xerox.com"))) '(:line-fold "No"))) but that's grotesque. I can also write (defmethod additional-mail-headers ((host '#.(parse-host "xerox.com"))) '(:line-fold "No")) which works for this case, but #. has scoping problems exposed by the next example. Suppose we're writing methods on individual numbers, but rather than sprinkle numbers all over the code, we use defconstant, as good style dictates. This is boiled down from a remote-procedure-call example. (defconstant begin-code 1) (defconstant end-code 2) (defconstant integer-code 3) (defconstant float-code 4) (defmethod decode (stream (opcode '#.begin-code)) ... begin processing a message ...) One problem with this occurs when using compile-file. CLtL isn't very clear on whether #. evaluates in an environment in which those defconstants have been evaluated. It's likely that the programmer has to play some games with eval-when to make this work. This could be fixed by tightening up the semantics of compilation in Common Lisp, but a worse problem is that #. does not and can not respect lexical scoping. Suppose we had (let ((begin-code 1)) (defmethod decode (stream (opcode '#.begin-code)) ... begin processing a message ...)) There is no way the #. can see the environment created by the LET which is still being read in at the time the #. is processed. It seems that it would make a lot more sense to put a regular Lisp form in the parameter-specializer-name, scoped completely normally, and let the defmethod macro (rather than the programmer) take care of any special mechanism needed to evaluate with respect to the proper environment, including compile-time defconstants. Common Lisp doesn't currently standardize all the primitives needed to write that defmethod portably, but I think that only strengthens the argument for making defmethod worry about those issues, instead of making every programmer worry about them. So I'd like to see the syntax of an individual parameter-specializer-name changed to use a different word instead of QUOTE, and to use a form that evaluates to the object, instead of the object itself. The form is evaluated at the time the method is defined; it is not evaluated each time the generic function is called. I have two suggestions for what word to use, one based on what test is being performed and the second based on the Common Lisp type system: (defmethod additional-mail-headers ((host (eql (parse-host "xerox.com")))) '(:line-fold "No")) (defmethod additional-mail-headers ((host (member (parse-host "xerox.com")))) '(:line-fold "No")) I mildly prefer EQL over MEMBER, but I thought I'd open up both suggestions for discussion. Each of these suggests an obvious generalization, EQL to other predicates and MEMBER to multiple individuals, and the choice might be based on which generalization we want people to think about, even if we don't propose to implement the generalization. ================ The final issue has to do with parameter-specializers rather than parameter-specializer-names, using the terminology of 87-002 page 1-18. I think that adding QUOTE as a type-specifier to Common Lisp is both unnecessary and confusing. (Yes, I know I suggested it. I was wrong.) Instead, the parameter-specializer for a method on an individual should be (MEMBER object), the type-specifier that Common Lisp already defines for this purpose. Note that there is no particular reason why the parameter-specializer should be the same as the parameter-specializer-name; they're already not the same for methods on classes.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 21:34:24 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87 18:30:48 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216931; Wed 19-Aug-87 21:31:58 EDT Date: Wed, 19 Aug 87 21:31 EDT From: David A. Moon Subject: meeting place To: Common-Lisp-Object-System@Sail.Stanford.edu In-Reply-To: <870819-173655-3259@Xerox> Message-ID: <870819213135.2.MOON@EUPHRATES.SCRC.Symbolics.COM> I don't care where we meet, but if it isn't Lucid someone should tell Jan Zubkoff, since she has been making arrangements for a room.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 20:41:16 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Aug 87 17:37:35 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 19 AUG 87 17:36:55 PDT Date: 19 Aug 87 17:36 PDT From: Gregor.pa@Xerox.COM Subject: meeting place To: Common-Lisp-Object-System@Sail.Stanford.edu cc: Gregor.pa@Xerox.COM Message-ID: <870819-173655-3259@Xerox> I just got back and haven't had a chance to really look through the mail. The messages I thought I should try to answer right away were the ones about meeting time and place. Speaking for myself and Danny, we would rather have two entire days of meetings. Also speaking for Danny and myself, we would rather meet at PARC this time. We met at Lucid last time, and parking and food are easier at PARC. We can get a nice conference room in a part of the building where we won't be bothered. I'll even try to get us one of those fancy (Japanese) whiteboards that makes copies of what is written on it.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 18:01:44 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 19 Aug 87 14:55:12 PDT Received: from relay2.cs.net by RELAY.CS.NET id ae09985; 19 Aug 87 17:46 EDT Received: from ti-csl by RELAY.CS.NET id ac19836; 19 Aug 87 17:33 EDT Received: from Jenner by tilde id AA03684; Wed, 19 Aug 87 15:19:37 CDT Message-Id: <2765391661-13139657@Jenner> Date: Wed, 19 Aug 87 15:21:01 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Names to Objects and Compiler-environment In-Reply-To: Msg of Tue, 18 Aug 87 20:29 EDT from "David A. Moon" Date: Tue, 18 Aug 87 20:29 EDT From: "David A. Moon" Subject: Names to Objects and Compiler-environment Date: Mon, 17 Aug 87 16:15:27 CDT From: Patrick H Dussud I agree with the general thrust of what you're saying, but have some nits to pick and a question to ask. I might have more to say on this topic later. Question: I had thought that environments referred only to the mapping from names (Lisp symbols) to objects, but in saying that ADD-METHOD, GET-METHOD, REMOVE-METHOD, and FIND-APPLICABLE-METHODS (not documented) need an environment argument, I think you're saying that environments also affect the mapping from generic-function objects to lists of method objects. Is this correct? Yes, I want to do this primarily because It allows to be more efficient in terms of structure copy. My file contains: (defmethod speed ((thing my-ship)) .....) ;;some other things but no DEFCLASS for my-ship and ;;no DEFGENERIC-OPTIONS for speed. During COMPILE-FILE I think it is unnecessary to copy the generic-function or/and the class, to hold the method definition. What I had in mind was to add the method to the runtime version of SPEED, in another namespace so a lookup for this method in the runtime environment is not affected. I realize that we can avoid this by copying the generic-function object to the compile environment, but then we will have to copy some other objects (those side effected by the defmethod) and end up having to copy a large portion of the world. Since we tend to store first class object instead of names, we can't get enough leverage off the name-to-object lookup. I tried to address this problem. And is there any other kind of mapping that they affect? I don't know, I can't think of any others but I might be ovelooking something. An environment of NIL should be defined to be synonymous with the run-time environment, for programmer convenience. One can get an environment by the function GET-CURRENT-ENVIRONMENT. If an implementation supports compile-environment, then a call to GET-CURRENT-ENVIRONMENT in the top level loop is not EQL to a call to GET-CURRENT-ENVIRONMENT inside a macro expansion while compiling a file. Does GET-CURRENT-ENVIRONMENT take no arguments? I believe that the &environment argument to a macro expander is the only viable way for the macro expander to know whether the code it's going to return has its meaning defined in terms of the compile-environment or the run-time environment. Thus I believe that the macro expander should pass its &environment argument to GET-CURRENT-ENVIRONMENT. To avoid confusion, we should either declare that these two kinds of environments are identical, eliminating the need for GET-CURRENT-ENVIRONMENT, or else we should find a new name for the CLOS kind of environment. If GET-CURRENT-ENVIRONMENT takes no arguments, then what you have is some form of dynamic scoping, rather than lexical scoping, and you can get scoping problems. Symbolics' implementation, and I believe TI's as well, currently works this way, using the special variable SYS:UNDO-DECLARATIONS-FLAG to inform macro expanders on behalf of which environment they are working. The genesis of this is historical and predates lexical scoping. This causes a number of subtle problems. CLOS should not make this mistake. I agree with you. Passing the &environment argument to get-current-environment is the best. I feared that the existing implementation would have to change too much. If we do that, the compiler must tie up their compile-environment to the macroexpand environment (which, to me, is a good thing ) and therefore must change. I don't think the two environments must be identical: a macroexpand environment is free to change at each top level form, the compile environment needs to be stay EQ for the extent of COMPILE-FILE. I would propose NAMESPACE instead of environment.?? GET-NEXT-ENVIRONMENT ENVIRONMENT. This function returns the next environment to lookup if any or NIL. This allows the implementation to implement search lists. I don't understand how adding GET-NEXT-ENVIRONMENT to the documented interface is related to the issue of search lists. The implementation can have those without anything special for them in the interface. If we want a metaclass to be written portably, to use environments, and be able to implement the searching by itself, GET-METHOD should be able to be coded like: search the method, using the specified environment as a tag and then using the next environment and so forth. Does that make sense? I guess it is tied to this assumption: [From my original message: Name-to-method mapping implementation should be left to the metaclass writer since it is tied up to the strategy of finding the applicable methods for method discrimination and method combination.]. If there is searching, and I think there needs to be if only so the compile environment can inherit from the run time environment, you need a negative inheritance mechanism, so that the compile environment can say such and such a method does not exist in the new version of this program being compiled, even though it exists in the old version that is being used to do the compilation. I agree. (REMOVE-METHOD gf .... ENV) for example has to store in the place where the metaclass will search that the method is not to be found in the context of ENV. Does this negative inheritance need to be specified? How does the implementation signal an object that it has been deleted from the compiler environment? I would prefer that object deallocation be left to the garbage collector. Are there any problems with that? The problem I see is that the objects are pointed to by more than the environment: The direct-subclasses slot of a runtime class might point to a compile-time class. The environment itself can be hold on to: A metaclass writer can store object on an Alist whose key is the environment. I don't think the garbage collector will be able to get rid of those objects. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 16:56:00 EDT Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 19 Aug 87 13:49:28 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 111131; Wed 19-Aug-87 16:50:17 EDT Date: Wed, 19 Aug 87 16:47 EDT From: Daniel L. Weinreb Subject: short form of define-method-combination To: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870819132057.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <870819164729.8.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Wed, 19 Aug 87 13:20 EDT From: David A. Moon However, I don't understand why you think the method-combination type of a generic function needs to be repeated in the defmethod, while the rest of the contract of the generic function does not need to be repeated. You seem to be setting up a hypothetical alternative, but I don't understand what the alternative is. We don't have a language for contracts. It just seems to me that it's very hard to understand what a method is doing, and easy to misunderstand it or be confused, if you don't see what kind of combination is being employed. When you see a BEFORE method, you know what that is. When you see an unqualified method, you naturally assume that it's a primary method, and that (for example) what it returns will be the result of the generic function call. But that's not true if it's an AND-combined method, or worse yet a PROGN combined method. It seems to me that the command provided by the programming environment to remind one of the arguments expected, values returned, and documentation of the generic function can also remind one of the method-combination type. If you convince me that the method-combination type deserves special treatment, then I'll change my proposal to make the qualifier mandatory instead of prohibited. I doubt I can come up with something much more convincing. It just seems a lot clearer to me. (DanG mentioned to me, two days ago, that he feels the same way.) In fact, I thought that the reason that qualifiers for things like AND and OR were first (1980?) introduced was because we felt they made the code clearer.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 14:27:06 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87 11:23:15 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216533; Wed 19-Aug-87 14:23:16 EDT Date: Wed, 19 Aug 87 14:22 EDT From: Sonya E. Keene Subject: Names to Objects and Compiler-environment To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <2765222127-2953787@Jenner> Message-ID: <870819142229.0.SKEENE@JUNCO.SCRC.Symbolics.COM> Date: Mon, 17 Aug 87 16:15:27 CDT From: Patrick H Dussud The name-to-object primitives we have in CLOS are: Object Function Metaclass Implementation dependent dependent Class CLASS-NAME No Yes Generic-function SYMBOL-FUNCTION No Yes Method GET-METHOD Yes * There's also GET-SETF-GENERIC-FUNCTION.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 13:24:13 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87 10:20:10 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216470; Wed 19-Aug-87 13:21:20 EDT Date: Wed, 19 Aug 87 13:20 EDT From: David A. Moon Subject: short form of define-method-combination To: Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870818182230.3.MOON@EUPHRATES.SCRC.Symbolics.COM>, <870818190658.2.DLW@CHICOPEE.SCRC.Symbolics.COM>, <870819093252.6.SKEENE@JUNCO.SCRC.Symbolics.COM>, <870819102506.5.DLW@CHICOPEE.SCRC.Symbolics.COM> Message-ID: <870819132057.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 18 Aug 87 19:06 EDT From: Daniel L. Weinreb I am not enthusiastic about this proposal. I have always liked having the qualifier in the defmethod form explicitly, because it enhances readability. Requiring the qualifier would satisfy my stated wants, provided that the qualifier wasn't optional (so there was only one way to write a primary method) and wasn't re-interned in the keyword package (so we aren't inventing symbols). However, I don't understand why you think the method-combination type of a generic function needs to be repeated in the defmethod, while the rest of the contract of the generic function does not need to be repeated. It seems to me that the command provided by the programming environment to remind one of the arguments expected, values returned, and documentation of the generic function can also remind one of the method-combination type. If you convince me that the method-combination type deserves special treatment, then I'll change my proposal to make the qualifier mandatory instead of prohibited.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 10:49:11 EDT Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 19 Aug 87 07:44:55 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110961; Wed 19-Aug-87 10:27:55 EDT Date: Wed, 19 Aug 87 10:25 EDT From: Daniel L. Weinreb Subject: short form of define-method-combination To: skeene@STONY-BROOK.SCRC.Symbolics.COM cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870819093252.6.SKEENE@JUNCO.SCRC.Symbolics.COM> Message-ID: <870819102506.5.DLW@CHICOPEE.SCRC.Symbolics.COM> I don't think the documentation string is adequate to produce the results I'd like to see. In practice, I just don't believe that programmers will, in fact, invariably (or even usually) remember to note the method combination type in the documentation string for every method that uses non-default method combination.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Aug 87 09:36:10 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87 06:32:28 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216238; Wed 19-Aug-87 09:33:33 EDT Date: Wed, 19 Aug 87 09:32 EDT From: Sonya E. Keene Subject: short form of define-method-combination To: DLW@ALDERAAN.SCRC.Symbolics.COM cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870818190658.2.DLW@CHICOPEE.SCRC.Symbolics.COM> Message-ID: <870819093252.6.SKEENE@JUNCO.SCRC.Symbolics.COM> Initially, I had the same opinion you state -- that having the qualifier in the defmethod form enhances readability, and that it was preferable to make that qualifier be required rather than forbidden. The reason for including the qualifier in the defmethod form is to document the method (how it will be combined with other methods). But we already provide a way to document a method, via the documentation string. So now I'm in favor of having the methods be unqualified instead of requiring that they be qualified. Either of the new suggestions would be better than the way it is now, where you can choose whether to include the qualifier or not.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 19 Aug 87 07:04:46 EDT Received: from Salvador.ms by ArpaGateway.ms ; 19 AUG 87 03:53:35 PDT Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 19 AUG 87 03:50:29 PDT Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (burdvax) [5.54/1.0] id AA22723; Wed, 19 Aug 87 06:50:11 EDT Received: by bigburd.PRC.Unisys.COM (bigburd) [5.54/1.0] id AA14819; Wed, 19 Aug 87 06:50:07 EDT From: fritzson@bigburd.PRC.Unisys.COM (Richard Fritzson) Message-Id: <8708191050.AA14819@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd with PUP; Wed, 19 Aug 87 06:50 EDT Date: 19 Aug 87 06:49 EDT (Wednesday) To: commonloops.pa@Xerox.COM Subject: with-slots bug in xerox pcl Cc: fritzson@bigburd.prc.unisys.com Now matter what I try, I can't get with-slots WITH use-accessors = T to behave differently than with-slots WITH use-accessors = NIL. I am using the Xerox Lyric version of PCL of 5/22/87 (rev 2), with the official Lyric release of Xerox Common Lisp. (defclass point () ((xcoord :initform 0 :type number) (ycoord :initform 0 :type number)) (:accessor-prefix point-) ) (setf foo (make-instance 'point)) (setf (point-xcoord foo) 10) ; Redefine point-xcoord to see whether it is used or not (defmethod point-xcoord ((p point)) (progn (print 'foo)(slot-value foo 'xcoord))) ; Now the accessor will also print "FOO" ; Define two methods, using with-slots (defmethod test-getx-1((p point)) (with-slots ((p :use-accessor T)) xcoord)) (defmethod test-getx-2((p point)) (with-slots ((p :use-accessor ())) xcoord)) ; But when we use them, they both use the accessor function, ; i.e. they both print "FOO" when executed. (test-getx-1 foo) (test-getx-2 foo)  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 20:32:25 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87 17:28:19 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216083; Tue 18-Aug-87 20:29:21 EDT Date: Tue, 18 Aug 87 20:29 EDT From: David A. Moon Subject: Names to Objects and Compiler-environment To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <2765222127-2953787@Jenner> Message-ID: <870818202904.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 17 Aug 87 16:15:27 CDT From: Patrick H Dussud I agree with the general thrust of what you're saying, but have some nits to pick and a question to ask. I might have more to say on this topic later. Question: I had thought that environments referred only to the mapping from names (Lisp symbols) to objects, but in saying that ADD-METHOD, GET-METHOD, REMOVE-METHOD, and FIND-APPLICABLE-METHODS (not documented) need an environment argument, I think you're saying that environments also affect the mapping from generic-function objects to lists of method objects. Is this correct? And is there any other kind of mapping that they affect? An environment of NIL should be defined to be synonymous with the run-time environment, for programmer convenience. One can get an environment by the function GET-CURRENT-ENVIRONMENT. If an implementation supports compile-environment, then a call to GET-CURRENT-ENVIRONMENT in the top level loop is not EQL to a call to GET-CURRENT-ENVIRONMENT inside a macro expansion while compiling a file. Does GET-CURRENT-ENVIRONMENT take no arguments? I believe that the &environment argument to a macro expander is the only viable way for the macro expander to know whether the code it's going to return has its meaning defined in terms of the compile-environment or the run-time environment. Thus I believe that the macro expander should pass its &environment argument to GET-CURRENT-ENVIRONMENT. To avoid confusion, we should either declare that these two kinds of environments are identical, eliminating the need for GET-CURRENT-ENVIRONMENT, or else we should find a new name for the CLOS kind of environment. If GET-CURRENT-ENVIRONMENT takes no arguments, then what you have is some form of dynamic scoping, rather than lexical scoping, and you can get scoping problems. Symbolics' implementation, and I believe TI's as well, currently works this way, using the special variable SYS:UNDO-DECLARATIONS-FLAG to inform macro expanders on behalf of which environment they are working. The genesis of this is historical and predates lexical scoping. This causes a number of subtle problems. CLOS should not make this mistake. GET-NEXT-ENVIRONMENT ENVIRONMENT. This function returns the next environment to lookup if any or NIL. This allows the implementation to implement search lists. I don't understand how adding GET-NEXT-ENVIRONMENT to the documented interface is related to the issue of search lists. The implementation can have those without anything special for them in the interface. If there is searching, and I think there needs to be if only so the compile environment can inherit from the run time environment, you need a negative inheritance mechanism, so that the compile environment can say such and such a method does not exist in the new version of this program being compiled, even though it exists in the old version that is being used to do the compilation. How does the implementation signal an object that it has been deleted from the compiler environment? I would prefer that object deallocation be left to the garbage collector. Are there any problems with that?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 20:11:48 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87 17:07:02 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216070; Tue 18-Aug-87 20:06:44 EDT Date: Tue, 18 Aug 87 20:06 EDT From: David A. Moon Subject: Re: ECOOP Reaction to CLOS To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8707092024.AA22131@hplabsz.hpl.hp.com>, The message of 6 Jul 87 14:30 EDT from Dick Gabriel Message-ID: <870818200622.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Some comments on characterizing the class precedence list algorithm. In my comments I will refer to this set of classes (slots omitted): (defclass a (b c w)) w x w y w x (defclass aa (b c d w)) \ / \ / \/ (defclass b (w x)) b c d w (defclass c (w y)) \ | / / (defclass d (w x)) \ | / / (defclass w ()) \ |/ / (defclass x ()) aa (defclass y ()) We've seen these classes before. By the rules in 87-002, the CPL of a is (a b c w y x) and of aa is (aa b c d w x y). Date: Thu, 9 Jul 87 13:24:38 pdt From: Jim Kempf The inheritance graph is searched depth first, left to right, up to joins. Superclasses at joins are placed in the class precedence list at the last occurance, rather than the first, since such superclasses are usually more general than their subclasses, and classes at the end of the class precedence list should be more general than those at the beginning. The qualitative effect is to achieve a linearization of the inheritance graph, with more specialized classes at the head of the class precedence list and more general classes at the tail, keeping together groups of classes which occur together in the inheritance graph. A more detailed explantion should go into what can go wrong. The Ducournau and Habib paper discusses this in a more formal way.... I like this informal way of explaining it, except that I never figured out precisely what "up to joins" means, and depending on the interpretation of that phrase, this explanation could be incorrect. When the depth first walk of the graph for aa above encounters w above c, that's a join. If it goes on to y, I don't think y is a join, nevertheless y is not next in the CPL, x is. Date: 06 Jul 87 1130 PDT From: Dick Gabriel What would constitute an understandable characterization of the CPL? Here are some examples of approaches: 1. We could have a set of constraints on the classes such that the CPL is the unique total ordering satisfying those constraints. If I understand the meaning of constraints as being additive, the example above shows that it can't be done with constraints. Taking a and adding d to make aa reverses the order of x and y, thus whatever constraint was controlling the order of x and y must have been removed when d was added. Perhaps this nonadditiveness is at the root of people's difficulty in understanding the CPL computation. 2. We could have a set of inheritance situations such that when two graphs of classes were inherited in particular ways, the new CPL was predictable. For example, suppose we have 2 graphs, G1 and G2, with no common classes except for the class named T and suppose that C1 and C2 are the bottom-most classes of G1 and G2, respectively; then if a class C is a subclass of C1 and C2 in that order, the classes in G1 precede the classes in G2, and the classes in G1 are in the same order as they are in the CPL for C1 and similarly for G2; T comes last. Characterization #2 is in fact true, and it's not too hard to see why. Suppose G1A is the second class in C1's class precedence list. After topological sort has added C1 to C's cpl, the rule at the top of page 1-15 comes into play because either C2 or G1A could be next. The rule selects G1A. By what amounts to induction, one can show that every class in G1 will have a direct subclass to the right of C2's direct subclass (C), and therefore every class in G1 will precede C2. I believe one can also show that the classes in G1 will appear in the same order in C's cpl as in C1's cpl. I don't think it's a coincidence that characterization #2 is true, I think making it true was one of the acceptance criteria for the CPL algorithm. The problems occur just when G1 and G2 do have common classes (other than T).  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 19:20:35 EDT Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 18 Aug 87 16:15:06 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110793; Tue 18-Aug-87 19:09:52 EDT Date: Tue, 18 Aug 87 19:06 EDT From: Daniel L. Weinreb Subject: short form of define-method-combination To: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu In-Reply-To: <870818182230.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <870818190658.2.DLW@CHICOPEE.SCRC.Symbolics.COM> I am not enthusiastic about this proposal. I have always liked having the qualifier in the defmethod form explicitly, because it enhances readability. I think it's hard to understand what a method is doing if you don't know how that method is going to be combined. Having the qualifier there reminds you what kind of combination is going to be used. In order to eliminate the problem of having two separate methods that do the same thing, I would rather make use of the qualifier be required than forbidden. I realize that this does not solve the problem of inventing symbols. However, I think the benefit in readability outweighs this consideration.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 18:40:05 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 18 Aug 87 15:34:39 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 18 AUG 87 15:33:17 PDT Date: 18 Aug 87 15:31 PDT From: Kelley.pa@Xerox.COM Subject: Re: ECOOP Reaction to CLOS In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Tue, 18 Aug 87 09:51:20 MST To: kempf%hplabsz@hplabs.HP.COM cc: Kelley.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu Message-ID: <870818-153317-1383@Xerox> > The CLOS proposed standard explicitly claims in general to obey the > implicit inheritance - explicit override rule, but it does not for |I couldn't find a reference to "implicit inheritance - explicit override" |in Part 1 of the 87-002 spec. What page is it on? I was refering primarily to page 1-7, the first paragraph both under Inheritance of Methods and Inheritance of Slots and Slot Options. Obeying implicit inheritance in general is claimed there (though explicit override is implicit :-). The implication that the rule was quoted as such in 87-002 was unintentionally misleading -- one too many explicits in my original statement. | ... the object essentially has duplicate |copies of logically the same state. This approach was used in |CommonObjects, and is one aspect of CommonObjects which seems to bother |programmers the most. ... If inheritance of methods with the same name in CommonObjects signals an error, that is inconsistent with its slot inheritance. |The problem here is that every algorithm for multiple inheritance loses |somehow. ... If tree-structured multiple |inheritance is used (where the entire tree of supers |is maintained, duplicating branches above joins) then duplicated state |occurs above join classes.... Based on the arguments in Snyder's OOPSLA 86 paper, I would claim this problem is really a feature in disguise. At any rate, presenting the effects of the proposed inheritance algorithm for CLOS would be more understandable if in conjunction with presenting the class ordering algorithm, violations of the "implicit inheritance - explicit override" rule are clearly marked as such. -- kirk  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 18:28:13 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87 15:22:02 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 215969; Tue 18-Aug-87 18:22:49 EDT Date: Tue, 18 Aug 87 18:22 EDT From: David A. Moon Subject: short form of define-method-combination To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870818182230.3.MOON@EUPHRATES.SCRC.Symbolics.COM> I would like to propose a small simplification of the short form of define-method-combination. Recognizing both an unqualified method and a method whose qualifier is the name of the method combination type as primary methods seems unnecessary and confusing. It muddles the issue of the identity of a method (these are two separate methods with separate identities, yet they do the same thing). In addition, the qualifier is the name of the method combination type but in the keyword package, so this is one more place where CLOS is inventing symbols that don't appear in the source of the program, and each time we do that it seems to cause trouble. A possible drawback of this simplification is that it might make it harder for users to understand the difference between "primary method" and "unqualified method", since there won't be a counterexample to the theory that the two terms are synonymous. The specific document amendments are as follows, referring to 87-002: 2-27 Remove "A method with the keyword symbol with the same name as {\it name\/} as its one qualifier is also defined to be a primary method. Attaching this qualifier to a primary method documents that this method is intended for use with an unusual form of method combination and can make programs easier to understand." 2-30 Remove ":and" after "defmethod func". Remove "(:and)" after "primary ()". 2-31 Remove "(:and)" after "methods ()". Remove "(:and)" after "primary ()" [two places]. A related point is that we forgot to say in the document that a primary method is required when using a method combination type defined with the short form of define-method-combination, just as when using standard method combination. We should say that explicitly.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 14:50:16 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87 11:45:56 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 215676; Tue 18-Aug-87 14:47:05 EDT Date: Tue, 18 Aug 87 14:46 EDT From: David A. Moon Subject: Agenda for September meeting To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870818144639.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Sonya and I have put together a proposed agenda for the meeting in September. Let's agree on what the agenda will be by the end of this week. Earlier I said that I wanted to leave by Friday noon, but in putting together the agenda it became clear that 1 1/2 days wasn't enough time. Hence we've written the agenda for two full days. Is that okay with everyone? Agenda for CLOS Meeting Sep 17-18 at Lucid in Menlo Park (first draft) THURSDAY MORNING: Discuss written proposals on major areas, circulated over the network before the meeting and brought to the meeting in hardcopy. Spend no more than 45 minutes on each proposal, determining yes, no, or needs further discussion. Expected areas for proposals: object creation, new draft of metaclass chapter, change-class, 1 or 2 others. BREAK Discuss a list of minor issues, to be circulated over the network before the meeting and brought to the meeting in hardcopy. Moon will provide a list (based on one that has already been circulated, updated from recent mail), others will probably add to the list. Spend no more than 10 minutes on each issue, determining yes, no, or needs further discussion. If yes, assign a volunteer to update the document accordingly. LUNCH (let's keep this short) Finish going through list of minor issues. BREAK Discuss proposals & issues that were determined to need further discussion in the morning, in priority order. Objective is to decide what will be in the document for the October X3J13 meeting. Things we can't agree on here will be listed in the document as open issues. END OF THURSDAY Individuals may want to work on proposal drafts, writing tasks, etc. during the evening. FRIDAY MORNING: Allocate remaining writing tasks and make sure we understand how we will produce a document in time for the October X3J13 meeting, to be mailed out around September 30. The objective should be for the tasks remaining after the meeting breaks up to be purely editorial. Prepare first drafts of material to go into the document, for all issues where group effort is required. Each issue should have an individual assigned as the leader for that issue, who writes the first draft which is then criticized by others who are interested. FRIDAY AFTERNOON: Review what was written in the morning. PREPARATION REQUIRED AHEAD OF TIME Use network mail to finalize list of issues to be discussed and to get everyone up to date on them. Circulate proposals and issues list by the Friday before the meeting (Sep 11). Mail out hardcopies of the latest version of the 87-002 document immediately (no further editing is planned, right?).  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 14:40:40 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 18 Aug 87 11:35:40 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 18 Aug 87 08:51:16 pdt Received: from hplabsz.hpl.hp.com by hplms2; Tue, 18 Aug 87 08:50:43 pdt Return-Path: Received: from hplabsz by hplabsz; Tue, 18 Aug 87 09:51:23 pdt Message-Id: <8708181551.AA15800@hplabsz.hpl.hp.com> To: Kelley.pa@Xerox.COM Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: ECOOP Reaction to CLOS In-Reply-To: Your message of 05 Aug 87 17:48:00 -0700. <870805-174848-5665@Xerox> Date: Tue, 18 Aug 87 09:51:20 MST From: kempf%hplabsz@hplabs.HP.COM Sorry it's taken so long to respond. > > The CLOS proposed standard explicitly claims in general to obey the > implicit inheritance - explicit override rule, but it does not for I couldn't find a reference to "implicit inheritance - explicit override" in Part 1 of the 87-002 spec. What page is it on? > In as much as implicit inheritance is a sub-conscious assumption of > application programmers, standard CLOS behaves in a counter intuitive > manner. In my opinion, inheritance should *never* be a sub-concious assumption. It should be an explict design decision, made after considering alternatives. If the supers are in a library to which the programmer does not have source, then enough information should be given in the library's documentation that the programmer can design accordingly. Full analysis might not be required during a prototyping phase, but nevertheless, the programmer should be familiar with the details of the supers. > (defclass border (object) (width)) > (defmethod close (b border) ...) > (defclass window (object) (width)) > (defmethod close (w window) ...) > (defclass bordered-window (border window)) > (setq b-window (make-instance 'bordered-window)) > (close b-window) ; with the current inheritance algorithm, only closes > the border. Does not close the window. > The following explores what could happen if the implicit inheritance - > explicit override rule were followed in CLOS. > (close b-window) would result in both the border and window close > methods getting called because it inherits them implicitly and has not > explicitly overridden them. > With implicit inheritance a class may have in addition to multiple > methods with the same name that all get called by one call, multiple > occurrences of a slot with the same name that are manipulated in one > operation so b-window would contain two slots named width. > (setf (slot-value b-window width) 0) > Would set both slots to 0. Consider what would happen with a join superclass. In your example OBJECT is a join superclass, since it is inherited through two supers (WINDOW and BORDER) in BORDERED-WINDOW. For the supers above the join, the base class gets two copies of slots, one through each branch through the join class. There are two alternatives about what to do with the two sets of slots: 1) Keep a seperate set for each branch of the join, 2) Merge them in some manner. If the first approach is taken, then the object essentially has duplicate copies of logically the same state. This approach was used in CommonObjects, and is one aspect of CommonObjects which seems to bother programmers the most. If the second approach is taken, it is possible for some methods to be invoked more than once on the same set of slots, making the method semantics for singly inherited and multiply inherited cases different (see below for more discussion). > A problem is what to do with the results of an operation on a slot name > that refers to two or more slots or on a call that refers to two or more > methods. Operating on these slots or methods that have not been > overridden could be specified to return a "multiple-inheritance-result" > object containing the multiple results. This seems to me to be more complicated than most application programmers will want. It would be hard to integrate with WITH-SLOTS, and would require more syntatic machinery for setting or getting slots, pathnames to the appropriate slot, or something similar. It seems inappropriate to burden programmers with having to deal with such extra syntatic machinery when slot merging will do the job most of the time. > Any code that depended on the results from instances of singly inherited > classes would not work correctly with instances of multiply inherited > classes. (In the example above, any code that depended on the value This is a general problem with linearizing multiple inheritance, but most programmers who have used Flavors or CommonLoops are used to it, and plan accordingly. It requires more knowledge about the supers than for singly inherited languages, however. The problem here is that every algorithm for multiple inheritance loses somehow. If linearizing multiple inheritance is used, then the problem with changing method semantics occurs. If tree-structured multiple inheritance is used (where the entire tree of supers is maintained, duplicating branches above joins) then duplicated state occurs above join classes. If graph structured multiple inheritance is used (where the graph of supers is maintained without duplication), methods can be invoked multiple times on the same slot. For a more detailed analysis, see Alan Snyder's paper in the last OOPSLA proceedings. What CLOS has tried to do (I think) is to provide Lisp programmers with what they are most used to (i.e. codify existing practice), and to do so in a manner which produces expected behavior most of the time. If a programmer requires something out of the ordinary, then more time and effort needs to be invested in learning more details, and, with the metaclass protocol, much flexibility for changing inheritance behavior is available. Where the CLOS inheritance algorithm could be faulted, is that it handles the inability to linearize an inheritance graph as an error, rather than providing hooks for the programmer to override the default. Alternatives to multiple inheritance for achieving the same effect (i.e. maximum code reuse) are the subject for another basenote and mailing list. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 11:25:30 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 18 Aug 87 08:20:03 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa00914; 18 Aug 87 11:18 EDT Received: from ti-csl by RELAY.CS.NET id af11433; 18 Aug 87 11:08 EDT Received: from dsg by tilde id AA23644; Tue, 18 Aug 87 09:44:15 CDT Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 17 Aug 87 16:14:24 CDT Message-Id: <2765222127-2953787@Jenner> Date: Mon, 17 Aug 87 16:15:27 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Names to Objects and Compiler-environment The name-to-object primitives we have in CLOS are: Object Function Metaclass Implementation dependent dependent Class CLASS-NAME No Yes Generic-function SYMBOL-FUNCTION No Yes Method GET-METHOD Yes * Name-to-method mapping implementation should be left to the metaclass writer since it is tied up to the strategy of finding the applicable methods for method discrimination and method combination. Besides name to object mapping, the implementation provides some generic name services (source filename recording, redefinition warnings...) that the metaclass wants/needs to use. This answers the * sign in the above table. I believe that we need a portable interface to those services. Compile environment: In order to avoid side-effecting the running environment during COMPILE-FILE, the environment stores definitions in another namespace (compile environment). The management of the environment(s) should be left to the implementation. All our name-to-object functions are affected by this. We could make the environment implicit and say that those function will return the object from the "right environment" (SYMBOL-FUNCTION might work like that on some implementations), but then it becomes hard to write GET-METHOD portably. I propose that we make the environment explicit, passed as an argument to CLASS-NAME, GET-METHOD, their SETF functions and related function such as FIND-APPLICABLE-METHODS. I believe that CLOS should not know a whole lot about environments so we don't require all the implementations currently supporting compile-environment to change. Another issue is the dynamic extent of the compile environment: The implementation control their lifetime. Their should be a way for the implementation to signal the fact that a CLOS object no longer needed because COMPILE-FILE is over. Proposal(This would be part of the metaclass protocol): 1- Environment: The implementation should provide some objects called environments. The implementation controls their dynamic extent and their representation. One can get an environment by the function GET-CURRENT-ENVIRONMENT. If an implementation supports compile-environment, then a call to GET-CURRENT-ENVIRONMENT in the top level loop is not EQL to a call to GET-CURRENT-ENVIRONMENT inside a macro expansion while compiling a file. GET-NEXT-ENVIRONMENT ENVIRONMENT. This function returns the next environment to lookup if any or NIL. This allows the implementation to implement search lists. The function (GET-RUNTIME-ENVIRONMENT) always returns the runtime environment. CLOS will use environment as a key into its data structures to mark an object defined in a given environment (ie a method defined in a file during COMPILE-FILE) or to look it up. 2- CLOS functions that must have an environment argument: CLASS-NAMED and its SETF form, ADD-METHOD, GET-METHOD, REMOVE-METHOD, FIND-APPLICABLE-METHODS, ENSURE-GENERIC-FUNCTION. Questions: Do we need to add an environment slot to STANDARD-CLASS, STANDARD-METHOD and STANDARD-GENERIC-FUNCTION to get the environment they were defined in? How do we provide a portable interface to those generic "name" services provided by the implementation? How does the implementation signal an object that it has been deleted from the compiler environment? The following might work but I am not sure: ADD-TO-ENVIRONMENT OBJECT ENVIRONMENT. Tells the implementation that the dynamic extent of OBJECT is the same as the dynamic extent of ENVIRONMENT. DELETED-FROM-ENVIRONMENT OBJECT ENVIRONMENT this function is called by the implementation on every object added to the environment by the call to Add-to-environment before invalidating ENVIRONMENT. typically, It is done at the end of COMPILE-FILE.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Aug 87 00:38:00 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 17 Aug 87 21:32:55 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 17 Aug 87 21:31:02 pdt Received: from hplabsz.hpl.hp.com by hplms2; Mon, 17 Aug 87 17:02:14 pdt Return-Path: Received: from hplabsz by hplabsz; Mon, 17 Aug 87 18:02:53 pdt Message-Id: <8708180002.AA10001@hplabsz.hpl.hp.com> To: Patrick H Dussud Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Environments, Naming, and CLOS (was Re: Name that Class) In-Reply-To: Your message of Thu, 13 Aug 87 10:25:05 -0500. <2764855505-13956774@Jenner> Date: Mon, 17 Aug 87 18:02:50 MST From: kempf%hplabsz@hplabs.HP.COM > 2) Inheritance lists would be no problem, since supers must be of > the same metaclass anyway. > That's not true, supers can be of other compatible metaclasses. I stand corrected. In the event of a name clash, some means of disambiguating the name to class mapping would be needed. One possiblility would be to extend the definition of "compatible" to include "not having classes with the same name". Provided, of course, that multiply named classes were seen to be such an important feature that they should be included (which I doubt). > > > But, as Patrick has pointed out, the issue is more complex. The name > to class (or name to generic function) binding has an additional component, > namely the environment. What I think we *really* want is a way to have > the name to object binding be dependent on the environment as well. > This is an entirely different issue from what you've been talking about. > Environments and metaclasses are orthogonal. To the extent that the metaclass protocol takes into account the processing environment, it may be possible for a particular metaclass to do things differently in an environment from others. For example, a metaclass supporting a language which always resolves inheritance at compile time would need to deal with the environment in a different way from the default metaclass, where inheritance is resolved much later. > I'll leave it at that for this note. Summarizing, my feeling is that > allowing a multiple name per class object binding has some serious problems > for user level code, since the names of class objects are and > probably should be settable. I don't feel offering the functionality > to users is particularly important at this time, but if people want > it, then I think restricting the name to object mapping to be one to > one on a metaclass by metaclass basis is probably the right way to go. > I don't see what can be gained by having one namespace per metaclass. I thin> k> > it compromises modularity. When you list your supers in DEFCLASS, you > don't/shouldn't have to care what metaclass they belong to as long as they are > compatible with your metaclass. I agree. I can't see much use for allowing multiple names for classes in the first place, since it requires more syntatic machinery on the part of the programmer to indicate precisely which class is meant in user level code. The point of the metaclass proposal was that, if anywhere, that might be a place where people might want to have multiple classes with the same name. Suppose, for example, you want to have a WINDOW class in CLOS and one in Smalltalk (or CommonObjects, or Flavors, etc.). But Common Lisp provides packages for seperating namespaces, and I think that's probably enough, as long as you don't insist on exporting more than one WINDOW. So you could have a FLAVORS::WINDOW and a SMALLTALK::WINDOW. Personally, I think that this issue (multiple names for classes) is a bit of a red herring. I just presented the metclass proposal as an example of how it might make sense, but, as was pointed out, additional machinery would be required at the syntatic level to support it. The package system, despite its faults, is the customary way of modularizing namespaces in Common Lisp, and I think we should stick with that for user level code. The issue of multiple names in different processing environments is somewhat different. Because the package system is read time only, and symbols map across compilation and loading into the same package, the package system cannot be used to allow a class of the same name to co-exist at compile time. Similarly for methods. In order for a class or a set of classes and their applicable methods to be compilable in the same file, the CLOS metaclass protocol must insert enough information into the compile time environment so that the methods can be defined. At the extreme, the classes being compiled could be simply be completely defined at compile time, but this will, of course trash any existing definitions. This is not a problem for implementations which an easily get new virtual address spaces (modulo lengthening the time required for compilation of a system), since most bootstrapping problems could be solved by simply throwing away the environment and getting a new one (there are probably some more subtle problems here which I'm missing). Is that a fair statement of the problem with environments and naming? As mentioned in previous notes, I think a section in Part I about what CLOS needs in terms of processing environment is important. I might add that the ANSI C standard has about 8 pages of material on the processing environment at the beginning. We are, of course, limited by what CLtL provides, but I think, within that limit, we can probably be more precise.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Aug 87 12:34:48 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 13 Aug 87 09:20:00 PDT Received: from relay2.cs.net by RELAY.CS.NET id ah09181; 13 Aug 87 11:56 EDT Received: from ti-csl by RELAY.CS.NET id ag11477; 13 Aug 87 11:49 EDT Received: from Jenner by tilde id AA15544; Thu, 13 Aug 87 10:22:32 CDT Message-Id: <2764855505-13956774@Jenner> Date: Thu, 13 Aug 87 10:25:05 CDT From: Patrick H Dussud To: Jim Kempf Cc: "David A. Moon" , common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Name That Class In-Reply-To: Msg of Tue, 11 Aug 87 16:01:13 pdt from Jim Kempf 2) Inheritance lists would be no problem, since supers must be of the same metaclass anyway. That's not true, supers can be of other compatible metaclasses. But, as Patrick has pointed out, the issue is more complex. The name to class (or name to generic function) binding has an additional component, namely the environment. What I think we *really* want is a way to have the name to object binding be dependent on the environment as well. This issue is more important than the issue of user level multiple names per class (even for metaclass programming) since it directly affects implementations which can't use virtual memory to segment processing steps, and could adversely affect bootstrapping in any event. As I mentioned in a previous note, I think this issue should be resolved by a comprehensive, well thought out statement about the processing model for the Concepts chapter. Then, individual functions which require interface modifications should be modified. As Patrick mentioned in his note, the environment need not be a CLtL environment; in fact, given the second class status of environments in Common Lisp, it is hard to see how it *could* be without some beefing up of what you can do with them. This is an entirely different issue from what you've been talking about. Environments and metaclasses are orthogonal. I'll leave it at that for this note. Summarizing, my feeling is that allowing a multiple name per class object binding has some serious problems for user level code, since the names of class objects are and probably should be settable. I don't feel offering the functionality to users is particularly important at this time, but if people want it, then I think restricting the name to object mapping to be one to one on a metaclass by metaclass basis is probably the right way to go. I don't see what can be gained by having one namespace per metaclass. I think it compromises modularity. When you list your supers in DEFCLASS, you don't/shouldn't have to care what metaclass they belong to as long as they are compatible with your metaclass. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Aug 87 18:13:15 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Aug 87 15:03:36 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 11 Aug 87 15:01:11 pdt Received: from hplabsz.hpl.hp.com by hplms2; Tue, 11 Aug 87 15:00:34 pdt Return-Path: Received: from hplabsz by hplabsz; Tue, 11 Aug 87 16:01:15 pdt Date: Tue, 11 Aug 87 16:01:13 pdt From: Jim Kempf Message-Id: <8708112201.AA26864@hplabsz.hpl.hp.com> To: "David A. Moon" Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Name That Class In-Reply-To: Your message of Mon, 10 Aug 87 14:42:00 -0400. <870810144215.3.MOON@EUPHRATES.SCRC.Symbolics.COM> I said: Date: Tue, 11 Aug 87 16:01:12 MST From: kempf@hplabsz >> 2) Have the name to class object binding for an entire class be handled >> by the metaclass protocol. Moon replied: > I don't understand how this could work. If one is given a class name and > one wants to find the corresponding class object, how do you know what > metaclass is relevant before you have found the class object? and Gregor said (somewhat earlier): >Even if we decide that class-name should return at most one name, I >think it is clear that a class can have more than one name. That is, >it is legal to use setf of symbol-class to make the multiple symbols >point to the same class. and Patrick said (even earlier): >The environment argument will be necessary to address the compile >environment problem. The term might be confusing, it is not necessary >an environment like the &environment argument in a macro definition. I've been rethinking this issue somewhat, and I think we need to consider how class names will be used. I can see three ways in which users may need to use class names: 1) In inheritance lists for indicating direct supers, 2) In parameter specializer lists for indicating that particular method parameters are specialized to particular classes (or their subclasses), 3) For instantiation, 4) For general queries (i.e. system building-"Is this class there?", etc). There will be more reasons for using class names if metaclass programming is taken into account. Let's just consider these for the moment and ask what would happen if a many to one mapping of classes to names (and vice versa) were allowed. If multiple names were allowed to be "bound" to a single class object, then the function CLASS-NAME(S) could potentially return a list. The function SYMBOL-CLASS (or CLASS-NAMED) could also return a list, since, for any particular name, there could be multiple class objects having it. That is, if we have FOO1 and FOO2 bound to two different class objects, and the following is legal: (setf (class-name foo1) 'baz) (setf (class-name foo2) 'baz) then the following: (symbol-class 'baz) should return a list with two elements, with the CAR EQ to FOO1 and the CADR EQ to FOO2. What would this mean for user code? For one thing, the following would be ambiguous: (defmethod doit ((x baz)) ... ) since there are now two possibilities for the class BAZ. One could argue that this should mean that the method should be selected if X is from either class, but that would be expanding the kind of parameter specializer to boolean selection, and users may begin to demand something like: (defmethod doit ((x (or foo1-class foo2-class))) ... ) which we may want to avoid. Of course, we could always demand that the user put in the class object directly, to disambiguate, but names are good for *something*, in this case, as a shorthand for not having to say something like: (defmethod doit ( (x (cadr (symbol-class 'baz))) ) .... ) The reason classes are different from functions is because function definition objects don't have settable names. You can't say: (setf (function-name fundef1) 'foo) (setf (function-name fundef2) 'foo) at least, not in portable Common Lisp (most implementations probably allow this sort of thing internally). In addition, the inverse mapping to SYMBOL-FUNCTION (from function definition objects to names, called FUNCTION-NAME in the above example) is not defined. With classes, the inverse mapping needs to be defined and settable, and that is what is compilicating the issue. There are ways to hack around it, designating one name the principle name, etc., but they all introduce more machinery that I think most users will want. Metaclasses could be used to allow multiple names per class only if the name to class binding were restricted to one to one within a metaclass. Across metaclasses, multiple names per class could be allowed. The various ways this would affect the programmer interface are as follows: 1) SYMBOL-CLASS would require an optional metaclass argument, which would default to STANDARD-CLASS. SYMBOL-CLASS would be used for general queries, in addition. 2) Inheritance lists would be no problem, since supers must be of the same metaclass anyway. 3) DEFMETHOD would require additional machinery to specify the metaclass of the parameters. Possible choices are: a) A DEFMETHOD option specifying that the parameters must be from a particular metaclass. This will give problems with mixing specializers, for example, if specializers of metaclass STANDARD-TYPE-CLASS are mixed with those of metaclass STANDARD-CLASS, as is likely. b) The syntax of specialized lambda lists be expanded to include some means of indicating that the class is of a particular metaclass. This is more flexible, but syntatically clumsier. Something like: (defmethod doit ((x foo nonstandard-class) y x) ... ) is what I have in mind. Defaulting to STANDARD-CLASS may help. c) DEFMETHOD only works with parameter lists whose classes are from a restricted set of metaclasses. STANDARD-TYPE-CLASS, and STANDARD-CLASS are obvious candidates. A user wanting to handle parameters of another metaclass would need to write their own parameter list parser, and their own top level macro. 4) Instantiation via. MAKE-INSTANCE would require either: a) An optional metaclass argument, b) The argument would need to be the class object itself rather than a symbol, c) A symbol argument could default to STANDARD-CLASS. I honestly think that even this is more machinery than most applications programmers are going to need. Most users are simply going to use the default metaclass, and won't want to have more than one name per class or more than one class per name. But, as Patrick has pointed out, the issue is more complex. The name to class (or name to generic function) binding has an additional component, namely the environment. What I think we *really* want is a way to have the name to object binding be dependent on the environment as well. This issue is more important than the issue of user level multiple names per class (even for metaclass programming) since it directly affects implementations which can't use virtual memory to segment processing steps, and could adversely affect bootstrapping in any event. As I mentioned in a previous note, I think this issue should be resolved by a comprehensive, well thought out statement about the processing model for the Concepts chapter. Then, individual functions which require interface modifications should be modified. As Patrick mentioned in his note, the environment need not be a CLtL environment; in fact, given the second class status of environments in Common Lisp, it is hard to see how it *could* be without some beefing up of what you can do with them. I'll leave it at that for this note. Summarizing, my feeling is that allowing a multiple name per class object binding has some serious problems for user level code, since the names of class objects are and probably should be settable. I don't feel offering the functionality to users is particularly important at this time, but if people want it, then I think restricting the name to object mapping to be one to one on a metaclass by metaclass basis is probably the right way to go. More important is a resolution of the name to object mapping in different processing environments, and this should probably be done in a comprehensive manner, including generic functions also. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Aug 87 17:26:14 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Aug 87 14:18:43 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 10 Aug 87 10:45:16 pdt Received: from hplabsz.hpl.hp.com by hplms2; Mon, 10 Aug 87 10:44:48 pdt Return-Path: Received: from hplabsz by hplabsz; Mon, 10 Aug 87 11:45:34 pdt Message-Id: <8708101745.AA15689@hplabsz.hpl.hp.com> To: "David A. Moon" Cc: common-lisp-object-system@SAIL.STANFORD.EDU, masinter.pa@XEROX.COM Subject: Re: TRACE Proposal (Version 1) In-Reply-To: Your message of Thu, 06 Aug 87 14:10:00 -0400. <870806141000.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 10 Aug 87 11:45:31 MST From: kempf%hplabsz@hplabs.HP.COM > A function-spec is either a symbol naming a function (i.e. a symbol > whose global function cell is bound to a function definition object) > or a list whose first element is a function specification type, and > whose tail indicates which particular function of that type should > be traced. > The Cleanup subcommittee of X3J13 were discussing something similar > a while back, starting from a different point. The DOCUMENTATION function > of Common Lisp introduces the concept of "definition types", and this > concept could be useful in other operations. For instance, it would be A definition type would certainly be a nicer way of handling this. It would unify how to indicate that a particular definition is wanted. > Note: Another useful enhancement would be to support a :BREAK flag, like > this: > (:METHOD :BREAK) > indicating that a break loop should be entered before and after the > function executes. > Here you see a conflict between lists as function-specs and lists as > lists of options, in the arguments to TRACE. Because of this your proposal > for TRACE is not compatible with what Symbolics currently does, but I don't > think that's too important for us. We say that a list is a list of options, > and if you want to trace a function whose name is a list, you have to do > (TRACE (:function ...)). But all this really > shows is that the syntax of TRACE is ridiculous. I usually ignore the TRACE > function and trace things through a command interface. Anyway, for your > proposal you have to decide between lists as function specs and lists as > options; I don't think you can mix them freely as you proposed. Of course > it would be a lot > e> asier if TRACE only traced one function at a time, > then the rest of the form could be used for options. That would be a bit > incompatible with CLtL. An alternative would be to introduce a BREAK macro: BREAK &REST {function-spec or definition}* [Macro] having the obvious functionality. Such a "functional" interface would avoid having to try indicating everything through one operation. I just suggested the :BREAK option because this similar to how we currently do it. > TRACE-EXECUTION object &OPTIONAL env [Generic Function] > I didn't completely understand this. It looks like there is some > incoherence about whether TRACE is an operation on functions or on > places in which you can store a function definition. In other words, > does tracing a function redefine the function or alter the object that > is the function's definition? In other words, does > (defun foo () ...) > (setq f #'foo) > (trace foo) > (funcall f) > generate trace-output or not? We have to decide one way or the other. > CLtL is obscure on this point. As is usual in CLOS, the idea here was to split trace functionality into two pieces a) a programmer interface (TRACE) b) a system level or metaclass protocol function (TRACE-EXECUTION). With reference to your example, certain implementations may support the ability to modify function definition objects directly to allow trace information to be inserted. Thus the FUNCALL in the example could be traceable. As the base note suggested, these implementations could then have a function spec (or definition type) for indicating that the function should be trace through the fundef object rather than through the symbol. Other implementations may only be able to trace though a wrapper on the function symbol. The function spec or definition type would be used for indicating to TRACE what to do, a corresponding TRACE-EXECUTION method would contain the implementation dependent code to do it. As to why go to the trouble of having an extra layer, consider a user who wants to write a method or generic function class for remote procedure calls. This user would like some way of handling debugging, and a generic function in the metaclass protocol seems like the right way to do it. A generic function would provide the system level interface for other kinds of debugging functionality. jak  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Aug 87 14:51:40 EDT Received: from [128.81.41.223] by SAIL.STANFORD.EDU with TCP; 10 Aug 87 11:45:49 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 152618; Mon 10-Aug-87 14:42:59 EDT Date: Mon, 10 Aug 87 14:42 EDT From: David A. Moon Subject: Re: Name That Class To: kempf%hplabsz@hplabs.HP.COM cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: <8708101815.AA15913@hplabsz.hpl.hp.com> Message-ID: <870810144215.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 10 Aug 87 12:15:15 MST From: kempf%hplabsz@hplabs.HP.COM 2) Have the name to class object binding for an entire class be handled by the metaclass protocol. Of the two, I prefer the second one, since it gives some flexibility for users wanting to define new metaclasses, and also gives some potential for resolving the compile time name to object mapping, since the metaclass can potentially control this, but perhaps in an implementation dependent manner. I'm willing to write up a proposal on this, if there is any interest. I don't understand how this could work. If one is given a class name and one wants to find the corresponding class object, how do you know what metaclass is relevant before you have found the class object?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Aug 87 14:30:48 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Aug 87 11:21:44 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 10 Aug 87 11:14:59 pdt Received: from hplabsz.hpl.hp.com by hplms2; Mon, 10 Aug 87 11:14:33 pdt Return-Path: Received: from hplabsz by hplabsz; Mon, 10 Aug 87 12:15:19 pdt Message-Id: <8708101815.AA15913@hplabsz.hpl.hp.com> To: "David A. Moon" Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: Name That Class In-Reply-To: Your message of Thu, 06 Aug 87 22:14:00 -0400. <870806221457.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 10 Aug 87 12:15:15 MST From: kempf%hplabsz@hplabs.HP.COM > As far as I am concerned, any of these three would work. My objection > to solution 3 is primarily that it is more complicated. In addition to this objection to solution 3, another is that while other things (particularly functions) can be multiply named, there is currently no portable way in CL to get the name (or names) of a function given a function definition object. If we are going to model class object naming similarly to function naming (as the name SYMBOL-CLASS seems to indicate) then we should probably be consistent with the way functions are done, or suggest that a FUNCTION-NAME or a FUNCTION-NAMES function be introduced which provides similar functionality; otherwise, people may become confused. But see below for further thoughts. > .... > (setf (class-named 'n1) nil) > # > Is this really how we want to undo these bindings? Nothing else in Common > Lisp I can think of works this way (storing nil). Also, a minor nit, CL > requires that such a setf form return nil, not the former value. > I think its easy to see how this whole thing would work for > generic-function-name, symbol-function, setf of symbol-function, > get-setf-generic-function and setf of get-setf-generic-function. > Agreed. Note that (setf (symbol-function 'foo) nil) isn't how we do > (fmakunbound 'foo) in CL currently. Your observation about undoing bindings is correct, and, again, to maintain consistency, CMAKUNBOUND would be the way do this if class name to object binding is modelled on function name to object binding. We seem to be slowly drifting towards using a name to object binding for classes which is modelled on the way function name to object bindings are handled. I wonder how useful the function model is for modelling class name to object bindings. In particular, is this going to lead to the proposal of a "class cell" like the "function cell" for a symbol? Considering the controversy surrounding the latter, I certainly hope not. Somehow, I would prefer a more object-oriented approach to resolving this problem. Two ways which I can think of offhand are: 1) Have the class name be a SETFable slot in the class object. SETFing a class object's name slot to NIL would be equivalent to making the class anonymous, if we abide by the convention that asking for the name of an anonymous class returns NIL (as was discussed in another note string). 2) Have the name to class object binding for an entire class be handled by the metaclass protocol. Of the two, I prefer the second one, since it gives some flexibility for users wanting to define new metaclasses, and also gives some potential for resolving the compile time name to object mapping, since the metaclass can potentially control this, but perhaps in an implementation dependent manner. I'm willing to write up a proposal on this, if there is any interest. Though I prefer a more object-oriented approach, I think it is important that the name to object mapping issue be resolved in a way that is self consistent and consistent with the rest of Common Lisp. jak  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Aug 87 18:20:26 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Aug 87 15:14:01 PDT Received: from Semillon.ms by ArpaGateway.ms ; 09 AUG 87 15:14:26 PDT Date: Sun, 9 Aug 87 15:14 PDT From: Gregor.pa@Xerox.COM Subject: Miscellaneous decisions taken or to be taken To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870809151423.5.GREGOR@SPIFF.isl.parc.xerox.com> Line-fold: no Date: Thu, 6 Aug 87 22:30 EDT From: David A. Moon I have updated my file of miscellaneous decisions taken or to be taken, based on my notes from the meeting we had in July and on mail received in response to the last time I mailed this out (about two weeks ago). In the usual way, I have included only parts of your message on which I am making specific comments. In several places I have sketched proposal which were on my to do list. I am about to go away for a week and don't have time between now and then to flesh these proposals out, but I think they are fairly clear from the sketches. 10 June 87 There was no response when Sonya mailed out a writeup for how the standard type classes are organized. Does that mean we agreed on that? Patrick agrees 7/29/87. It's in the document file now. I have it on my list of things to do to come up with a picture of how all the standard classes (including standard type classes) are organized. I have this on the whiteboard in my office now. In a separate message, I will send out the name of a press file which contains a simple version of such a picture. If people could FTP that press file and try printing it, then I could now if its worth trying to cast the whole picture in that format. p1-18 It is not specified whether get-setf-generic-function is a setf-able form. I suggest that it be made so. This would allow one to trace setf-generic-function's without having to know their names. This set off a discussion of how TRACE should work that maybe doesn't bear directly on CLOS. Kempf is working on a proposal. Moon thinks this would be okay provided it is understood as setting the mapping from a name to a generic function, not side-effecting the generic function. See class-name discussion below (2-13). Yes, I believe get-setf-generic-function should be a setfable form with the same provision as Moon mentions. The way to think of get-setf-generic-function is just like symbol-function and symbol-class. (This may mean that it would be appropriate to rename it to symbol-setf-generic-function.) Later in this message, I will make some other comments which address this issue. p1-24 Should we have a call-next-method? which calls such a next method if it exists, else returns nil (rather than signalling an error?). This seems useful rather than having to define many base methods on object. Common Lisp reserves question mark for the user; this could be named CALL-NEXT-METHOD-OR-NIL, or something like that. Kempf: signalling an error is sufficient, this probably isn't needed. In July we wondered whether there should be a way to get a list of the remaining methods. I'm not sure what operations on that list, besides checking its length, would be permitted. I am not sure what you mean by this. Surely other non-destructive operations would be legal as well. For example, one could implement some sort of "tracing" :around method by having it get the list of next methods, and calling each of their functions. But clearly it would not be legal to rplaca or rplacd that list. 2-13(?) The generic function class-name is not written up. It returns a name for the class as argument. I believe that (class-name class) should be setf-able. Can a class have more than one name? Should class-name then return a second argument -- the rest of the names this class is known by. Kempf thinks the class name should be changeable and only one name at a time should be allowed. Moon agrees. See additional discussion of class names below (2-13). As I said in another message, I don't believe class-name should be setfable. symbol-class (nee class-named) should be setfable, it is possible that it should update class-named as well, the details of how that updating might work were the subject of my other message. Even if we decide that class-name should return at most one name, I think it is clear that a class can have more than one name. That is, it is legal to use setf of symbol-class to make the multiple symbols point to the same class. p2-35 The argument order of the setf method ought to be documented here. Gregor proposed that new-value be the first argument. Any problem with this? Kempf doesn't care but his users want it to be the second argument. Moon doesn't care but his users are used to it being the last argument. In July we suggested making the new-value argument a required argument that comes after all the other required arguments, and before the optional, rest, and keyword arguments. Then we said we'd discuss it further in the mail. I think we agreed that the turning of two setf argument lists into one should depend only on the argument lists, and not on the generic function object. [My notes include an illegible comment, I think it means that I still hope we can keep things abstract enough that we don't have to document how the two setf argument lists are turned into one. But maybe it means that we will document it, but still have defmethod-setf so that most users don't have to think about it (only users making setf methods "directly").] I have several coments. First, I believe it is very important that this operation only be a function of the two lambda lists. Second, I would rather the rules of this operation be documented. That is, I would not be as happy if we just provided a function (make-setf-method-lambda-list) which did the work. Providing that function in addition to documenting its behavior might be a good idea though. Third, as we agreed, its fine with me to have it be the last required argument. But I think we need to be careful how we word this. Because we have to make it clear what happens in implementations which have non-standard lambda-list-keywords. p2-54 slot-missing should be documented It's a generic function of a class, an object, and a slot name. I suppose the default method signals a condition of the same name? Gregor will propose the details. slot-missing is a generic function which takes three required arguments and an optional fourth argument. The three required arguments are the class of the object, the object and the name of the slot. The fourth argument is the new value for the slot if slot-missing is being called by setf of slot-value. This set of arguments allows people to define methods on the metaclass for handling slot-missing. For example, a low performance implementation of dynamic slots could work this way. (defmethod slot-missing ((class dynamic-class) obj slot &optional (nv nvp)) (if nvp (set-dynamic-slot obj slot nv) (get-dynamic-slot obj slot))) The default method on slot-missing signals an error of the same name. 2-6 call-next-method dynamic versus indefinite extent The document says it has dynamic extent; we need to be sure that we really mean that. In July we said "implementation flexibility, not really a language thing", but I'm damned if I can figure out what that means (optimizing calculation of the effective method?). I am pretty sure what we meant was we didn't want to have to worry about the case where someone returns a closure that includes a call to call-next-method, and then redefines the class or method structure so that the closure would have to call different 'next methods'. 2-13 class-named needs a new name for consistency. get-class would be wrong because the other get-xxx functions aren't name operations. symbol-class is the agreed name. It needs an environment argument to deal with the issue of compile environment versus run-time environment. The errorp argument gets in the way, because it's an optional argument--we could get rid of it, or we could make both arguments keywords. I think we agree that symbol-class should be setf'able, but can it only be set once for a given symbol or is it allowed to change the symbol-to-class-object mapping? Kempf: Need consensus on a general solution of the compile environment issue before fixing individual functions such as symbol-class. The symbol-to-class-object mapping should be changeable. Bobrow: symbol-class should be setf'able. Gregor: setf'able. Issue is consistency of symbol-class with class-name. 1) No class-name. 2) No consistency. 3) class-names returns a list of names and setf of symbol-class maintains it. 2 is unreasonable. I like 1 but 3 is good too. (setf (class-named 'n1) nil) is how you undo the binding. Note that this same analysis applies to generic-function-name and setf of symbol-function and get-setf-generic-function. Bobrow: I like 3. Moon: class-names would need an environment argument too. I guess any of these is okay but 2 is how everything else works. I don't like undoing the binding by setting to NIL (CL Cleanup may propose a general mechanism for undoing named definitions). If this whole mess isn't an argument for a lisp-1 I don't know what is. At this point I guess we need: symbol-class symbol-setf-generic-function (both of the above need to be setfable) (there needs to be a mechanism for making each unbound) (we need to decide how they interact with class-name and generic-function-name) 2-16 boa-arglist should support &key and &allow-other-keys. 2-18 default boa-arglist to be specified The current initialization proposal doesn't have constructors? 2-40 get-setf-generic-function needs an errorp, but it and ensure-generic-function should be subsumed by get-generic-function which would do all the right things. We seem to have lost Gregor's proposal for get-generic-function. Or was it called ensure-generic-function? Gregor promised to mail out the proposal. I propose that we keep get-setf-generic-function, but that we rename it to symbol-setf-generic-function. In addition, I propose that we do the following: ensure-generic-function, add-named-method and any other CLOS function that takes the name of a generic function as an argument can also take a list like (SETF ) which means the setf-generic function for that argument. I propose that ensure-generic-function do basically what defgeneric-options and defgeneric-options-setf used to do except that ensure-generic-function would be a function (that is it would evaluate its arguments). This isn't a problem since defgeneric-options didn't take any &body arguments anyways. The real thing that needs to be worked out here is what happens if the generic function already exists, but is different in some ways than the description in the arguments to ensure-generic-function. 2-57 with-slots :prefix package problem; This was discussed in the mail and then the ball was dropped. What's in the document is unworkable because it depends on the dynamic value of *package* at macro-expansion time, but Common Lisp doesn't guarantee anything about when macro-expansion occurs. Moon would prefer to flush the :prefix option. An alternative that was discussed was to use symbol-package of the prefix, both here and in defclass accessor construction, as the package, relying on the likelyhood of prefixes always ending in delimiter characters and exported symbols never ending in delimiter characters. July: We agreed to resolve this in the mail. Kempf, Moon: Flush :prefix. I like the prefix option, although I agree that this is a serious problem. 2-57 What does with-slots do for slots that exist in the class but don't have accessors, when :use-accessors t is specified (or defaulted)? July: it shadows any outer bindings of the slot name, and if you actually access that pseudo-variable, it signals an error. What if by the time you actually run the body of the method, the slot has an accessor. That is to say, what if you do the following: (defclass foo () (a b c)) (defmethod bar ((o foo)) ;Put this in a file, (with-slots (o) (list a b c))) ;compile and load it. (defclass foo () (a b c) (:accessor-prefix foo-)) (bar (make-instance 'foo)) Does this signal an error? It seems to me that the real problem with this case is the same as the real problem with the above case. It all hinges on exactly when macro-expansion time is and that is not specified. Other issues: What can be done with method objects, e.g. can one method be added to more than one generic function? I believe it should signal an error to attempt to put a method on more than one generic function. My model of this is that if you want to do something like that, you can take one function, use it as the method function of multiple methods, each of which would be on a different generic function. I'm not sure if we said anywhere what happens when you call a generic function and there is no applicable method; I think it ought to signal an error. Gregor volunteered to send some mail about this. This is a generic function like slot-missing. There is a generic function NO-MATCHING-METHOD which is called with the generic function as the first argument and the arguments to the generic function as the remaining arguments. This allows people to defined method to handle the no matching method case either on the class of the generic function or on the individual generic function. The default method for no-matching-method signals an error of the same type. -------  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 7 Aug 87 22:02:35 EDT Received: from Catawba.ms by ArpaGateway.ms ; 07 AUG 87 16:22:13 PDT Return-Path: Redistributed: CommonLoops.pa Received: from XX.LCS.MIT.EDU by Xerox.COM ; 07 AUG 87 15:54:29 PDT Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 7 Aug 87 15:44-EDT Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 54906; 7 Aug 87 15:27:51-EDT Date: Fri, 7 Aug 87 14:43 EDT From: RpK%acorn@LIVE-OAK.LCS.MIT.EDU Subject: COERCE To: CommonLoops.pa@Xerox.COM Message-ID: <870807144321.1.RPK@ACORN.Gold-Hill.DialNet.Symbolics.COM> I haven't been following discussion of the how closely integrated Common Loops/CLOS should be with Common Lisp, but it seems to me that that the CLASS-CHANGED generic function can help extend COERCE in a powerful manner. Comments ?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Aug 87 22:38:01 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87 19:29:18 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208512; Thu 6-Aug-87 22:29:57 EDT Date: Thu, 6 Aug 87 22:30 EDT From: David A. Moon Subject: Miscellaneous decisions taken or to be taken To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870727224638.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <870806223002.9.MOON@EUPHRATES.SCRC.Symbolics.COM> I have updated my file of miscellaneous decisions taken or to be taken, based on my notes from the meeting we had in July and on mail received in response to the last time I mailed this out (about two weeks ago). If anyone doesn't see their response included, or thinks their favorite issue is missing, please let me know and I will apologize for my error and add it. I hope that we can use this file to help drive progress. The major issues of object creation and class redefinition are not in here, being handled individually. The rest of this message is the file. Page separator characters don't seem to go through, so I have replaced each with 16 equal signs. This page is things that I think we agreed that we had decided after the March meeting and before the July meeting. 27 May 87 call-next-method is allowed to take arguments, however it is an error to give it arguments that would change the set of applicable methods. I think we're saying this signals an error, and mentioning that in some simple cases the lack of need for an error check can be proved at compile time, but in general a run-time check is required. Specify precisely the type of error signalling. 10 June 87 There was no response when Sonya mailed out a writeup for how the standard type classes are organized. Does that mean we agreed on that? Patrick agrees 7/29/87. It's in the document file now. p2-19 Values: I thought we agreed that all top level forms should return the object. It says here defclass "returns the name of the class" p2-22 Same comment as 2-19, for defgeneric-options 2-24 ditto for defgeneric-options-setf Kempf agrees they should return the object. Moon isn't sure, because defun, defvar, deftype, and defstruct return the name. As far as I can tell every defxxx form in CLtL returns the name. The problem is that we haven't admitted that defmethod has a name. In July we decided (for the previous three) to return the object for all CLOS defxxx functions (being inconsistent with Common Lisp, but consistent within CLOS). The document file has been updated. ================ This page is a list of issues on which we should make decisions, brought up by Danny. Where I saw responsive answers in the mail (there were very few) I have edited them in. I've removed comments that were purely editorial comments on the document. p1-12 Should defclass be allowed to change the metaclass of an existing class? Under what conditions should a subclass of standard-class have the same properties wrt instance updating as standard class? Kempf says you shouldn't be allowed to change the metaclass, because the representations might differ and existing instances might not be transformable. Gregor says the metaclass protocol includes a predicate function that controls this, and Patrick and Jim agree. p1-17 "It is currently under discussion whether to provide constructs for giving generic functions local names." Do we want to have this discussion, or to punt on this syntax. I recall we did come up with some reasonble semantics for a GFLET and GFLABELS. In July we decided to defer this. 2 Aug 87 RPG offered to write a proposal. p1-18 It is not specified whether get-setf-generic-function is a setf-able form. I suggest that it be made so. This would allow one to trace setf-generic-function's without having to know their names. This set off a discussion of how TRACE should work that maybe doesn't bear directly on CLOS. Kempf is working on a proposal. Moon thinks this would be okay provided it is understood as setting the mapping from a name to a generic function, not side-effecting the generic function. See class-name discussion below (2-13). p1-19 "... Common Lisp be modified to include the following semantics for quote in a type specifier: (deftype quote (object) '(member ,object)))" Has any proposal for this been given to the cleanup committee? Yes: ISSUE: TYPE-MEMBER-SINGLETON, Proposal TYPE-MEMBER-SINGLETON:QUOTE It hasn't really gone through the mill yet, though. In July Moon volunteered to make sure this happens. p1-24 Should we have a call-next-method? which calls such a next method if it exists, else returns nil (rather than signalling an error?). This seems useful rather than having to define many base methods on object. Common Lisp reserves question mark for the user; this could be named CALL-NEXT-METHOD-OR-NIL, or something like that. Kempf: signalling an error is sufficient, this probably isn't needed. In July we wondered whether there should be a way to get a list of the remaining methods. I'm not sure what operations on that list, besides checking its length, would be permitted. 2-13(?) The generic function class-name is not written up. It returns a name for the class as argument. I believe that (class-name class) should be setf-able. Can a class have more than one name? Should class-name then return a second argument -- the rest of the names this class is known by. Kempf thinks the class name should be changeable and only one name at a time should be allowed. Moon agrees. See additional discussion of class names below (2-13). We need to decide whether class-name of an anonymous class is nil or signals an error. The concensus seems to be to return nil. p2-26 I believe that short form method combination ought to be a macro in the standard library, and documented there, not in the basic principles. I think the standard combinations :append, :and, :or, ... should also be put in the standard library too. Kempf agrees. Moon can't have an opinion until he knows what this library is and whether it's going to be as much of a joke as the Common Lisp Yellow Pages. p2-35 The argument order of the setf method ought to be documented here. Gregor proposed that new-value be the first argument. Any problem with this? Kempf doesn't care but his users want it to be the second argument. Moon doesn't care but his users are used to it being the last argument. In July we suggested making the new-value argument a required argument that comes after all the other required arguments, and before the optional, rest, and keyword arguments. Then we said we'd discuss it further in the mail. I think we agreed that the turning of two setf argument lists into one should depend only on the argument lists, and not on the generic function object. [My notes include an illegible comment, I think it means that I still hope we can keep things abstract enough that we don't have to document how the two setf argument lists are turned into one. But maybe it means that we will document it, but still have defmethod-setf so that most users don't have to think about it (only users making setf methods "directly").] p2-39 Arguments: "list of t's" should be replaced by "list whose elements are the class named t" since get-method only takes specializers, not names of specializers. Agreed. p2-46 Last line: If call-next method is extended ..." I see no reason for additional keyword arguments. Moon doesn't remember the issue. It may have been consistency; if call-next-method can specify the arguments, then so can make-method-call. You need one keyword argument to specify the methods and another to specify funcall versus apply. It could also have been that call-next-method would be implemented in terms of make-method-call, and therefore would need to be able to specify the arguments. p2-51 print-object should take a depth argument. Moon strongly disagrees and points to the fourth bullet. I believe this issue was discussed to death on the Common Lisp mailing list a few months or a year ago. The point is that every single method for print-object should not have to deal with *print-level*; that's unmodular. Kempf raised a consistency argument (with defstruct?) but we decided not to change print-object. p2-54 slot-missing should be documented It's a generic function of a class, an object, and a slot name. I suppose the default method signals a condition of the same name? Gregor will propose the details. ================ This page is a list I made in March, keyed by page numbers in the document. Issues mentioned earlier, or that have since died, have been removed. I've removed comments that were purely editorial comments on the document. 2-6 call-next-method dynamic versus indefinite extent The document says it has dynamic extent; we need to be sure that we really mean that. In July we said "implementation flexibility, not really a language thing", but I'm damned if I can figure out what that means (optimizing calculation of the effective method?). 2-9 semantic difficulties discussion was shortened for the document so much that much of the point was lost. At some point we need to decide how much we want to standardize about this and where we want to say it; in the main standard or in some kind of implementation guide. 2-13 class-named needs a new name for consistency. get-class would be wrong because the other get-xxx functions aren't name operations. symbol-class is the agreed name. It needs an environment argument to deal with the issue of compile environment versus run-time environment. The errorp argument gets in the way, because it's an optional argument--we could get rid of it, or we could make both arguments keywords. I think we agree that symbol-class should be setf'able, but can it only be set once for a given symbol or is it allowed to change the symbol-to-class-object mapping? Kempf: Need consensus on a general solution of the compile environment issue before fixing individual functions such as symbol-class. The symbol-to-class-object mapping should be changeable. Bobrow: symbol-class should be setf'able. Gregor: setf'able. Issue is consistency of symbol-class with class-name. 1) No class-name. 2) No consistency. 3) class-names returns a list of names and setf of symbol-class maintains it. 2 is unreasonable. I like 1 but 3 is good too. (setf (class-named 'n1) nil) is how you undo the binding. Note that this same analysis applies to generic-function-name and setf of symbol-function and get-setf-generic-function. Bobrow: I like 3. Moon: class-names would need an environment argument too. I guess any of these is okay but 2 is how everything else works. I don't like undoing the binding by setting to NIL (CL Cleanup may propose a general mechanism for undoing named definitions). 2-16 (slot-name form) should be allowed as an abbreviation for (slot-name :initform form). People have been assuming this, but it never finds its way into the document. In July we rejected this. Since people keep assuming it, we have to document explicitly that it is not allowed. 2-16 boa-arglist should support &key and &allow-other-keys. 2-18 default boa-arglist to be specified 2-18 (:accessor-prefix nil) is not a good way to say "use the slot names as the accessor names". We need to fix this. We could add another option, or remove the whole prefix feature, and require accessor names always to be listed explicitly. In July we agreed to discuss this in the mail. 2-19 uninitialized slots should be an error to reference, not be defined to return an unstandardized value with no error. I'm willing not to require that it signals an error if people feel that would be an undue burden, otherwise I prefer that reading an uninitialized slot signals an error. In July we decided that signalling an error here should depend on the declared safety level. Dick has proposed terminology for this. Kempf: it should signal an error. 2-38 need a way to recover documentation of a method-combination type July: do this by adding a new value for the second argument to DOCUMENTATION. But the whole writeup on DOCUMENTATION is screwy, and we need a new proposal. When the CL-Cleanup subcommittee finishes cleaning up the concept of "definition" (I think it's waiting for Masinter to propose something) then DOCUMENTATION should follow. 2-40 get-setf-generic-function needs an errorp, but it and ensure-generic-function should be subsumed by get-generic-function which would do all the right things. We seem to have lost Gregor's proposal for get-generic-function. Or was it called ensure-generic-function? Gregor promised to mail out the proposal. 2-42 make-generic-function should be deleted, redocumented as a class that can be given to make-instance July: Agreed 2-45 make-method should be deleted, redocumented as a class that can be given to make-instance July: Agreed 2-57 with-slots :prefix package problem; This was discussed in the mail and then the ball was dropped. What's in the document is unworkable because it depends on the dynamic value of *package* at macro-expansion time, but Common Lisp doesn't guarantee anything about when macro-expansion occurs. Moon would prefer to flush the :prefix option. An alternative that was discussed was to use symbol-package of the prefix, both here and in defclass accessor construction, as the package, relying on the likelyhood of prefixes always ending in delimiter characters and exported symbols never ending in delimiter characters. July: We agreed to resolve this in the mail. Kempf, Moon: Flush :prefix. 2-57 What does with-slots do for slots that exist in the class but don't have accessors, when :use-accessors t is specified (or defaulted)? July: it shadows any outer bindings of the slot name, and if you actually access that pseudo-variable, it signals an error. ================ Documented holes in chapters 1 and 2 of 87-002. We publicly promised X3J13 that we would finish these and have a new draft of 87-003 by the next meeting. 1-5, 2-44 The initialization protocol for make-instance is not yet specified. 1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes is still under discussion. Document has been updated in draft. Need Cleanup Committee proposals for fixes to the type system. 2-7, 2-46 [The proposed extension to call-next-method has been accepted.] This may not have been put into the document yet. 2-41, 2-48 [Perhaps we can adopt the condition signalling system now.] ================ Other issues: What can be done with method objects, e.g. can one method be added to more than one generic function? Kempf: There may be a problem if the method invokes CALL-NEXT-METHOD. [I wasn't able to understand his description of the problem -- Moon] Ida: make-specializable seems to be missing Gregor's proposal for ensure-generic-function will subsume this. Moon: method arglist congruence still doesn't satisfy me. I have some ideas about this but unfortunately have not managed to pull them together. To be resolved as part of the initialization protocol discussion. Should we just flush multiple-value-prog2, as leading to more discussion than is warranted by its simplification of the presentation of define-method-combination? Kempf: Yes. Which symbols defined by the standard go in what package? July: I think we said some will go in LISP: and some will go in CLOS: and we don't know yet where to draw the line. The top level macros and functions should be part of LISP. The internal functions specified for the sake of metaclass programming can reside in CLOS. If CLOS is an optional part of CL, are the symbols in the LISP package even when the option is not present? Probably. Should we flush defmethod-setf and friends in favor of function specs? It probably turns out they could be just in the macros and not in the underlying Lisp. The big issue is standardizing where the "new-value" argument goes; but we may do that anyway (mentioned earlier in this file). What about the setf of values extension that Common Lisp provides syntactic space for but does not currently prescribe? Kempf: I think we ought to keep DEFMETHOD-SETF, but use function specs (or something like them) as the programmer interface to TRACE. Should we adopt the :component-order class-option from Flavors, as a simple way for the user to have control of the CPL without making him write his own algorithm? Gregor doesn't like the ability to specify constraints on the ordering of classes that only apply conditionally, i.e. if those classes are actually present among the superclasses. He considers this bad style. Moon volunteered to write a proposal with some examples, and we agreed to resolve this over the mail. The fact that symbol-function (the user callable primitive) needs to be split from the subprimitive for implementators that gets and sets the "real" function definition of a symbol. This is so when a symbol's function definition is a generic function object, the "real" definition can be something that is easier for the implementation to call. July: We need to say explicitly somewhere that calling symbol-function of the name of a generic function is required to return the generic function object, not the "real" definition. Kempf: I don't see splitting SYMBOL-FUNCTION as an issue for the standard, though it may be for certain implementations. Moon: Right, the only standardization issue is making sure SYMBOL-FUNCTION returns the generic function object, not something internal. See earlier discussion of class-names (2-13), which affects symbol-function. I'm not sure if we said anywhere what happens when you call a generic function and there is no applicable method; I think it ought to signal an error. Gregor volunteered to send some mail about this. CALL-NEXT-METHOD with no more methods should do something similar, but not identical. We could call a generic function like NO-MATCHING-METHOD, but it would be better to signal a condition (assuming conditions are adopted into Common Lisp). The error message should give some information about the classes of the parameters, to help debugging. Clarify that because class names and classes are type-specifiers, they can be validly be used in THE special forms and in TYPE declarations. We forgot this when we clarified that class objects can be used with TYPEP and SUBTYPEP. July: agreed funcallable-standard-class should be documented. It is a metaclass. This is what makes generic function objects funcallable. There is a slot that is the actual function that gets called. I think Gregor volunteered to propose details. Need to be able to get at the obsolete classes associated with a class, to put methods on them. Patrick has proposed. Need discussion of how instances are transformed one step at a time when a class has been redefined multiple times. Not all of the "corrections and amendments" handed out at the March 1987 X3J13 meeting in Palo Alto have been put into the document yet. The corrections are in but the amendments and the revised explanation of slot inheritance are awaiting review by the group. Kempf 29 Jul 87: There was no mention made of compile time optimization, which I believe I made some initial proposals on in late April or early May. I've been meaning to revisit them. 2-30: Note the third paragraph on p.2-30 of 87-002, speaking of signalling an error when the arbitrary order of two methods affects the result. I suggest that this error be mandatory instead of optional.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Aug 87 22:19:34 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87 19:14:07 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208497; Thu 6-Aug-87 22:14:54 EDT Date: Thu, 6 Aug 87 22:14 EDT From: David A. Moon Subject: Re: Name That Class To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <870728-192157-1316@Xerox> Message-ID: <870806221457.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 28 Jul 87 19:21 PDT From: Gregor.pa@Xerox.COM It seems to me that there are ways for class-named and setf of such to work. I think only two of these are reasonable, but I will include the third for completeness. Note that this same analysis applies to generic-function-name and setf of symbol-function and get-setf-generic-function. I will do class names first. A class C 'is bound to' a given name Ni iff (class-named Ni) returns C. In all this solutions, we document class-named and setf of class-named. We say that class-named returns the class is bound to a particular name. We say that setf of class-named can be used to set the binding of a class to a name. All agreed, except I think we decided a month ago to rename class-named to symbol-class, to be more consistent with the rest of Common-Lisp. Solution 1: Only document class-named and setf of class-named. Most implementations will have some magic for printing out a class's name when it has one. Solution 2: Document class-named and setf of class-named. Also document class-name, but say that the the class may or may not 'bound' to that name. Solution 3: Document class-named and class-names and setf of class-named. Say that setf of class-named can be used to bind a clas to a name. Say that class-names returns the list of all names that a class is bound to. It seems to me that solution 1 and solution 3 are the only reasonable ones. My general dislike of names makes me prefer solution 1, but I think that solution 3 actually provides users some important functionality. That's interesting, because I prefer solution 2, for the simple reason that everything else I can think of that has a name works that way. The symbol->object mapping is the "real" one, and the object->symbol mapping is only a helpful hint for printing things out, but isn't necessarily kept consistent with the symbol->object (a programming environment might try to keep it consistent). As far as I am concerned, any of these three would work. My objection to solution 3 is primarily that it is more complicated. My objection to solution 1 is that it is the same as solution 2 as soon as the users discover what the name of the class-name function is, and no useful purpose is served by making this name implementation-dependent. .... (setf (class-named 'n1) nil) # Is this really how we want to undo these bindings? Nothing else in Common Lisp I can think of works this way (storing nil). Also, a minor nit, CL requires that such a setf form return nil, not the former value. I think its easy to see how this whole thing would work for generic-function-name, symbol-function, setf of symbol-function, get-setf-generic-function and setf of get-setf-generic-function. Agreed. Note that (setf (symbol-function 'foo) nil) isn't how we do (fmakunbound 'foo) in CL currently.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Aug 87 15:55:20 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87 12:49:12 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208071; Thu 6-Aug-87 14:09:57 EDT Date: Thu, 6 Aug 87 14:10 EDT From: David A. Moon Subject: TRACE Proposal (Version 1) To: kempf%hplabsz@hplabs.HP.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU, Masinter.pa@XEROX.COM In-Reply-To: <8707311807.AA10361@hplabsz.hpl.hp.com> Message-ID: <870806141000.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: Fri, 31 Jul 87 12:07:37 MST From: kempf%hplabsz@hplabs.HP.COM As promised, here is an initial draft of a proposal for modifying the TRACE macro (CLtL, pp. 440-441) to better support object-oriented programming.... This looks interesting. I have a couple of comments to offer right now. A function-spec is either a symbol naming a function (i.e. a symbol whose global function cell is bound to a function definition object) or a list whose first element is a function specification type, and whose tail indicates which particular function of that type should be traced. The Cleanup subcommittee of X3J13 were discussing something similar a while back, starting from a different point. The DOCUMENTATION function of Common Lisp introduces the concept of "definition types", and this concept could be useful in other operations. For instance, it would be nice to be able to remove any definition (function, variable, type, setf) through a uniform interface. "Definition type" and "function spec type" are not the same concept, however there seems to be enough overlap here that some coordination is probably called for. I don't remember for sure, but I think Larry Masinter volunteered to make a proposal for "definition types" when he got time. .... Note: Another useful enhancement would be to support a :BREAK flag, like this: (:METHOD :BREAK) indicating that a break loop should be entered before and after the function executes. Here you see a conflict between lists as function-specs and lists as lists of options, in the arguments to TRACE. Because of this your proposal for TRACE is not compatible with what Symbolics currently does, but I don't think that's too important for us. We say that a list is a list of options, and if you want to trace a function whose name is a list, you have to do (TRACE (:function ...)). But all this really shows is that the syntax of TRACE is ridiculous. I usually ignore the TRACE function and trace things through a command interface. Anyway, for your proposal you have to decide between lists as function specs and lists as options; I don't think you can mix them freely as you proposed. Of course it would be a lot easier if TRACE only traced one function at a time, then the rest of the form could be used for options. That would be a bit incompatible with CLtL. TRACE-EXECUTION object &OPTIONAL env [Generic Function] I didn't completely understand this. It looks like there is some incoherence about whether TRACE is an operation on functions or on places in which you can store a function definition. In other words, does tracing a function redefine the function or alter the object that is the function's definition? In other words, does (defun foo () ...) (setq f #'foo) (trace foo) (funcall f) generate trace-output or not? We have to decide one way or the other. CLtL is obscure on this point.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Aug 87 15:55:04 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87 12:48:53 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208062; Thu 6-Aug-87 13:55:31 EDT Date: Thu, 6 Aug 87 13:55 EDT From: David A. Moon Subject: Miscellenia To: Common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 2 Aug 87 20:25 EDT from Dick Gabriel Message-ID: <870806135534.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 02 Aug 87 1725 PDT From: Dick Gabriel Moon writes: ``p1-17 "It is currently under discussion whether to provide constructs for giving generic functions local names." Do we want to have this discussion, or to punt on this syntax. I recall we did come up with some reasonble semantics for a GFLET and GFLABELS.'' I am willing to write up a proposal for this, basing it on our latest thoughts from the mail, if people wish. I do not feel strongly about this at the moment. Please do write the proposal. But I wouldn't consider this high priority at the moment, since you don't feel strongly about it and no one else has said they feel strongly.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Aug 87 20:56:47 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Aug 87 17:51:40 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 05 AUG 87 17:48:48 PDT Date: 5 Aug 87 17:48 PDT From: Kelley.pa@Xerox.COM Subject: Re: ECOOP Reaction to CLOS In-reply-to: Jim Kempf 's message of Thu, 9 Jul 87 13:24:38 pdt To: kempf%hplabsz@hplabs.HP.COM Cc: common-lisp-object-system@sail.stanford.edu Message-ID: <870805-174848-5665@Xerox> In dealing with the intractability of the effect of the proposed CLOS mechanism for multiple inheritance, violation of the "implicit inheritance - explicit override" rule should be factored out of the complexity of the linearization algorithm. Each contribute to the complexity of the CLOS proposal, but hopefully by distinguishing them and dealing with each seperately, the total complexity can be reduced. The CLOS proposed standard explicitly claims in general to obey the implicit inheritance - explicit override rule, but it does not for multiple inheritance of slots and methods with the same name. Instead, it actually reverses the rule in this case. Overriding is implicit and one must explicitly inherit (via qualifiers). In as much as implicit inheritance is a sub-conscious assumption of application programmers, standard CLOS behaves in a counter intuitive manner. (defclass border (object) (width)) (defmethod close (b border) ...) (defclass window (object) (width)) (defmethod close (w window) ...) (defclass bordered-window (border window)) (setq b-window (make-instance 'bordered-window)) (close b-window) ; with the current inheritance algorithm, only closes the border. Does not close the window. The following explores what could happen if the implicit inheritance - explicit override rule were followed in CLOS. (close b-window) would result in both the border and window close methods getting called because it inherits them implicitly and has not explicitly overridden them. With implicit inheritance a class may have in addition to multiple methods with the same name that all get called by one call, multiple occurrences of a slot with the same name that are manipulated in one operation so b-window would contain two slots named width. (setf (slot-value b-window width) 0) Would set both slots to 0. A problem is what to do with the results of an operation on a slot name that refers to two or more slots or on a call that refers to two or more methods. Operating on these slots or methods that have not been overridden could be specified to return a "multiple-inheritance-result" object containing the multiple results. Any code that depended on the results from instances of singly inherited classes would not work correctly with instances of multiply inherited classes. (In the example above, any code that depended on the value returned by the "close" method on an instance of the window class would not work on an instance of the bordered-window class.) A blatant error would usually be generated at run time. A warning of potential such behavior at definition time might be a desireable feature. All the unqualified inherited methods with the same name would still have to get executed in some order. However, it would be possible to simply specify that these operations are executed in a random order. -- kirk  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Aug 87 01:48:07 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Aug 87 22:43:16 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 4 Aug 87 14:52:14 pdt Received: from hplabsz.hpl.hp.com by hplms2; Tue, 4 Aug 87 14:51:51 pdt Return-Path: Received: from hplabsz by hplabsz; Tue, 4 Aug 87 15:52:31 pdt Message-Id: <8708042152.AA10558@hplabsz.hpl.hp.com> To: Danny Bobrow Cc: common-lisp-object-system@SAIL.STANFORD.EDU, olthoff%hplabsz@hplabs.HP.COM Subject: Re: Technical corrections in 87-002 X-Mailer: mh6.5 In-Reply-To: Your message of 28 Jul 87 15:02:00 -0700. <870728-150405-2277@Xerox> Date: Tue, 04 Aug 87 15:52:27 MST From: kempf%hplabsz@hplabs.HP.COM Sorry it's taken so long to answer this. JAK> As a counterexample, consider R := {(c1,c2) (c2,c3) (c3 c5) (c2 c4) (c4 JAK> c6)} This is, in fact, incorrect, as Danny pointed out. It should be: R = { (c1,c2),(c2,c3),(c3,c4),(c3,c5),(c4,c6) } by the algorithm at the top of pg. 1-14. But see below for more. JAK> The inheritance graph for this is; JAK> c5 c6 JAK> | | JAK> c3 c4 JAK> | | JAK> \ / JAK> \ / JAK> c2 JAK> | JAK> c1 DB> This counterexample is wrong in that the inheritance graph must specify DB> a local ordering of c3 and c4 (if vertical means direct superclass and DB> horizontal is an ordered list. The intention was that the numbers would indicate the local precedence ordering. Thus the CLOS definitions would look like: (defclass c6 () ...) (defclass c5 () ...) (defclass c4 (c6) ...) (defclass c3 (c5) ...) (defclass c2 (c3 c4) ...) (defclass c1 (c2) ...) In fact, the counterexample is wrong, but the interesting fact is WHY. The counterexample was generated by looking at the pie example on pg. 1-15, where R is given as: R = { (pie,apple) (pie,cinnamon),(apple,cinnamon),(apple,fruit), (cinnamon,spice),(fruit,food),(spice,food),(food,t) } However, this is incorrect. The correct value of R before the start of CPL construction is: R = { (pie,apple),(apple,cinnamon),(apple,fruit),(cinammon,spice), (fruit,food),(spice,food),(food,t) } This follows by merging the R(C) for each of the classes: R(pie) = { (pie,apple),(apple,cinnamon) } R(apple) = { (apple,fruit) } R(cinnamon) = { (cinnamon,spice) } R(fruit) = { (fruit,food) } R(spice) = { (spice,food) } R(food) = { (food,T) } Thus the entry (pie,cinnamon) in R is incorrect, and leads to a lack of the local precedence order being reflected in R. The R in the counterexample was constructed directly from this example. Perhaps someone has noted this before and corrected it. In any event, I suspect that some of the confusion expressed by Sherlis and others at the March meeting may have been a result of trying to understand the algorithm via the example. We have had several people here run into that problem. DB> The partial order relationship that Dick defines is the one using the DB> relation "is the same or is subclass of" This one is reflexive, though DB> we don't have a simple name for it. This relationship should be sufficient, but I think it should be made explicit on the top of pg. 1-14. We need not have a simple name, as long as it is defined. Leaving it implict leaves room for confusion. I hope whoever is the current custodian of 87-002 can make these corrections. jak  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Aug 87 19:59:56 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 3 Aug 87 16:56:04 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 3 Aug 87 15:32:53 pdt Received: from hplabsz.hpl.hp.com by hplms2; Mon, 3 Aug 87 15:32:17 pdt Return-Path: Received: from hplabsz by hplabsz; Mon, 3 Aug 87 16:33:03 pdt Message-Id: <8708032233.AA06651@hplabsz.hpl.hp.com> To: Dick Gabriel Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Miscellenia In-Reply-To: Your message of 02 Aug 87 17:25:00 -0700. Date: Mon, 03 Aug 87 16:32:57 MST From: kempf%hplabsz@hplabs.HP.COM > > ``p1-17 "It is currently under discussion whether to provide constructs > for giving generic functions local names." Do we want to have this > discussion, or to punt on this syntax. I recall we did come up with some > reasonble semantics for a GFLET and GFLABELS.'' > I am willing to write up a proposal for this, basing it on our latest > thoughts from the mail, if people wish. I do not feel strongly about > this at the moment. I also don't feel strongly about it at the moment, but a proposal would be good, if other people agree. Originally, there was some talk about a GFLAMBDA, but that didn't seem to make it into the document. If you're open for suggestions, a useful primitive that might address all these uses might be GFUNCTION, similar to the FUNCTION special form, except it takes multiple lambda's as arguments. > [Note: Hackers are proud of having invented the `mumble' convention. However, > there is rarely anything new under the sun. Here is a quote from the Saturday , > August 25, 1753 Adventurer by Samuel Johnson: > ``I remember,'' says he, ``it was on just such a morning as > this that I and my lord Mumble and the Duke of Tenterden were > out upon a ramble....'' > ``Tenterden'' is someone who tends a den.] Interesting. My English friends tend to use "doobrey" as an unbound in similar circumstances, viz. DEF. Perhaps, in the 200 odd years since we've been independent, the language has diverged, like the pronounciation of "clerk". I used to occasionally use "X" as an unbound, but, thanks to Bob Schieffler, that's out now. jak  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 3 Aug 87 18:05:37 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 03 AUG 87 14:49:41 PDT Date: 3 Aug 87 14:46 PDT From: Gregor.pa@Xerox.COM Subject: OOPSLA Lisp and Object-Oriented Programming Workshop To: CommonLoops.pa@Xerox.COM Reply-to: Gregor.pa@Xerox.COM Message-ID: <870803-144941-1933@Xerox> Many of you may have already seen the following message. To those people, I apologize for the duplication. It occurred to us that many people on this list may not have gotten an announcement of the CLOS workshop at OOPSLA. In order to give those people a chance to submit a position paper for this workshop, the deadline is being extended until September 1. Let me add that I encourage people who have extensive experience using PCL as a stand-in for CLOS to submit position papers for this workshop. From: Dick Gabriel Subject: OOPSLA Lisp and Object-Oriented Programming Workshop There will be a workshop on Lisp and Object-Oriented Programming on Monday October 5 from 9am until noon at OOPSLA. The Common Lisp Object System (CLOS) will be the highlight of the workshop, with presentations about CLOS by the designers along with critiques, analyses, and responses to the Object System, the latter selected based on contributed position papers. Attendance will be limited to people who know Lisp and are familiar with existing object-oriented languages. If you would like to attend, please send me a 1-2 page description of your position regarding either the Common Lisp Object System or Lisp/object-oriented programming before September 1; netmail is acceptable. Invitations will be sent on September 5. Attendance is limited to 35 people. Richard P. Gabriel Lucid, Inc 707 Laurel Street Menlo Park, CA 94025 (415)329-8400 rpg@sail.stanford.edu ----- End Forwarded Messages -----  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 3 Aug 87 16:10:18 EDT Received: from Salvador.ms by ArpaGateway.ms ; 03 AUG 87 12:58:24 PDT Return-Path: Redistributed: commonloops.pa Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by Xerox.COM ; 03 AUG 87 12:55:02 PDT Received: from bigburd.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (burdvax) [5.54/1.0] id AA18987; Mon, 3 Aug 87 15:54:42 EDT Received: by bigburd.PRC.Unisys.COM (bigburd) [5.54/1.0] id AA14712; Mon, 3 Aug 87 15:54:38 EDT From: fritzson@bigburd.PRC.Unisys.COM (Richard Fritzson) Message-Id: <8708031954.AA14712@bigburd.PRC.Unisys.COM> Received: from Ringmaster by bigburd with PUP; Mon, 3 Aug 87 15:54 EDT Date: 3 Aug 87 15:54 EDT (Monday) To: commonloops.pa@Xerox.COM Subject: redefinition problem Cc: fritzson@bigburd.prc.unisys.com This seems like the kind of problem which should have already been reported if it really is a bug, but I haven't found mention of it anywhere. It goes like this: If I mistakenly define point: (defclass point () ((xcoord :initform 0 :type string) (ycoord :initform 0 :type string)) (:accessor-prefix pos- ) (:documentation "Points on a cartesian plane.") ) so that the slots are typed as string instead of number then, after I do, (setq foo (make-instance 'point)) I find that (setf (pos-xcoord foo) 99) fails, but (setf (pos-xcoord foo) "99") succeeds. No surprises. But once I retype the declass expression, (defclass point () ((xcoord :initform 0 :type number) (ycoord :initform 0 :type number)) (:accessor-prefix pos- ) (:documentation "Points on a cartesian plane.") ) AND REDO THE SETQ FOO (setq foo (make-instance 'point)) I still find that (setf (pos-xcoord foo) 99) fails because "99 is not of type STRING".  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Aug 87 20:28:43 EDT Date: 02 Aug 87 1725 PDT From: Dick Gabriel Subject: Miscellenia To: Common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: ``p1-17 "It is currently under discussion whether to provide constructs for giving generic functions local names." Do we want to have this discussion, or to punt on this syntax. I recall we did come up with some reasonble semantics for a GFLET and GFLABELS.'' I am willing to write up a proposal for this, basing it on our latest thoughts from the mail, if people wish. I do not feel strongly about this at the moment. Moon writes: ``p2-19 Values: I thought we agreed that all top level forms should return the object. It says here defclass "returns the name of the class"'' I believe we originally tried to be consistent with all other DEFs in returning a name. I believe we decided it was ok to return an object in CLOS DEFs. [Note: Hackers are proud of having invented the `mumble' convention. However, there is rarely anything new under the sun. Here is a quote from the Saturday, August 25, 1753 Adventurer by Samuel Johnson: ``I remember,'' says he, ``it was on just such a morning as this that I and my lord Mumble and the Duke of Tenterden were out upon a ramble....'' ``Tenterden'' is someone who tends a den.] -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Jul 87 14:14:19 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 31 Jul 87 11:09:44 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Fri, 31 Jul 87 11:07:37 pdt Received: from hplabsz.hpl.hp.com by hplms2; Fri, 31 Jul 87 11:07:05 pdt Return-Path: Received: from hplabsz by hplabsz; Fri, 31 Jul 87 12:07:43 pdt Message-Id: <8707311807.AA10361@hplabsz.hpl.hp.com> To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: TRACE Proposal (Version 1) X-Mailer: mh6.5 Date: Fri, 31 Jul 87 12:07:37 MST From: kempf%hplabsz@hplabs.HP.COM As promised, here is an initial draft of a proposal for modifying the TRACE macro (CLtL, pp. 440-441) to better support object-oriented programming. The proposal is motivated by the expressed need of our applications programmers. Sometimes, they would like to only trace when a particular method is run, rather than tracing every method when the generic function is invoked. Additionally, some constructs in Common Lisp which are usually implemented as functions (macroexpansions, SETF's) are currently not tracable through the TRACE function, but rather require extra effort. There is obviously lots of room for implementation dependency here, and some things which would be nice to do portably (like tracing local function invocations) are difficult because Common Lisp doesn't have the right constructs (like no first class environments). The proposal is a combination of Moon's function spec idea, at the programmer interface level, and Danny's generic function idea, at the system level. I think most Common Lisp implementors probably include some help for tracing methods already, if they implement an object-oriented language. --------------------------------------------------------------------------------- TRACE &REST {function-spec}* [Macro] Invoking TRACE with one or more function specifications causes the functions specified to be traced. Henceforth whenever a specified function is invoked, information about the call, the arguments passed, and the returned values, if any, will be printed to the stream that is the value of *TRACE-OUTPUT*. A function-spec is either a symbol naming a function (i.e. a symbol whose global function cell is bound to a function definition object) or a list whose first element is a function specification type, and whose tail indicates which particular function of that type should be traced. The complete set of function specification types will necessarily be implementation specific, but all implementations are required to provide the following: -Invocation of the function named by via. 's global function cell are traced. (:SETF )-If the generalized variable reference indicated by is tracable, then invocations of the function implementing the SETF operation will be traced. (:METHOD )- If the method whose parameter specializer list and generic function are indicated in the specification is tracable, then invocations through the generic function name will be traced. (:MACRO-FUNCTION )-If has a global function definition that is a macro definition, then invocations of the macro function through will be traced. >>>>others? Some which I can think of that might be useful are: (:LOCAL )-Invocations of the function named when the current environment is are traced. Problems: Environments are second-class in Common Lisp. Something similar would be: (:LOCAL )-Same, except would get at the environment via. a global function name. This won't take care of FLETS inside FLETS, nor of FLETS at the top level, however. This could also be potentially handled via. the macro's environment parameter. (:FUNDEF )-Invocations of the function definition object are traced, regardless of whether they are through a global or local name symbol. Problems: Wrapping the function to trace invocation may require modifying the function definition object, which may not be possible in all implementations of Common Lisp. Slot initialization functions, and lambdas are other items which need consideration. Note: Another useful enhancement would be to support a :BREAK flag, like this: (:METHOD :BREAK) indicating that a break loop should be entered before and after the function executes. Most implementations support this, but it is not in CLtL. This may be an issue for the cleanup committee, however. <<<<<<<<<< TRACE-EXECUTION object &OPTIONAL env [Generic Function] TRACE-EXECUTION discriminates on object to select an implementation specific method that arranges for the executable entity associated with object to be traced. The optional env environment parameter is for those implementations which require environmental information to arrange for tracing to occur. Implementations are required to provide TRACE-EXECUTION as the system level entry point for implementing trace functionality. The exact nature and number of methods associated with TRACE-EXECUTION will differ, depending on what function specifications are supported by TRACE, but every implementation needs to support the following: SYMBOL-The function indicated by the symbol will be traced when invoked in the environment. If the function is a macro, then tracing will occur when the macro function is invoked. If the function definition is bound to the symbol's global function definition cell, then invocations of the function via. its global name will be traced. If the function is a local function, then only invocations when the environment parameter is the current environment will be traced, provided the implementation can arrange for it. METHOD-The method function is traced when invoked. GENERIC-FUNCTION-The generic function is traced when the discriminator code is invoked. FUNCALLABLE-STANDARD-CLASS-???? need more information about what this is. >>>>>>>>>others? Some which I can think of are: FUNCTION-Invocation of the function is traced, regardless of whether invocation is through a named symbol. This will obviously depend on whether modifications in fundefs are allowed to support tracing.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 31 Jul 87 12:42:13 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 31 Jul 87 09:38:35 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 30 Jul 87 15:21:28 pdt Received: from hplabsz.hpl.hp.com by hplms2; Thu, 30 Jul 87 15:21:04 pdt Return-Path: Received: from hplabsz by hplabsz; Thu, 30 Jul 87 16:21:49 pdt Message-Id: <8707302221.AA01264@hplabsz.hpl.hp.com> To: Patrick H Dussud Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Miscellaneous decisions taken or to be taken In-Reply-To: Your message of Thu, 30 Jul 87 07:57:57 -0500. <2763637077-14200445@Jenner> Date: Thu, 30 Jul 87 16:21:46 MST From: kempf%hplabsz@hplabs.HP.COM > > We need to decide whether class-name of an anonymous class is nil. > > Two choices are 1) NIL 2) CLASS-NAME signals an error. I vote for the > second. An anonymous class should be a class with NO name. > If we signal an error on class-name, then we have to come up with a > predicate to test if the class is named or not. Is it worth the trouble? This is a problem. Also with unnamed generic function objects, and methods. In the interest of simplicity, I'd be willing to forgo this. I can't think of why anyone would want to name a class NIL anyway. > The environment argument will be necessary to address the compile > environment problem. The term might be confusing, it is not necessary > an environment like the &environment argument in a macro definition. > We need some more discussion on this first. I agree that the the compile environment problem needs solution (especially for single address space implementations) but I'd rather see some concensus on a general solution before bringing up specific functions. Even if it means having to revise the parameter lists of some functions. > > I think they should all go into CLOS, except those which are already in > LISP (like DOCUMENTATION) or those which are designed to replace aspects > of LISP already existing (like PRINT-OBJECT). Very few are in these categories. > > We said that some of the symbols will go to LISP because CLOS is > supposed to be part of ANSI Common Lisp. The top level macros and > functions should be part of LISP. The internal functions specified for > the sake of metaclass programming can reside in CLOS. Does this mean that a decision was made at the July meeting on the point Pavel Curtis raised at the March meeting about what relationship CLOS should have with the full language standard? Unless implementors of Common Lisp are required to implement CLOS in order to have "full ANSI Standard Common Lisp", I think it would be better to allow some flexibility in where the symbols go. > > I'm not sure if we said anywhere what happens when you call a generic > > function and there is no applicable method; I think it ought to signal > > an error. > > Yes, and CALL-NEXT-METHOD should do the same. Again, we need to clarify > in the context of Dick's proposed error naming scheme. > If we can assume that the ANSI will standardize an error handler then I > am in favor of signalling an error and specifying the signal name. If > we can't assume that, I would rather call a generic function like > NO-MATCHING-METHOD. I agree with your preferences here. The error message should also give some information about the classes of the parameters, in addition, to help debugging.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Jul 87 16:09:40 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 30 Jul 87 13:06:15 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 29 JUL 87 18:36:33 PDT Date: 29 Jul 87 18:36 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Name That Class In-reply-to: Gregor.pa's message of 28 Jul 87 19:21 PDT To: Gregor.pa@Xerox.COM cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870729-183633-103@Xerox> I support proposal 3 (setf(class-named ) ) and (class-names ) for the reasons given danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Jul 87 09:15:59 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 30 Jul 87 06:12:35 PDT Received: from [128.89.1.80] by RELAY.CS.NET id aa02415; 30 Jul 87 9:08 EDT Received: from ti-csl by RELAY.CS.NET id ad12225; 30 Jul 87 9:02 EDT Received: from Jenner by tilde id AA02135; Thu, 30 Jul 87 07:59:04 CDT Message-Id: <2763637077-14200445@Jenner> Date: Thu, 30 Jul 87 07:57:57 CDT From: Patrick H Dussud To: kempf%hplabsz@hplabs.hp.com Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Miscellaneous decisions taken or to be taken In-Reply-To: Msg of Wed, 29 Jul 87 16:25:25 -0700 from kempf%hplabsz@hplabs.hp.com > We need to decide whether class-name of an anonymous class is nil. Two choices are 1) NIL 2) CLASS-NAME signals an error. I vote for the second. An anonymous class should be a class with NO name. If we signal an error on class-name, then we have to come up with a predicate to test if the class is named or not. Is it worth the trouble? Additionally, it would be nice if top level forms would also print out something at compile time. Our applications developers are asking for some feedback about what gets done at compile time. Maybe that's an implementation issue, though. You're right, it is an implementation issue, some compilers have a verbose option. > 2-13 class-named needs a new name for consistency. get-class would be wrong > because the other get-xxx functions aren't name operations. symbol-class > is the agreed name. It needs an environment argument. The errorp argument > gets in the way. I think we agree that symbol-class should be setf'able, > but can it only be set once for a given symbol or is it allowed to change > the symbol-to-class-object mapping? Why an environment argument? Since we haven't agreed to lexically scoped class names, this would seem unnecessary. Is it to deal with the ERRORP argument? Why do people think it will get in the way? Why not just make it a keyword argument? A user might want to not have it signal an error especially in metaclass programming. If whether or not it signals an error is dependent on a (second-class) environment argument, then it will be more difficult for a user to arrange. I think the name SYMBOL-CLASS is OK, and that it should be allowed to change the symbol-to-class-object mapping. The important thing in CLOS is the object, and the name to object mapping should be changable. The environment argument will be necessary to address the compile environment problem. The term might be confusing, it is not necessary an environment like the &environment argument in a macro definition. > What can be done with method objects, e.g. can one method be added > to more than one generic function? There may be a problem if the method invokes CALL-NEXT-METHOD. This relates back to whether CALL-NEXT-METHOD is dynamic or indefinite in extent. If it is dynamic, then there should be no problem, since the binding of CALL-NEXT-METHOD is done when the method begins executing, at the latest, or during calculation of the effective method, at the earliest. Thus the same method object on multiple generic functions would be no problem, since that case could be detected and establishment of CALL-NEXT-METHOD's binding deferred as late as possible. If the extent is indefinite, then the binding could potentially remain outside of a particular method invocation, and so adding the same method to more than one generic function may cause a problem. > Which symbols defined by the standard go in what package? > July: I think we said some will go in LISP: and some will go in CLOS: and > we don't know yet where to draw the line. I think they should all go into CLOS, except those which are already in LISP (like DOCUMENTATION) or those which are designed to replace aspects of LISP already existing (like PRINT-OBJECT). Very few are in these categories. We said that some of the symbols will go to LISP because CLOS is supposed to be part of ANSI Common Lisp. The top level macros and functions should be part of LISP. The internal functions specified for the sake of metaclass programming can reside in CLOS. > Gregor doesn't like the ability to specify constraints on the ordering > of classes that only apply conditionally, i.e. if those classes are > actually present among the superclasses. He considers this bad style. > Moon volunteered to write a proposal with some examples, and we agreed > to resolve this over the mail. I agree with Gregor. I think that user specified changes in the CPL should be controlled through COMPUTE-CLASS-PRECEDENCE-LIST, or, if the default algorithm can't make a decision. Let's see what Moon's proposal before discussing the issue. > I'm not sure if we said anywhere what happens when you call a generic > function and there is no applicable method; I think it ought to signal > an error. Yes, and CALL-NEXT-METHOD should do the same. Again, we need to clarify in the context of Dick's proposed error naming scheme. If we can assume that the ANSI will standardize an error handler then I am in favor of signalling an error and specifying the signal name. If we can't assume that, I would rather call a generic function like NO-MATCHING-METHOD.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Jul 87 03:25:20 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 30 Jul 87 00:20:49 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Wed, 29 Jul 87 15:26:18 pdt Received: from hplabsz.hpl.hp.com by hplms1; Wed, 29 Jul 87 15:24:58 pdt Return-Path: Received: by hplabsz; Wed, 29 Jul 87 16:25:29 pdt Message-Id: <8707292225.AA09896@hplabsz.hpl.hp.com> To: "David A. Moon" Cc: common-lisp-object-system@SAIL.STANFORD.EDU, kempf@hplabsz.hpl.hp.com Subject: Re: Miscellaneous decisions taken or to be taken In-Reply-To: Your message of Mon, 27 Jul 87 22:46:00 -0400. <870727224638.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 29 Jul 87 16:25:25 -0700 From: kempf%hplabsz@hplabs.HP.COM On anything not noted, I've got no opinion. There was no mention made of compile time optimization, which I believe I made some initial proposals on in late April or early May. I've been meaning to revist them, will try to get to that in the next week or so. If anybody thinks this isn't important and should be dropped, let me know. Our applications developers are asking for it, however. On initialization: > 1-5, 2-44 The initialization protocol for make-instance is not yet > specified. I take it there was no agreement at the July meeting to a full specification? If so, then can someone write up the specification and post it? PART I: > 27 May 87 call-next-method is allowed to take arguments, however it is > an error to give it arguments that would change the set of applicable > methods. I think we're saying this signals an error, and mentioning > that in some simple cases the lack of need for an error check can be > proved at compile time, but in general a run-time check is required. This is fine. Do we need to further clarify the error based on Dick's note about error signaling? > 10 June 87 There was no response when Sonya mailed out a writeup for how > the standard type classes are organized. Does that mean we agreed on that? Yes, modulo consideration of Patrick's suggested change in <2762944528-5369042@Jenner> for purposes of minimizing category errors. But I assume from the note he posted today, that he is satisfied with Sonya's note. > p1-12 Should defclass be allowed to change the metaclass of an existing > class? Under what conditions should a subclass of standard-class have > the same properties wrt instance updating as standard class? > Kempf says you shouldn't be allowed to change the metaclass, I think > because existing interfaces might not be transformable. > Gregor says the metaclass protocol includes a predicate function > that controls this. The reason was because the representations might differ. Consider a metaclass where the types of the slots were restricted. Instances of classes of a metaclass which did not have those restrictions might be difficult to update automatically. However, I think Gregor's solution of a metaclass protocol predicate (generic) function to control this would be sufficient. This doesn't answer the second question, however, I'll abstain on that one. I don't believe instance updating belongs in the language in the first place, but rather in the environment. PART II: > p1-17 "It is currently under discussion whether to provide constructs > for giving generic functions local names." Do we want to have this > discussion, or to punt on this syntax. I recall we did come up with some > reasonble semantics for a GFLET and GFLABELS. > > In July we decided to defer this. Let's forget it for now. I've got some ideas, but I won't rehash them. > p1-18 It is not specified whether get-setf-generic-function is a > setf-able form. I suggest that it be made so. This would allow one to > trace setf-generic-function's without having to know their names. > This set off a discussion of how TRACE should work that maybe doesn't > bear directly on CLOS. > Moon thinks this would be okay provided it is understood as setting the > mapping from a name to a generic function, not side-effecting the > generic function. I've been thinking about modifications to TRACE to support tracing of generic functions, which combines aspects of Danny's idea of making TRACE a generic function and Moon's function specs. I'll try to get it written up and posted by the end of the week. I think it's important that this be addressed, since our applications developers are beginning to express the need for the ability to trace individual methods, as well as invocation of the generic function. > p1-24 Should we have a call-next-method? which calls such a next method > if it exists, else returns nil (rather than signalling an error?). This > seems useful rather than having to define many base methods on object. CommonObjects had two messaging forms for this, but my general inclination is to conform with what happens when an attempt to invoke a generic function is made with an argument set for which there is no matching method. Currently, an error is signalled, and I think that it should also be for CALL-NEXT-METHOD. > We need to decide whether class-name of an anonymous class is nil. Two choices are 1) NIL 2) CLASS-NAME signals an error. I vote for the second. An anonymous class should be a class with NO name. > p2-19 Values: I thought we agreed that all top level forms should return > the object. It says here defclass "returns the name of the class" > p2-22 Same comment as 2-19, for defgeneric-options > 2-24 ditto for defgeneric-options-setf > Kempf agrees they should return the object. Moon isn't sure, because > defun, defvar, deftype, and defstruct return the name. As far as I can > tell every defxxx form in CLtL returns the name. The problem is that > we haven't admitted that defmethod has a name. > In July we decided (for the previous three) to return the object for > all CLOS defxxx functions (being inconsistent with Common Lisp). Additionally, it would be nice if top level forms would also print out something at compile time. Our applications developers are asking for some feedback about what gets done at compile time. Maybe that's an implementation issue, though. > p2-35 The argument order of the setf method ought to be documented here. > Gregor proposed that new-value be the first argument. Any problem with > this? > Kempf doesn't care but his users want it to be the second argument. > Moon doesn't care but his users are used to it being the last argument. > In July we suggested making the new-value argument a required argument that > comes after all the other required arguments, and before the optional, rest > and keyword arguments. Then we said we'd discuss it further in the mail. > I think we agreed that the turning of two setf argument lists into one > should > depend only on the argument lists, and not on the gen eric function object. > [My notes include an illegible comment, I think it means that I still hope > we can keep things abstract enough that we don't have to document > how the two setf argument lists are turned into one.] This sounds good to me. > p2-39 Arguments: "list of t's" should be replaced by "list of classes > named t" since get-method only takes specializers, not names of > specializers. Yes, except I'd phrase it as "a list whose elements are the class object for the the class named T". As I understand it, there is only one class T. > p2-51 print-object should take a depth argument. > Moon strongly disagrees and points to the fourth bullet. I believe this > issue was discussed to death on the Common Lisp mailing list a few months > or a year ago. > The point is that every single method for print-object should not have to > deal with *print-level*; that's unmodular. > Kempf raised a consistency argument (with defstruct?) but we decided > not to change print-object. I agree with Moon. Some implementors may scream (as I did), but it's probably not too late to correct this blemish. PART III: > 2-6 call-next-method dynamic versus indefinite extent > The document says it has dynamic extent; we need to be sure that we > really mean that. In July we said "implementation flexibility, not > really a language thing", but I'm damned if I can figure out what > that means. Yes, this needs to be resolved. See my comments below about adding methods to more than one generic function. Although I wasn't there, I think the "implementation flexibility" comment had something to do with optimizing calculation of the effective method. Indefinite extent would favor this, but dynamic extent would give more flexibility with regard to what could be done with method objects. Indefinite extent sounds good to me, but I'm not particularly choosy, however, I think it should be pinned down. > 2-9 semantic difficulties discussion was shortened for the document so much > that much of the point was lost. At some point we need to decide how much > we want to standardize about this and where we want to say it; in the main > standard or in some kind of implementation guide. I think these semantic difficulties point out a fundamental problem with CHANGE-CLASS. It is neither a full versioned class capability nor an environmental undo capability, but rather a hack somewhere in between. Having said my peace (and above, about instance changing), I'll forgoe any further comments. > 2-13 class-named needs a new name for consistency. get-class would be wrong > because the other get-xxx functions aren't name operations. symbol-class > is the agreed name. It needs an environment argument. The errorp argument > gets in the way. I think we agree that symbol-class should be setf'able, > but can it only be set once for a given symbol or is it allowed to change > the symbol-to-class-object mapping? Why an environment argument? Since we haven't agreed to lexically scoped class names, this would seem unnecessary. Is it to deal with the ERRORP argument? Why do people think it will get in the way? Why not just make it a keyword argument? A user might want to not have it signal an error especially in metaclass programming. If whether or not it signals an error is dependent on a (second-class) environment argument, then it will be more difficult for a user to arrange. I think the name SYMBOL-CLASS is OK, and that it should be allowed to change the symbol-to-class-object mapping. The important thing in CLOS is the object, and the name to object mapping should be changable. > 2-16 (slot-name form) should be allowed as an abbreviation > for (slot-name :initform form). People have been assuming this, > but it never finds its way into the document. > In July we rejected this. Since people keep assuming it, we have > to document explicitly that it is not allowed. Yes. > 2-16 boa-arglist should support &key and &allow-other-keys. Agreed. > 2-19 uninitialized slots should be an error to reference, not be defined > to return an unstandardized value with no error. I'm willing not to require > that it signals an error if people feel that would be an undue burden, > otherwise I prefer that reading an uninitialized slot signals an error. I agree that it should signal an error. > In July we decided that signalling an error here should depend on the > declared safety level. Dick has proposed terminology for this. Dick's terminology is good. We probably need to backpatch it into the document (it should probably be backpatched into CLtL too, but that's not for us to decide). > 2-57 with-slots :prefix package problem; This was discussed in the mail and > then the ball was dropped. What's in the document is unworkable because it > depends on the dynamic value of *package* at macro-expansion time, but Common > Lisp doesn't guarantee anything about when macro-expansion occurs. Moon would > prefer to flush the :prefix option. An alternative > that was discussed was to > use symbol-package of the prefix, both here and in defclass accessor construc- tion, > as the package, relying on the likelyhood of prefixes always ending in delimi- ter > characters and exported symbols never ending in delimiter characters. > July: We agreed to resolve this in the mail. I agree with Moon. > 2-57 What does with-slots do for slots that exist in the class but don't > have accessors, when :use-accessors t is specified (or defaulted)? > July: it shadows any outer bindings of the slot name, and if you > actually access that pseudo-variable, it signals an error. Agreed. > Documented holes in chapters 1 and 2 of 87-002. We publicly promised > X3J13 that we would finish these and have a new draft of 87-003 by the > next meeting. See my note of 27 July to Dick about holes in Chapter 1. I'll be replying to Danny's comments on it shortly. > 1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes > is still under discussion. Has a Cleanup Committee proposal been submitted for the type system? > What can be done with method objects, e.g. can one method be added > to more than one generic function? There may be a problem if the method invokes CALL-NEXT-METHOD. This relates back to whether CALL-NEXT-METHOD is dynamic or indefinite in extent. If it is dynamic, then there should be no problem, since the binding of CALL-NEXT-METHOD is done when the method begins executing, at the latest, or during calculation of the effective method, at the earliest. Thus the same method object on multiple generic functions would be no problem, since that case could be detected and establishment of CALL-NEXT-METHOD's binding deferred as late as possible. If the extent is indefinite, then the binding could potentially remain outside of a particular method invocation, and so adding the same method to more than one generic function may cause a problem. > Ida: make-specializable seems to be missing > Gregor's proposal for get-generic-function will subsume this. Wasn't ENSURE-GENERIC-FUNCTION supposed to replace this? > Should we just flush multiple-value-prog2, as leading to more discussion > than is warranted by its simplification of the presentation of > define-method-combination? Yes. > Which symbols defined by the standard go in what package? > July: I think we said some will go in LISP: and some will go in CLOS: and > we don't know yet where to draw the line. I think they should all go into CLOS, except those which are already in LISP (like DOCUMENTATION) or those which are designed to replace aspects of LISP already existing (like PRINT-OBJECT). Very few are in these categories. > Should we flush defmethod-setf and friends in favor of function specs? > It probably turns out they could be just in the macros and not in the > underlying Lisp. The big issue is standardizing where the "new-value" > argument goes; but we may do that anyway (mentioned earlier in this file). I think we ought to keep DEFMETHOD-SETF, but use function specs (or something like them) as the programmer interface to TRACE. See my comments above about TRACE. > Should we adopt the :component-order class-option from Flavors, as a > simple way for the user to have control of the CPL without making him > write his own algorithm? > Gregor doesn't like the ability to specify constraints on the ordering > of classes that only apply conditionally, i.e. if those classes are > actually present among the superclasses. He considers this bad style. > Moon volunteered to write a proposal with some examples, and we agreed > to resolve this over the mail. I agree with Gregor. I think that user specified changes in the CPL should be controlled through COMPUTE-CLASS-PRECEDENCE-LIST, or, if the default algorithm can't make a decision. > The fact that symbol-function (the user callable primitive) needs to > be split from the subprimitive for implementators that gets and sets > the "real" function definition of a symbol. This is so when a symbol's > function definition is a generic function object, the "real" definition > can be something that is easier for the implementation to call. I don't see splitting SYMBOL-FUNCTION as an issue for the standard, though it may be for certain implementations. Currently, most of the PCL-derived implementations have no trouble with this. > July: We need to say explicitly somewhere that calling symbol-function > of the name of a generic function is required to return the generic > function object, not the "real" definition. Yes. > I'm not sure if we said anywhere what happens when you call a generic > function and there is no applicable method; I think it ought to signal > an error. Yes, and CALL-NEXT-METHOD should do the same. Again, we need to clarify in the context of Dick's proposed error naming scheme. > Clarify that because class names and classes are type-specifiers, they can be > validly be used in THE special forms and in TYPE declarations. We forgot this > when we clarified that class objects can be used with TYPEP and SUBTYPEP. > July: agreed Yes. Again, as mentioned in the beginning, this relates back to compile time optimization. > funcallable-standard-class should be documented. It is a metaclass. > This is what makes generic function objects funcallable. There is a slot > that is the actual function that gets called. Agreed.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jul 87 17:22:48 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 29 Jul 87 14:15:18 PDT Received: from relay2.cs.net by RELAY.CS.NET id ae29814; 29 Jul 87 17:07 EDT Received: from ti-csl by RELAY.CS.NET id ae07913; 29 Jul 87 17:02 EDT Received: from dsg by tilde id AA02476; Wed, 29 Jul 87 15:11:11 CDT Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Wed, 29 Jul 87 15:00:19 CDT Message-Id: <2763575892-10524347@Jenner> Date: Wed, 29 Jul 87 14:58:12 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Class redefinition and class-changed. In-Reply-To: Msg of Sat, 25 Jul 87 01:26 EDT from "David A. Moon" We have our choice of three ways to define what happens when a class is redefined: (1) A new class object is created, the name-to-class-object mapping is changed, defclass-defined methods implied by the new definition are put on the new class object, all methods other than defclass-defined methods that apply to the old class are made to apply also to the new class, subclasses of the old class are made to be subclasses of the new class instead, and superclasses of the old class are made to be also superclasses of the new class. If we had done this, there would have been an explicit representation of versions of a class, and there would not have been any concept of "obsolete classes." I don't like this one for the reasons Gregor and Danny gave. This means that -both- arguments to CLASS-CHANGED could be instances of obsolete classes. It also means that our CLASS-CHANGED method can't specialize its second parameter, because at first that will be the class FOO, but after FOO is redefined again, it will be an obsolete class. If we don't specialize the second parameter, it seems we could be confused by CLASS-CHANGED being called when CHANGE-CLASS was used to change an instance of FOO into an instance of BAR. This is not a problem if CHANGE-CLASS, like all other generic functions, first updates its argument to the latest definition of its class, before changing it to the new class; then a method specialized to an obsolete class in its first parameter can never be called with the second parameter an instance of anything other than the next newer version of the same class. This all seems slightly kludgey, but does seem like it should work. I like this approach the best because it is more object oriented than the third one and seems more modular. However it has the problem Danny mentioned about applicable methods: [Bobrow]: I think we have only two choices with respect to methods applicable to obsolete instances-- 1) All methods applicable to the class itself i.e. the obsolete-class is a subclass of the new class 2) Only slot-value-using class. A problem with the first is what happens if a method is removed from a class before an obsolete instance is converted to a real instance. For example, in the famous rho-theta example, suppose we have x-y points (ones with x and y as slots), and decide to change class to store only rho and theta. Then after redefining the class, a naive user might 1) build a class-changed method that used the methods for rho and theta for conversion 2) believe that these rho and theta methods could be removed from the rho-theta-point class. In this description I have made it obvious why this is wrong. But suppose this were a case where both of generic functions for rho and theta used another routine that was no longer needed. The user might easily delete that one. I think that it might be better to go to 2, though clearly it makes class-changed have a lot less easily accessible power. I don't like danny's 1) because as he shows, it does not work. I don't like 2) because it breaks modularity. You have to know if an accessor is implemented as a physical slot access and if not, you have to know what the accessor was doing. This knowledge is contained in your class and its superclasses. How about this one? 1b)All methods applicable to the class itself at the time of the redefinition. It would be up to the implementation to choose the best way of doing it. The third way to define what happens when a class is redefined, mentioned earlier, is as follows: Don't try to use CLASS-CHANGED for both changing the class of an instance and updating an instance to a new version of its class. Invent a new generic function CLASS-REDEFINED, which is called when an instance is updated to a new version of its class. This avoids the complicated concept of "obsolete classes", at the cost of conveying the former state of the instance in a less object-oriented fashion. Perhaps CLASS-REDEFINED would receive three arguments: an instance of the class, already updated to the latest definition of the class, a property list associating slot names to slot values, with one entry for each slot that is no longer present, and a list of slot names of slots that were newly added to the instance. Thus when a class is redefined: (3) The old class object is modified, defclass-created methods that aren't created by the new defclass are removed, new defclass-created methods are added, and the modification is propagated to subclasses. This is simpler than (1) or (2). The third way is simpler indeed. My main objection to this is that CLASS-REDEFINED methods have to know all about the implementation of the class and superclasses (physical slots and methods) AND the whole story about the successive redefinitions. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jul 87 13:40:52 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Jul 87 10:34:40 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 201218; Wed 29-Jul-87 13:27:29 EDT Date: Wed, 29 Jul 87 13:26 EDT From: Sonya E. Keene Subject: updated documentation To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870729132641.0.SKEENE@JUNCO.SCRC.Symbolics.COM> I wrote new versions of the functions, concepts, and design chapters. The documentation now includes the write-up about Standard Type Classes which I sent to this list several months ago. I didn't receive any comments about it, probably because the text was cluttered up with tex formatting directives. When we format the document again it will be easier for people to read this section and make their comments then. I changed the documentation to state that the def-XXX macros return objects, not names. We agreed on this change at our Cambridge meeting a couple weeks ago. The only problem with this is some awkwardness about the value of define-method-combination. There is no CLOS object for representing a method combination type. define-method-combination expands into a defmethod, so its result is a method object.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jul 87 13:31:13 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 29 Jul 87 10:25:11 PDT Received: from relay2.cs.net by RELAY.CS.NET id ac27103; 29 Jul 87 13:10 EDT Received: from ti-csl by RELAY.CS.NET id af06356; 29 Jul 87 13:02 EDT Received: from Jenner by tilde id AA12158; Wed, 29 Jul 87 11:22:06 CDT Message-Id: <2763562862-9741514@Jenner> Date: Wed, 29 Jul 87 11:21:02 CDT From: Patrick H Dussud To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: Miscellaneous decisions taken or to be taken In-Reply-To: Msg of Mon, 27 Jul 87 22:46 EDT from "David A. Moon" 10 June 87 There was no response when Sonya mailed out a writeup for how the standard type classes are organized. Does that mean we agreed on that? I agree with it. p1-12 Should defclass be allowed to change the metaclass of an existing class? Under what conditions should a subclass of standard-class have the same properties wrt instance updating as standard class? Kempf says you shouldn't be allowed to change the metaclass, I think because existing interfaces might not be transformable. Gregor says the metaclass protocol includes a predicate function that controls this. I agree with Gregor.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 29 Jul 87 00:35:26 EDT Date: 28 Jul 87 2126 PDT From: Dick Gabriel Subject: Partial Orderings To: common-lisp-object-system@SAIL.STANFORD.EDU You can define a partial ordering based on irreflexive relations by using the `antirelation' and NOT. For example, instead of less than or equal, you can use greater than and NOT. If you don't believe me, believe Knuth Volume 1. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 22:29:24 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87 19:22:30 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 19:21:57 PDT Date: 28 Jul 87 19:21 PDT From: Gregor.pa@Xerox.COM Subject: Re: Name That Class In-reply-to: Dick Gabriel 's message of 27 Jul 87 11:59 PDT To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870728-192157-1316@Xerox> It seems to me that there are ways for class-named and setf of such to work. I think only two of these are reasonable, but I will include the third for completeness. Note that this same analysis applies to generic-function-name and setf of symbol-function and get-setf-generic-function. I will do class names first. A class C 'is bound to' a given name Ni iff (class-named Ni) returns C. In all this solutions, we document class-named and setf of class-named. We say that class-named returns the class is bound to a particular name. We say that setf of class-named can be used to set the binding of a class to a name. Solution 1: Only document class-named and setf of class-named. Most implementations will have some magic for printing out a class's name when it has one. Solution 2: Document class-named and setf of class-named. Also document class-name, but say that the the class may or may not 'bound' to that name. Solution 3: Document class-named and class-names and setf of class-named. Say that setf of class-named can be used to bind a clas to a name. Say that class-names returns the list of all names that a class is bound to. For example: (setq foo (make-instance 'standard-class)) # (setf (class-named 'n1) foo) # (setf (class-named 'n2) foo) # (class-names foo) (N1 N2) (setf (class-named 'n1) nil) # (setf (class-named 'n2) nil) # (class-names foo) () It seems to me that solution 1 and solution 3 are the only reasonable ones. My general dislike of names makes me prefer solution 1, but I think that solution 3 actually provides users some important functionality. I think its easy to see how this whole thing would work for generic-function-name, symbol-function, setf of symbol-function, get-setf-generic-function and setf of get-setf-generic-function.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 22:14:11 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87 19:07:26 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 19:04:56 PDT Date: 28 Jul 87 19:04 PDT From: Gregor.pa@Xerox.COM Subject: Re: initialization meeting notes In-reply-to: David A. Moon 's message of Mon, 27 Jul 87 22:05 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870728-190456-1292@Xerox> From: Moon (One line of the above has been uppercased, the only ASCII way to highlight it.) I hope this is an erroneous example, and you're not really proposing that otherwise-uninitialized slots should be initialized to NIL. Yes, this example is erroneous. What I was trying to capture was that an :after initialize-instance method would be able to tell if a slot had been set. I thought we agreed that defclass would translate the initforms into functions and at the metaclass level they would appear as functions. I don't think we need a new way, besides lambda, for capturing lexical environments. (Of course implementations are not required to make new functions in all cases; especially in the case of constant initforms, they will probably make a closure of an existing function.) This implies that one cannot use metaclass protocol to recover the original forms that appeared in the defclass. Maybe we didn't agree on this, I couldn't find anything about it in my notes from the meeting. Can we converge on this now? I remember now that we had agreed that both initforms and default initargs would be translated into functions by defclass. Note that this does not necessarily mean that its impossible to reconstruct the defclass form for a class. We could say that at the metaclass level, there is a separate mechanism for communicating the form that was in the defclass. But I would just as soon agree that there is no such mechanism at the metaclass level. Actually, I think the fact that Common Lisp doesn't have first class lexical environments means that its impossible to construct an 'equivalent' defclass form which an editor might put up for the user to edit a little and then re-evaluate. Only specific implementations, in an implementation specific way will be able to do this. On the other hand, if Common Lisp had first class lexical environments, this would be easy. An unemployment would be lower. And the national debt would be under control, and glphh... uh...  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 20:58:11 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87 17:51:25 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 17:51:21 PDT Date: 28 Jul 87 17:51 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: initialization meeting notes In-reply-to: David A. Moon 's message of Mon, 27 Jul 87 22:05 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870728-175121-1220@Xerox> This implies that one cannot use metaclass protocol to recover the original forms that appeared in the defclass. This seems an unecssary mistake (we could have redundant information at the very least). I agree that we need not have any "new way, besides lambda, for capturing lexical environments."  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 19:55:28 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87 16:48:48 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 16:48:45 PDT Date: 28 Jul 87 16:48 PDT From: Gregor.pa@Xerox.COM Subject: Re: Class Redefinition In-reply-to: Danny Bobrow 's message of 28 Jul 87 15:26 PDT To: Bobrow.pa@Xerox.COM cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870728-164845-1137@Xerox> As far as "it would be nice if different classes weren't EQ" goes. Stop thinking about names and naming! If you do, I think it becomes easier to see why the obsolete class should be a new object and the old class object should be updated to have the new definition. defclass just associates a class with a name for convenience. Many programs will use anonymous classes. In these programs, changes in an anymous or a named class might cause anymous or named classes to become obsolete. The obsolete class mechanism needs to support both anonymous and named classes. In order to do that, the 'redirection' needs to be at the level of the class object not at the level of the class name.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 19:49:16 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87 16:42:35 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 16:42:34 PDT Date: 28 Jul 87 16:42 PDT From: Gregor.pa@Xerox.COM Subject: Re: Class Redefinition In-reply-to: Danny Bobrow 's message of 28 Jul 87 15:26 PDT To: Bobrow.pa@Xerox.COM cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870728-164234-1120@Xerox> The need for get-class-for-next-redefinition doesn't really have anything to do with multi-processing as far as I can see. Suppose that (the class of) one of the objects actually involved in defining a method on class-changed was going to be rendered obsolete by a certain defclass form. In that case, you would need to define the method before you actually change the class definition.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 18:57:56 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 28 Jul 87 15:49:56 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa18740; 28 Jul 87 18:40 EDT Received: from ti-csl by RELAY.CS.NET id aa01279; 28 Jul 87 18:30 EDT Received: from Jenner by tilde id AA20926; Tue, 28 Jul 87 15:53:07 CDT Message-Id: <2763492729-5527834@Jenner> Date: Tue, 28 Jul 87 15:52:09 CDT From: Patrick H Dussud To: "David A. Moon" Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class redefinition and class-changed. In-Reply-To: Msg of Sat, 25 Jul 87 01:26 EDT from "David A. Moon" I don't like Patrick's particular proposal, though. GET-OBSOLETE-CLASSES-FOR-REDEFINITION is too complicated, because it returns a whole alist rather than being just the primitive. In addition, I don't think the set of "classes implicated in the class-redefinition of CLASS" is computable until the details of the redefinition are known. Suppose (defclass one () (a b)) (defclass two (one) (c)) (defclass three (one) (d)) Now suppose we redefine one as follows: (defclass one () (a b d)) Referring to the third paragraph on page 1-11 of 87-002, one and two are "implicated", but three is not, or at least, whether three is implicated is implementation-dependent. But if the new slot had been named e, both two and three would have been implicated. I don't think the information in Patrick's alist is needed anyway; when defining a method, one only defines it for the obsolete class corresponding to one class. If a different method needs to be defined for an obsolete subclass, the function can be called again. I see. I don't care that much about the alist as long as we can get the obsolete class of "one". Thus I would replace Patrick's proposal with GET-OBSOLETE-CLASS-FOR-REDEFINITION which takes one argument, a class, and returns one value, the obsolete class that is a copy of the current definition of the class and will be used the next time the class is redefined; this is created the first time you ask for it. Perhaps GET-OBSOLETE-CLASS-FOR-NEXT-REDEFINITION would be a better name. As Danny proposed, a primitive to get the obsolete classes corresponding to redefinitions that have already taken place is useful, for instance in case you didn't realize ahead of time that you would need a CLASS-CHANGED method and now want to patch up the program. I would suggest a function GET-OBSOLETE-CLASSES-FOR-PAST-REDEFINITIONS which takes one argument, a class, and returns one value, a list of obsolete classes, newest first. Sounds OK. I'll have to think some more about the rest of the message. Our connection with Arpanet was broken and we got it back just one hour ago. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 18:33:13 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87 15:26:54 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 15:26:43 PDT Date: 28 Jul 87 15:26 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Class Redefinition In-reply-to: Dick Gabriel 's message of 27 Jul 87 12:24 PDT To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870728-152643-2322@Xerox> rpg says It would be nice if different classes weren't EQ. Is there no way to make this work? The problem is what is a different class. People build networks of objects, including classes. The point of the spec is that these networks (including the one in the class lattice) should have to change when a class is changed. People do not always refer to classes by names. Response to Moon: Although I have not thought about it a lot, I think Moon's refinements GET-CLASS-FOR-NEXT-REDEFINITION and GET-OBSOLETE-CLASSES seems fine. I don't understand the experience of why one gets into trouble making CLASS-CHANGED methods after redefinition as Moon says, but perhaps it is because I am not working in a true multi-process system. I think we have only two choices with respect to methods applicable to obsolete instances-- 1) All methods applicable to the class itself i.e. the obsolete-class is a subclass of the new class 2) Only slot-value-using class. A problem with the first is what happens if a method is removed from a class before an obsolete instance is converted to a real instance. For example, in the famous rho-theta example, suppose we have x-y points (ones with x and y as slots), and decide to change class to store only rho and theta. Then after redefining the class, a naive user might 1) build a class-changed method that used the methods for rho and theta for conversion 2) believe that these rho and theta methods could be removed from the rho-theta-point class. In this description I have made it obvious why this is wrong. But suppose this were a case where both of generic functions for rho and theta used another routine that was no longer needed. The user might easily delete that one. I think that it might be better to go to 2, though clearly it makes class-changed have a lot less easily accessible power.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Jul 87 17:53:00 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87 14:46:58 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 14:46:54 PDT Date: 28 Jul 87 14:46 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Category Errors In-reply-to: Dick Gabriel 's message of 24 Jul 87 14:59 PDT To: RPG@SAIL.STANFORD.EDU cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870728-144654-2241@Xerox> Here is a generic function ``in CLOS'': Add-method generic-function method And here is how we have ``carefully laid out ... the range of legal arguments'' to it: Arguments: The generic-function argument is a generic function object. The method argument is a method object. The lambda-list of the method function must be congruent with the lambda-lists of any other methods associated with the generic function and with the lambda-list of the generic function. (page 2-5, FUNCTIONS) We should have been more careful about our wording perhaps. Because we have not yet formalized the notion of protocol, we have had to say the the first argument is a generic-function. But it could of course be any object that satisfied the same protocol (could act as the argument to some set of generic-functions). It is the ability to specialize (make "is a generic-function object" mean "be an instance of a subclass of generic-function object") and the ability to create alternative implementations that is one of the important improvements that object oriented programming adds to Lisp -- Hence a MAJOR feature. Users who ask "what's that thing?" have not understood object oriented programming, and it is up to us to help explain it -- not apologize for it.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 23:19:59 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87 20:12:22 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 200153; Mon 27-Jul-87 22:46:48 EDT Date: Mon, 27 Jul 87 22:46 EDT From: David A. Moon Subject: Miscellaneous decisions taken or to be taken To: Common-Lisp-Object-System@SAIL.STANFORD.EDU Message-ID: <870727224638.5.MOON@EUPHRATES.SCRC.Symbolics.COM> I have updated my file of miscellaneous decisions taken or to be taken, based on my notes from the meeting we had in July. The rest of this message is it. This page is things that I think we agreed that we had decided after the March meeting and before the July meeting. 27 May 87 call-next-method is allowed to take arguments, however it is an error to give it arguments that would change the set of applicable methods. I think we're saying this signals an error, and mentioning that in some simple cases the lack of need for an error check can be proved at compile time, but in general a run-time check is required. 10 June 87 There was no response when Sonya mailed out a writeup for how the standard type classes are organized. Does that mean we agreed on that? ! This page is a list of issues on which we should make decisions, brought up by Danny. Where I saw responsive answers in the mail (there were very few) I have edited them in. I've removed comments that were purely editorial comments on the document. p1-12 Should defclass be allowed to change the metaclass of an existing class? Under what conditions should a subclass of standard-class have the same properties wrt instance updating as standard class? Kempf says you shouldn't be allowed to change the metaclass, I think because existing interfaces might not be transformable. Gregor says the metaclass protocol includes a predicate function that controls this. p1-17 "It is currently under discussion whether to provide constructs for giving generic functions local names." Do we want to have this discussion, or to punt on this syntax. I recall we did come up with some reasonble semantics for a GFLET and GFLABELS. In July we decided to defer this. p1-18 It is not specified whether get-setf-generic-function is a setf-able form. I suggest that it be made so. This would allow one to trace setf-generic-function's without having to know their names. This set off a discussion of how TRACE should work that maybe doesn't bear directly on CLOS. Moon thinks this would be okay provided it is understood as setting the mapping from a name to a generic function, not side-effecting the generic function. p1-19 "... Common Lisp be modified to include the following semantics for quote in a type specifier: (deftype quote (object) '(member ,object)))" Has any proposal for this been given to the cleanup committee? Yes: ISSUE: TYPE-MEMBER-SINGLETON, Proposal TYPE-MEMBER-SINGLETON:QUOTE It hasn't really gone through the mill yet, though. In July Moon volunteered to make sure this happens. p1-24 Should we have a call-next-method? which calls such a next method if it exists, else returns nil (rather than signalling an error?). This seems useful rather than having to define many base methods on object. Common Lisp reserves question mark for the user; this could be named CALL-NEXT-METHOD-OR-NIL, or something like that. In July we wondered whether there should be a way to get a list of the remaining methods. I'm not sure what operations on that list, besides checking its length, would be permitted. 2-13(?) The generic function class-name is not written up. It returns a name for the class as argument. I believe that (class-name class) should be setf-able. Can a class have more than one name? Should class-name then return a second argument -- the rest of the names this class is known by. Kempf thinks the class name should be changeable and only one name at a time should be allowed. Moon agrees. We need to decide whether class-name of an anonymous class is nil. p2-19 Values: I thought we agreed that all top level forms should return the object. It says here defclass "returns the name of the class" p2-22 Same comment as 2-19, for defgeneric-options 2-24 ditto for defgeneric-options-setf Kempf agrees they should return the object. Moon isn't sure, because defun, defvar, deftype, and defstruct return the name. As far as I can tell every defxxx form in CLtL returns the name. The problem is that we haven't admitted that defmethod has a name. In July we decided (for the previous three) to return the object for all CLOS defxxx functions (being inconsistent with Common Lisp). p2-26 I believe that short form method combination ought to be a macro in the standard library, and documented there, not in the basic principles. I think the standard combinations :append, :and, :or, ... should also be put in the standard library too. Kempf agrees. Moon can't have an opinion until he knows what this library is and whether it's going to be as much of a joke as the Common Lisp Yellow Pages. p2-35 The argument order of the setf method ought to be documented here. Gregor proposed that new-value be the first argument. Any problem with this? Kempf doesn't care but his users want it to be the second argument. Moon doesn't care but his users are used to it being the last argument. In July we suggested making the new-value argument a required argument that comes after all the other required arguments, and before the optional, rest, and keyword arguments. Then we said we'd discuss it further in the mail. I think we agreed that the turning of two setf argument lists into one should depend only on the argument lists, and not on the generic function object. [My notes include an illegible comment, I think it means that I still hope we can keep things abstract enough that we don't have to document how the two setf argument lists are turned into one.] p2-39 Arguments: "list of t's" should be replaced by "list of classes named t" since get-method only takes specializers, not names of specializers. Agreed. p2-46 Last line: If call-next method is extended ..." I see no reason for additional keyword arguments. Moon doesn't remember the issue. It may have been consistency; if call-next-method can specify the arguments, then so can make-method-call. You need one keyword argument to specify the methods and another to specify funcall versus apply. It could also have been that call-next-method would be implemented in terms of make-method-call, and therefore would need to be able to specify the arguments. p2-51 print-object should take a depth argument. Moon strongly disagrees and points to the fourth bullet. I believe this issue was discussed to death on the Common Lisp mailing list a few months or a year ago. The point is that every single method for print-object should not have to deal with *print-level*; that's unmodular. Kempf raised a consistency argument (with defstruct?) but we decided not to change print-object. p2-54 slot-missing should be documented It's a generic function of a class, an object, and a slot name. Gregor will propose the details. ! This page is a list I made in March, keyed by page numbers in the document, that hasn't been shown to anyone yet. Issues mentioned earlier, or that have since died, have been removed. I've removed comments that were purely editorial comments on the document. 2-6 call-next-method dynamic versus indefinite extent The document says it has dynamic extent; we need to be sure that we really mean that. In July we said "implementation flexibility, not really a language thing", but I'm damned if I can figure out what that means. 2-9 semantic difficulties discussion was shortened for the document so much that much of the point was lost. At some point we need to decide how much we want to standardize about this and where we want to say it; in the main standard or in some kind of implementation guide. 2-13 class-named needs a new name for consistency. get-class would be wrong because the other get-xxx functions aren't name operations. symbol-class is the agreed name. It needs an environment argument. The errorp argument gets in the way. I think we agree that symbol-class should be setf'able, but can it only be set once for a given symbol or is it allowed to change the symbol-to-class-object mapping? 2-16 (slot-name form) should be allowed as an abbreviation for (slot-name :initform form). People have been assuming this, but it never finds its way into the document. In July we rejected this. Since people keep assuming it, we have to document explicitly that it is not allowed. 2-16 boa-arglist should support &key and &allow-other-keys. 2-18 default boa-arglist to be specified 2-18 (:accessor-prefix nil) is not a good way to say "use the slot names as the accessor names". We need to fix this. We could add another option, or remove the whole prefix feature, and require accessor names always to be listed explicitly. In July we agreed to discuss this in the mail. 2-19 uninitialized slots should be an error to reference, not be defined to return an unstandardized value with no error. I'm willing not to require that it signals an error if people feel that would be an undue burden, otherwise I prefer that reading an uninitialized slot signals an error. In July we decided that signalling an error here should depend on the declared safety level. Dick has proposed terminology for this. 2-38 need a way to recover documentation of a method-combination type July: do this by adding a new value for the second argument to DOCUMENTATION. But the whole writeup on DOCUMENTATION is screwy, and we need a new proposal. When the CL-Cleanup subcommittee finishes cleaning up the concept of "definition" (I think it's waiting for Masinter to propose something) then DOCUMENTATION should follow. 2-40 get-setf-generic-function needs an errorp, but it and ensure-generic-function should be subsumed by get-generic-function which would do all the right things. We seem to have lost Gregor's proposal for get-generic-function. Gregor promised to mail out the proposal. 2-42 make-generic-function should be deleted, redocumented as a class that can be given to make-instance July: Agreed 2-45 make-method should be deleted, redocumented as a class that can be given to make-instance July: Agreed 2-57 with-slots :prefix package problem; This was discussed in the mail and then the ball was dropped. What's in the document is unworkable because it depends on the dynamic value of *package* at macro-expansion time, but Common Lisp doesn't guarantee anything about when macro-expansion occurs. Moon would prefer to flush the :prefix option. An alternative that was discussed was to use symbol-package of the prefix, both here and in defclass accessor construction, as the package, relying on the likelyhood of prefixes always ending in delimiter characters and exported symbols never ending in delimiter characters. July: We agreed to resolve this in the mail. 2-57 What does with-slots do for slots that exist in the class but don't have accessors, when :use-accessors t is specified (or defaulted)? July: it shadows any outer bindings of the slot name, and if you actually access that pseudo-variable, it signals an error. ! Documented holes in chapters 1 and 2 of 87-002. We publicly promised X3J13 that we would finish these and have a new draft of 87-003 by the next meeting. 1-5, 2-44 The initialization protocol for make-instance is not yet specified. 1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes is still under discussion. 2-7, 2-46 [The proposed extension to call-next-method has been accepted.] 2-41, 2-48 [Perhaps we can adopt the condition signalling system now.] ! Other issues: What can be done with method objects, e.g. can one method be added to more than one generic function? Ida: make-specializable seems to be missing Gregor's proposal for get-generic-function will subsume this. Moon: method arglist congruence still doesn't satisfy me. I have some ideas about this but unfortunately have not managed to pull them together. Should we just flush multiple-value-prog2, as leading to more discussion than is warranted by its simplification of the presentation of define-method-combination? Which symbols defined by the standard go in what package? July: I think we said some will go in LISP: and some will go in CLOS: and we don't know yet where to draw the line. Should we flush defmethod-setf and friends in favor of function specs? It probably turns out they could be just in the macros and not in the underlying Lisp. The big issue is standardizing where the "new-value" argument goes; but we may do that anyway (mentioned earlier in this file). What about the setf of values extension that Common Lisp provides syntactic space for but does not currently prescribe? Should we adopt the :component-order class-option from Flavors, as a simple way for the user to have control of the CPL without making him write his own algorithm? Gregor doesn't like the ability to specify constraints on the ordering of classes that only apply conditionally, i.e. if those classes are actually present among the superclasses. He considers this bad style. Moon volunteered to write a proposal with some examples, and we agreed to resolve this over the mail. The fact that symbol-function (the user callable primitive) needs to be split from the subprimitive for implementators that gets and sets the "real" function definition of a symbol. This is so when a symbol's function definition is a generic function object, the "real" definition can be something that is easier for the implementation to call. July: We need to say explicitly somewhere that calling symbol-function of the name of a generic function is required to return the generic function object, not the "real" definition. I'm not sure if we said anywhere what happens when you call a generic function and there is no applicable method; I think it ought to signal an error. Gergor volunteered to send some mail about this. Clarify that because class names and classes are type-specifiers, they can be validly be used in THE special forms and in TYPE declarations. We forgot this when we clarified that class objects can be used with TYPEP and SUBTYPEP. July: agreed funcallable-standard-class should be documented. It is a metaclass. This is what makes generic function objects funcallable. There is a slot that is the actual function that gets called. I think Gregor volunteered to propose details. Need to be able to get at the obsolete classes associated with a class, to put methods on them. Patrick has proposed. Need discussion of how instances are transformed one step at a time when a class has been redefined multiple times.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 22:12:47 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87 19:05:41 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 200139; Mon 27-Jul-87 22:06:01 EDT Date: Mon, 27 Jul 87 22:05 EDT From: David A. Moon Subject: initialization meeting notes To: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870723180901.2.GREGOR@SPIFF.isl.parc.xerox.com> Message-ID: <870727220545.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 23 Jul 87 18:09 PDT From: Gregor.pa@Xerox.COM In this message I try to summarize what we agreed at the meeting in Boston. Thanks for getting all this on-line. I see only two things to disagree with here, so we should start putting our heads down and agreeing on the next level of detail. (defmethod initialize-instance ((obj object) &rest initargs) ;; The default initialize-instance method deals with setting the ;; values of slots from slot-filling-initargs and from initforms. ;; ;; The rules are that the leftmost initarg which is declared ;; as setting a slot (with the :initarg slot option) actually ;; does set it (or is it the rightmost?); and that slots which ;; are not set by an initarg have their :initform evaluated and ;; used to set them. ) It's leftmost, because that's the way duplicated &key arguments work in all other Common Lisp functions. Actually there are two issues here: (1) If the same initarg appears more than once in the initargs list, the leftmost occurrence is used and later occurrences are ignored. This is just consistency with &key and there's really no choice. (2) If more than one initarg is defined to fill a given slot, and more than one of these initargs appears in the initargs list, what happens? Flavors takes the rightmost, but that's a misfeature. We should either signal an error or take the leftmost. It's a one-line change to make Flavors take the leftmost (it will be a few microseconds slower, due to doing MEMBER of a one-element list instead of EQ, not enough slowdown to matter). I like taking the leftmost better than signalling an error. (defclass ship () ((x :initarg :x) (y :initarg :y))) (defmethod initialize-instance :after ((s ship) &key startp) (when startp (start s))) (defmethod start ((s ship)) (with-slots ((s :use-accesors nil)) (if (AND X Y) (error "Have to set X and Y before starting a ship.")))) (One line of the above has been uppercased, the only ASCII way to highlight it.) I hope this is an erroneous example, and you're not really proposing that otherwise-uninitialized slots should be initialized to NIL. the only serious problem has to do with arranging for the default initarg value forms to be evaluated in the lexical environment of the defclass. (Of course if environments were first class objects this would be trivial...) I thought we agreed that defclass would translate the initforms into functions and at the metaclass level they would appear as functions. I don't think we need a new way, besides lambda, for capturing lexical environments. (Of course implementations are not required to make new functions in all cases; especially in the case of constant initforms, they will probably make a closure of an existing function.) This implies that one cannot use metaclass protocol to recover the original forms that appeared in the defclass. Maybe we didn't agree on this, I couldn't find anything about it in my notes from the meeting. Can we converge on this now?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 20:06:46 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 27 Jul 87 17:00:15 PDT Received: from relay2.cs.net by RELAY.CS.NET id ad05828; 27 Jul 87 17:02 EDT Received: from ti-csl by RELAY.CS.NET id aw25936; 27 Jul 87 16:51 EDT Received: from Jenner by tilde id AA12921; Mon, 27 Jul 87 09:16:28 CDT Message-Id: <2763382458-15423174@Jenner> Date: Mon, 27 Jul 87 09:14:18 CDT From: Patrick H Dussud To: Dick Gabriel Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class Redefinition In-Reply-To: Msg of 24 Jul 87 1645 PDT from Dick Gabriel Date: 24 Jul 87 1645 PDT From: Dick Gabriel Subject: Class Redefinition The problem with class redefinition is that the updating of instances can be caused by arbitrary events, as far as the user is concerned. If none of DEFCLASS, ADD-METHOD, MAKE-METHOD, CLASS-NAMED, the evaluation of the special form FUNCTION, and garbage collection can update instances, then if a CLOS implementation does not have multitasking, the following will work (or something like it): (let ((obsolete-class (class-named 'heh-heh))) (defclass heh-heh ...) (add-method #'class-changed (make-method ;later, make-instance () `(,obsolete-class ,(class-named 'heh-heh)) #'...))) This code is not quite right, the new class object (produce by defclass heh-heh is the same as the old one (the one you bound to obsolete-class). [pg 1-11] The following will work. (let ((current-class (class-named 'heh-heh))) (defclass heh-heh ...) (add-method #'class-changed (make-method ;later, make-instance () `(,(get-obsolete-version current-class) ,current-class) #'...))) If there is a CLOS implementation with all of the properties named above except it does have multitasking (including incremental GC), then some form or macro like ATOMICALLY wrapped around the above will work. Right. However, the CPU time spent in ATOMICALLY can be quite large, realistically some implementation will not be able to give an upper bound for its elapsed time from start to completion. If a CLOS implementation has to make sure that this time is kept short, it will have to bear yet another constraint that could be avoided. Something like this should work: (let ((obsolete-class (class-named 'heh-heh)) (new-class (make-instance 'standard-class ...))) ;make an anonymous class ;that is the new HEH-HEH (add-method #'class-changed (make-method ;later, make-instance () `(,obsolete-class ,new-class) #'...)) (name-that-class new-class 'heh-heh)) ;Hm, what is this function? This does not work for the same reason the first example did not work. However I don't see how to fix this one without resorting to my proposal. It would go like this: (let* ((current-class (class-named 'heh-heh)) (obsolete-class (assoc current-class (GET-OBSOLETE-CLASSES-FOR-REDEFINITION current-class)))) (add-method #'class-changed (make-method ;later, make-instance () `(,obsolete-class ,current-class) #'...)) (defclass heh-heh ...)) ;(name-that-class new-class 'heh-heh)) I think, though, that it probably makes sense to have Danny's version of GET-OBSOLETE-CLASS for the same reason that I don't like UNIX - it's too easy to do a DEFCLASS of an existing class and then wish you had a handle on the old one. I think we need to decide whether Patrick's versions of getting obsolete classes are worth having around to simplify life. If you can find another solution to your second example (ie without using ATOMICALLY), I would be inclined to live with Danny's proposal. I think we forgot to define NAME-THAT-CLASS. It should be the thing such that MAKE-INSTANCE + ( ) = (DEFCLASS NAME ...). This thing will be in the metaclass protocol Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 15:29:43 EDT Date: 27 Jul 87 1224 PDT From: Dick Gabriel Subject: Class Redefinition To: common-lisp-object-system@SAIL.STANFORD.EDU Moon says: . I know that the specification states that my code won't work, but many folks (and not unsophisticated ones) will think it should. It would be nice if different classes weren't EQ. Is there no way to make this work? Isn't it true that the only place we need to have a class and its redefined class be the same is within method selection, and can't we use surrogates there? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 15:06:14 EDT Date: 27 Jul 87 1159 PDT From: Dick Gabriel Subject: Name That Class To: common-lisp-object-system@SAIL.STANFORD.EDU (setf (class-named ...) ...) is good. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 13:52:30 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jul 87 10:46:17 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 JUL 87 10:46:00 PDT Date: 27 Jul 87 10:45 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Name That Class In-reply-to: David A. Moon 's message of Mon, 27 Jul 87 12:53 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM Message-ID: <870727-104600-1451@Xerox> I thought CLASS-NAMED was SETF'able, but 87-002 doesn't say so. Should we change that? Yes. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 13:07:19 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87 10:01:41 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 199639; Mon 27-Jul-87 12:58:38 EDT Date: Mon, 27 Jul 87 12:58 EDT From: David A. Moon Subject: Class Redefinition To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 24 Jul 87 19:45 EDT from Dick Gabriel Message-ID: <870727125813.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 24 Jul 87 1645 PDT From: Dick Gabriel .... Something like this should work: (let ((obsolete-class (class-named 'heh-heh)) (new-class (make-instance 'standard-class ...))) ;make an anonymous class ;that is the new HEH-HEH (add-method #'class-changed (make-method ;later, make-instance () `(,obsolete-class ,new-class) #'...)) (name-that-class new-class 'heh-heh)) ;Hm, what is this function? This doesn't conform to 87-002's specification that redefining a class updates the existing class object, rather than replacing it with a new class object. Indeed, if we changed that, we wouldn't need the concept of "obsolete classes", as I pointed out in my message of early Saturday morning (sent after you wrote this message, but before I saw your message; we've had a lot of network problems lately, first with window-caulkers parking their scaffolding in the middle of the through-the-air segment of our network for a week, then MIT air conditioning failure, and who knows what else.) However, because methods are classified by class objects rather than class names, replacing the old class object with a new one has its own complexities.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 13:06:52 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87 10:01:19 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 199633; Mon 27-Jul-87 12:53:29 EDT Date: Mon, 27 Jul 87 12:53 EDT From: David A. Moon Subject: Name That Class To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 24 Jul 87 19:45 EDT from Dick Gabriel Message-ID: <870727125306.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 24 Jul 87 1645 PDT From: Dick Gabriel I think we forgot to define NAME-THAT-CLASS. It should be the thing such that MAKE-INSTANCE + ( ) = (DEFCLASS NAME ...). I thought CLASS-NAMED was SETF'able, but 87-002 doesn't say so. Should we change that?  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 12:39:22 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 27 Jul 87 09:32:43 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Mon, 27 Jul 87 09:31:19 pdt Received: from hplabsz.hpl.hp.com by hplms1; Mon, 27 Jul 87 09:30:46 pdt Return-Path: Received: by hplabsz; Mon, 27 Jul 87 07:45:32 pdt Message-Id: <8707271445.AA11199@hplabsz.hpl.hp.com> To: rpg@SAIL.STANFORD.EDU Cc: common-lisp-object-system@SAIL.STANFORD.EDU, olthoff@hplabsz.hpl.hp.com, kempf@hplabsz.hpl.hp.com Subject: Technical corrections in 87-002 X-Mailer: mh6.5 Date: Mon, 27 Jul 87 07:45:28 -0800 From: kempf%hplabsz@hplabs.HP.COM Dick: Apologies if this arrives more than once. Our mail system is changing. The formal specification of method application and combination is completed, and a couple of omissions, typos, and other technical errors were found. While I agree with Moon that it probably isn't a good idea to inject a level of formalism into CLOS beyond that customary for the Common Lisp community, I hope that the results of work from those who are interested in such formalism can be fed back into the design process, in the spirit of trying to make the CLOS specification as precise as possible. Here are the corrections: 1) The use of the term "partial order" on pg. 1-15, paragraph 1 implies a relation on R which is reflexive, antisymmetric, and transitive. From the text of the paragraph, this relation is presumably the "is a subclass of" relation. However, earlier in the document, reflexivity is explicitly excluded from the "is a subclass of" relation (pg. 1-4, paragraph 3), since a class is defined to be neither a superclass nor a subclass of itself. Either the partial order needs to be replaced with a different order not requiring reflexivity (semiorder, etc.) or the "is a subclass of" relation needs to be redefined so that it is reflexive. Note that the latter solution is used in more technical treatments of typing systems (e.g. Cardelli and Wegner, Computing Surveys, 17, 1985, pp. 471-522). 2) As noted in the followup to my posting of the preliminary formal specification for method applicaton and combination, the phrase "either method may precede the other" on p. 1-21, last paragraph is not technically correct, since the two methods are incomparable with regard to precedence. The algorithm is nevertheless sound, because it describes sorting of method equivalence classes rather than methods, and precedence between equivalence classes, so the ordering of elements in a specific equivalence class is arbitrary. 3) With reference to my original posting, the case of both specializers being quoted objects cited on pg. 1-22, paragraph 3 cannot occur at that point in the algorithm. Either one or the other can be a quoted object, but since , by that point in the algorithm: a) the two methods being compared must differ on the parameter specializer, and, b) in order for a method to be applicable at all and the specializer to be a quoted object, the specializer must be EQL to the parameter, this condition cannot occur. 4) The formal description of class precedence list calculation on pg. 1-15, paragraph 3 is lacking a condition. In the third line, it is not sufficient just to require the existence of an index i, but also its minimality. As a counterexample, consider R := {(c1,c2) (c2,c3) (c3 c5) (c2 c4) (c4 c6)} The inheritance graph for this is; c5 c6 | | c3 c4 | | \ / \ / c2 | c1 In the first step, cpl := [c1] and R := R\{(c1,c2)}, where A\B denotes the set A with all elements of A INTERSECT B removed (quotient set). Next step: cpl := [c1 c2] and R := {(c2,c3) (c2,c4)}. Now the set of classes without predecessors is {c3 c4}. Then, according to the description of the algorithm on pg. 1-15 paragraph 3, j=2 is the largest number such that "there exists i=3 with c3 being the direct superclass of c2," but i=4 also holds with this property, so it cannot be determined whether c3 or c4 should be added to the class precedence list. Requiring the minimal i to be used will remove the ambiguity, in the example, making c3 the next element of the cpl. I hope these corrections can be added to the next draft of the CLOS document. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Jul 87 12:37:04 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 27 Jul 87 09:29:49 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Mon, 27 Jul 87 09:28:47 pdt Received: from hplabsz.hpl.hp.com by hplms1; Mon, 27 Jul 87 09:28:24 pdt Return-Path: Received: by hplabsz; Mon, 27 Jul 87 09:26:23 pdt Message-Id: <8707271526.AA11550@hplabsz.hpl.hp.com> To: Dick Gabriel Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class Redefinition In-Reply-To: Your message of 24 Jul 87 16:45:00 -0700. Date: Mon, 27 Jul 87 09:26:20 -0700 From: kempf%hplabsz@hplabs.HP.COM > > (name-that-class new-class 'heh-heh)) ;Hm, what is this function ? > I think we forgot to de> f> ine NAME-THAT-CLASS. It should be the thing such > that MAKE-INSTANCE + ( ) = (DEFCLASS NAME ...). Something like: (setf (class-name new-class) 'heh-heh) should work. The name is not listed as a slot in STANDARD-CLASS in the 87-003 metaobject protocol, however. jak ------- End of Forwarded Message  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Jul 87 10:27:01 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 25 Jul 87 07:20:02 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198991; Sat 25-Jul-87 01:27:15 EDT Date: Sat, 25 Jul 87 01:26 EDT From: David A. Moon Subject: Class redefinition and class-changed. To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <2761765326-16486571@Jenner>, <870709-115412-4166@Xerox>, <2761916421-9049515@Jenner>, <8707151658.AA08774@hplabsz.hpl.hp.com>, <2762427556-15862063@Jenner>, <870723-194110-1523@Xerox>, <2763117294-15749125@Jenner>, <870724-085147-2517@Xerox>, <2763144693-1137879@Jenner> Message-ID: <870725012629.9.MOON@EUPHRATES.SCRC.Symbolics.COM> I have several comments to offer on this conversation. I haven't managed to organize the separate comments into as coherent a whole as I would like. I believe Patrick's argument that it is necessary to define the CLASS-CHANGED method -before- redefining the class. Symbolics has a lot of experience with doing it the other way and it's unpleasant. I hope the reasoning for this has been established now and doesn't need additional argument (Danny, please speak up if you don't believe it yet). I don't like Patrick's particular proposal, though. GET-OBSOLETE-CLASSES-FOR-REDEFINITION is too complicated, because it returns a whole alist rather than being just the primitive. In addition, I don't think the set of "classes implicated in the class-redefinition of CLASS" is computable until the details of the redefinition are known. Suppose (defclass one () (a b)) (defclass two (one) (c)) (defclass three (one) (d)) Now suppose we redefine one as follows: (defclass one () (a b d)) Referring to the third paragraph on page 1-11 of 87-002, one and two are "implicated", but three is not, or at least, whether three is implicated is implementation-dependent. But if the new slot had been named e, both two and three would have been implicated. I don't think the information in Patrick's alist is needed anyway; when defining a method, one only defines it for the obsolete class corresponding to one class. If a different method needs to be defined for an obsolete subclass, the function can be called again. Thus I would replace Patrick's proposal with GET-OBSOLETE-CLASS-FOR-REDEFINITION which takes one argument, a class, and returns one value, the obsolete class that is a copy of the current definition of the class and will be used the next time the class is redefined; this is created the first time you ask for it. Perhaps GET-OBSOLETE-CLASS-FOR-NEXT-REDEFINITION would be a better name. As Danny proposed, a primitive to get the obsolete classes corresponding to redefinitions that have already taken place is useful, for instance in case you didn't realize ahead of time that you would need a CLASS-CHANGED method and now want to patch up the program. I would suggest a function GET-OBSOLETE-CLASSES-FOR-PAST-REDEFINITIONS which takes one argument, a class, and returns one value, a list of obsolete classes, newest first. There seems to be some confusion about how class redefinition works in CLOS and what an "obsolete class" is. Let me restate what the 87-002 document says in simpler language: Redefining a class never creates a new class object to replace the existing class object; it always modifies the existing class object. Thus there are no objects that exactly represent "versions" of a class. There is also the concept of "obsolete instances", which have dynamic extent and are created solely to pass as the first argument to CLASS-CHANGED. When CLASS-CHANGED is called as a result of the user calling CHANGE-CLASS, the obsolete instance is simply an instance of the old class. When CLASS-CHANGED is called as a result of updating an instance to reflect the latest definition of its class, the obsolete instance contains the slot values of the un-updated instance and therefore needs to have a class that has those slots: this is an "obsolete class". An obsolete class is a copy of a class remembering the slots, methods, and superclasses it had before it was redefined. Redefining a class only creates an obsolete class when certain kinds of changes are made to the class (see the third paragraph on page 1-11 of 87-002). For each past version of a class that is sufficiently different from the current version, there is an obsolete class object. Note that these are all obsolete versions of the original class, they are not obsolete versions of each other. Redefining a class also redefines subclasses of the class, so several obsolete classes could be created. 87-002 doesn't say so, but I believe the obsolete subclasses should be subclasses of the obsolete class and not of the original class. The second paragraph on page 1-12 of 87-002 could be interpreted as saying that the only methods that are applicable to an obsolete instance I-sub-O are the methods M-sub-C that were deleted from the class when it was redefined. I do not believe this is what was intended--I believe we intended to say that all methods that were applicable to instances of the class before it was redefined are applicable to I-sub-O (unless additional redefinitions have been done, for instance deleting those methods entirely). If we really intended only deleted methods to be applicable, it would be remarkably useless: for instance, deleted slots could be accessed by normal means, but non-deleted slots could not be accessed except by SLOT-VALUE, except in the case where the :ACCESSOR slot-option had been removed. Again, in the x-y-rho-theta example, if methods for accessing values that are conceptually slots but are not physically represented as slots were not applicable, it would be necessary to violate modularity and duplicate the functionality of those methods within the CLASS-CHANGED method. We have our choice of three ways to define what happens when a class is redefined: (1) A new class object is created, the name-to-class-object mapping is changed, defclass-defined methods implied by the new definition are put on the new class object, all methods other than defclass-defined methods that apply to the old class are made to apply also to the new class, subclasses of the old class are made to be subclasses of the new class instead, and superclasses of the old class are made to be also superclasses of the new class. If we had done this, there would have been an explicit representation of versions of a class, and there would not have been any concept of "obsolete classes." (2) The old class object is modified, defclass-created methods that aren't created by the new defclass are removed, new defclass-created methods are added, an anonymous obsolete class object is created, the modification is propagated to subclasses which may create obsolete class objects for them that are subclasses of the first obsolete class created, superclasses of the original class are to be also superclasses of the obsolete class, and all methods that applied to the original class are made to apply also to the new class. (2) is what we did in 87-002. (2) is not simpler than (1), but it has the advantage that classes maintain their identity as objects. (3) There is a third way, which I will describe later in this message. Referring again to the third paragraph on page 1-11 of 87-002, there is another use for a primitive to get the obsolete class before redefining the class. Not all redefinitions of a class call CHANGE-CLASS and CLASS-CHANGED. Suppose someone changes a class in such a way that they need to call a function to update each instance, but they have not actually add, removed, or renamed slots. 87-002 does not provide any mechanism for this. The programmer would probably resort to adding a dummy slot to force instance updating. I think a better approach would be to specify that calling GET-OBSOLETE-CLASS-FOR-NEXT-REDEFINITION forces the next redefinition of this class (directly or by redefining a superclass) to update instances, even if it would not otherwise need to. There are basically three approaches to the problem of writing a CLASS-CHANGED method that updates an instance to reflect one particular edit of the class's definition: (1) Use the classes of the two arguments to CLASS-CHANGED to encode this information. This is what the 87-002 document says, however it doesn't work. (2) Use a third argument to CLASS-CHANGED to encode the information, such as a sequence number saying how many times the class had been redefined. This seems kludgey and was rejected in the past. (3) Don't allow such precise control over instance updating in CLOS, instead only allow CLASS-CHANGED methods that work for updates from -any- version of the class to the current version. This is copping out, however it's practical, since it's what Flavors does. There are two reasons (1) doesn't work. First, 87-002 doesn't provide a way to get the obsolete class for a particular edit, which you need in order to define a method that applies specifically to that edit. This is what Patrick's proposal addresses. Second, there is a problem when the class is redefined multiple times. Suppose we do (defclass foo () (a)) (defclass foo () (a b)) (defclass foo () (a b c)) (defclass foo () (a b c d)) and in connection with the third definition we need a CLASS-CHANGED method to initialize the slot C. We don't want this method to be called for instances that already have a slot C and are getting a slot D added, so we want the method to specialize its first parameter as well as its second. The problem is that CLOS has no way to define one method that applies to the first and second obsolete classes, but not to the third obsolete class. In order to define this method, we have to know the exact editing history of the class FOO, which seems unreasonable. We can't fix this by making the second obsolete class a subclass of the first obsolete class, because if the user removes a slot we would have a class that has fewer slots than its superclass, which CLOS does not allow. We could call GET-OBSOLETE-CLASSES-FOR-PAST-REDEFINITIONS to get the entire list of obsolete classes for the class FOO, and then we could iterate over that list seeing which obsolete classes had a slot C and which didn't, and define CLASS-CHANGED methods accordingly, but this starts to look like an elaborate rigamarole for something that should have been simple. The above assumes that we believe what page 1-12 of 87-002 implies, namely that instances are updated directly to the latest version of the class ("the second argument is an instance of the class C"). Alternatively, we could specify that "ontogeny recapitulates phylogeny" and the instance is repeatedly updated one step at a time, until it reaches the current definition of its class. In the FOO example above, we would define the CLASS-CHANGED method that initializes C to specialize its first parameter to the second obsolete class, with confidence that instances of the original FOO would first get a slot B, then would get a slot C, then would get a slot D, and in the second of the three steps, our method would be called. This means that -both- arguments to CLASS-CHANGED could be instances of obsolete classes. It also means that our CLASS-CHANGED method can't specialize its second parameter, because at first that will be the class FOO, but after FOO is redefined again, it will be an obsolete class. If we don't specialize the second parameter, it seems we could be confused by CLASS-CHANGED being called when CHANGE-CLASS was used to change an instance of FOO into an instance of BAR. This is not a problem if CHANGE-CLASS, like all other generic functions, first updates its argument to the latest definition of its class, before changing it to the new class; then a method specialized to an obsolete class in its first parameter can never be called with the second parameter an instance of anything other than the next newer version of the same class. This all seems slightly kludgey, but does seem like it should work. Is there any chance of garbage collecting all these obsolete classes when there are no longer any instances that haven't been updated yet? We'd also like to garbage collect the data structures required to make methods applicable to the original class also applicable to the obsolete class. I doubt it's possible to GC this stuff, the whole data structure seems too interconnected. The third way to define what happens when a class is redefined, mentioned earlier, is as follows: Don't try to use CLASS-CHANGED for both changing the class of an instance and updating an instance to a new version of its class. Invent a new generic function CLASS-REDEFINED, which is called when an instance is updated to a new version of its class. This avoids the complicated concept of "obsolete classes", at the cost of conveying the former state of the instance in a less object-oriented fashion. Perhaps CLASS-REDEFINED would receive three arguments: an instance of the class, already updated to the latest definition of the class, a property list associating slot names to slot values, with one entry for each slot that is no longer present, and a list of slot names of slots that were newly added to the instance. Thus when a class is redefined: (3) The old class object is modified, defclass-created methods that aren't created by the new defclass are removed, new defclass-created methods are added, and the modification is propagated to subclasses. This is simpler than (1) or (2). The FOO example given above is implemented by defining a CLASS-REDEFINED method that checks whether slot C is a new slot before initializing it. The problem is that there can only be one CLASS-REDEFINED method, since there is only one class object, so if the class is redefined multiple times in ways that need CLASS-REDEFINED methods, this one method must contain unmodular knowledge of all the redefinitions. In addition, in the x-y-rho-theta example, if there are methods for accessing values that are conceptually slots but are not physically represented as slots, the CLASS-REDEFINED method has to know about the underlying slots used by these methods, in case those slots have been deleted. This "third way" seems simpler than the other two, so I hope that someone can debug the problems mentioned in the previous paragraph. If not, we need to make several changes mentioned here and there in this message in order to make obsolete classes work.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Jul 87 10:25:06 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 25 Jul 87 07:19:49 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198981; Fri 24-Jul-87 22:34:00 EDT Date: Fri, 24 Jul 87 22:33 EDT From: David A. Moon Subject: Category Errors To: Common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 24 Jul 87 14:36 EDT from Dick Gabriel Message-ID: <870724223320.7.MOON@EUPHRATES.SCRC.Symbolics.COM> As a believer in open systems who doesn't think there should be distinctions between system and user programs, I believe that Dick's arguments for defense against defining bogus methods for MAKE-INSTANCE are equally as good arguments for defense against defining bogus methods for any user-defined generic function. Remember that not all user-written programs are used only by their author. Dick, would you agree that if CLOS removes this blemish, it should be done with a mechanism that is easily accessible to the programmer-in-the-street? My second point was that although I favor removing this blemish, CLOS currently contains several other similar blemishes added in the name of simplicity (example, no equivalent to Flavors' :required-methods defflavor option), so I predict that we will end up leaving this blemish in. That's not an argument, just an observation.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 19:51:14 EDT Date: 24 Jul 87 1645 PDT From: Dick Gabriel Subject: Class Redefinition To: common-lisp-object-system@SAIL.STANFORD.EDU The problem with class redefinition is that the updating of instances can be caused by arbitrary events, as far as the user is concerned. If none of DEFCLASS, ADD-METHOD, MAKE-METHOD, CLASS-NAMED, the evaluation of the special form FUNCTION, and garbage collection can update instances, then if a CLOS implementation does not have multitasking, the following will work (or something like it): (let ((obsolete-class (class-named 'heh-heh))) (defclass heh-heh ...) (add-method #'class-changed (make-method ;later, make-instance () `(,obsolete-class ,(class-named 'heh-heh)) #'...))) If there is a CLOS implementation with all of the properties named above except it does have multitasking (including incremental GC), then some form or macro like ATOMICALLY wrapped around the above will work. Something like this should work: (let ((obsolete-class (class-named 'heh-heh)) (new-class (make-instance 'standard-class ...))) ;make an anonymous class ;that is the new HEH-HEH (add-method #'class-changed (make-method ;later, make-instance () `(,obsolete-class ,new-class) #'...)) (name-that-class new-class 'heh-heh)) ;Hm, what is this function? I think, though, that it probably makes sense to have Danny's version of GET-OBSOLETE-CLASS for the same reason that I don't like UNIX - it's too easy to do a DEFCLASS of an existing class and then wish you had a handle on the old one. I think we need to decide whether Patrick's versions of getting obsolete classes are worth having around to simplify life. I think we forgot to define NAME-THAT-CLASS. It should be the thing such that MAKE-INSTANCE + ( ) = (DEFCLASS NAME ...). -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 18:07:06 EDT Date: 24 Jul 87 1459 PDT From: Dick Gabriel Subject: Category Errors To: common-lisp-object-system@SAIL.STANFORD.EDU Danny says: ``We have NOT laid out the range of legal arguments for generic functions.'' My comment was: ``We've carefully laid out, in most cases, the range of legal arguments to functions and generic functions in CLOS....'' I guess I shouldn't rely on subtle wording to get across a subtle point. Here is a generic function ``in CLOS'': Add-method generic-function method And here is how we have ``carefully laid out ... the range of legal arguments'' to it: Arguments: The generic-function argument is a generic function object. The method argument is a method object. The lambda-list of the method function must be congruent with the lambda-lists of any other methods associated with the generic function and with the lambda-list of the generic function. (page 2-5, FUNCTIONS) The thing in CLOS that is already the same sort of ``blemish'' as this category error is discrimination on individuals. Blemish, beauty mark: At least we can agree that in both cases an observer is justified in thinking ``what's that thing?'' -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 17:43:55 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jul 87 14:36:59 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198777; Fri 24-Jul-87 17:02:52 EDT Date: Fri, 24 Jul 87 17:02 EDT From: David A. Moon Subject: First Try at Terminology To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 8 Jul 87 12:28 EDT from Dick Gabriel Message-ID: <870724170213.5.MOON@EUPHRATES.SCRC.Symbolics.COM> I might quibble with one or two details, in particular the idea that it is possible to prevent programmers from discovering and depending upon what a particular implementation does in a particular undefined situation, however on the whole this seems pretty good. I'd like to see the terminology for erroneous situations tightened up for all of Common Lisp, not just CLOS. I don't think that it's the business of the CLOS subcommittee to do this. In other words, I'm uncomfortable with the idea that "the CLOS subcommittee of X3J13 is the only subcommittee that ever does anything" (incidentally this is not quite true) implies that "the CLOS subcommittee should do everything." We can use a working terminology in our deliberations, but we should be prepared to convert to whatever standard terminology is defined for Common Lisp as a whole, when that happens. This suggests that we should do something fairly simple and not develop an elaborate formalism. Simply separating the cases of "an error is always signalled", "an error is signalled unless you tell the compiler not to check for it", "the effect is undefined", and "the effect is implementation-dependent" seems sufficient to me.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 17:43:47 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jul 87 14:36:38 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198754; Fri 24-Jul-87 16:44:25 EDT Date: Fri, 24 Jul 87 16:43 EDT From: David A. Moon Subject: initialization meeting notes To: Gregor.pa@Xerox.COM cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <870723180901.2.GREGOR@SPIFF.isl.parc.xerox.com> Message-ID: <870724164346.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No There's a bunch of other stuff in the notes that didn't make it into your message. Perhaps I'll send a summary of that in a later message, but the most important thing right now from my point of view was a statement (page 4) about open-coding which I think means that the procedural model is to be done in such a way that it does not decrease achievable performance of creating instances; in particular, the system is allowed to recognize that the standard methods are being called for make-instance of a particular class and use a different implementation that produces equivalent results. This will have to be defined in more precise language in the final specification, so that it is quite clear what users can and cannot depend on.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 17:33:55 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Jul 87 14:22:08 PDT Received: from relay2.cs.net by RELAY.CS.NET id ah10487; 24 Jul 87 17:10 EDT Received: from ti-csl by RELAY.CS.NET id am08816; 24 Jul 87 17:04 EDT Received: from Jenner by tilde id AA14334; Fri, 24 Jul 87 15:24:33 CDT Message-Id: <2763145381-1179246@Jenner> Date: Fri, 24 Jul 87 15:23:01 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Category Errors In-Reply-To: Msg of Fri, 24 Jul 87 14:33 EDT from "David A. Moon" STANDARD-CLASS does not support metaclass specific methods like CLASS-PROTOTYPE, METACLASS-CLASS does. This part, however, won't work. As I understand it, CLASS-PROTOTYPE has to work on all classes, because of the way the generic function dispatching in the initialization protocol is going to work. We still haven't nailed down the initialization protocol, but I think the part of it we all seem to agree on already requires all classes to have a prototype. This is true, I forgot about it when I wrote this part. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 17:27:37 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Jul 87 14:21:16 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa10495; 24 Jul 87 17:10 EDT Received: from ti-csl by RELAY.CS.NET id al08816; 24 Jul 87 17:04 EDT Received: from Jenner by tilde id AA14079; Fri, 24 Jul 87 15:14:43 CDT Message-Id: <2763144693-1137879@Jenner> Date: Fri, 24 Jul 87 15:11:33 CDT From: Patrick H Dussud To: Danny Bobrow Cc: DUSSUD%Jenner%ti-csl.CSNet@RELAY.CS.NET, common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class redefinition and class-changed. In-Reply-To: Msg of 24 Jul 87 08:48 PDT from Danny Bobrow Date: 24 Jul 87 08:48 PDT From: Danny Bobrow Subject: Re: Class redefinition and class-changed. It doesn't have to guess. If the class changed method is defined before any any method is called on an obsolete instance, it will be used. Otherwise not. Hence users should define such class-changed methods immediately (soon) after redefining the class. In multiprocessing or interruptible environment, immediately is a weak concept at best. You might get in a race condition with another computation unit that touches instances. Furthermore, you can't prove that some instances haven't been updated before you define the changed-class method. How do you propose to solve this? Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 17:26:45 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 24 Jul 87 14:20:00 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUL 87 14:19:44 PDT Date: 24 Jul 87 14:19 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Category Errors In-reply-to: Dick Gabriel 's message of 24 Jul 87 11:36 PDT To: RPG@SAIL.STANFORD.EDU cc: Common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870724-141944-3247@Xerox> My point was that one could rationally design CLOS to be able to distinguish between classes and meta-classes, and hence we would be justified in trying to prevent category errors. If it were clear that one could be sure that a definition were in error, then perhaps we could consider enforcing some restrictions. However, it is a rational thing to experiment with various new types of object system, defining methods for all the protocol of interest, and not use any preexisting class as a super-class (this is particularly a good idea if one wants to make sure that the new implementation is complete). To force a user to use a particular (perhaps empty) metaclass just for a declaration surely violates the spirit of Lisp. We've carefully laid out, in most cases, the range of legal arguments to functions and generic functions in CLOS; we could easily do that here, whereas it's difficult to control a user who wants to act irrationally with code all of his own invention. We have NOT laid out the range of legal arguments for generic functions. We have specified how they behave for arguments of particular classes; tha is, we have described some method(s) on generic functions, and their contract. A major point of object oriented programming is to allow users to add their own methods to generic functions. To talk about THE AUTHOR OF A GENERIC FUNCTION is to make the same mistake. Generic functions have certain contracts, but not ones that restrict them to certain classes of arguments. I think that to dismiss the point as some fluke in thought process before understanding the issues does ill justice to the specification process, even though I believe we will allow the blemish. I think understanding the issue is important. So we agree on that point. But I feel that the "blemish" is really a beauty mark. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 14:43:28 EDT Date: 24 Jul 87 1136 PDT From: Dick Gabriel Subject: Category Errors To: Common-lisp-object-system@SAIL.STANFORD.EDU Moon writes: ``I don't think this is fundamentally different from someone defining a method on spaceships for a generic function that is only supposed to be used with windows.'' Danny replies: ``I think this is exactly right.'' As I mentioned in my note, I don't care that this blemish appears in CLOS, but I do insist that we understand that reasonable people will consider it to be a blemish. The reason for this is also the reason that Danny's reply is incorrect. The differences between someone writing a method on spaceships for a generic function that is only supposed to be used with windows and someone writing a method on a base-level class for the generic function MAKE-INSTANCE are these: 1. MAKE-INSTANCE is a generic function defined in CLOS, and we have the ability to enforce the user not making this sort of error. We've carefully laid out, in most cases, the range of legal arguments to functions and generic functions in CLOS; we could easily do that here, whereas it's difficult to control a user who wants to act irrationally with code all of his own invention. 2. Mistakenly writing methods for some class not intended to be the subject of the generic function by the author of that generic function is most likely a user-level semantic error, while defining a method on a class where the person defining the generic function intends methods to be on meta-classes is a category error - that's why I called it a ``category error'' rather than a ``source of potential user bugs.'' The error lies in confusing two levels of classes defined in CLOS rather than in confusing two classes defined by a user. My point was that one could rationally design CLOS to be able to distinguish between classes and meta-classes, and hence we would be justified in trying to prevent category errors. Or we could choose not to do that. I think that to dismiss the point as some fluke in thought process before understanding the issues does ill justice to the specification process, even though I believe we will allow the blemish. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 14:39:15 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jul 87 11:33:48 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198616; Fri 24-Jul-87 14:34:24 EDT Date: Fri, 24 Jul 87 14:33 EDT From: David A. Moon Subject: Re: Category Errors To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <2762944528-5369042@Jenner> Message-ID: <870724143345.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 22 Jul 87 07:35:28 CDT From: Patrick H Dussud .... I propose the following in order to categorize metaclass programming and class programming: CLASS | STANDARD-CLASS | METACLASS-CLASS Now, all metaclass objects are instances of METACLASS-CLASS instead of STANDARD-CLASS. This is to say that standard-class can be defined like: (defclass STANDARD-CLASS (CLASS) (:metaclass METACLASS-CLASS)) I believe this is a good suggestion. That is, it appeals to my aesthetic sense, although I have not been able to come up with any specific programming activities that require it. STANDARD-CLASS does not support metaclass specific methods like CLASS-PROTOTYPE, METACLASS-CLASS does. This part, however, won't work. As I understand it, CLASS-PROTOTYPE has to work on all classes, because of the way the generic function dispatching in the initialization protocol is going to work. We still haven't nailed down the initialization protocol, but I think the part of it we all seem to agree on already requires all classes to have a prototype. Similarly, functions like CLASS-DIRECT-SUPERCLASSES are part of metaclass programming, but that doesn't mean they are only applicable to metaclasses. They are applicable to all classes.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 12:00:53 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 24 Jul 87 08:54:27 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUL 87 08:51:47 PDT Date: 24 Jul 87 08:48 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Class redefinition and class-changed. In-reply-to: Patrick H Dussud 's message of Fri, 24 Jul 87 07:34:54 CDT To: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870724-085147-2517@Xerox> I think we should specify that instance updating will not occur before the first method on an obsolete instance is called. I see two problems with this approach: - How would the environment guess that a class-changed method will (or will not) be defined? It doesn't have to guess. If the class changed method is defined before any any method is called on an obsolete instance, it will be used. Otherwise not. Hence users should define such class-changed methods immediately (soon) after redefining the class. - Even if you see it as an environment support, we need to specify this support at the metaclass level since class redefinition will be specified. I don't think we can afford to leave holes like that in the metaclass protocol. The meta-object support necessary is to provide a mechanism to obtain the obsolete class so that class-changed methods can be defined, and to specify when these methods can be defined in order to effect all instances that need to be updated. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jul 87 09:29:11 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Jul 87 06:23:14 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa05351; 24 Jul 87 9:23 EDT Received: from ti-csl by RELAY.CS.NET id aa06359; 24 Jul 87 9:16 EDT Received: from Jenner by tilde id AA01610; Fri, 24 Jul 87 07:33:49 CDT Message-Id: <2763117294-15749125@Jenner> Date: Fri, 24 Jul 87 07:34:54 CDT From: Patrick H Dussud To: Danny Bobrow Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class redefinition and class-changed. In-Reply-To: Msg of 23 Jul 87 19:41 PDT from Danny Bobrow I agree that your arguments imply your conclusion. I think however, that it would be better to say that "updating of the instances is done at an implementation-dependent time sometime after the class is redefined." Since this is really an environment support feature, I think we should specify that it will not occur before the first method on an obsolete instance is called. I see two problems with this approach: - How would the environment guess that a class-changed method will (or will not) be defined? - Even if you see it as an environment support, we need to specify this support at the metaclass level since class redefinition will be specified. I don't think we can afford to leave holes like that in the metaclass protocol. Patrick.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 23 Jul 87 23:00:11 EDT Received: from Burger.ms by ArpaGateway.ms ; 23 JUL 87 19:42:39 PDT Return-Path: Redistributed: commonloops.pa Received: from hplabs.HP.COM by Xerox.COM ; 23 JUL 87 19:41:14 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 23 Jul 87 16:25:35 pdt Received: from hplrds (hplrds) by hplms2; Thu, 23 Jul 87 15:35:01 pdt Return-Path: Received: from hplrds.hpl.hp.com by hplrds ; Thu, 23 Jul 87 15:34:46 pdt Message-Id: <8707232234.AA01212@hplrds> To: commonloops%hplrds@hplabs.HP.COM Cc: chiarelli%hplrds@hplabs.HP.COM, kempf%hplrds@hplabs.HP.COM Subject: 'Class-named' X-Mailer: mh6.5 Date: Thu, 23 Jul 87 15:34:42 PDT From: Roy D'Souza If you make the change to 'class-named' that I suggested in my last message, you will also have to go through the PCL sources and edit all the places where 'class-named' is invoked, toggling the value, when supplied, for . There are 9 of these in 6 files: [Before:] defclass.l: (unless (class-named (cadr option) t) defclass.l: (let* ((existing (class-named name t)) defclass.l: (or (class-named super t) low.l: (class-named name t) methods.l: (or (class-named type-specifier nil) slots.l: `(not (null (memq (class-named ,type ()) std-class.l: (setq temp (class-named sup t))) std-class.l: (or (class-named class t) test.l: (let ((class (class-named c 't))) [After:] defclass.l: (unless (class-named (cadr option) nil) defclass.l: (let* ((existing (class-named name nil)) defclass.l: (or (class-named super nil) low.l: (class-named name nil) methods.l: (or (class-named type-specifier t) slots.l: `(not (null (memq (class-named ,type t) std-class.l: (setq temp (class-named sup nil))) std-class.l: (or (class-named class nil) test.l: (let ((class (class-named c 'nil))) Roy D'Souza dsouza@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jul 87 22:47:30 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jul 87 19:41:29 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 23 JUL 87 19:41:10 PDT Date: 23 Jul 87 19:41 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Class redefinition and class-changed. In-reply-to: Patrick H Dussud 's message of Fri, 10 Jul 87 10:00:21 CDT To: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870723-194110-1523@Xerox> The necessary and sufficient condition for this is to be able to get hold of an obsolete version of a class. I don't agree. We said in chapter 1 that the updating of the instances is done at an implementation-dependent time. I agree that your arguments imply your conclusion. I think however, that it would be better to say that "updating of the instances is done at an implementation-dependent time sometime after the class is redefined." Since this is really an environment support feature, I think we should specify that it will not occur before the first method on an obsolete instance is called. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jul 87 22:22:06 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jul 87 19:16:29 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 23 JUL 87 19:16:02 PDT Date: 23 Jul 87 19:15 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Category Errors In-reply-to: David A. Moon 's message of Tue, 21 Jul 87 12:35 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870723-191602-1486@Xerox> I don't think this is fundamentally different from someone defining a method on spaceships for a generic function that is only supposed to be used with windows. The only reason I can see that confusion between classes and metaclasses seems worse than confusion between spaceships and windows is that metaclasses are less familiar. I think this is exactly right. If we didn't want to follow the usual Lisp philosophy of giving the user enough rope to hang himself, Leave the rope. We don't put strong typing in Lisp either. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 Jul 87 21:19:39 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jul 87 18:12:34 PDT Received: from Semillon.ms by ArpaGateway.ms ; 23 JUL 87 18:11:32 PDT Date: Thu, 23 Jul 87 18:09 PDT From: Gregor.pa@Xerox.COM Subject: initialization meeting notes To: Common-Lisp-Object-System@Sail.Stanford.edu Message-ID: <870723180901.2.GREGOR@SPIFF.isl.parc.xerox.com> Line-fold: no In this message I try to summarize what we agreed at the meeting in Boston. The basis for this message is the 4 pages of notes which Sonya took and which Sonya, Dave and I went over just before the meeting ended. I have tried to include in this message only what we actually agreed on. I will send out my comments and suggestions in a separate message. First, a brief summary of what we agreed: - there will be a :initarg slot option - will will support remote initarg defaulting by having an defclass option like :default-initargs. - there will be a procedural model of how the whole thing works. Extensions to initialization behavior other than simple-slot-filling-initargs and initarg-remote-defaulting will be done by defining a method on the appropriate generic function. Another important thing which we agreed is that we are going to have to go back and re-examine our rules for argument list congruence. The existing rules clearly get in our way for doing initialization. In a separate message I will try to summarize those problems. In the meeting, we put up some code for make-instance and initialize-instance. I am including that here: (defmethod make-instance ((class-name 'symbol) &rest initargs) (apply #'make-instance (class-named class-name) initargs)) (defmethod make-instance ((class standard-class) &rest initargs) (let* ((proto (class-prototype class)) (defaulted-initargs (default-initargs proto initargs))) (check-initargs class defaulted-initargs) (let ((instance (apply #'allocate-instance class defaulted-initargs))) (apply #'initialize-instance instance defaulted-initargs) instance))) (defmethod initialize-instance ((obj object) &rest initargs) ;; The default initialize-instance method deals with setting the ;; values of slots from slot-filling-initargs and from initforms. ;; ;; The rules are that the leftmost initarg which is declared ;; as setting a slot (with the :initarg slot option) actually ;; does set it (or is it the rightmost?); and that slots which ;; are not set by an initarg have their :initform evaluated and ;; used to set them. ) An effect of putting the slot setting stuff in the default method on initialize-instance is that most programmers will want to define their initialize-instance methods as :after methods. This means an instance will get initialized in order from most general to least general. The default method for default-initargs implements the initarg remote defaulting behavior using the :default-initargs class option. The default method for check-initargs checks the validity of the initargs by checking two sources: 1. an initarg is valid if it is specified as a slot-filling initarg. 2. an initarg is valid if it is specified as a &key argument in one of the applicable methods on initialize-instance. Here is an example of a use of this protocol: (defclass ship () ((x :initarg :x) (y :initarg :y))) (defmethod initialize-instance :after ((s ship) &key startp) (when startp (start s))) (defmethod start ((s ship)) (with-slots ((s :use-accesors nil)) (if (and x y) (error "Have to set X and Y before starting a ship.")))) (defclass homing-ship (ship) () (:default-initargs :x 0 :y 0)) (defmethod home ((s homing-ship)) (with-slots ((s :use-accessors nil)) (setq x 0 y 0))) We also agreed that there would be documented functions for finding out about the initargs that set slots for a class and also finding out about the default initargs for a class. This doesn't seem to be too hard; the only serious problem has to do with arranging for a the default initarg value forms to be evaluated in the lexical environment of the defclass. (Of course if environments were first class objects this would be trivial...) -------  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 23 Jul 87 14:38:43 EDT Received: from Burger.ms by ArpaGateway.ms ; 23 JUL 87 11:28:11 PDT Return-Path: Redistributed: commonloops.pa Received: from seismo.CSS.GOV by Xerox.COM ; 23 JUL 87 11:22:14 PDT Received: from mcvax.UUCP by seismo.CSS.GOV (5.54/1.14) with UUCP id AA28609; Thu, 23 Jul 87 14:22:04 EDT Received: by mcvax.cwi.nl; Thu, 23 Jul 87 20:04:14 +0200 (MET) Received: by cernvax.UUCP (4.12/4.7) id AA01976; Thu, 23 Jul 87 19:16:42 +0200 Received: by delphi.uucp (1.1/SMI-3.0DEV3) id AA04084; Thu, 23 Jul 87 17:57:21 -0100 Date: Thu, 23 Jul 87 17:57:21 -0100 From: mcvax!delphi!stefano@seismo.CSS.GOV (Stefano Diomedi) Message-Id: <8707231657.AA04084@delphi.uucp> To: commonloops.pa@Xerox.COM Subject: make-call-arguments In PCL version 4/29/87 prime April 29, 1987 I had to change the function make-call-arguments (file "fixup.lsp") because: 1. it seemed not able to manage properly the supplied-p parameter optionally present in a keyword parameter. This is the actual change: (when key ;; &key appears in the lambda list. Remove &key from the ;; lambda list then replace all the keywords with pairs of ;; the actual keyword followed by the value variable. ;; Have to parse the hairy triple case of &key. (let ((key-args (iterate ((arg in (cdr key))) (until (eq arg '&allow-other-keys)) (cond ((symbolp arg) (collect (make-keyword arg)) (collect arg)) ; it seems a bug when there is a supplied-p parameter ; ((cddr arg) ; (collect (caddr arg)) ; (collect (car arg))) ; a possible solution - DELPHI 23 Jul 87 ((listp (car arg)) (collect (caar arg)) (collect (cadar arg))) (t (collect (make-keyword (car arg))) (collect (car arg))))))) (if key-args (setf (car key) (car key-args) (cdr key) (cdr key-args)) (setf (cdr key) nil lambda-list (remove '&key lambda-list))))) This is the example I used: ------------------------------------------------------------ ;;; ;;; testing the supplied-p parameters in defmethod ;;; (in-package 'pcl) (defclass point () (x y) (:accessor-prefix point-)) (defmethod move ((p point) &key newx newy &allow-other-keys) (with-slots (p) (setf x newx y newy)) ) (defclass 3d-point (point) v (z) (:accessor-prefix point-)) (defmethod move ((p 3d-point) &key newx newy (newz 0 newz-p)) (run-super) (with-slots (p) (setf z newz)) (when newz-p (print "newz-p"))) (setq pp (make-3d-point)) (move pp :newx 4 :newy 5 :newz 6) ------------------------------------------------------------ 2. it doesn't manage properly the optional variables This is the actual change: (let ((optional (memq '&optional lambda-list))) (when optional ;; The &optional keyword appears in the lambda list. ;; Get rid of it, by moving the rest of the lambda list ;; up, then go through the optional arguments, replacing ;; them with the real symbol. (setf (car optional) (cadr optional) (cdr optional) (cddr optional)) (iterate ((loc on optional)) #| (when (memq (car loc) lambda-list-keywords) (unless (memq (car loc) '(&rest &key &allow-other-keys)) (error "The non-standard lambda list keyword ~S appeared in the~%~ lambda list of a method in which CALL-NEXT-METHOD is used.~%~ PCL can only deal with standard lambda list keywords.")) (when (listp (car loc)) (setf (car loc) (caar loc)))) |# ; a possible solution - DELPHI 23 Jul 87 (if (memq (car loc) lambda-list-keywords) (progn (unless (memq (car loc) '(&rest &key &allow-other-keys)) (error "The non-standard lambda list keyword ~S appeared in the~%~ lambda list of a method in which CALL-NEXT-METHOD is used.~%~ PCL can only deal with standard lambda list keywords.")) (setq loc nil)) (when (listp (car loc)) (setf (car loc) (caar loc)))) ))) Stefano Diomedi DELPHI - Italy  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jul 87 19:06:19 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 22 JUL 87 15:47:57 PDT Date: 22 Jul 87 15:08 PDT From: Gregor.pa@Xerox.COM Subject: Re: Two questions and two comments In-reply-to: macgreg@vaxa.isi.edu's message of Thu, 02 Jul 87 15:53:06 PDT To: macgreg@vaxa.isi.edu cc: CommonLoops.pa@Xerox.COM Message-ID: <870722-154757-1030@Xerox> Here are some answers to questions you asked some time ago. Sorry for the delay. Sometimes I find myself holding onto a class object and wanting to know the value of one of its class variables. Does/will CLOS provide a way to access class variables other than via class instances (sometimes I haven't yet allocated any instances when I need the value)? Try using CLASS-PROTOTYPE to get the cached, prototype instance of a class. Like this: (slot-value (class-prototype *foo-class*) 'some-class-variable) Comment: For the sake of uniformity, I would vote that initforms of class variables be evaluated just as they are for instance variables -- I get temporarily tripped-up every so often by the inconsistency in the syntax. The fact that this doesn't happen is a bug in the current version of PCL. Second question: The "add-named-class" function allows us to create a class "on-the-fly" without having to use "eval". Is there a similar construct for creating methods at run time (i.e., will it be advertised)? PCL obviously has such a function, since methods can be created as a side-effect of calling "add-named-class". By the way, is "add-name-class" part of CLOS, or just a PCL feature? Yes, there is a function called add-named-method. I expect both add-named-class and add-named-method will be part of the CLOS spec. Suggestion: I did some timings on compiled segments of CLOS code (on a Symbolics), and found that a slot access is 20 times faster if a "with-slots" is declared with :use-accessors = nil than if the slot is accessed with the ordinary syntax (and its 30 times faster than a "slot-value" form). So, there is great incentive to place "with-slots" declarations everywhere. I've invented a "let-slots" macro which expands to a "let" statement with a "with-slots" inside of it, which looks much more attractive than having to declare both statements. My suggestion is to put something equivalent to "let-slots" into CLOS. The magnitude of these performance characteristics is a (mis)feature of PCL. This is changing in PCL, for example, the 20 times ratio you cite will probably be more like 5 in the next release. What's more, as implementation-specific versions start appearing, it will go down even farther. The real reason to :use-accessors or not is that it means two different things to use accessors or not. :use-accessors t means call a generic function to get/set the value of the slot; a generic function on which I might define methods by hand. :use-accessors nil, because it goes through slot-value, means that there are no generic functions which could be specialized to change the way the "slot" values are computed in the body of the with-slots.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 22 Jul 87 16:39:37 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 22 JUL 87 13:16:33 PDT Return-Path: Redistributed: commonloops.pa Received: from hplabs.HP.COM by Xerox.COM ; 22 JUL 87 13:13:39 PDT Received: from hplms2 by hplabs.HP.COM with TCP ; Wed, 22 Jul 87 13:09:52 pdt Received: from hplrds (hplrds) by hplms2; Wed, 22 Jul 87 13:09:35 pdt Return-Path: Received: from hplrds.hpl.hp.com by hplrds ; Wed, 22 Jul 87 13:09:19 pdt Message-Id: <8707222009.AA05107@hplrds> To: commonloops%hplrds@hplabs.HP.COM Cc: gregor%hplrds@hplabs.HP.COM, chiarelli%hplrds@hplabs.HP.COM, kempf%hplrds@hplabs.HP.COM Subject: 'class-named' in PCL 5-22-rev3 on HP Common Lisp X-Mailer: mh6.5 Date: Wed, 22 Jul 87 13:09:15 PDT From: Roy D'Souza In PCL 5-22-rev3 on HP Common Lisp: The CLOS document on pg. 2-13 indicates that if is NIL, 'class-named' will not signal an error if a class corresponding to the symbol supplied is not found. If is unsupplied or non-NIL, an error will be signalled. class-named &optional [Function] The implementation exhibits the opposite behavior: An error is signalled if is NIL, and defaults to NIL. An easy fix is to make the following changes to function 'class-named' in the file 'macros.lisp': ; In file macros.lisp: ;(defun class-named (name &optional no-error-p) ; Remove this line (defun class-named (name &optional (error-p T)) ; Add this line (or (gethash name *class-name-hash-table*) ;;;;;;(cond (no-error-p nil) ; Remove this line (cond ((null error-p) nil) ; Add this line ((legal-class-name-p name) (error "No class named: ~S." name)) (t (error "~S is not a legal class name." name))))) ;;; end Roy D'Souza dsouza@hplabs.hp.com (415) 857-7557  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jul 87 13:19:32 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Jul 87 10:13:59 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 196114; Tue 21-Jul-87 12:35:38 EDT Date: Tue, 21 Jul 87 12:35 EDT From: David A. Moon Subject: Category Errors To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 8 Jul 87 12:38 EDT from Dick Gabriel Message-ID: <870721123511.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 08 Jul 87 0938 PDT From: Dick Gabriel Suppose that MAKE-INSTANCE is a generic function. Its definition might look like this: (defmethod make-instance ((class standard-class) &rest args)...) Notice that the class of the argument CLASS is STANDARD-CLASS, which indicates that the operation of MAKE-INSTANCE is controlled at the meta-object level. Suppose someone were to write: (defmethod make-instance ((class apple-pie) &rest args)...) I don't think this is fundamentally different from someone defining a method on spaceships for a generic function that is only supposed to be used with windows. The only reason I can see that confusion between classes and metaclasses seems worse than confusion between spaceships and windows is that metaclasses are less familiar. If we didn't want to follow the usual Lisp philosophy of giving the user enough rope to hang himself, we could add a feature such as the following (defgeneric-options make-instance (class &rest initargs) (:parameter-specializer-restriction class (or class symbol))) which says methods can't be defined with a parameter specializer for the first parameter (named class) that isn't a subtype of (or class symbol). Using the type system to express the restriction, rather than inventing a new concept of levels, seems both more general and easier to understand. However, I don't really think we want to add this kind of restriction, at least, it wouldn't be consistent with the minimalist design criterion we have used elsewhere in CLOS.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jul 87 09:44:53 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 22 Jul 87 06:39:08 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa18126; 22 Jul 87 9:35 EDT Received: from ti-csl by RELAY.CS.NET id ab14379; 22 Jul 87 9:31 EDT Received: from Jenner by tilde id AA23150; Wed, 22 Jul 87 07:33:54 CDT Message-Id: <2762944528-5369042@Jenner> Date: Wed, 22 Jul 87 07:35:28 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Category Errors In-Reply-To: Msg of 08 Jul 87 0938 PDT from Dick Gabriel From Gabriel: One minor point that came up at the Symbolics meeting last Thursday was category errors and whether we should try to outlaw them somehow. Here is an example of a category error: Suppose that MAKE-INSTANCE is a generic function. Its definition might look like this: (defmethod make-instance ((class standard-class) &rest args)...) Notice that the class of the argument CLASS is STANDARD-CLASS, which indicates that the operation of MAKE-INSTANCE is controlled at the meta-object level. Suppose someone were to write: (defmethod make-instance ((class apple-pie) &rest args)...) (make-instance (class-prototype (class-named 'apple-pie)) ...) Here someone would be making a category error by defining a method on MAKE-INSTANCE at the wrong level - the class level. What makes this easy for a programmer to do this is the availability of CLASS-PROTOTYPE. However, it is never hard to do because the programmer can write: (defvar *apple-pie-prototype* (make-instance 'apple-pie)) to get his class prototype. We have two alternatives: 1. Let sea of classes/metaclasses remain a miasma and inform programmer that he ought not mix things up. 2. Define a notion of class category or classs level and have a category of generic function for each class category. From Ken Kahn: I think it would be a mistake to build barriers between class and metaclass protocols. One of the strong appeals of CLOS is that one can experiment within its framework. We once worked out how Object Lisp's view that classes and instances are pretty much the same could be implemented in PCL. A good fraction of the OOP community believes in these "prototypes" which unify classes and instances. We should be careful not to prohibit CLOS from evolving in that direction if people come to believe its a win. I kind of agree with both Dick's and ken's concerns. The user should be able to do metaclass programming if he wants to but this should be an intent, not an accident. CLASS-PROTOTYPE working for standard-classes is a good example of something intended to be used for metaclass programming but works also for non metaclass classes. I propose the following in order to categorize metaclass programming and class programming: CLASS | STANDARD-CLASS | METACLASS-CLASS Now, all metaclass objects are instances of METACLASS-CLASS instead of STANDARD-CLASS. This is to say that standard-class can be defined like: (defclass STANDARD-CLASS (CLASS) (:metaclass METACLASS-CLASS)) STANDARD-CLASS does not support metclass specific methods like CLASS-PROTOTYPE, METACLASS-CLASS does. Somebody defining a new metaclass (or wanting to do metaclass programming with his objects) will use METACLASS-CLASS as metaclass. It will be a conscious decision. The make-instance problem still exists but will not arise by accident, somebody will have to do a trick like: (defvar *apple-pie-prototype* (make-instance 'apple-pie)) and will probably get what he deserves. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Jul 87 10:56:14 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 16 Jul 87 07:52:13 PDT Received: from relay2.cs.net by RELAY.CS.NET id ab01711; 16 Jul 87 10:24 EDT Received: from ti-csl by RELAY.CS.NET id ac00916; 16 Jul 87 10:17 EDT Received: from Jenner by tilde id AA07022; Thu, 16 Jul 87 08:00:48 CDT Message-Id: <2762427556-15862063@Jenner> Date: Thu, 16 Jul 87 07:59:16 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class redefinition and class-changed. In-Reply-To: Msg of Wed, 15 Jul 87 10:58:31 -0700 from kempf%hplabsz@hplabs.hp.com > GET-OBSOLETE-VERSION class > returns the preceding obsolete version of this class, or NIL if none. > This allows users to define methods at any time on the obsolete class. > Obsolete classes themselves may also have an obsolete-version. Obsolete > classes also respond to Is this meant to imply that there can be multiple versions of classes floating about? If so, then perhaps class versioning needs to be investigated more closely. I am not sure I agree with the term VERSION. An obsolete class object is not a version of the class because it is here just to support the class-changed protocol. It is not meant to have permanent instances. Surrogate might be more appropriate. In the sense there can only be instances of "current class" outside of the execution of CLASS-CHANGED, I don't think we need to worry about class versioning. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Jul 87 13:04:53 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 15 Jul 87 10:00:19 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Wed, 15 Jul 87 09:58:27 pdt Received: from hplabsz.hpl.hp.com by hplms1; Wed, 15 Jul 87 09:58:07 pdt Return-Path: Received: by hplabsz; Wed, 15 Jul 87 10:58:34 pdt Message-Id: <8707151658.AA08774@hplabsz.hpl.hp.com> To: Patrick H Dussud Cc: Danny Bobrow Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class redefinition and class-changed. In-Reply-To: Your message of Fri, 10 Jul 87 10:00:21 CDT. <2761916421-9049515@Jenner> Date: Wed, 15 Jul 87 10:58:31 -0700 From: kempf%hplabsz@hplabs.HP.COM > GET-OBSOLETE-VERSION class > returns the preceding obsolete version of this class, or NIL if none. > This allows users to define methods at any time on the obsolete class. > Obsolete classes themselves may also have an obsolete-version. Obsolete > classes also respond to Is this meant to imply that there can be multiple versions of classes floating about? If so, then perhaps class versioning needs to be investigated more closely. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Jul 87 13:44:53 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 13 Jul 87 10:39:10 PDT Received: from relay2.cs.net by RELAY.CS.NET id ad17106; 13 Jul 87 13:12 EDT Received: from ti-csl by RELAY.CS.NET id an13899; 13 Jul 87 13:05 EDT Received: from Jenner by tilde id AA06513; Fri, 10 Jul 87 16:44:10 CDT Message-Id: <2761940409-10490738@Jenner> Date: Fri, 10 Jul 87 16:40:09 CDT From: Patrick H Dussud To: Jim Kempf Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Metaclass Protocol Goals In-Reply-To: Msg of Thu, 9 Jul 87 13:30:59 pdt from Jim Kempf Patrick's design rationale looks like a good beginning, and would be a good addition to the beginning of 87-003, as motivation for the metaclass protocol. I had a couple of comments and questions: Thank you for your comments. >Class behavior and instance behavior are othorgonal in CLOS. The >metaclass protocol must preserve this orthoganality. I'm not quite sure I understand what you mean by class and instance behavior being orthogoal. Since class objects are instances of the metaclass, this statement would seem not to be true for classes when considered as instances. What I meant is that the metaclass does affect the way classes parse their defclass, compute class precedence list, gather their slots... all these things are class business. On the other hand, it affects how instances are allocated, laid out, accessed. That's instance business. These two sorts of businesses are independent. I may want to keep a CLOS Syntax, CPL, etc, but have my instances represented differently. I may want to define a FLAVOR metaclass and represent its instances the way the default CLOS metaclass represents them. >- The side effects on CLOS objects (Classes, generic-functions, methods) >that spread across object links should be exposed. >Compute-class-precedence-list is a good example. I'm not sure I understand what you mean by "be exposed". What I think you mean by "side effects on CLOS objects that spread across object links" is protocols which affect objects whose structure acts as templates for other objects (is that so?). As an example, the structure of a class object acts as a template for instances. If you mean that methods affecting the structure of such "template objects" should be included in the public metaobject protocol, then I agree. Exposed means documented (what it is), with a protocol that goes with it (what you can do, how you do it). "Side effects on CLOS objects that spread across object links" means the side effects that affect some other objects, not just the one you intended to side-effect. For example, if you redefine a class, you are likely to affect other classes besides the one you are redefining. These side effects are particularly important to specify because they can spread across metaclasses. If metaclass A handles class redefinition one way and metaclass B handles it in a different way, then clearly we have a problem if we can mix classes of A with classes of B. >- It should be possible to access some exposed slots of a CLOS object >without side-effect. I agree with this, but I think it might be difficult to achieve in practice. With method combination, it should be possible for the designer of a metaclass to define a daemon method on any method in the protocol which cause side effects to occur. I can think of a couple solutions to this off the top of my head. One is to suggest that metaclass programmers follow a convention of not defining daemon methods which cause side effects, another is to specifically forbid defining daemon methods on metaclass methods, possibly through a declaration mechanism (as I suggested in an earlier note this spring). Probably the former is better, since daemon methods for doing things like updating browsers when classes are defined might be useful. We define a protocol, not a language. A protocol is a set of rules that someone must observe in order to preserve the integrity of the system. If we say "This should be side effect free", it means that someone writing a new metaclass must satisfy this constraint if he expect CLOS to continue working right. We certainly don't want to do anything complicated to enforce it. >- We probably need to care about the compile environment. We don't have >to specify what it is but where, in our protocol it should be looked up >or side effected. At least we must make sure that we don't go against >the following statements: >1)Compile-file does not side effect the running environment. >2)It is possible to implement a cross loader (Something that loads files >in order to make some class definitions, etc that will affect >the compilation but not the running environment). What I was trying to say here is we must define provision for implementations to do a good job of defining a compilation environment, not to require it. Using the PCLOS implementation from Gregor, I tried a quick and dirty implementation of a seperate compile time namespace for CommonObjects on CLOS and ran into some serious problems. Running into problems because the implementation does not allow you to do it is one thing, running into problems because the metaclass protocol makes it impossible is another thing. Patrick.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 11 Jul 87 04:01:52 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 10 JUL 87 18:56:23 PDT Return-Path: Received: from ohm.ece.cmu.edu by Xerox.COM ; 10 JUL 87 17:02:18 PDT Received: by ohm.ece.cmu.edu (5.51/5.17) id AA11156; Fri, 10 Jul 87 16:30:15 EDT Date: Fri, 10 Jul 87 16:30:15 EDT From: James Daniell Message-Id: <8707102030.AA11156@ohm.ece.cmu.edu> To: CommonLoops.PA@Xerox.COM Subject: Addition to Mailing List Please add me to your pcl mailing list. ==> daniell@ohm.ece.cmu.edu <== Thank-you in advance, Jim Daniell  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 11 Jul 87 04:01:35 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 10 JUL 87 18:48:36 PDT Date: 10 Jul 87 13:13 PDT From: Gregor.pa@Xerox.COM Subject: Re: random compilation In-reply-to: Rick.Busdiecker@h.cs.cmu.edu's message of 10 Jul 87 13:02 EDT To: Rick.Busdiecker@h.cs.cmu.edu cc: CommonLoops.PA@Xerox.COM Message-ID: <870710-184836-102@Xerox> This misfeature of runtime compilation is scheduled to go away entirely. It is getting better for what thats worth. You could fix your bug by putting (class-of 1) before the call to make-specializable, the call to class-of will cause the compilation and then you will be OK.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 11 Jul 87 04:01:22 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 10 JUL 87 15:10:13 PDT Date: 10 Jul 87 13:13 PDT From: Gregor.pa@Xerox.COM Subject: Re: random compilation In-reply-to: Rick.Busdiecker@h.cs.cmu.edu's message of 10 Jul 87 13:02 EDT To: Rick.Busdiecker@h.cs.cmu.edu cc: CommonLoops.PA@Xerox.COM Message-ID: <870710-151013-103@Xerox> This misfeature of runtime compilation is scheduled to go away entirely. It is getting better for what thats worth. You could fix your bug by putting (class-of 1) before the call to make-specializable, the call to class-of will cause the compilation and then you will be OK.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 11 Jul 87 04:01:11 EDT Received: from Salvador.ms by ArpaGateway.ms ; 10 JUL 87 11:20:51 PDT Return-Path: Received: from H.CS.CMU.EDU by Xerox.COM ; 10 JUL 87 11:19:20 PDT Date: 10 Jul 87 13:02 EDT From: Rick.Busdiecker@h.cs.cmu.edu To: CommonLoops.PA@Xerox.COM Subject: random compilation Message-Id: <552934942/rfb@h.cs.cmu.edu> I know that something about this has come up previously, but I don't remember whether/how it was resolved. Why does PCL do load and/or eval time compilation and will this "feature" go away? This seems like an approach which is bound to tickle bugs and shouldn't(?) really be necessary. In CMU Common Lisp, if one calls (pcl::make-specializable 'pathname) and then later calls pathname the pathname invocation causes some compilation, the compiler calls machine-instance, machine-instance calls open, which or course calls pathname, i.e. infinite recursion by calling pathname. Rick  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 11 Jul 87 04:00:58 EDT Received: from Salvador.ms by ArpaGateway.ms ; 10 JUL 87 07:57:51 PDT Return-Path: Received: from Cs.Ucl.AC.UK by Xerox.COM ; 10 JUL 87 07:55:12 PDT Received: from csvax.aberdeen.ac.uk by nss.Cs.Ucl.AC.UK via Janet with NIFTP id aa04010; 10 Jul 87 15:51 BST Date: Fri, 10 Jul 87 15:48:08 GMT From: Steve Messick To: "commonloops.pa" <@Cs.Ucl.AC.UK:commonloops.pa@xerox.com> Subject: null lambda-list Cc: messick%csvax.aberdeen.ac.uk@Cs.Ucl.AC.UK Message-ID: <870710-075751-535@Xerox> May a generic function have a null lambda-list? OK, I can't see much use for it, but is it legal? In pcl (system date 5/22/87 (rev 3)) the following form dies: (defmethod foo ()) Furthermore, both following forms appear to construct methods which require 1 parameter: (defmethod foo () (b)) (defmethod foo (b)) The () might be considered a method qualifier except method qualifiers are required to be non-nil atoms. --steve  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Jul 87 13:29:59 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 10 Jul 87 10:25:57 PDT Received: from relay2.cs.net by RELAY.CS.NET id ae21575; 10 Jul 87 11:54 EDT Received: from ti-csl by RELAY.CS.NET id ag17093; 10 Jul 87 11:47 EDT Received: from Jenner by tilde id AA26237; Fri, 10 Jul 87 10:04:49 CDT Message-Id: <2761916421-9049515@Jenner> Date: Fri, 10 Jul 87 10:00:21 CDT From: Patrick H Dussud To: Danny Bobrow Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: Class redefinition and class-changed. In-Reply-To: Msg of 9 Jul 87 11:51 PDT from Danny Bobrow Date: 9 Jul 87 11:51 PDT From: Danny Bobrow Subject: Re: Class redefinition and class-changed. Goals: - There should be a way to define a method for class-changed on the obsolete class and the class. - This method needs to be defined before any the instances is changed, otherwise it wouldn't get invoked on all the instances of the class. Agreed. The necessary and sufficient condition for this is to be able to get hold of an obsolete version of a class. I don't agree. We said in chapter 1 that the updating of the instances is done at an implementation-dependent time. It means that unless you prepare your methods in advance (before the class is actually redefined) you are going to let some instances be updated without proper class-changed method invokation. The worst part is you may not find out about it. A necessary condition is to be able to get hold of an obsolete version of a class before the class is changed. Proposal: Changing a class updates a database to allow the following generic functions to work. GET-OBSOLETE-VERSION class returns the preceding obsolete version of this class, or NIL if none. This allows users to define methods at any time on the obsolete class. Obsolete classes themselves may also have an obsolete-version. Obsolete classes also respond to GET-UPDATED-VERSION obsolete-class with the next class or NIL This allows following the chain in the opposite direction I don't have much objection to this. However, I don't see it as sufficient to implement the goals you agreed upon. I see your proposal as a complement to mine. (let ((obsolete-class (cdr (assoc class (GET-OBSOLETE-CLASSES-FOR-REDEFINITION class ))))) Add method on class-changes.... redefine the class class ... (eq obsolete-class (GET-OBSOLETE-VERSION class))) => T Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 22:36:47 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 19:32:59 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUL 87 19:03:04 PDT Date: 9 Jul 87 19:03 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Metaclass Protocol Goals In-reply-to: Jim Kempf 's message of Thu, 9 Jul 87 13:30:59 pdt To: kempf%hplabsz@hplabs.HP.COM cc: common-lisp-object-system@sail.stanford.edu Message-ID: <870709-190304-4903@Xerox> Patrick>- It should be possible to access some exposed slots of a CLOS object >without side-effect. Jim> I agree with this, but I think it might be difficult to achieve ... It is not difficult to document for CLOS. If a package adds behavior to CLOS, then a user of that package should document its behavior. This is not a matter for program control -- just for social control.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 17:35:47 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 14:31:26 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 14:28:00 pdt Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 14:27:40 pdt Return-Path: Received: by hplabsz; Thu, 9 Jul 87 14:28:20 pdt Date: Thu, 9 Jul 87 14:28:20 pdt From: Jim Kempf Message-Id: <8707092128.AA22639@hplabsz.hpl.hp.com> To: Kahn.pa@Xerox.COM, kempf%hplabsz@hplabs.HP.COM Subject: Re: Category Errors Cc: common-lisp-object-system@sail.stanford.edu >I think it would be a mistake to build barriers between class and >metaclass protocols. One of the strong appeals of CLOS is that one can >experiment within its framework. We once worked out how Object Lisp's >view that classes and instances are pretty much the same could be >implemented in PCL. A good fraction of the OOP community believes in >these "prototypes" which unify classes and instances. We should be >careful not to prohibit CLOS from evolving in that direction if people >come to believe its a win. > I agree with this viewpoint in principle, which is why I wouldn't want to see any stronger barriers be erected than packageization. That seems to me to be the minimum to keep people happy who want to maintain some distance and are already uncomfortable with the metaclass protocol, and those who believe that no barriers are appropriate. Someone wanting to implement Object Lisp need only use both the user interface and metaclass symbols.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 16:59:05 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 13:55:05 PDT Received: from Semillon.ms by ArpaGateway.ms ; 09 JUL 87 13:49:06 PDT Date: Thu, 9 Jul 87 13:48:39 PDT From: Ken Kahn Subject: Re: Category Errors In-Reply-To: <8707092025.AA22144@hplabsz.hpl.hp.com> To: Jim Kempf cc: common-lisp-object-system@sail.stanford.edu Message-ID: <870709-134906-4431@Xerox> I think it would be a mistake to build barriers between class and metaclass protocols. One of the strong appeals of CLOS is that one can experiment within its framework. We once worked out how Object Lisp's view that classes and instances are pretty much the same could be implemented in PCL. A good fraction of the OOP community believes in these "prototypes" which unify classes and instances. We should be careful not to prohibit CLOS from evolving in that direction if people come to believe its a win. References kempf%hplabsz@hplabs.HP.COM's message of Thu, 9 Jul 87 13:25:28 PDT -- Re: Category Errors  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 16:52:12 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 12:07:25 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUL 87 11:54:12 PDT Date: 9 Jul 87 11:51 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Class redefinition and class-changed. In-reply-to: Patrick H Dussud 's message of Wed, 8 Jul 87 16:02:06 CDT To: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net cc: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <870709-115412-4166@Xerox> Goals: - There should be a way to define a method for class-changed on the obsolete class and the class. - This method needs to be defined before any the instances is changed, otherwise it wouldn't get invoked on all the instances of the class. Agreed. The necessary and sufficient condition for this is to be able to get hold of an obsolete version of a class. Proposal: Changing a class updates a database to allow the following generic functions to work. GET-OBSOLETE-VERSION class returns the preceding obsolete version of this class, or NIL if none. This allows users to define methods at any time on the obsolete class. Obsolete classes themselves may also have an obsolete-version. Obsolete classes also respond to GET-UPDATED-VERSION obsolete-class with the next class or NIL This allows following the chain in the opposite direction Providing this chain allows defining pair-wise updaters from an obsolete to its updated version, a general updating protocal that will follow the chain from any old version to the current version, and accelerators between any old-version and any later version on the chain.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 16:36:24 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 13:32:33 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:30:54 pdt Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:30:20 pdt Return-Path: Received: by hplabsz; Thu, 9 Jul 87 13:30:59 pdt Date: Thu, 9 Jul 87 13:30:59 pdt From: Jim Kempf Message-Id: <8707092030.AA22198@hplabsz.hpl.hp.com> To: common-lisp-object-system@sail.stanford.edu Subject: Re: Metaclass Protocol Goals Patrick's design rationale looks like a good beginning, and would be a good addition to the beginning of 87-003, as motivation for the metaclass protocol. I had a couple of comments and questions: >Class behavior and instance behavior are othorgonal in CLOS. The >metaclass protocol must preserve this orthoganality. I'm not quite sure I understand what you mean by class and instance behavior being orthogoal. Since class objects are instances of the metaclass, this statement would seem not to be true for classes when considered as instances. >- The side effects on CLOS objects (Classes, generic-functions, methods) >that spead across object links should be exposed. >Compute-class-precedence-list is a good example. I'm not sure I understand what you mean by "be exposed". What I think you mean by "side effects on CLOS objects that spread across object links" is protocols which affect objects whose structure acts as templates for other objects (is that so?). As an example, the structure of a class object acts as a template for instances. If you mean that methods affecting the structure of such "template objects" should be included in the public metaobject protocol, then I agree. >- It should be possible to access some exposed slots of a CLOS object >without side-effect. I agree with this, but I think it might be difficult to achieve in practice. With method combination, it should be possible for the designer of a metaclass to define a daemon method on any method in the protocol which cause side effects to occur. I can think of a couple solutions to this off the top of my head. One is to suggest that metaclass programmers follow a convention of not defining daemon methods which cause side effects, another is to specifically forbid defining daemon methods on metaclass methods, possibly through a declaration mechanism (as I suggested in an earlier note this spring). Probably the former is better, since daemon methods for doing things like updating browsers when classes are defined might be useful. >- We probably need to care about the compile environment. We don't have >to specify what it is but where, in our protocol it should be looked up >or side effected. At least we must make sure that we don't go against >the following statements: >1)Compile-file does not side effect the running environment. >2)It is possible to implement a cross loader (Something that loads files >in order to make some class definitions, etc that will affect >the compilation but not the running environment). Given the design of the Common Lisp, this might be very difficult to achieve. Using the PCLOS implementation from Gregor, I tried a quick and dirty implementation of a seperate compile time namespace for CommonObjects on CLOS and ran into some serious problems. Basically, for languages such as CommonObjects which compute alot of their inheritance information at compile time, the only alternative to side effecting the compile time environment is to somehow maintain the information and update global structures only when its safe. This approach is used in our native code CommonObjects implementation, and it is expensive. The CommonObjects on CLOS compiles about twice as fast because it just side effects the compile time environment. In the CLOS language, if attention is not paid to side effects, then classes need to be defined in the compile time environment so that method definintions being defined in the same file (a logical way to organize a body of software) can be compiled. Aside from problems with bootstrapping CLOS itself (which Gregor seems to pretty well have under control in the portable implementation), much of the reason for not side effecting the compile time environment goes away with multiple virtual address spaces. A "spoiled" compile time environment can just be thrown away. Of course, this doesn't solve the problem for machines where multiple virtual address spaces are not an option. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 16:33:30 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 13:29:00 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:27:28 pdt Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:27:01 pdt Return-Path: Received: by hplabsz; Thu, 9 Jul 87 13:27:41 pdt Date: Thu, 9 Jul 87 13:27:41 pdt From: Jim Kempf Message-Id: <8707092027.AA22154@hplabsz.hpl.hp.com> To: common-lisp-object-system@sail.stanford.edu Subject: Re: First Try at Terminology >The definition of a situation is designed to cover function invocations, >macro calls, and instances of the use of special forms as well as >conditions that might arise within a running CLOS system. A situation is >not a purely syntactic state of affairs, because the preconditions for an >error usually requires that something about the nature of the arguments >to a function, for example, be known. The wording of these definitions will >need further work. Why not go one step further and use preconditions and postconditions on the functions and macros, ala` Hoare logic? Example from 87-002 spec (RET is the returned value, ARG the argument): CLASS-OF Pre: T Post: RET is an element of C, the set of defined classes, if ARG is an instance of a class | error The postconditions could contain error postconditions of three types: 1) errors at all optimization levels (1 in the original message) 2) errors at the lowest only (2 in the orignal message) 3) errors which implementations are permitted to extend CLOS to cover. >I believe we wish to control where extensions to CLOS are allowed to occur. >The first four terms are designed to control semantic extensions while the >fifth is designed to control syntactic extensions, which are somewhat >different. Yes, this is a laudable goal, but I fear that any attempt to do this in English may remain open to ambiguous interpretation. >I believe we want to define precise terms such as these and use them >exactly in the CLOS specification so that, rather than the CLOS >specification being a pseudo-user's-guide as CLtL is, it can be a >specification suitable for an implementor. 100% agreement. Barring any agreement on more rigorous formalism, I can live with the terminology in the base note. It's a whole lot better than CLtL. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 16:32:33 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 13:26:44 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:25:13 pdt Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:24:51 pdt Return-Path: Received: by hplabsz; Thu, 9 Jul 87 13:25:28 pdt Date: Thu, 9 Jul 87 13:25:28 pdt From: Jim Kempf Message-Id: <8707092025.AA22144@hplabsz.hpl.hp.com> To: common-lisp-object-system@sail.stanford.edu Subject: Re: Category Errors > > 1. Let sea of classes/metaclasses remain a miasma and inform > programmer that he ought not mix things up. > > 2. Define a notion of class category or classs level and have a > category of generic function for each class category. This is a difficult one, and relates to Patrick's goal of maintaining metaclass protocol and class protocol orthogonally. Pros are that it can avoid having programmers make mistakes like defining MAKE-INSTANCE on a class, as cited in the base note, cons are that a programmer might actually *want* to have a particular class be instantiated slightly differently. Given Lisp's tendency to allow a programmer to do anything, as long as the name for doing it can be found, I think 1) should be the choice, except the "sea of classes/metaclasses" ought probably to be broken up into little bays and gulfs via. the package system. With some method names (like MAKE-INSTANCE) there is no hope, since they are firmly in the programmer interface. With the rest of the metaobject protocol, the names should be exported from a seperate package, so that only programmers who want to do metaclass programming need be concerned with them. One can reasonably argue that a programmer using CLOS should be familar enough with the programmer interface functions to be able to avoid an accidental redefinition of the methods there, but we should certainly not require CLOS programmers to be familar with metaclass names unless they intend to do metaclass programming. Jim Kempf kempf@hplabs.hp.com  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Jul 87 16:30:30 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87 13:26:09 PDT Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:24:30 pdt Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:23:58 pdt Return-Path: Received: by hplabsz; Thu, 9 Jul 87 13:24:38 pdt Date: Thu, 9 Jul 87 13:24:38 pdt From: Jim Kempf Message-Id: <8707092024.AA22131@hplabsz.hpl.hp.com> To: rpg@sail.stanford.edu Subject: Re: ECOOP Reaction to CLOS Cc: common-lisp-object-system@sail.stanford.edu >I want to make clear what it is I said about the CPL computation: I stated >that the effect of the CPL algorithm was difficult to understand, not that >the algorithm is difficult to understand. The difference between the two >is that an algorithm can be easy to grasp while a characterization of it >suitable for a programmer to understand is not available. In contrast, >the algorithm for computing the strongly connected components of a graph >is easy to understand as an algorithm, and it is easy to understand what >it does because the definition of a strongly connected component is easy >to understand. The CPL is understood to be a total ordering on a class >and its superclasses, but the only characteriztion of it that I know of is >that the CPL is the total ordering computed by the algorithm. That >algorithm is understandable at the operational level, but there is no easy >characterization of it. I think what most programmers want is a two sentence explanation of how inheritance works in CLOS. The equivalent for Smalltalk is: Child classes get all the methods and all the slots of their parents. Any methods defined with the same name as the parent defined in the child override the parent's method. I propose this for CLOS: The inheritance graph is searched depth first, left to right, up to joins. Superclasses at joins are placed in the class precedence list at the last occurance, rather than the first, since such superclasses are usually more general than their subclasses, and classes at the end of the class precedence list should be more general than those at the beginning. The qualitative effect is to achieve a linearization of the inheritance graph, with more specialized classes at the head of the class precedence list and more general classes at the tail, keeping together groups of classes which occur together in the inheritance graph. Well, that's three sentences, but I think most people won't mind. A more detailed explantion should go into what can go wrong. The Ducournau and Habib paper discusses this in a more formal way. The essense is that if two or more subclasses share two or more join superclasses, then the algorithm can fail. In such cases, the two join superclasses are two alternative end elements for the sublist CPL containing the subclasses, so there is no unique linearization. Scherlis's comments about programmer hooks at the Palo Alto meeting might be appropriate here, since the programmer could choose which join superclass is more general, but I think the appropriate place to put in these hooks is the metaobject protocol, and not something like prompting the programmer. >Intellectual honesty compels me to point out things like this when >I address an audience. I suppose it annoys people when I do that, >but maybe we should give some thought to designing a language such that >there are few oppurtunities for ``Gabriel's inevitable critique.'' I have no problem with such critiques, however, I think at some point we need to iterate to a design which we all feel comfortable with, and which application developers can use. My impression of the inheritance algorithm is that it refines and solidifies current practice which is *precisely* what a standard should do. Whether or not it is the ultimate in linguistic software reuse mechanisms is another question. I don't think it is, but until I know the answer, have tested it with a couple of applications, and have discussed it extensively with other people, I'm sure not going to recommend that it be made a standard. Jim Kempf kempf@hplabs.hp.com  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 9 Jul 87 10:22:03 EDT Received: from Salvador.ms by ArpaGateway.ms ; 09 JUL 87 04:41:55 PDT Return-Path: Received: from RUTGERS.EDU by Xerox.COM ; 09 JUL 87 04:40:42 PDT Received: by RUTGERS.EDU (5.54/1.14) with UUCP id AA27331; Thu, 9 Jul 87 07:41:58 EDT Received: by moss.ATT.COM (smail2.5) id AA12495; 9 Jul 87 07:37:37 EDT (Thu) To: CommonLoops.pa@Xerox.COM In-Reply-To: Donald Maffly's message of Wed, 8 Jul 87 14:02:57 -0100 <8707081302.AA21688@cricph.UUCP> Subject: Re: PCL Date: 9 Jul 87 07:37:37 EDT (Thu) From: tk@moss.att.com (Tom Kirk) Message-Id: <8707090737.AA12495@moss.ATT.COM> I would like to second that interest in finding some way of obtaining PCL without being required to have FTP access. Myself and several colleagues would like to be able to use PCL, but Bell Laboratories is unfortunately not on the Internet. Could someone perhaps offer uucp access to the software? It seems that the size of PCL is modest enough to make this a reasonable distribution mechanism; it doesn't even preclude relatively frequent updates. Any help that anyone can offer would be greatly appreciated. Tom Kirk AT&T Bell Laboratories  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 8 Jul 87 20:10:37 EDT Received: from Salvador.ms by ArpaGateway.ms ; 08 JUL 87 14:39:05 PDT Return-Path: Received: from seismo.CSS.GOV by Xerox.COM ; 08 JUL 87 14:37:28 PDT Received: from mcvax.UUCP by seismo.CSS.GOV (5.54/1.14) with UUCP id AA14350; Wed, 8 Jul 87 17:37:19 EDT Received: by mcvax.cwi.nl; Wed, 8 Jul 87 23:32:45 +0200 (MET) Received: by diku.dikunet.uucp (4.12/smail2.2/04-15-87) id AA17065; Wed, 8 Jul 87 22:51:27 -0200 Received: by cricph.UUCP (4.12/4.7) id AA21688; Wed, 8 Jul 87 14:02:57 -0100 Date: Wed, 8 Jul 87 14:02:57 -0100 From: mcvax!cricph!dma@seismo.CSS.GOV (Donald Maffly) Message-Id: <8707081302.AA21688@cricph.UUCP> To: CommonLoops.pa@Xerox.COM Subject: PCL We recently recieved information from you about PCL. You mention that PCL will only be distributed to people with FTP connections. Unfortunately, we are in Denmark, and we do not have an FTP connection. The motivation you give for this is that there will be many updates to PCL, which makes a FTP connection very attractive. But we are not so interested in the updates (so long as the original version is relatively bug free). However, we ARE interested in something (anything!!) that we can use now that will have some resemblance to CLOS. Can't we get PCL on tape? If not, what other options can you recommend? Desparate, Donald Maffly, CRI, Denmark  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Jul 87 19:47:24 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 8 Jul 87 16:43:20 PDT Received: from relay2.cs.net by RELAY.CS.NET id aa01894; 8 Jul 87 19:38 EDT Received: from ti-csl by RELAY.CS.NET id aa05802; 8 Jul 87 19:31 EDT Received: from Jenner by tilde id AA05525; Wed, 8 Jul 87 16:05:23 CDT Message-Id: <2761765326-16486571@Jenner> Date: Wed, 8 Jul 87 16:02:06 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Class redefinition and class-changed. Redefining a class will provoke instances of this class to be changed to the new class using the change-class protocol. However there is no specified way to take advantage of the class-changed generic function. Goals: - There should be a way to define a method for class-changed on the obsolete class and the class. - This method needs to be defined before any the instances is changed, otherwise it wouldn't get invoked on all the instances of the class. Proposal: Before committing the class to redefinition, we specify a way to get the obsolete class objects and thus, define methods for class-changed. Since a class redefinition will propagate down, it will be useful to get the closure of all the redefintions. GET-OBSOLETE-CLASSES-FOR-REDEFINITION will return an alist whose keys are the classes implicated in the class-redefinition of CLASS and whose contents are the obsolete classes. Syntax: GET-OBSOLETE-CLASSES-FOR-REDEFINITION CLASS &optional (REDEFINITION-CLOSURE-P t) GET-OBSOLETE-CLASSES-FOR-REDEFINITION is a generic function. CLASS is a class object if REDEFINITION-CLOSURE-P not provided or non nil, all the classes implicated in the class redefinition of CLASS are returned as keys of the resulting alist. If REDEFINITION-CLOSURE-P is nil, then the alist returned contains only one entry for CLASS. Besides obsolete class creation, get-obsolete-classes-for-redefinition does not side effect. In other words, it it OK to call it more than once and the returned obsolete classes are EQ from one call to the other. Once the methods are defined, the class redefinition can be executed. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Jul 87 12:42:37 EDT Date: 08 Jul 87 0938 PDT From: Dick Gabriel Subject: Category Errors To: common-lisp-object-system@SAIL.STANFORD.EDU One minor point that came up at the Symbolics meeting last Thursday was category errors and whether we should try to outlaw them somehow. Here is an example of a category error: Suppose that MAKE-INSTANCE is a generic function. Its definition might look like this: (defmethod make-instance ((class standard-class) &rest args)...) Notice that the class of the argument CLASS is STANDARD-CLASS, which indicates that the operation of MAKE-INSTANCE is controlled at the meta-object level. Suppose someone were to write: (defmethod make-instance ((class apple-pie) &rest args)...) (make-instance (class-prototype (class-named 'apple-pie)) ...) Here someone would be making a category error by defining a method on MAKE-INSTANCE at the wrong level - the class level. What makes this easy for a programmer to do this is the availability of CLASS-PROTOTYPE. However, it is never hard to do because the programmer can write: (defvar *apple-pie-prototype* (make-instance 'apple-pie)) to get his class prototype. We have two alternatives: 1. Let sea of classes/metaclasses remain a miasma and inform programmer that he ought not mix things up. 2. Define a notion of class category or classs level and have a category of generic function for each class category. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Jul 87 12:32:45 EDT Date: 08 Jul 87 0928 PDT From: Dick Gabriel Subject: First Try at Terminology To: common-lisp-object-system@SAIL.STANFORD.EDU At the Symbolics meeting we decided to introduce some terminology about erroneous situations for use in the final document. Here is a first attempt at that terminology - Sit is a situation and Syn is syntax: The terminology defined in 1 - 4 refers to situations that might occur, while the terminology defined in 5 refers to syntax. A ``situation'' is one of the following: 1. an expression in which the first form is given or specified and the remaining subexpressions are either given, specified, or evaluate to objects satisfying certain constraints; 2. a state of affairs within a running CLOS system. Examples: When the function + is given a non-number as an argument, that is a situation under definition 1; when a numeric operation causes an arithmetic overflow, that is a situation under definition 2. ``Syntax'' refers to the nature of the lambda-list of a function, the nature of the defmacro lambda-list of a macro, and the number and nature of the subexpressions in a special form. In the specification of CLOS, the behavior of programs in all situations is described, and the options available to the implementor are defined; no implementation is allowed to extend the syntax or semantics of CLOS except as explicitly defined in the CLOS specification. In particular, no implementation is allowed to extend the syntax of CLOS in such a way that ambiguity between the specified syntax of CLOS and those extensions is possible. The following are descriptive phrases and their meanings: 1. ``When Sit occurs an error is signaled.'' The meaning of this terminology is: a. If this situation occurs, an error will be signaled in code compiled under all compiler safety optimization levels and in the interpreter. b. Valid CLOS programs may rely on the fact that an error will be signaled in code compiled under all compiler safety optimization levels and in the interpreter. c. Every CLOS implementation is required to detect such an error in code compiled under all compiler safety optimization levels and in the interpreter. 2. ``When Sit occurs an error should be signaled.'' The meaning of this terminology is: a. If this situation occurs, an error will be signaled at least in code compiled under one compiler safety optimization level and in the interpreter. b. Valid CLOS programs may not rely on the fact that an error will be signaled. c. Every CLOS implementation is required to detect such an error at least in code compiled under one compiler safety optimization level and in the interpreter. d. When an error is not signaled, the results are undefined (see below). 3. ``When Sit occurs the results are undefined.'' The meaning of this terminology is: a. If this situation occurs, the results are unpredictable. The results may range from harmless to fatal to the running CLOS system. b. No valid CLOS programs should cause this situation to happen. c. CLOS implementations are allowed to detect this situation and signal an error, but no CLOS implementation is required to detect the situation. d. No implementation is allowed to extend the semantics of CLOS to this situation; the effects of the situation may be harmless, but they must remain undefined. 4. ``CLOS may be extended to cover Sit.'' The meaning of this terminology is that an implementation is free to treat Sit in one of four ways: a. When Sit occurs, an error is signaled; b. When Sit occurs, an error is signaled at least in code compiled under one compiler safety optimization level and in the interpreter. c. When Sit occurs, the results are undefined; or d. When Sit occurs, the results are defined and specified. In addition, this terminology means that: e. No portable CLOS program can depend on the effects of this situation, and all portable CLOS programs are required to treat the situation as undefined. 5. ``Implementations are free to extend the syntax Syn.'' The meaning of this terminology is: a. Implementations are allowed to define unambiguous extensions to that syntax. The CLOS specification may disallow certain extensions while allowing others. ***************************************************************************** The following is a discussion of the motivation behind these terms. Of course, there is no commitment yet to these terms: This is simply the first proposal. The definition of a situation is designed to cover function invocations, macro calls, and instances of the use of special forms as well as conditions that might arise within a running CLOS system. A situation is not a purely syntactic state of affairs, because the preconditions for an error usually requires that something about the nature of the arguments to a function, for example, be known. The wording of these definitions will need further work. On syntax, I believe we want the default to be that no extensions are allowed - that is, any extensions must be explicitly allowed. I particularly wish to disallow syntactic extensions that extend the number of arguments to a function or a macro or the number of subexpressions in a special form. These terms are a reaction to current CLtL terminology and the various interpretations of it. The entire gamut of interpretations of CLtL terms is valid, but there are more interpretations than terms. This proposal is intended to identify the reasonable interpretations of CLtL terminology and provide terms for those intepretations, so that, I hope, the terms and interpretations are one-to-one. 1. ``When Sit occurs an error is signaled.'' This term is borrowed from CLtL. I think we need a more precise definition that talks about errors being signaled in code compiled under all compiler optimization levels. Current practice in Common Lisp includes only signaling errors in code that was compiled under high compiler safety optimization levels. Because there is a constant desire to elide such checks in compiled code on stock hadware, we should separate out cases in which we want errors signaled in code compiled under all compiler optimization levels from those in which we allow implementations to provide a high-speed, unsafe operations - my recollection is that CLtL ``is an error'' was intended to accomplish that separation, but that is not the current prevailing interpretation. Hence the term: 2. ``When Sit occurs an error should be signaled.'' Some people who interpret CLtL maintain that, under a strict reading of CLtL, CLOS ``signals an error'' corresponds to CLtL ``signals an error'' and CLOS ``an error should be signaled'' corresponds to CLtL ``is an error.'' This does not correspond to current practice, in which CLtL ``signals an error'' generally corresponds to CLOS ``signals an error'' or ``should signal an error,'' while CLtL ``is an error'' generally corresponds to CLOS ``is undefined'' or ``is extendable.'' 3. ``When Sit occurs the results are undefined.'' The intention of this is to allow implementations to not worry about what happens in Sit, because CLOS does not permit programs to be written that fall into Sit, and no implementation is allowed to extend the semantics of CLOS to provide useful behavior in Sit. Some people have claimed that CLtL ``is an error'' corresponds to CLOS ``is undefined.'' I might expect that we would add wording to this to the effect that an implementation may include documentation about a situation of this sort that states that the results are harmless, but no implementation is allowed to state what actually happens. 4. ``CLOS may be extended to cover Sit.'' This term in intended to cover yet another reading of CLtL ``is an error,'' namely that an implementation is allowed to extend the language to cover an otherwise erroneous situation. 5. ``Implementations are free to extend the syntax Syn.'' I believe we wish to control where extensions to CLOS are allowed to occur. The first four terms are designed to control semantic extensions while the fifth is designed to control syntactic extensions, which are somewhat different. I believe we want to define precise terms such as these and use them exactly in the CLOS specification so that, rather than the CLOS specification being a pseudo-user's-guide as CLtL is, it can be a specification suitable for an implementor. -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Jul 87 14:38:11 EDT Date: 06 Jul 87 1130 PDT From: Dick Gabriel Subject: ECOOP Reaction To: common-lisp-object-system@SAIL.STANFORD.EDU As Kempf points out, there was some negative reaction to CLOS at my presentation, but most of it was directed at the lack of encapsulation and protection, multiple inheritance, and the use of CLOS as a knowledge representation system. I might point out that most of the people who raised objections during the presentation came up to me afterwards to get a hold of the spec, the code, etc. I want to make clear what it is I said about the CPL computation: I stated that the effect of the CPL algorithm was difficult to understand, not that the algorithm is difficult to understand. The difference between the two is that an algorithm can be easy to grasp while a characterization of it suitable for a programmer to understand is not available. In contrast, the algorithm for computing the strongly connected components of a graph is easy to understand as an algorithm, and it is easy to understand what it does because the definition of a strongly connected component is easy to understand. The CPL is understood to be a total ordering on a class and its superclasses, but the only characteriztion of it that I know of is that the CPL is the total ordering computed by the algorithm. That algorithm is understandable at the operational level, but there is no easy characterization of it. What would constitute an understandable characterization of the CPL? Here are some examples of approaches: 1. We could have a set of constraints on the classes such that the CPL is the unique total ordering satisfying those constraints. 2. We could have a set of inheritance situations such that when two graphs of classes were inherited in particular ways, the new CPL was predictable. For example, suppose we have 2 graphs, G1 and G2, with no common classes except for the class named T and suppose that C1 and C2 are the bottom-most classes of G1 and G2, respectively; then if a class C is a subclass of C1 and C2 in that order, the classes in G1 precede the classes in G2, and the classes in G1 are in the same order as they are in the CPL for C1 and similarly for G2; T comes last. But we do not have such a characterization; Moon's constraints are close to it, but not good enough. Possibly we can search for the characterization. Remember that at the Palo Alto meeting in March, smart people like Scherlis could not understand the effect of the algorithm, although they (and he) thought the algorithm was simple. Intellectual honesty compels me to point out things like this when I address an audience. I suppose it annoys people when I do that, but maybe we should give some thought to designing a language such that there are few oppurtunities for ``Gabriel's inevitable critique.'' -rpg-  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 5 Jul 87 03:32:11 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUL 87 23:08:17 PDT Return-Path: Received: from vaxa.isi.edu by Xerox.COM ; 02 JUL 87 19:29:33 PDT Posted-Date: Thu, 02 Jul 87 15:53:06 PDT Message-Id: <8707022253.AA02122@vaxa.isi.edu> Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51) id AA02122; Thu, 2 Jul 87 15:53:09 PDT To: CommonLoops.pa@Xerox.COM Cc: macgreg@vaxa.isi.edu Subject: Two questions and two comments Date: Thu, 02 Jul 87 15:53:06 PDT From: macgreg@vaxa.isi.edu Sometimes I find myself holding onto a class object and wanting to know the value of one of its class variables. Does/will CLOS provide a way to access class variables other than via class instances (sometimes I haven't yet allocated any instances when I need the value)? Comment: For the sake of uniformity, I would vote that initforms of class variables be evaluated just as they are for instance variables -- I get temporarily tripped-up every so often by the inconsistency in the syntax. Second question: The "add-named-class" function allows us to create a class "on-the-fly" without having to use "eval". Is there a similar construct for creating methods at run time (i.e., will it be advertised)? PCL obviously has such a function, since methods can be created as a side-effect of calling "add-named-class". By the way, is "add-name-class" part of CLOS, or just a PCL feature? Suggestion: I did some timings on compiled segments of CLOS code (on a Symbolics), and found that a slot access is 20 times faster if a "with-slots" is declared with :use-accessors = nil than if the slot is accessed with the ordinary syntax (and its 30 times faster than a "slot-value" form). So, there is great incentive to place "with-slots" declarations everywhere. I've invented a "let-slots" macro which expands to a "let" statement with a "with-slots" inside of it, which looks much more attractive than having to declare both statements. My suggestion is to put something equivalent to "let-slots" into CLOS.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 5 Jul 87 03:32:01 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUL 87 22:52:39 PDT Date: 2 Jul 87 17:18 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Is there a substitute for define-method-combination? In-reply-to: Timothy.Freeman@theory.cs.cmu.edu's message of Mon, 29 Jun 87 23:48:00 EDT To: Timothy.Freeman@theory.cs.cmu.edu cc: commonloops.pa@Xerox.COM Message-ID: <870702-225239-102@Xerox> PCL does not yet implement method combination, individual methods, or defgeneric-options. I think it has most everything else, though some names may not have been updated yet. But watch this space. danny  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 5 Jul 87 03:31:51 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUL 87 20:16:35 PDT Date: 2 Jul 87 17:18 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Is there a substitute for define-method-combination? In-reply-to: Timothy.Freeman@theory.cs.cmu.edu's message of Mon, 29 Jun 87 23:48:00 EDT To: Timothy.Freeman@theory.cs.cmu.edu cc: commonloops.pa@Xerox.COM Message-ID: <870702-201635-103@Xerox> PCL does not yet implement method combination, individual methods, or defgeneric-options. I think it has most everything else, though some names may not have been updated yet. But watch this space. danny  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Jul 87 11:47:06 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Jul 87 08:43:36 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 187240; Thu 2-Jul-87 16:58:59 EDT Date: Thu, 2 Jul 87 16:58 EDT From: David A. Moon Subject: ECOOP Reaction to CLOS To: common-lisp-object-system@sail.stanford.edu In-Reply-To: <8707021535.AA22501@hplabsc> Message-ID: <870702165857.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 2 Jul 87 08:35:59 pdt From: Jim Kempf I hope someone will post the results of the Boston meeting, particularly any decisions on initialization. Definitely. Because of the long weekend, and because Gregor will be off work Monday and Tuesday, you can expect to see this around the second half of next week. I wouldn't say we made any hard and fast decisions, but we certainly made a lot of progress and we should be able to finish that up and make actual decisions through the mail. We talked about having another meeting and the scheduling for that will have to be discussed through the mail.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Jul 87 12:20:56 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 2 Jul 87 09:11:09 PDT Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 2 Jul 87 09:10:20 pdt Received: by hplabsc ; Thu, 2 Jul 87 08:35:59 pdt Date: Thu, 2 Jul 87 08:35:59 pdt From: Jim Kempf Message-Id: <8707021535.AA22501@hplabsc> To: common-lisp-object-system@sail.stanford.edu Subject: ECOOP Reaction to CLOS My impression from talking to people at ECOOP was that most people were fairly positive about Dick's talk. He did get some flak about the inheritance algorithm, but I think this was due to the presentation. If you tell someone that something is too complicated to understand, the likely response is that you should make the design simpler so they can understand it. In my opinion, it is simply unacceptable to go around saying this. The algorithm isn't any more complicated than the one used for LR parser generation (to which Aho, Sethi, and Ullman devote 37 pages in the new Dragon book) or normalization of a relational database schema (to which Date devotes 23 pages). The fact that the algorithm is the right one is bostered by a paper by Ducournau and Habib at ECOOP, which examined a class of graph linerization algorithms having desirable qualitative properties, of which the CLOS algorithm is a member. Therefore, I hope someone can stand up at OOPSLA and do a better job of explaining it. It may take some time, and will probably require some more examples, particularly of how things can go wrong, but I think it will, in the end, gain more support for CLOS and increase programmer understanding. People should feel good about using it, not just because its the standard, but also because it does what they want and they understand that. I hope someone will post the results of the Boston meeting, particularly any decisions on initialization. Jim Kempf kempf@hplabs.hp.com  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 30 Jun 87 00:12:44 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 29 JUN 87 20:53:57 PDT Return-Path: Received: from THEORY.CS.CMU.EDU by Xerox.COM ; 29 JUN 87 20:47:42 PDT Date: Mon, 29 Jun 87 23:48:00 EDT From: Timothy.Freeman@theory.cs.cmu.edu To: commonloops.pa@Xerox.COM Subject: Is there a substitute for define-method-combination? Message-ID: <1987.6.30.3.6.12.Timothy.Freeman@theory.cs.cmu.edu> I want to do something that could be done fairly easily with define-method-combination, but unfortunately PCL doesn't have define-method-combination yet. Is there a summary anywhere of how PCL differs from the CLOS spec? I spent some time trying to understand the documentation for define-method-combination before discovering that it was unimplemented. I could have saved that time if I had a list of all of the CLOS functions and macros which are not implemented in PCL.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 29 Jun 87 19:59:13 EDT Received: from Salvador.ms by ArpaGateway.ms ; 29 JUN 87 16:42:58 PDT Return-Path: Received: from EDDIE.MIT.EDU by Xerox.COM ; 29 JUN 87 16:40:52 PDT Received: by EDDIE.MIT.EDU with UUCP with smail2.3 with sendmail-5.31/4.7 id ; Mon, 29 Jun 87 19:35:55 EDT Received: by primerd.prime.com (3.2/SMI-3.0DEV3/smail) id AA07781; Mon, 29 Jun 87 18:50:07 EDT Message-Id: <8706292250.AA07781@primerd.prime.com> Received: from S66.Prime.PDN by ENX.Prime.PDN; 29 Jun 87 18:38:28 EST Received: (from user MMODEL) by S66.Prime.PDN; 29 Jun 87 18:36:45 EDT To: COMMONLOOPS.PA@Xerox.COM From: primerd!MMODEL@S66.Prime.PDN.ARPA Date: 29 Jun 87 18:36:45 EDT To: (CommonLoops.pa@Xerox.COM) From: Mitchell Model (MModel@S66) Subject: with-slots and local variables This is a repeat of a message sent a week ago -- since I haven't received it from the mailing list, I suspect it didn't get through. I apologize if this is actually a duplicate. There is an inconsistency in the way WITH-SLOTS handles symbols that are both locally bound and instance variable names. Suppose flavor ONE has a slot called NAME. Then, in the expansion of: (WITH-SLOTS ((SELF :CLASS ONE)) (LET ((NAME 'FIRST)) (SETQ NAME 'SECOND) (PRINT NAME))) the SETQ expression is replaced by the machinery to set the IV's value to 'SECOND, but NAME is left untouched in the PRINT statement. Yes, it is better not to use an IV name as a local variable name, but with lots of mixins flying around, and deep inheritance hierarchies, a user of a class may not always realized what all the names are or may be careless or may forget, etc. The fix is a single change to EXPAND-WITH-SLOTS: wrap (AND (NULL (VARIABLE-LEXICAL-P (CADR FORM))) (NULL (VARIABLE-SPECIAL-P (CADR FORM))) ...) around the SETQ that begins the second clause of the COND that handles SETQ/SETF forms, so that that clause is not invoked if the variable being set is bound locally or is special. --- Mitchell Model  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 29 Jun 87 14:05:14 EDT Received: from Salvador.ms by ArpaGateway.ms ; 29 JUN 87 10:52:36 PDT Date: 29 Jun 87 10:47 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: generic constructor functions In-reply-to: Rick.Busdiecker@h.cs.cmu.edu's message of 26 Jun 87 22:43 EDT To: Rick.Busdiecker@h.cs.cmu.edu cc: CommonLoops.PA@Xerox.COM Message-ID: <870629-105236-2657@Xerox> Is there any reason not to have class constructor functions be generic functions? Constructors can't possibly be generic function since they do not take the class as an argument. They only take values for the slots.  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 26 Jun 87 23:21:14 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 JUN 87 20:05:00 PDT Return-Path: Received: from H.CS.CMU.EDU by Xerox.COM ; 26 JUN 87 20:03:22 PDT Date: 26 Jun 87 22:43 EDT From: Rick.Busdiecker@h.cs.cmu.edu To: CommonLoops.PA@Xerox.COM Subject: generic constructor functions Message-Id: <551760235/rfb@h.cs.cmu.edu> Is there any reason not to have class constructor functions be generic functions? I'd like to be able to do something like: (defclass device () (viewports ...) (:constructor make-device)) (defclass viewport () (device ...) (:constructor make-viewport ((device device) ...))) (defclass X-device (device) (display ...) (:constructor make-X-device)) (defclass X-viewport (viewport) () (:constructor make-viewport ((device X-device) ...))) instead of something like: (defclass device () ((viewport-constructor 'make-generic-viewport) viewports ...) (:constructor make-device)) (defclass viewport () (device ...) (:constructor make-generic-viewport)) (defmethod make-viewport ((device device) &rest args) (apply (viewport-constructor device) args)) (defclass X-device (device) ((viewport-constructor 'make-X-viewport) display ...) (:constructor make-X-device)) (defclass X-viewport (viewport) () (:constructor make-X-viewport)) The only advantage that I can think of having constructors be standard functions is speed and I think that the advantages of having them be generic functions out-weigh that consideration. Rick  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Jun 87 12:11:06 EDT Date: 25 Jun 87 0901 PDT From: Dick Gabriel Subject: Random Thoughts Concerning Initialization To: common-lisp-object-system@SAIL.STANFORD.EDU Reading over Gregor's latest proposal I am struck by the choices we have: 1. In Moon's proposal, we introduce a new programming language within the DEFCLASS syntax. This language solves the initialization problem efficiently with minimal syntax. Other problems reducable to initialization might also be so reduced by users, leading to confusing programming methodologies. 2. In Gabriel's proposal, we introduce some additional lambda-list syntax and semantics to effect the distribution of arguments to methods. This also requires complex initialization protocol to be written in a verbose manner, and it complicates lambda-lists in an unpleasant manner. 3. In Gregor's proposal, we solve the initialization problem by reducing it to a problem of manipulating argument lists. The code (sans macros) is verbose and complicated. In addition, we end up treating passed arguments as lists, which I find to be an unpleasant exposure of representation. If we approach the initialization question along the lines Gregor suggests, and if we look at the nature of generic functions (dispatching to code based on examination of passed arguments), it seems there is some tendency towards introducing into the language a means of operating on passed arguments. One reason we had trouble with generic functions that discriminated on more than the required arguments is that we had a hard time manipulating the passed arguments. If we choose a solution to initialization that involves manipulating passed arguments, we possibly ought to provide an abstraction for passed arguments - a set of passed arguments along with a set of operators that take them apart, put them together, and invoke functions on them? I believe Seus [Talcott] went some distance in this direction.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jun 87 15:05:49 EDT Date: 24 Jun 87 1155 PDT From: Dick Gabriel Subject: Request to Moon for Thursday's Discussion To: common-lisp-object-system@SAIL.STANFORD.EDU Dave, could you possibly gather some information about the current uses of initialization in Genera? It would be useful to know what the most complex requirements are, what the typical requirements are, etc, in a real system. For example, how often would the CLOS :initform protocol serve? -rpg-  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jun 87 13:52:15 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jun 87 10:45:11 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 180885; Wed 24-Jun-87 12:59:08 EDT Date: Wed, 24 Jun 87 12:58 EDT From: David A. Moon Subject: Object Creation To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870624125852.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Here's how I would do the x/y/rho/theta example: ;;; Abstract class that can be specialized to use either ;;; polar or cartesian representation (defclass position () ()) (defmethod initialize-instance :before ((self position) &key x y rho theta) (when (or x y) (set-cartesian-position self (or x 0) (or y 0))) (when (or rho theta) (set-polar-position self (or rho 0) (or theta 0)))) ;;; Default methods. One pair or the other must be shadowed. (defmethod cartesian-position ((self position)) (multiple-value-call #'polar-to-cartesian (polar-position self))) (defmethod set-cartesian-position ((self position) x y) (multiple-value-call #'set-polar-position self (cartesian-to-polar x y))) (defmethod polar-position ((self position)) (multiple-value-call #'cartesian-to-polar (cartesian-position self))) (defmethod set-polar-position ((self position) rho theta) (multiple-value-call #'set-cartesian-position self (polar-to-cartesian rho theta))) ;;; Internal subroutines for coordinate transformation (defun polar-to-cartesian (rho theta) (values (* rho (cos theta)) (* rho (sin theta)))) (defun cartesian-to-polar (x y) (if (and (zerop x) (zerop y)) (values 0 0) (values (sqrt (+ (* x x) (* y y))) (atan y x)))) ;;; Useful macro (defmacro with-direct-slots ((instance) &body body) `(with-slots ((,instance :use-accessors nil)) ,@body)) ;;; Instantiable class that uses cartesian representation (defclass cartesian-position (position) (x y)) (defmethod cartesian-position ((self cartesian-position)) (with-direct-slots (self) (values x y))) (defmethod set-cartesian-position ((self cartesian-position) new-x new-y) (with-direct-slots (self) (setq x new-x y new-y))) ;;; Instantiable class that uses polar representation (defclass polar-position (position) (rho theta)) (defmethod polar-position ((self polar-position)) (with-direct-slots (self) (values rho theta))) (defmethod set-polar-position ((self polar-position) new-rho new-theta) (with-direct-slots (self) (setq rho new-rho theta new-theta)))  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 24 Jun 87 10:42:20 EDT Received: from Semillon.ms by ArpaGateway.ms ; 24 JUN 87 07:23:34 PDT Return-Path: Received: from Cs.Ucl.AC.UK (TUNNEL.CS.UCL.AC.UK) by Xerox.COM ; 24 JUN 87 07:21:54 PDT Received: from csvax.aberdeen.ac.uk by nss.Cs.Ucl.AC.UK via Janet with NIFTP id aa08524; 24 Jun 87 15:12 BST Date: Wed, 24 Jun 87 15:09:49 GMT From: Steve Messick To: "commonloops.pa" <@Cs.Ucl.AC.UK:commonloops.pa@xerox.com> Subject: defmethod-setf patch for DEC CL v2.0 Cc: messick%csvax.aberdeen.ac.uk@Cs.Ucl.AC.UK Message-ID: <870624-072334-2173@Xerox> DEC Common Lisp Release 2.0 has a bug in its backquote handler which causes defmethod-setf to fail if more than one argument appears in its specialized-lambda-list. The following patch applies to pcl with *pcl-system-date* "5/22/87 (rev 3) May 22nd, 1987". I've heard rumors of more recent releases of DEC CL; perhaps this bug has been fixed in them. --steve ;;; file: braid0.lisp (defun do-defmethod-setf-defsetf (generic-function-name arglist &optional (new-value-arglist '(new-value))) (let ((setf-name (make-setf-generic-function-name generic-function-name))) (do-defsetf generic-function-name arglist new-value-arglist #-(and dec vax) ``(,',setf-name ,,@new-value-arglist ,,@arglist) #+(and dec vax) (list* 'list (list 'quote setf-name) (append new-value-arglist arglist)) )))  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jun 87 00:46:30 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jun 87 21:13:04 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 180419; Wed 24-Jun-87 00:12:34 EDT Date: Wed, 24 Jun 87 00:12 EDT From: David A. Moon Subject: Object creation To: Common-Lisp-Object-System@sail.stanford.edu Message-ID: <870624001226.9.MOON@EUPHRATES.SCRC.Symbolics.COM> I've been studying the huge piles of mail on this subject. I'm not sure that all of the ideas that were intended to be conveyed got through to me, since there was so much mail and so many contradictions and minor errors. Hence I apologize if what follows misses the point. I couldn't find anything that directly addressed the issues I raised in my message of 29 May; the one dividing things up into eight parts, of which only three are actually needed if we want to keep things simple. Did it get lost in the network? My hardcopy of Dick's message of 31 May has "agreed" written all over it. The conclusion I drew was that we aren't doing automatic programming here and the generic-function-dispatch mechanism is pretty limited in what programming tasks it can do automatically for us. Still, it would be nice if we could come up with a general paradigm for the procedural description of inheritance and use it uniformly for classes, methods, slots, and initializations, and also make it available to users with their own things-that-inherit; I don't have any specific suggestions on this yet. One thing that I think we have learned is that it seems to be a mistake to try to abstract away the caching that happens in every real implementation of inheritance; we need to separate the generic functions that gather and combine information from the superclasses, from the generic functions that are called when an object is created; the cache that sits between them needs to be made explicit. I do have some thoughts to offer on the various schemes that have been discussed for object creation at the meta-object level. It seems that there are three rather different things that this could be for: (1) The language used by ordinary, rank-and-file programmers to write their programs. (2) A procedural explanation of the semantics, so that there is no magic and everything is explained in terms of something else. This seems to be where Patrick's suggested generic, high-level tools fit in. (3) A way to modify very basic aspects of the system's behavior, for instance changing the way initargs inherit. Taking these in order: (1) I feel that a successful standard will provide simple ways to do simple things. A good argument that controlling object creation only at the meta-object level is too difficult is contained in Gregor's message of 15 June. In the x-y-rho-theta example, the compute-initargs method for position looks impressive, but if you study it carefully you will realize that it is actually a complicated no-op! Regardless of whether this method or the default method is called, the result will be the same: a list containing the supplied initargs plus all of the unsupplied ones with their default values from class-default-initargs. I suspect that what happened here is that Gregor got so bogged down in the complexity of describing the x/y/rho/theta class in these very low-level procedural terms, that he forgot what the original point was. Gregor is a smart guy, so I think what this shows is that an object-oriented system that works this way is too difficult for anyone to use without making mistakes. Actually, this is probably a non-issue. Correct me if I am wrong, but I think we have already agreed that we want a simple, high-level way to do simple object-creation, with the procedural level behind the scenes where it belongs. (2) I think having a procedural explanation of the semantics is a good idea. If I earlier gave the impression that I was opposed to that, it was a misimpression. I do have some reservations, which I think fall into two categories: (a) This level of the standard involves a lot more detail than the simple programmer interface, and there is correspondingly more possibility for errors. Two examples that I noticed were failure to carry along a lexical environment with forms, so that they can be evaluated in the lexical environment in which they were written; and confusion between method selection by the class of the instance versus by the class of the class. These are small errors and fairly easy to fix. For example, the first could be fixed by using functions instead of forms and the second could be fixed by being consistent. The point is simply that there are more things to go wrong and it will take longer to get them right, because we are standardizing an implementation (at some level of abstraction) rather than standardizing only a description of how any implementation must behave. (b) There is the danger of ripping too many holes in the veil of abstraction between the user and the implementation, eliminating the freedom to choose an implementation optimized for particular circumstances. We have often made this mistake in the Lisp Machine world in the past, and paid for it later. One example of this problem is that I haven't been able to figure out whether some of the proposals that have been discussed require the methods for class-default-initargs to be called every time make-instance is called, thus ruling out precomputation and caching of this information. Similarly I wasn't able to figure out whether initializing many of the slots by copying a template containing the values of constant initforms would be a valid implementation, or whether the initforms actually have to be evaluated at the time we say they are evaluated. A more serious problem is that if the two operations, collection of the inherited default value forms and evaluation of these forms, are combined into one generic function, such as compute-initargs, it becomes impossible to collect these forms without evaluating them and compile them into a function. This is really the same point I made earlier, that trying to hide the existence of caches isn't working. A third problem, which I mention because it's of a completely different nature, is that if the standard mandates that each little aspect of a class must be expressed as a method, and we actually have to create method objects, compiled-function objects, and generic-function dispatch table entries for each of those methods, it's going to tie up a large amount of space. In a large system like Genera, a rough, no doubt inaccurate estimate I made came out to 3/4 megabyte. The point of these reservations is that if we're going to include this level of detail in the standard, we have to be very careful what we say and be sure we know what it implies. (3) I'm not very happy about the idea of the user being able to redefine very basic aspects of the behavior of the system, such as the way the supplied initargs are combined with the default initargs. It seems like this would weaken the idea of a standard, because there would be no contract that the system could safely be assumed to obey. Actually what bothers me here is not the idea that it is possible to redefine these things, because I'm an open-system kind of guy and if people want to yank the foundations out from under themselves that's okay with me. What really bothers me is the idea that redefining this stuff will be part of ordinary day to day programming, rather than just something that you do when you're experimenting with new kinds of object systems; changing the rules should be intentional, not accidental. Where do we go from here? I think we should go back to figuring out what the language used daily by rank-and-file programmers is. Once we think we agree on that, we should verify that it makes sense by agreeing on the procedural description of it; there will be some iteration of these two steps (there has already been some). The biggest issue seems to be what suite of features we want in that language, for example, is the extra complexity of allowing initargs to be defaulted worthwhile?  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 23 Jun 87 07:37:06 EDT Received: from Semillon.ms by ArpaGateway.ms ; 23 JUN 87 04:21:02 PDT Return-Path: Received: from SUMEX-AIM.STANFORD.EDU by Xerox.COM ; 23 JUN 87 04:18:29 PDT Date: Tue, 23 Jun 87 04:17:15 PDT From: Reed Hastings Subject: initform bug To: commonloops.pa@Xerox.COM Stanford-Phone: (415) 725-3850 Message-ID: <12312764826.29.HASTINGS@SUMEX-AIM.STANFORD.EDU> Initforms on slots allocated on a class are NOT getting evaluated. ==> (defclass heart () ((color :initform 'red :allocation :class)) (:accessor-prefix nil)) # ==> (setq h (make-instance 'heart)) #S(HEART) ==> (color h) (QUOTE RED) -------  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Jun 87 19:31:39 EDT Received: from Semillon.ms by ArpaGateway.ms ; 17 JUN 87 12:49:49 PDT Return-Path: Received: from VAX.BBN.COM by Xerox.COM ; 17 JUN 87 12:46:22 PDT To: Arun cc: commonloops.pa@Xerox.COM, pai-developers@VAX.BBN.COM Subject: Re: Browsers? In-reply-to: Your message of Tue, 16 Jun 87 15:43:28 -0400. <8706161945.AA12099@ohio-state.ARPA> Date: Wed, 17 Jun 87 15:39:28 -0400 From: kanderso@VAX.BBN.COM Message-ID: <870617-124949-2095@Xerox> Date: Tue, 16 Jun 87 15:43:28 EDT From: Arun Subject: Browsers? To: commonloops.pa@XEROX.COM Has anyone implemented Class and/or Instance browsers (ala the Loops browsers) for PCL, for either TI Explorers or Xerox D-machines? ...arun ------- We have a pop up class browser that is convenient to use with ZMACS, and a stand alone class structure editor. They run on Symbolics LISPM and were developed by our Parallel AI Tools project that is developing a version of PCL for the Butterfly. k  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Jun 87 14:36:39 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 JUN 87 08:56:04 PDT Return-Path: Received: from postgres.Berkeley.EDU by Xerox.COM ; 17 JUN 87 08:54:13 PDT Received: by postgres.Berkeley.EDU (5.57/1.26) id AA29418; Wed, 17 Jun 87 08:53:20 PDT Date: Wed, 17 Jun 87 08:53:20 PDT From: luis%postgres.Berkeley.EDU@berkeley.edu (Luis Miguel) Message-Id: <8706171553.AA29418@postgres.Berkeley.EDU> To: Welch%OSU-20@ohio-state.arpa, commonloops.pa@Xerox.COM Subject: Re: Browsers? I am implementing a class browser for Suns 3. It runs on Excl, using Dave Martin's XCL interface to X. /Luis  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Jun 87 11:08:07 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 JUN 87 07:51:02 PDT Return-Path: Received: from decwrl.dec.com by Xerox.COM ; 17 JUN 87 07:48:29 PDT Received: from rhea.dec.com by decwrl.dec.com (5.54.3/4.7.34) id AA03676; Wed, 17 Jun 87 07:47:50 PDT Message-Id: <8706171447.AA03676@decwrl.dec.com> Date: Wed, 17 Jun 87 07:42:56 PDT From: robbins%ramona.DEC@decwrl.dec.com To: CommonLoops.pa@Xerox.COM Subject: PCL & VAX Lisp >We have had alot of difficulty in compiling the VAX versions of the last few >releases of Common LOOPS. I know it is unreasonable to ask for help debugging >our compiled code, but it would be much easier in the future if the VAX LISP >version could also include a binary directory, like the other versions. It >would save us quite alot of time that we spend trying to compile the source. >Thanks again, Thomas Hornick > hornick@stsci.ARPA What version of VAX Lisp do you have and what problems have you run in to? -- Rich Robbins VAX Lisp Development Group Robbins%Bach.Decnet@Hudson.Dec.Com  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Jun 87 11:07:58 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 JUN 87 07:31:26 PDT Return-Path: Received: from hudson.dec.com by Xerox.COM ; 17 JUN 87 07:27:54 PDT Date: 17 Jun 87 10:26:00 EDT From: "RAMONA::ROBBINS" Subject: PCL & VAX Lisp To: "commonloops.pa" cc: burock::mailer! Reply-To: "RAMONA::ROBBINS" Message-ID: <870617-073126-1464@Xerox> >We have had alot of difficulty in compiling the VAX versions of the last few >releases of Common LOOPS. I know it is unreasonable to ask for help debugging >our compiled code, but it would be much easier in the future if the VAX LISP >version could also include a binary directory, like the other versions. It >would save us quite alot of time that we spend trying to compile the source. >Thanks again, Thomas Hornick > hornick@stsci.ARPA What version of VAX Lisp do you have and what problems have you run in to? -- Rich Robbins VAX Lisp Development Group Robbins%Bach.Decnet@Hudson.Dec.Com ------  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Jun 87 08:07:39 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 JUN 87 04:39:49 PDT Return-Path: Received: from burdvax.PRC.Unisys.COM (BIGBURD.PRC.UNISYS.COM) by Xerox.COM ; 17 JUN 87 04:33:07 PDT Received: from bigburd.PRC.Unisys.Com by burdvax.PRC.Unisys.COM (burdvax.PRC.Unisys.Com) [5.54/1.0] id AA17142; Wed, 17 Jun 87 07:32:34 EDT Received: by bigburd.PRC.Unisys.Com (5.54/4.7) id AA22293; Wed, 17 Jun 87 07:32:31 EDT From: Richard Fritzson Message-Id: <8706171132.AA22293@bigburd.PRC.Unisys.Com> Received: from Plebian by bigburd with PUP; Wed, 17 Jun 87 07:32 EDT Date: 17 Jun 87 07:30 EDT (Wednesday) Subject: Re: What am I doing wrong? In-Reply-To: Arun Welch's message of Tue, 16 Jun 87 17:14:07 edt To: Arun Welch Cc: commonloops.pa@Xerox.COM Date: Tue, 16 Jun 87 17:14:07 edt From: Arun Welch I don't understand whats wrong here. Could someone point out my mistake, or is this a bug? 133> (defclass test-class () (s1 :initform 3.4 :type number :accessor get-s1-again)) Arg not a LIST 3.4 134> The slot third argument to defclass is a LIST of slot descriptions. Try this: (defclass test-class () ((s1 :initform 3.4 :type number :accessor get-s1-again))) Also for browsing (well, just looking at) a single class or instance in PCL on a Xerox, you can just use INSPECT if you load Gregor's PCL-ENV file. It has a couple of glitches in it (and he hasn't posted a new version of it recently (hint hint)) but it has been vey useful to me. -Rich Fritzson ----- End Forwarded Messages -----  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 17 Jun 87 05:47:30 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 16 JUN 87 21:44:45 PDT Return-Path: Received: from THEORY.CS.CMU.EDU by Xerox.COM ; 16 JUN 87 21:42:29 PDT Date: Wed, 17 Jun 87 00:43:20 EDT From: Timothy.Freeman@theory.cs.cmu.edu To: commonloops.pa@Xerox.COM Subject: bug in lucid-low of 4/29/87 Prime version of PCL Message-ID: <1987.6.17.4.34.36.Timothy.Freeman@theory.cs.cmu.edu> The 4/29/87 version of PCL (which is NOT the most recent one) causes the Lucid Common Lisp (Sun version 2.0.3) debugger to sometimes try to print most of memory to the screen. Here's how to recreate the problem, after you have loaded PCL: Foo.lisp contains: (in-package :foo) (use-package :user) Foo.lisp has been compiled, and this happens: > (setq system::*debug-print-level* nil system::*debug-print-length* nil) NIL > (in-package :foo) # > 'hi HI > (in-package :user) # > (export 'hi) T > (load "foo") >>Error: If the FOO package were to 'use' the USER package, there would be name conflicts with symbols found in the following packages ("USER") The particular symbols involved are: (USER:HI) SYSTEM:FASLOAD: Required arg 0 (FILENAME): #P"/usrea0/tsf/test/foo.2bin" Keyword arg 1 (VERBOSE): NIL Keyword arg 2 (PRINT): NIL Keyword arg 3 (IF-DOES-NOT-EXIST): :ERROR Keyword arg 4 (DEFAULT-PATHNAME): ".lbin" Keyword arg 5 (CODE-AREA): #S(LUCID::AREA NIL "Readonly-Non-Pointer-Area" NIL 0 NIL (# . #) NIL (0 . 0) NIL (328581110 . 0) NIL (328581110 . 0) NIL 0 NIL #S(LUCID::REGION NIL 0 NIL (# . # Received: from ohio-state.ARPA by Xerox.COM ; 16 JUN 87 14:12:12 PDT Return-Path: Received: by ohio-state.ARPA (4.12/6.1.OSU-CIS) id AA00493; Tue, 16 Jun 87 17:14:07 edt Date: Tue, 16 Jun 87 17:14:07 edt From: Arun Welch Message-Id: <8706162114.AA00493@ohio-state.ARPA> To: commonloops.pa@Xerox.COM Subject: What am I doing wrong? I don't understand whats wrong here. Could someone point out my mistake, or is this a bug? 133> (defclass test-class () (s1 :initform 3.4 :type number :accessor get-s1-again)) Arg not a LIST 3.4 134> I'm using PCL version 29-may, in the Lyric version of Xerox Lisp. ...arun  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 16 Jun 87 21:24:34 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 16 JUN 87 13:47:44 PDT Return-Path: Received: from stsci.arpa by Xerox.COM ; 16 JUN 87 13:45:00 PDT Received: Tue, 16 Jun 87 13:47:50 EDT from cygnus.arpa by stsci.arpa (3.2/1.0) Received: by cygnus.arpa (3.2/SMI-3.2) id AA16058; Tue, 16 Jun 87 13:52:01 EDT Date: Tue, 16 Jun 87 13:52:01 EDT From: hornick@stsci.arpa (Tom Hornick) Message-Id: <8706161752.AA16058@cygnus.arpa> To: CommonLoops.pa@Xerox.COM We have had alot of difficulty in compiling the VAX versions of the last few releases of Common LOOPS. I know it is unreasonable to ask for help debugging our compiled code, but it would be much easier in the future if the VAX LISP version could also include a binary directory, like the other versions. It would save us quite alot of time that we spend trying to compile the source. Thanks again, Thomas Hornick hornick@stsci.ARPA  Received: from Xerox.COM (TCP 1200400040) by AI.AI.MIT.EDU 16 Jun 87 21:24:09 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 16 JUN 87 12:46:11 PDT Return-Path: Received: from ohio-state.ARPA by Xerox.COM ; 16 JUN 87 12:44:13 PDT Return-Path: Received: from OSU-20 (osu-20.ARPA) by ohio-state.ARPA (4.12/6.1.OSU-CIS) id AA12099; Tue, 16 Jun 87 15:45:58 edt Message-Id: <8706161945.AA12099@ohio-state.ARPA> Date: Tue, 16 Jun 87 15:43:28 EDT From: Arun Subject: Browsers? To: commonloops.pa@Xerox.COM Has anyone implemented Class and/or Instance browsers (ala the Loops browsers) for PCL, for either TI Explorers or Xerox D-machines? ...arun -------  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Jun 87 22:31:54 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 15 Jun 87 19:20:30 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 15 JUN 87 15:06:21 PDT Date: 15 Jun 87 15:06 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: new new initialization protocol blues In-reply-to: Gregor.pa's message of 15 Jun 87 11:06 PDT To: Gregor.pa@Xerox.COM cc: Common-Lisp-Object-System@Sail.Stanford.edu, Bobrow.pa@Xerox.COM Message-ID: <870615-150621-108@Xerox> 1) It is useful to be able to allocate storage for an instance without having to evaluate all the initforms, for example, to build a class-prototype without risking an error. Either this must be a function that is called by allocate-instance, or it can be the job of allocate instance. But in Gregor's message (and my earlier message) we stated that The method for allocate-instance on standard-class is documented to allocate storage and evaluate and store all the initforms. A useful alternative may be to make the method for allocate-instance only allocate storage for the instance. Then the primary method on object for initialize-instance would be documented to evaluate and store all the initforms. 2) Gregor's method not only exposes the proposed implementation of initargs as methods, but suggests that the user must program using this verbose style. Here is a useful macro, shown only in an example, that would usually be used by users to specify how to handle inputs to specify slot-values. The name of the macro can obviously be improved. User-code: (define-initialize-instance-after-method x-y-position (pos &key start-the-engine) ((x :x number "a number") ;; initialize x a slot, checking its type as a number (y :second) ;; initialize y as a slot, using keyword :second z) ;; initialize z as a slot, using z as the keyword (when start-the-engine (fire-up pos))) ;; other user init code ---- Translation: (defmethod initialize-instance :after ((pos x-y-position) &key start-the-engine ((:x #:g1) nil #:g2) ((:y #:g3) nil #:g4) ((z #:g5) nil #:g6) &allow-other-keys) (when #:g2 (check-type #:g1 number "a number") (setf (slot-value pos 'x) #:g1)) (when #:g4 (setf (slot-value pos 'y) #:g3)) (when #:g6 (check-type #:g5 z-type) ;; this here if :type specified in the class (setf (slot-value pos 'z) #:g5)) ;; Now comes the user-supplied body. (when start-the-engine (fire-up pos)))  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Jun 87 14:24:41 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 15 Jun 87 11:17:55 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 15 JUN 87 11:06:40 PDT Date: 15 Jun 87 11:06 PDT From: Gregor.pa@Xerox.COM Subject: new new initialization protocol blues To: Common-Lisp-Object-System@Sail.Stanford.edu cc: Bobrow.pa@Xerox.COM, Gregor.pa@Xerox.COM Message-ID: <870615-110640-1411@Xerox> Here is another example of a fully procedural initialization protocol. This message also includes an example of using that protocol to solve the x-y-rho-theta problem. In this protocol, make-instance, compute-initargs, class-default-initargs and class-legal-initargs are documented generic functions. The method for make-instance on standard-class is documented to call compute-initargs and allocate-instance. The method for allocate-instance on standard-class is documented to allocate storage and evluate and store all the initforms. The method for compute-initargs on object is documented to call class-default-initargs and class-legal-initargs and do the kind of defaulting we have all come to expect. Many users will just want to define methods on class-default-initargs and class-legal-initargs. Users trying to deal with problems like the x-y-rho-theta problem will usually have to define methods on compute-initargs as well. (defmethod make-instance ((class symbol) &rest supplied-initargs) (apply #'make-instance (class-named symbol) supplied-initargs)) (defmethod make-instance ((class standard-class) &rest supplied-initargs) (let* ((proto (class-prototype class)) (total-initargs (compute-initargs proto supplied-initargs)) (instance (apply #'allocate-instance class total-initargs))) (apply #'initialize-instance instance total-initargs) instance)) (defmethod compute-initargs ((object object) supplied-initargs) (let* ((default (class-default-initargs object)) (legal (class-legal-initargs object)) (total supplied-initargs) (magic-value (list nil))) (do ((prop default (cddr prop)) (val (cdr default) (cddr val))) ((null prop)) (when (eq (getf total prop magic-value) magic-value) (push (eval val) total) (push prop total))) (do ((prop total (cddr prop))) ((null prop)) (unless (member prop legal) (error "~S is not a legal initarg for the class ~S" prop (class-of object)))) total)) (defgeneric-options class-legal-initargs (class) (:method-comination-type append)) (defmethod class-legal-initargs ((class object)) '(:allow-other-keys)) (defgeneric-options class-default-initargs (class) (:method-combination-type append)) (defmethod class-default-initargs ((class object)) ()) ;;; ;;; Here is an example of all this in use to solve the notorious ;;; x-y-rho-theta problem. ;;; We define a class named position, which can be mixed into ;;; a class that implements either x-y-position primitives or ;;; rho-theta-position primitives. This class takes care of providing ;;; the other set of primitives, and more importantly takes care of ;;; handling the :x :y :rho :theta defaulting properly. ;;; (defclass position () ()) (defmethod class-legal-initargs ((pos position)) '(:rho :theta :x :y)) (defmethod class-default-initargs ((pos position)) '((:x 0) (:y 0) (:rho 0) (:theta 0))) (defmethod compute-initargs ((pos position) supplied) (let ((x-p (memq ':x supplied)) (y-p (memq ':y supplied)) (r-p (memq ':rho supplied)) (t-p (memq ':theta supplied)) (defaults (class-default-initargs class))) (when (and (or x-p y-p) (or r-p t-p)) (error "make up your mind loser")) (cond ((and x-p y-p)) ((and r-p t-p)) (x-p (setf (getf supplied :y) (eval-default-initarg (getf defaults :y)))) (y-p (setf (getf supplied :x) (eval-default-initarg (getf defaults :x)))) (r-p (setf (getf supplied :theta) (eval-default-initarg (getf defaults :theta)))) (t-p (setf (getf supplied :rho) (eval-default-initarg (getf defaults :rho))))) (call-next-method pos supplied))) (defmethod x-position ((p position)) (convert-rho-theta-to-x (rho-position p) (theta-position p))) (defmethod y-position ((p position)) (convert-rho-theta-to-y (rho-position p) (theta-position p))) (defmethod rho-position ((p position)) (convert-x-y-to-rho (x-position p) (y-position p))) (defmethod theta-position ((p position)) (convert-x-y-to-theta (x-position p) (y-position p))) (defclass x-y-position (position) (x y)) (defmethod initialize-instance :after ((pos x-y-position) &key x y &allow-other-keys) (setf (slot-value pos 'x) x (slot-value pos 'y) y)) (defclass rho-theta-position (position) (rho theta)) (defmethod initialize-instance :after ((pos rho-theta-position) &key rho theta &allow-other-keys) (setf (slot-value pos 'rho) rho (slot-value pos 'theta) theta))  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Jun 87 15:12:07 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Jun 87 12:04:07 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 12 JUN 87 11:38:02 PDT Date: 12 Jun 87 11:37 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Order of Initialization In-reply-to: Jim Kempf 's message of Thu, 11 Jun 87 08:16:39 pdt To: Common-lisp-object-system@SAIL.STANFORD.EDU, RPG@SAIL.STANFORD.EDU Message-ID: <870612-113802-1764@Xerox> I think that if the INITIALIZE-INSTANCE (or whatever is ultimately agreed to be the name) user customizable method could be designated the right place to put special initialization needs, like the requirement for initialization to proceed in a particular order, then the need for specifying the order within the class itself goes away. However, it is important that the spec specifically state that the user cannot depend on the order of initialization for :INITFORMs, otherwise, someone is bound to do so. RIGHT (Meaning I agree)  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Jun 87 13:14:38 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Jun 87 10:02:05 PDT Received: from relay2.cs.net by RELAY.CS.NET id ad01370; 12 Jun 87 12:54 EDT Received: from ti-csl by RELAY.CS.NET id ag22147; 12 Jun 87 12:49 EDT Received: by tilde id AA18373; Fri, 12 Jun 87 11:11:18 CDT Message-Id: <2759501598-3981583@Jenner> Date: Fri, 12 Jun 87 11:13:18 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Metaclass Protocol This message is a first-cut attempt at a design rationale for the metaclass protocol. The metaclass protocol being quite large, it will be easier if we discuss and agree on the design rationale first. We want to standardize the metaclass protocol to meet these objectives: - Allow for portable compatible extensions to the CLOS model. 1)Some might change the instances representation/behavior while retaining a compatible top-level interface; Persistent objects systems and Distributed objects systems are some examples. 2)Some might extend the model by changing the classes behavior like Delegation instead of Inheritance or they can implement another object system for backward compatibility reasons (like Flavors, Common Objects...). It would be desirable to allow a certain degree of coexistence between classes belonging to different metaclasses. - Allow for generic high level tools(Inspectors, generators, analyzers). As a number of extensions will become available, there will be a need for a single set of tools able to deal equally well with those extensions. Requirements: The metaclass protocol should allow the implementation to pick the best optimization strategy (in terms of code generation and instance representation). The metaclass protocol should allow for any programming development styles. The idea is that an implementation should be able to support both smooth incremental development and efficient wholesale file compilation. The metaclass protocol should support first class objects and anonymous generic functions. - Class behavior and instance behavior are othorgonal in CLOS. The metaclass protocol must preserve this orthoganality. The metaclass protocol should be as modular as possible. I would want to be able to write a Persistent-mixin metaclass and then mix it with STANDARD-CLASS to get a persistent standard-class or with FLAVORS to get a persistent flavors metaclass, instead of having to implement a full-blown metaclass for every case. I think those objectives and requirements open up some specific issues: - The side effects on CLOS objects (Classes, generic-functions, methods) that spead across object links should be exposed. Compute-class-precedence-list is a good example. - It should be possible to access some exposed slots of a CLOS object without side-effect. An inspector may need to access the Class-precedence-list slot of a class without triggering compute-class-precedence-list on the class. I think that means we need to have a way to indicate when a slot contains valid data. - We probably need to care about the compile environment. We don't have to specify what it is but where, in our protocol it should be looked up or side effected. At least we must make sure that we don't go against the following statements: 1)Compile-file does not side effect the running environment. 2)It is possible to implement a cross loader (Something that loads files in order to make some class definitions, etc that will affect the compilation but not the running environment). The list of requirement and issues is far from being complete, but it probably covers enough to get the discussion started. Patrick.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Jun 87 15:51:39 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Jun 87 12:42:47 PDT Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 11 Jun 87 12:41:51 pdt Received: by hplabsc ; Thu, 11 Jun 87 12:40:41 pdt Date: Thu, 11 Jun 87 12:40:41 pdt From: Jim Kempf Message-Id: <8706111940.AA02450@hplabsc> To: Moon@STONY-BROOK.SCRC.Symbolics.COM, common-lisp-object-system@sail.stanford.edu Subject: Re: SETF- method names > Date: Thu, 11 Jun 87 07:45:01 pdt > From: Jim Kempf > > >2) With generic functions, there is such a level of indirection without > >using a name, namely the generic function object. If TRACE were a > >generic function that had an implementation dependent method on > >GENERIC-FUNCTION, it would wqork fine. So again no names are needed. > > > >Actually this opens its own can of worms. I can't figure out from CLtL >whether TRACE is intended to be an operation on function names, or on >functions. Perhaps it is intentionally left to the discretion of the >particular programming environment. All I know is that in Maclisp and >Zetalisp it was defined to be an operation on function names; but making >it operate on generic-function and method objects would make it an >operation on functions. Here's an example to show what I mean by the >distinction: > >(defun foo (x) (print x)) >(let ((f (function foo))) > (trace foo) > (funcall f 105)) > >If TRACE is an operation on function names, this just prints 105. If it's >an operation on functions, it generates tracing output as well. > True, it could complicate implementations. The typical way of dealing with tracing via names is to wrap the fundef with a wrapper function, and hang the wrapper off the symbol's function cell. This doesn't demand anything special of the fundef or symbol, since symbols are typically writable. If TRACE becomes an operation on fundefs, it's got to modify the fundef object, perhaps (extrapolating from the implementation I'm aware of) putting a jump to the trace function as the first instruction in the fundef. This may get difficult, if fundefs are in restricted parts of memory, like nonwritable, which often is used for sharing executable code between processes in different address spaces (again, in the implementation I know best). jak  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Jun 87 14:25:49 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Jun 87 11:03:38 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 170333; Thu 11-Jun-87 14:02:24 EDT Date: Thu, 11 Jun 87 14:02 EDT From: David A. Moon Subject: Re: SETF- method names To: common-lisp-object-system@sail.stanford.edu In-Reply-To: <8706111445.AA28326@hplabsc> Message-ID: <870611140213.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 11 Jun 87 07:45:01 pdt From: Jim Kempf >2) With generic functions, there is such a level of indirection without >using a name, namely the generic function object. If TRACE were a >generic function that had an implementation dependent method on >GENERIC-FUNCTION, it would wqork fine. So again no names are needed. > Actually this opens its own can of worms. I can't figure out from CLtL whether TRACE is intended to be an operation on function names, or on functions. Perhaps it is intentionally left to the discretion of the particular programming environment. All I know is that in Maclisp and Zetalisp it was defined to be an operation on function names; but making it operate on generic-function and method objects would make it an operation on functions. Here's an example to show what I mean by the distinction: (defun foo (x) (print x)) (let ((f (function foo))) (trace foo) (funcall f 105)) If TRACE is an operation on function names, this just prints 105. If it's an operation on functions, it generates tracing output as well. A this would solve the problem nicely, for those cases where the funcallable object is well defined (fundefs, generic functions, symbols w. function cell bound, methods, etc.). The problem remains with SETF forms which take generalized variable references, like SVREF, since there is currently no way to obtain the funcallable object corresponding to the SETF "method" (to use CLtL terminology). You actually mean the funcallable object called by the form that is returned by the SETF "method"; those type of SETF-"methods" are macros, unlike CLOS setf-methods, which are functions. Yes, this is a problem and I don't know of any good answers to it; after all, the SETF form might well expand into a call to a different function depending on seemingly minor variations in details of the arguments. Not a problem for CLOS, just a problem for CL. Your technique of macroexpanding a sample form and assuming that the function that appears there is the one that is going to be called is probably as good as any.  Received: from SAIL.STANFORD.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Jun 87 11:23:29 EDT Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Jun 87 08:19:31 PDT Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 11 Jun 87 08:17:56 pdt Received: by hplabsc ; Thu, 11 Jun 87 08:16:39 pdt Date: Thu, 11 Jun 87 08:16:39 pdt From: Jim Kempf Message-Id: <8706111516.AA28670@hplabsc> To: Bobrow.pa@Xerox.COM, kempf%hplabsc@hplabs.HP.COM Subject: Re: Order of Initialization Cc: Common-lisp-object-system@SAIL.STANFORD.EDU, RPG@SAIL.STANFORD.EDU >I think one should not depend on the order. I agree, however, there may be cases where the order does matter. >Consider the ambiguity >resulting from two class definitions: > >(defclass c1 () > ((x :initform (initx1)) > (y :initform (inity)))) > >(declass c2 (c1) > ((x :initform (initx2))) > >These can be in a file in either order. Which order for eveluation of >(initx2) and (inity) do you think is correct. I can think of arguments >for both. Further, consider > >(defclass c3 (c1) > ((z :initform (initz)) > (y :initform (inity2)) > (x :initform (initx3)))) > In this particular example, the class precedence list for C1 would be: (C1 STANDARD-OBJECT T) the initializer for the X slot would be INITX2, and the initializer for the Y slot would be INITY. For C2, the class precedence list would be: (C2 C1 STANDARD-OBJECT T) and, according to the rules on pg. 1-8:1-9 of 87-002 (and provided it is decided to stick with them), the initializer for X would be INITX2 and that for Y would be INITY. If one uses the class precedence list to impose a global ordering on initialization, and the lexical order within the class to impose a local ordering, one could argue that the initialization order INITX2, INITY would make sense. >So my choice is 3, the user should not depend on the