Received: from piglet.parc.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA11864; Thu, 26 Apr 90 17:34:53 -0700 Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA20842; Thu, 26 Apr 90 17:35:25 PDT Received: from arisia.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA11191; Tue, 24 Apr 90 17:18:19 PDT Received: from nero.parc.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA19836; Tue, 24 Apr 90 17:17:00 -0700 Received: by nero.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA02175; Tue, 24 Apr 90 17:16:34 PDT Received: from Messages.7.14.N.CUILIB.3.45.SNAP.NOT.LINKED.nero.parc.xerox.com.sun4.40 via MS.5.6.nero.parc.xerox.com.sun4_40; Tue, 24 Apr 90 17:16:33 -0700 (PDT) Message-Id: Date: Tue, 24 Apr 90 17:16:33 -0700 (PDT) From: Danny Bobrow To: Dussud@Lucid.com, Gray@Lucid.com, JonL@Lucid.com, RPG@Lucid.com, Moon@Stony-Brook.SCRC.Symbolics.com, Cyphers@Stony-Brook.SCRC.Symbolics.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, "Gregor J. Kiczales" Subject: Re: user interface macros Cc: rivieres@parc.xerox.com, bobrow@parc.xerox.com, gregor@parc.xerox.com In-Reply-To: <19900424043758.2.GREGOR@SPIFF.parc.xerox.com> References: <19900424043758.2.GREGOR@SPIFF.parc.xerox.com> Resent-To: mop-archive@arisia.Xerox.COM Resent-From: Gregor J. Kiczales Resent-Date: Thu, 26 Apr 90 17:34 PDT Resent-Message-Id: <19900427003451.9.GREGOR@SPIFF.parc.xerox.com> "The only exception is that the function {\bf ensure-generic-function} will be called and generic function metaobjects will be created during compiler processing of {\bf defmethod} and {\bf defgeneric} macros. This is discussed in the section ``Processing Method Bodies''." Later you say that the information used will be that IN EFFECT on the generic function at the time the method is defined. But when compiling a file, you may be changing the generic function (e.g. changing the set of required arguments). Don't we need to be explicit about what is in effect, and what is inherited from the run-time. "\beginNote Canonicalized slot specifications are called a property list and strictly speaking they are. Later, when the canonicalized slot specification is used it will be used as keyword arguments and values to a generic function which will, in turn, pass it to {\bf make-instance} for use as a set of initialization arguments and values. \endNote" A suggested rewording \beginNote A canonicalized slot specification is a property list. It will be used as keyword arguments to a generic function which will, in turn, pass them to {\bf make-instance} for use as a set of initialization arguments. \endNote ---- WORD MISSING: The value specified by an {\bf :accessor} slot option is <> two element list: ----- In Figure 3-2 the defclass expansion, in one case you reverse the order of elements with the same slot-option name :readers '(mach mach-speed) and in the other you don't :locator '(sst-mach mach-location) Should this be specified? ---- "The {\bf :lambda-list} keyword argument is supplied in the call, its value is the lambda list of the method reduced to a generic function lambda list." "reduced to a g-f lambda-list" is not defined here or in Chapter 1 or 2. If a method has a keyword argument, is that keyword one included in the generic function lambda-list? In the example on page 3-8, not only is there no &key color, but there is not even the &key in the lambda-list in the call to the ensure-generic-function. e" and also to mean "write a file that can later be loaded and will produce similar objects." You'll know you've got it right when the specification does not admit any difference between EVAL and calling the result of COMPILE. You're concerned with the case of one Lisp or two (the compiling lisp and the loading/running Lisp), but you're not concerned with whether the representation of Lisp programs is S-expressions or machine code. I suggest eliminating all use of the word "compile" except in the compound form "compile-file." -3 ":lambda-list '(p l)" looks wrong. Shouldn't it be ":lambda-list '(p l &optional (visibly t) &key color)" ? Drop the quote marks before "':qualifiers" etc. to be consistent with figure 3-2. In the caption: Delete "the" in "...are the additional initargs..." Received: from piglet.parc.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA11860; Thu, 26 Apr 90 17:34:42 -0700 Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA20834; Thu, 26 Apr 90 17:35:14 PDT Date: Mon, 23 Apr 90 11:17 PDT From: Gregor J. Kiczales Subject: final MOP push To: Dussud@Lucid.com, Gray@Lucid.com, JonL@Lucid.com, RPG@Lucid.com, Moon@Stony-Brook.SCRC.Symbolics.com, Cyphers@Stony-Brook.SCRC.Symbolics.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com Cc: rivieres@parc.xerox.com, bobrow@parc.xerox.com Message-Id: <19900423181752.4.GREGOR@SPIFF.parc.xerox.com> Bfcc: BD:>Gregor>mail>outgoing-mail-9.text.newest Resent-To: mop-archive@arisia.Xerox.COM Resent-From: Gregor J. Kiczales Resent-Date: Thu, 26 Apr 90 17:34 PDT Resent-Message-Id: <19900427003440.7.GREGOR@SPIFF.parc.xerox.com> Now that PCL is out of the way, I can tell you that I have committed myself, between now and June 1rst, to working on the MOP. MOP related work is the only big thing I will be doing between now and then. Jim desRivieres, who many of you know by name, has also committed himself until June to MOP work. Danny Bobrow will also be working with us, but not full-time. In fact, we have been working on this for the past several weeks, and have made a lot of progress. That is why I feel comfortable writing to you about it now. We are working on two things. 1) Produce a final draft of the specification. This isn't intended to be an official document, but is intended to document, as best as possible, what can be said about the MOP. This document won't be the tight spec ala chapters 1 and 2 we had once hoped for, but we do expect it will be useful. I believe that it is important to get as much feedback about what this document says as possible, given the time constraints. I would hope that we could get it to a state where it could serve as documentation for the `defacto standard' MOP that people want to do. To achieve that, at least the vendors involved are going to have to like what it says. Having the current users like it is important as well. I would like to widen the circle of people on this message in a couple of weeks, see comments about this at the end of this message. I am taking primary responsibility for this work. 2) Produce a document which serves to explain some of the rationale behind the MOP. The document begins by presenting a simplified version of a metacircular interpreter for CLOS. From there, it moves through a set of motivated examples, showing modifications which give the user the kind of control required to handle the example. Each of these modifications, in effect, introduces another part of the (simplified) MOP. So, in its style, this document is a step-by-step MOP-ification of a (simplified) CLOS. This form makes it possible to introduce the concepts a MOP manipulates; a way of thinking about it; rationale for it; and examples of using it all in a nice story line. A lot of work is required to get the simplifications and story line for this right. We have been making good progress on that here, but will also want feedback on this paper. Jim is taking primary responsibility for this work. My purpose in sending this message now is to let you know what is happening here. I want to set up a mailing list that we can use for discussing these documents. At first, because of the time constraints, I want to have just the people who have worked on this before on this list. Please let me know if you notice someone who I should add to the list. In a couple of weeks, I want to add more people, one from each of the concerned vendors and a number of the more experienced users. I plan to mail the newest version of the section on user interface macros in the next 24 hours. Thanks for your past and future help on this. Received: from piglet.parc.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA11875; Thu, 26 Apr 90 17:35:05 -0700 Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA20858; Thu, 26 Apr 90 17:35:37 PDT Received: from Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA18536; Thu, 26 Apr 90 10:33:29 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 26 APR 90 10:28:51 PDT Return-Path: Received: from lucid.com ([192.26.25.1]) by Xerox.COM ; 26 APR 90 10:26:07 PDT Received: from challenger ([192.31.212.17]) by heavens-gate.lucid.com id AA18932g; Thu, 26 Apr 90 10:20:53 PDT Received: by challenger id AA02957g; Thu, 26 Apr 90 10:22:20 PDT Date: Thu, 26 Apr 90 10:22:20 PDT From: Patrick Dussud Message-Id: <9004261722.AA02957@challenger> To: gregor@parc.xerox.com Cc: bobrow@parc.xerox.com, Dussud@lucid.com, Gray@lucid.com, JonL@lucid.com, Moon@Stony-Brook.SCRC.Symbolics.com, Cyphers@Stony-Brook.SCRC.Symbolics.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, rivieres@parc.xerox.com, rpg@lucid.com Subject: Comments Resent-To: mop-archive@arisia.Xerox.COM Resent-From: Gregor J. Kiczales Resent-Date: Thu, 26 Apr 90 17:35 PDT Resent-Message-Id: <19900427003502.3.GREGOR@SPIFF.parc.xerox.com> Typo on page 3-8: setf -> eql It seems to me that the processing of the method lambda-list (unspecialize, extract specializers....) should be done in method(s) specialized on the generic function object. I allows for experimenting with new specializations of method parameters without changing the defgeneric and defmethod macros. Patrick. % -*- Mode: TeX -*- \input macros % Here are some additional macros I use: \def\boxit#1{\vbox{\hrule\hbox{\vrule\kern3pt\vbox{\kern3pt#1\kern3pt}\kern3pt\vrule}\hrule}} \def\Defmethp #1 #2{{\let\vtop=\Vtop\bf #1 {\tt #2}\hfill\brac{\it {\tt progn} Method\/}} \Vskip\normalparskip!} \def\method#1#2{{\bit method} {\bf #1 (#2)}} %\def\method#1#2{method {\bf #1 (#2)}} \def\bmethod#1#2{{\bit :before method} {\bf #1 (#2)}} \def\shortmethod#1#2 {\vskip\parskip\hbox to\hsize{\hskip\leftskip{\bf #1 {\tt (#2)}} \hfill\brac{\it Primary Method\/}}} \def\shortaftermethod#1#2 {\vskip\parskip\hbox to\hsize{\hskip\leftskip{\bf #1 {\tt :after (#2)}} \hfill\brac{\it After Method\/}}} % Wrap this around a collection of \shortxxx to keep them closer together. \def\beginShorts{\begingroup\vskip\parskip\parskip=0pt} \def\endShorts{\endgroup} \def\today{\ifcase\month\or January\or Febuary\or March\or April\or May\or June\or July\or August\ September \or October \or November\or December\fi \space\number\day, \number\year} \def\beginfncom#1{\begincom{#1}\ftype{Function}} \def\begingfcom#1{\begincom{#1}\ftype{Standard Generic Function}} \def\reserved-packages{{\bf common-lisp}, {\bf common-lisp-user}, or {\bf keyword}} % End of special MOP macros. \draftremark{\hbox{\vbox{\hbox{\prmeleven } \line{\prmeleven Draft 11: \today \hfil Do Not Distribute}}}} \tolerance=2500 \def\bookline{\CLOS\ Specification} \def\chapline{Metaobject Protocol} \def\newpage{\vfill\eject} \beginChapter 3.{Common Lisp Object System Specification}% {Metaobject Protocol}{Metaobject Protocol} Authors: Gregor Kiczales and Daniel G. Bobrow {\ifdraft Draft Dated: \today \hfil\break\fi} All Rights Reserved Do not reproduce or redistribute copies of this draft without the permission of the authors. The authors wish to thank <>. \endTitlePage \beginSection{A section name} \beginSubsection{Expansion of the User Interface Macros} A list in which the first element is one of the symbols {\bf defclass}, {\bf defmethod}, {\bf defgeneric}, {\bf define-method-combination}, {\bf generic-function}, {\bf generic-flet} or {\bf generic-labels}; and which has proper syntax for that macro is called a {\bit user interface macro form}. For convenience, when the meaning is unambiguous, this terminology is often abbreviated. A user interface macro form may be called a macro form or, for example, a {\bf defclass} user interface macro form may be called a {\bf defclass} form. User interface macro forms can be {\bit evaluated}, {\bit compiled}, or a compiled macro form can be {\bit executed}. The effect of evaluating or executing a user interface macro form is specified in terms of calls to specified functions and generic functions which actually provide the behavior of the macro. The arguments received by these functions and generic functions are derived in a specified way from the macro form. Only minimal aspects of the effect of compiling user interface macro forms are specified. Converting a user interface macro form into the arguments to the appropriate functions and generic functions involves two major issues. The first is the conversion of the macro argument syntax into a form more suitable for later processing. The second is the processing of macro arguments which are forms to be evaluated (including method bodies). In the syntax of the {\bf defclass} macro, the {\it initform} and {\it default-initarg-initial-value-form} arguments are forms which will be evaluated one or more times after the macro form is evaluated or executed. Special processing must be done on these arguments to ensure that the lexical scope of the forms is captured properly. This is done by building a closure of zero arguments which can be called to evaluate the form in its lexical environment. In the syntax of the {\bf defmethod} and {\bf defgeneric} macros the {\it form*} arguments are lists of forms which comprise the body of the method definitions. This list of forms must be processed specially to capture the lexical scope of the macro form. In addition, the lexical functions available only in the body of methods must be introduced. To allow this and any other special processing (such as slot access optimization), a specializable protocol is used for the body of methods. This is discussed in the section ``Processing the Bodies of Methods''. \beginsubsubsection{Compiler Processing of the User Interface Macros} It is common practice for the compiler, while processing a file or set of files, to maintain information about the definitions that have been compiled so far. Among other things, this makes it possible to ensure that a global macro definition ({\bf defmacro} form) which appears in a file will affect uses of the macro later in that file. This information about the state of the compilation is called the {\bit compile-file environment}. When compiling files containing CLOS definitions, it is useful to maintain certain additional information in the compile-file environment. This can make it possible to issue various kinds of style warnings (e.g. lambda list congruence) and to do various performance optimizations that would not otherwise be possible. At this time, there is such significant variance in the way existing Common Lisp implementations handle compile-file environments that it would be premature to specify this mechanism. Consequently, this document provides only a minimal description of the compiler processing of the user-interface macros. Specific implementations are free to provide additional definition of their compile-file environment mechanism. This document defines just enough of the compiler processing of the user interface macros to allow portable metaobject classes to determine whether instances are being created to represent definitions in the compile file environment. In such cases, the values of other keyword and initialization arguments may differ from the specified values so portable code must test for such cases to prevent encountering unexpected values. Testing for these cases is possible because compiler processing of the user-interface macros calls the functions {\bf ensure-class} and {\bf ensure-generic-function} with a non-null value for the {\bf :environment} keyword argument. In addition, when {\bf make-instance} is called to create a metaobject in the compile-file environment, the {\bf :environment} initialization argument will have a non-null value. In general, whether and when portable metaobject classes will be instantiated to represent definitions in the compile file environment is not defined. The only exception is that the function {\bf ensure-generic-function} will be called and generic function metaobjects will be created during compiler processing of {\bf defmethod} and {\bf defgeneric} macros. This is discussed in the section ``Processing Method Bodies''. \endsubsubsection%{Compiler Processing of the User Interface Macros} \beginsubsubsection{The defclass Macro} The evaluation or execution of a {\bf defclass} form results in a call to the {\bf ensure-class} function. The arguments received by {\bf ensure-class} are derived from the {\bf defclass} form in a defined way. The exact macroexpansion of the {\bf defclass} form is not defined, only the relationship between the arguments to the {\bf defclass} macro and the arguments received by the {\bf ensure-class} function. \beginlist \item{\bull} The {\it name} argument to {\bf defclass} becomes the {\it name} (first required) argument to {\bf ensure-class}. This is the only positional argument accepted by {\bf ensure-class}, all other arguments are keyword arguments. \item{\bull} The {\it direct superclasses} argument to {\bf defclass} becomes the value of the {\bf :direct-superclasses} keyword argument to {\bf ensure-class}. \item{\bull} The {\it direct slots} argument to {\bf defclass} becomes the value of the {\bf :direct-slots} keyword argument to {\bf ensure-class}. Special processing of this value is done to regularize the form of each slot specification and to properly capture the lexical scope of the initforms. This is done by converting each slot specification to a property list called a {\bit canonicalized slot specification}. The resulting list of canonicalized slot specifications is the value of the {\bf :direct-slots} keyword argument. Each canonicalized slot specification is formed from the corresponding slot specification as follows: \beginNote Canonicalized slot specifications are called a property list and strictly speaking they are. Later, when the canonicalized slot specification is used it will be used as keyword arguments and values to a generic function which will, in turn, pass it to {\bf make-instance} for use as a set of initialization arguments and values. \endNote \itemitem{\bull} The name of the slot is the value of the {\bf :name} property. \itemitem{\bull} When the {\bf :initform} slot option is present in the slot specification, then both the {\bf :initform} and {\bf :initfunction} properties are present in the canonicalized slot specification. The value of the {\bf :initform} property is the initform. The value of the {\bf :initfunction} property is a closure of zero arguments which, when called, evaluates the initform in its proper lexical environment. \itemitem{\bull} The value of the {\bf :initargs} property is a list of the values of each {\bf :initarg} slot option. \itemitem{\bull} The value of the {\bf :readers} property is a list of the values of each {\bf :reader} and {\bf :accessor} slot option. \itemitem{\bull} The value of the {\bf :writers} property is a list of the values specified by each {\bf :writer} and {\bf :accessor} slot option. The value specified by a {\bf :writer} slot option is just the value of the slot option. The value specified by an {\bf :accessor} slot option is two element list: the first element is the symbol {\bf setf}, the second element is the value of the slot option. \itemitem{\bull} All other slot options appear as the values of properties with the same name as the slot option. Note that this includes not only the remaining specified slot options ({\bf :allocation} and {\bf :type}), but also any other options and values appearing in the slot specification. If one of these slot options appears more than once, the value of the property will be a list of the specified values. \itemitem{\bull} The implementation is free to add additional keyword arguments and values to the canonicalized slot specification provided that these are not symbols in the \reserved-packages packages. \item{\bull} The {\it default initargs} class option, if it is present in the {\bf defclass} form, becomes the value of the {\bf :default-initargs} keyword argument to {\bf ensure-class}. Special processing of this value is done to properly capture the lexical scope of the default value forms. This is done by converting each default initarg in the class option into a {\bit canonicalized default initarg}. The resulting list of canonicalized default initargs is the value of the {\bf :default-initargs} keyword argument to {\bf ensure-class}. A canonicalized default initarg is a list of three elements. The first element is the name; the second is a closure of zero arguments which, when called, evaluates the default value form in its proper lexical environment; and the third is the actual form itself. \item{\bull} Any other class options become the value of keyword arguments with the same name. The value of the keyword argument is the tail of the class option. If any class option appears more than once in the {\bf defclass} form an error is signalled. \endlist The result of the call to {\bf ensure-class} is returned as the result of evaluating or executing the {\bf defclass} form. Examples of typical {\bf defclass} forms and expansions are shown in figures and . Note that these are only sample expansions, what is defined is not the form of the expansion, but rather the arguments received by {\bf ensure-class}. \boxfig{ \vskip-.14in \screen! (defclass plane (moving-object graphics-object) ((altitude :initform 0 :accessor plane-altitude) (speed)) (:default-initargs :engine *jet*)) (eval-when (:load-toplevel :execute) (ensure-class plane :direct-superclasses '(moving-object graphics-object) :direct-slots (list (list ':name 'altitude ':initform '0 ':initfunction #'(lambda () 0) ':readers '(plane-altitude) ':writers '((setf plane-altitude))) (list ':name 'speed)) :default-initargs (list (list ':engine #'(lambda () *jet*) '*jet*)))) \endscreen! } \caption{A defclass form with standard slot and class options. Also shown is one possible correct expansion.} \endfig \boxfig{ \vskip-.14in \screen! (defclass sst (plane) ((mach :mag-step 2 :locator sst-mach :locator mach-location :reader mach-speed :reader mach)) (:metaclass faster-class) (:another-option foo bar)) (eval-when (:load-toplevel :execute) (ensure-class 'sst :direct-superclasses '(plane) :direct-slots (list (list ':name 'mach ':mag-step '2 ':locator '(sst-mach mach-location) ':readers '(mach mach-speed))) :metaclass 'faster-class :another-option '(foo bar))) \endscreen! } \caption{A defclass form with non-standard class and slot options. Also shown is one possible correct expansion.} \endfig \endsubsubsection%{The defclass Macro} \beginsubsubsection{The defmethod Macro} The evaluation or execution of a {\bf defmethod} form requires first that the body of the method be converted to a method function. This process is described in the section ``Processing of Method Bodies''. The result of this process is a method function and a set of additional initialization arguments to be used when creating the new method. Given these, the evaluation or execution of a {\bf defmethod} form proceeds in three steps. The first step ensures the existence of a generic function with the specified name. This is done by calling the function {\bf ensure-generic-function}. The first argument in this call is the generic function name specified in the {\bf defmethod} form. The {\bf :lambda-list} keyword argument is supplied in the call, its value is the lambda list of the method reduced to a generic function lambda list. The second step is the creation of the new method metaobject by calling {\bf make-instance}. The class of the new method metaobject is determined by calling {\bf generic-function-default-method-class} on the result of the call to {\bf ensure-generic-function} from the first step. The initialization arguments received by the call to {\bf make-instance} are as follows: \beginlist \item{\bull} The value of the {\bf :qualifiers} initarg is a list of the qualifiers which appeared in the {\bf defmethod} form. No special processing is done on these values. \item{\bull} The value of the {\bf :lambda-list} initarg is the unspecialized lambda list for the method. \item{\bull} The value of the {\bf :specializers} initarg is a list of the specializer names for the method. For {\bf eql} specializers, this is a list in which the first element is the symbol {\bf setf} and the second element is the result of evaluating the eql specializer form in the lexical environment of the {\bf defmethod} form. For any other kind of specializer, this is the value from the {\bf defmethod} form with no special processing done. \item{\bull} The value of the {\bf :function} initarg is the method function. \item{\bull} Any other initargs produced in conjunction with the method function are also included. \item{\bull} The implementation is free to include additional initialization arguments provided these are not symbols in the \reserved-packages packages. \endlist In the third step, {\bf add-method} is called to add the newly created method to the set of methods associated with the generic function metaobject. The result of the call to {\bf add-method} is returned as the result of evaluating or executing the {\bf defmethod} form. An example showing a typical {\bf defmethod} form and its expansion is shown in figure . The processing of the method body for this method is shown in figure . \boxfig{ \vskip-.14in \screen! (defmethod move :before ((p position) (l (eql 0)) &optional (visiblyp t) &key color) (set-to-origin p) (when visiblyp (show-move p 0 color))) (eval-when (:load-toplevel :execute) (let ((#:g001 (ensure-generic-function 'move :lambda-list '(p l)))) (add-method #:g001 (make-instance (generic-function-default-method-class #:g001) ':qualifiers '(:before) ':specializers (list 'position (list 'eql 0)) ':lambda-list '(p l &optional (visiblyp t) &key color) ':function (function ) ':additional-initarg-1 't ':additional-initarg-2 '39)))) \endscreen! } \caption{A sample defmethod form and one possible correct expansion. In the expansion, is the result of calling make-method-lambda as described in the section ``Processing Method Bodies''. The initargs after :function are the additional initargs returned from the call to make-method-lambda.} \endfig \endsubsubsection%{The defmethod Macro} \beginsubsubsection{Processing Method Bodies} The body of a {\bf defmethod} macro or {\bf :method} argument to a {\bf defgeneric} macro is a list of forms. Before a method can be created, this list of forms must be converted to a method function. This conversion is a two step process. The first step occurs during macroexpansion of the macro form. In this step, the method body is converted to a lambda expression called a {\bit method lambda}. This conversion is based on information associated with the generic function definition in effect at the time the macro form is expanded. For {\bf defmethod} forms, the generic function definition is obtained by calling {\bf ensure-generic-function} with a first argument of the generic function name specified in the macro form. The {\bf :lambda-list} keyword argument is not passed in this call. If the {\bf defmethod} form is being expanded by the file compiler, so that it can be executed later, the call also includes a non-null value for the {\bf :environment} keyword argument. For {\bf defgeneric} forms, the generic function definition is obtained by calling {\bf ensure-generic function} with arguments derived from the macro form as described in the section ``The defgeneric Macro'' except that the {\bf :initial-methods} keyword argument is not included. If the {\bf defgeneric} form is being expanded by the file compiler, so that it can be executed later, the call to {\bf ensure-generic-function} also includes a non-null value for the {\bf :environment} keyword argument. Given the generic function, production of the method lambda proceeds by calling {\bf make-method-lambda}. The first argument in this call is the generic function obtained as described above. The second argument is the result of calling {\bf class-prototype} on the result of calling {\bf generic-function-default-method-class} on the generic function. The third argument is a lambda expression formed from the method lambda list, the declarations and the method body. The generic function {\bf make-method-lambda} returns two arguments. The first is the method lambda itself. The second is a list of initialization arguments and values. These will be included in the initialization arguments when the method is created. Note that because these initialization arguments appear in the expansion of the macro form, and because this can happen as part of a file compilation, all of the initialization argument values must have applicable methods for the generic function {\bf make-load-form}. In the second step, the method lambda is converted to a closure which properly captures the lexical scope of the macro form. This is done by having the method lambda appear in the macroexpansion as the argument of the {\bf function} special form. When the expansion is actually evaluated or executed the result of this special form is the method function. \endsubsubsection%{Processing Method Bodies} \endSubsection%{Expansion of the User Interface Macros} \endSection%{A section name} \endChapter \bye Received: from piglet.parc.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA11877; Thu, 26 Apr 90 17:35:08 -0700 Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA20862; Thu, 26 Apr 90 17:35:39 PDT Received: from arisia.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA19114; Thu, 26 Apr 90 12:21:04 PDT Received: from LUCID.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA05243; Thu, 26 Apr 90 12:20:04 -0700 Received: from ptl-club ([192.31.212.51]) by heavens-gate.lucid.com id AA19931g; Thu, 26 Apr 90 12:16:47 PDT Received: by ptl-club id AA01916g; Thu, 26 Apr 90 12:11:39 PDT Date: Thu, 26 Apr 90 12:11:39 PDT From: Jon L White Message-Id: <9004261911.AA01916@ptl-club> To: Moon@STONY-BROOK.SCRC.Symbolics.COM Cc: gregor@parc.xerox.com, bobrow@parc.xerox.com, rivieres@parc.xerox.com, rpg@lucid.com, Moon@STONY-BROOK.SCRC.Symbolics.COM, Dussud@lucid.com, Gray@lucid.com, Cyphers@STONY-BROOK.SCRC.Symbolics.COM, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, jonl@lucid.com In-Reply-To: David A. Moon's message of Thu, 26 Apr 90 11:43 EDT <19900426154319.8.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Subject: user interface macros Resent-To: mop-archive@arisia.Xerox.COM Resent-From: Gregor J. Kiczales Resent-Date: Thu, 26 Apr 90 17:35 PDT Resent-Message-Id: <19900427003505.4.GREGOR@SPIFF.parc.xerox.com> re: 2. If a method has a keyword argument, is that keyword one included in the generic function lambda-list? In the example on page 3-8, not only is there no &key color, but there is not even the &key in the lambda-list in the call to the ensure-generic-function. Hmm, I thought chapter 1 and 2 did say this. They sure need to so that you can know what the congruence rules of a generic function without a defgeneric is. Don't spend too much time fixing this before you receive the comments from Cyphers and me, which will point out that this is all wrong anyway. That argument shouldn't be passed in that call at all. I agree. I've already sent an critique of that internally here at Lucid, and was planning to fold that into a more general critique of this whole section, which will perhaps be done later tonight. -- JonL -- Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA27556; Thu, 26 Apr 90 23:56:41 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 26 APR 90 17:33:29 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 26 APR 90 17:32:35 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA20821; Thu, 26 Apr 90 17:33:12 PDT Date: Thu, 26 Apr 90 17:32 PDT From: Gregor J. Kiczales Subject: this list now exists To: mop.pa@Xerox.COM Message-Id: <19900427003238.6.GREGOR@SPIFF.parc.xerox.com> This mailing list now exists and, needless to say, you are on it. The archive is on arisia.xerox.com in /pcl/archive/mop.text. At the moment, the other people on this list are: Danny Bobrow Bobrow@parc.xerox.com Scott Cyphers Cyphers@Stony-Brook.SCRC.Symbolics.com Jim desRivieres desrivieres@parc.xerox.com Patrick Dussud Dussud@Lucid.com Jutta Estenfeld jutta@ztivax.siemens.com Jonh Foderaro jkf@franz.com Dick Gabriel RPG@Lucid.com David Gray Gray@Lucid.com Gregor Kiczales Gregor@parc.xerox.com Yasuhiko Kiuchi Kiuchi@parc.xerox.com Shinnder Lee sdlee@iuvax.cs.indiana.edu Yoshihiro Masuda Masuda.kspafx@parc.xerox.com David Moon Moon@Stony-Brook.SCRC.Symbolics.com Andreas Paepcke paepcke@hplap.hpl.hp.com Jon L White JonL@Lucid.com In the next few days, I will be adding new people to the list. These people will be users and implementors of the MOP. Thanks in advance for your help. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA19374; Fri, 27 Apr 90 15:02:39 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 27 APR 90 14:53:40 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 27 APR 90 14:52:27 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 786059; 27 Apr 90 17:52:15 EDT Date: Fri, 27 Apr 90 17:58 EDT From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM Sender: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: user interface macros To: Gregor J. Kiczales Cc: mop.pa@Xerox.COM In-Reply-To: <19900424043758.2.GREGOR@SPIFF.parc.xerox.com> Message-Id: <19900427215856.1.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No This is just the first installment of comments, another message to fill in the parts that have .... here will follow next week (probably Monday). Comments from Moon and Cyphers on CLOS user interface macros section. Indented text is from the TeX source, to provide context. Issues sorted by category: >>> Typos and omissions, wording problems User interface macro forms can be {\bit evaluated}, {\bit compiled}, or a compiled macro form can be {\bit executed}. This sentence is a bit confusing. I think it meant to say "User interface macro forms can be {\bit evaluated} or {\bit compiled} and {\bit executed}." Since that is true of all macros, I'm not really sure why it needs to be said at all. In the syntax of the {\bf defclass} macro, the {\it initform} and {\it default-initarg-initial-value-form} arguments are forms which will be evaluated one or more times after the macro form is evaluated or executed. Special processing must be done on these arguments to ensure that the lexical scope of the forms is captured properly. This is "is" --> "can be" done by building a closure of zero arguments which can be called to evaluate the form in its lexical environment. Everywhere this says "closure" it should say "function." "Closure" is not a real Common Lisp word. In implementations that distinguish closures from bare functions, this value is allowed to be a bare function if that gives the specified semantics. All that matters is you can funcall this thing with no arguments and it returns the proper value. (eval-when (:load-toplevel :execute) This eval-when is pointless since "load eval" is the default. Forgot to mention :documentation in the initialization arguments in the expansion of defmethod. (add-method #:g001 (make-instance (generic-function-default-method-class #:g001) ':qualifiers '(:before) ':specializers (list 'position (list 'eql 0)) ':lambda-list '(p l &optional (visiblyp t) &key color) ':function (function ) ':additional-initarg-1 't ':additional-initarg-2 '39 These additional initargs aren't allowed to be in the keyword package. Given the generic function, production of the method lambda proceeds by calling {\bf make-method-lambda}. The first argument in this call is the generic function obtained as described above. The second argument is the result of calling {\bf class-prototype} on the result of calling {\bf generic-function-default-method-class} on the generic function. The third argument is a lambda expression formed from the Insert "unspecialized" method lambda list, the declarations and the method body. Is the documentation included here (it isn't needed since documentation is an initialization argument for the method). >>> Inconsistency with X3J13 \itemitem{\bull} The implementation is free to add additional keyword arguments and values to the canonicalized slot specification provided that these are not symbols in the \reserved-packages packages. This is bound up with an attempt to make things extensible that does not work. That's discussed more below. Here I just want to discuss the \reserved-packages packages stuff. Everywhere this document refers to symbols hidden from the user, it says it wrong. The correct wording derives from this paragraph of PACKAGE-CLUTTER:REDUCE version 7: No external symbols of the LISP package may have properties with property indicators that are either external symbols of packages defined in the standard or are otherwise accessible in the USER package. Also there's another mistake, it restricts both the argument name and value when it should only be restricting the argument name. The word "property name" (from CLtL p.24) is the correct word to refer to the even-numbered elements of a canonicalized slot specification. So the correct wording here is: The implementation is free to add additional properties to the canonicalized slot specification provided that the property names are not accessible in the common-lisp-user package and are not exported by any package defined in the Common Lisp standard. If you want you can list explicitly the packages defined in the Common Lisp standard but I don't see the point of that. This also applies to this text under defmethod: \item{\bull} The implementation is free to include additional initialization arguments provided these are not symbols in the \reserved-packages packages. >>> Inconsistency with earlier decisions that may not have been written down When defmethod calls ensure-generic-function, it must not supply the :lambda-list argument. ensure-generic-function has to know the difference between a call from defgeneric (which always replaces the lambda-list), and a call from defmethod (which never replaces the lambda-list). Symbolics CLOS works as outlined in this message: Date: Tue, 26 Sep 89 17:58 PDT From: Gregor.pa@Xerox.COM Subject: Re: Expansions of CLOS defining macros To: David A. Moon , Scott Cyphers cc: GSB@STONY-BROOK.SCRC.Symbolics.COM Message-ID: <19890927005844.2.GREGOR@SPIFF.parc.xerox.com> Do we get the right behavior by having the existing methods enfore the following? (For purposes of this imagine that a generic function has three properties: its state, its lambda list and its congruence) make-instance of a generic function with no :lambda-list initarg creates a generic function in state `UNSET-CONGRUENCE', that has no lambda list or congruence. make-instance of a generic function with a :lambda-list creates one in state `SET-CONGRUENCE', the lambda list and congruence are taken from the initarg add-method to a generic function in state UNSET-CONGRUENCE does no congruence checking and changes its state to `METHODS', it also sets the lambda list and congruence from the method. (unless the lambda-list is already set, and congruent with the method, in which case the lambda list keeps its value -- see remove-method to understand this) add-method to a generic function in state SET-CONGRUENCE does the specified congruence checking (and may signal an error) and changes its state to `METHODS', the congruence and lambda list are not changed if remove-method removes the last method of a generic function, it changes the state to UNSET-CONGRUENCE, the congruence and lambda list are unaffected. reinitialize-instance on a generic function in state SET-CONGRUENCE or UNSET-CONGRUENCE will gladly change the generic functions lambda list and congruence and leave the generic function in state SET-CONGRUENCE reinitialize-instance on a generic-function in state METHODS will only change the lambda list if it agrees with the generic functions congruence. Date: Wed, 27 Sep 89 11:47 PDT From: Gregor.pa@Xerox.COM Subject: Re: Expansions of CLOS defining macros To: Scott Cyphers cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, GSB@STONY-BROOK.SCRC.Symbolics.COM Message-ID: <19890927184723.4.GREGOR@SPIFF.parc.xerox.com> So :lambda-list becomes an optional initarg (89-003 page 3-65 says it's required, so this would need to be changed if it hasn't been already). Yes, that is right. This isn't quite -- If the generic function was defgeneric'd, adding and then removing a method shouldn't allow methods to be added which aren't congruent to the lambda list in the defgeneric. See below. Yes. I think we need two states, METHODS, which is just GENERIC-FUNCTION-METHODS, and LAMBDA-LIST-SUPPLIED-P. Your states would be SET-CONGRUENCE is (and LAMBDA-LIST-SUPPLIED-P (not METHODS)) and UNSET-CONGRUENCE is (not (or LAMBDA-LIST-SUPPLIED-P METHODS)). Remove-method doesn't need to do anything special. add-method sets the lambda-list if (not (or LAMBDA-LIST-SUPPLIED-P METHODS)), and checks for congruence otherwise (which is just what you said). OK. (let ((#:g001 (ensure-generic-function 'move :lambda-list '(p l)))) (add-method #:g001 :LAMBDA-LIST shouldn't be here!. It is the wrong value too. >>> Unmotivated incompatibilities with 89-003 In the arguments to ENSURE-CLASS, this document has :DIRECT-SUPERCLASSES and :DIRECT-SLOTS where 89-003 has :SUPERCLASSES and :SLOTS. Symbolics CLOS uses :DIRECT-SUPERCLASSES (based on mail with Gregor a few months ago) but :SLOTS. For consistency, :DIRECT-SLOTS would be better, but we've passed the point of being able to remove :SLOTS, although we could make :SLOTS mean :DIRECT-SLOTS. Similarly, :DIRECT-DEFAULT-INITARGS should replace :DEFAULT-INITARGS. Although no document and no implementation uses :DIRECT-DEFAULT-INITARGS currently, it would be more consistent. A canonicalized default initarg is a list of three elements. The first element is the name; the second is a closure of zero arguments which, when called, evaluates the default value form in its proper lexical environment; and the third is the actual form itself. Symbolics CLOS and 89-003 put the form before the function. Why was the order gratuitously changed? Also, there needs to be provision for implementation additions (we use one), just as in the canonicalized slot specification. Just allow the list to have more than three elements, where elements after the first three are implementation dependent. The second step is the creation of the new method metaobject by calling {\bf make-instance}. The class of the new method metaobject is determined by calling {\bf generic-function-default-method-class} on the result of the call to {\bf ensure-generic-function} from the first step. The name in 89-003 and in Symbolics CLOS is generic-function-method-class. Why the gratuitous change? \item{\bull} The value of the {\bf :specializers} initarg is a list of the specializer names for the method. For {\bf eql} specializers, this is a list in which the first element is the symbol {\bf setf} and the second element is the result of evaluating the eql specializer form in the lexical environment of the {\bf defmethod} form. For any other kind of specializer, this is the value from the {\bf defmethod} form with no special processing done. It's too weird to make this a list of elements that are parameter specializers in one case and parameter specializer names in the other case. 89-003 p.3-69 requires parameter specializers here, i.e. classes rather than class names. See also 89-003 p.3-16. So not only is this weird, it's also a gratuitous incompatibility. Note that when a parameter specializer is a class, the class can be required to exist when the defmethod is executed since a forward-referenced-class could always be used. In Symbolics CLOS the class must actually be defined when the defmethod is executed, which seems reasonable to me. I couldn't find any discussion of this in any relevant-looking X3J13 cleanup issue. >>> Attempts to add extensibility that don't work .... to be written .... .... will cover class-options, slot-options, the issue of options that can occur multiple times, and method-body processing .... >>> Other differences from Symbolics CLOS implementation \item{\bull} The {\it direct superclasses} argument to {\bf defclass} becomes the value of the {\bf :direct-superclasses} keyword argument to {\bf ensure-class}. We do this differently. If the {\it direct superclasses} is NIL, then the metaclass is asked for the list of direct superclasses to be used, using class-default-direct-superclasses. For STANDARD-CLASS, (STANDARD-OBJECT) is used, for FUNCALLABLE-STANDARD-CLASS, (FUNCALLABLE-INSTANCE), etc. Thus ENSURE-CLASS receives the actual list of direct superclasses. In our way of defaulting these, it is possible for a metaclass to make classes which have no superclasses. The result of class-default-direct-superclasses is a list of class objects even though the :direct-superclasses is otherwise a list of class names; this might be a mistake, but does allow for anonymous classes as default direct superclasses. >>> Proposed different ideas .... class parsing .... .... method parsing .... .... this might be the right place to object to NULL as the local environment test .... .... environment reducer function .... Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA23994; Fri, 27 Apr 90 17:18:51 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 27 APR 90 17:17:30 PDT Return-Path: Received: from lucid.com ([192.26.25.1]) by Xerox.COM ; 27 APR 90 17:16:50 PDT Received: from ptl-club ([192.31.212.51]) by heavens-gate.lucid.com id AA02440g; Fri, 27 Apr 90 17:13:54 PDT Received: by ptl-club id AA02801g; Fri, 27 Apr 90 17:08:50 PDT Date: Fri, 27 Apr 90 17:08:50 PDT From: Jon L White Message-Id: <9004280008.AA02801@ptl-club> To: gregor@parc.xerox.com Cc: mop.pa@Xerox.COM In-Reply-To: Gregor J. Kiczales's message of Mon, 23 Apr 90 21:37 PDT <19900424043758.2.GREGOR@SPIFF.parc.xerox.com> Subject: user interface macros I have just a couple of substantive, semantic comments on this proposal (not just typos nor the sort of minor questions that Jim des Rivieres and a couple others had.) First I want to address the question of why the focus on defining macros, and then I want to point out a gap in the current definition of ENSURE-GENERIC-FUNCTION that made it difficult for Lucid's implementation to use it directly. To what end specify the macro expansions exactly? Some of the more questionable items of development in the Jan 1989 version of this part of the MOP proposal apparently have been deleted; in particular, excessive use of Lisp code as actual specification, and a nearly impossible concern for "compilation environments". As we have subsequently come to realize, the "compilation environments" issue is not at all a problem unique to CLOS, or to CLOS metaobject protocols, since the compiler committee has addressed it in the context of any toplevel definer macro such as DEFUN, DEFMACRO, DEFCLASS, DEF and so on [albeit, with basically very little change from the previous state of underspecification, which is actually good, since it allows implementations to do "special processing" on DEFUN without detracting from the user's ability to write his own, portable expansions of DEFUN- like definer macros.] But there are still several serious problems with trying to be specific about the CLOS defining macro expansions. First off, it has nothing to do directly with a metaojbect protocol; for this, we need a clear definition of a functional interface to metaobject creation and manipulation, along with the explicit items in the initialization protocol for classes and generic functions. ENSURE-GENERIC-FUNCTION, ENSURE-CLASS, and ADD-METHOD are steps in the right direction; we will also need the statement of what initargs are defined for creations in the basic metaobject classes. A comparison can be made with the ordinary function protocols. What's important for defining functions are clear semantics for LAMBDA, BLOCK, SETF of SYMBOL-FUNCTION, SETF of MACRO-FUNCTION and so on; the actual way in which DEFUN and DEFMACRO might expand into them is then obvious, but irrelevant. In fact the current situation is such that they might even expand into implementation-specific primitives -- not even using these documented facilities at all -- to achieve the defining effect specified for DEFUN and DEFMACRO. But the writer of portable code is guaranteed that these "documented facilities" are completely adequate for making definitions in the portable language. Rather, I think the only point of mentioning the expansion of the definer "user interface" macros is that our experience with metaobject creations over the past two years, via portable constructs, *had* to be limited to these macros. So it's natural that we would tend to think of the issues involved in terms of the exterior interface syntax. Some of you who have been on the Common-Lisp-Object-System mailing list for a long time may remember that precisely this question arose several years ago. And someone (who? maybe Dave Moon) suggested that while we indeed needed the functional interface for class, method, and generic function creations, the predominate usage by end users would be in terms of the succinct definer macros like DEFCLASS and DEFMETHOD. Thus we *had* to have syntax and semantics for these macros defined in the basic document; but the definitions for the functional interface, while logically more primitive, could be postponed until the metaboject layer became more fully defined. Indeed the need by an end-user for the functional layer would only really come into play when his application became involved in "meta" manipulations. Sample usages of the basic functions, such as ENSURE-CLASS and ENSURE-GENERIC-FUNCTION, are indeed appropriate to have in the language specification, to show how one can create whatever class or generic functions he wishes *** using only the functional interface. But detailed specification -- in terms of required language specification -- of these expansions serves no more purpose to CLOS than explicit coding of a DEFUN macro expander would serve for Common Lisp in general. Incidentally, since the time of release of the "Rainy Day" PCL, I have privately praised the development in it of the class creation protocol, whereby most all of the old ADD-NAMED-CLASS functionality is distributed out to methods on the regular initialization protocol functions. Proof of the effectiveness of this is your (Gregor's) reply to someone on the PCL mailing list about how to make an incremental change in a class's superclass and subclass links -- instead of having to re-fetch the parts of a class definition and cons up a new DEFCLASS macro for for EVALuation, why, a rather trivial call to REINITIALIZE-INSTANCE now does it. This is precisely what end-users are looking for in a metaobject protocol; and we all await with bated breath your and Jim's delineation of this part. Notice also how two question raised during the past couple days about this proposal would be re-cast had the proposal been oriented towards the specification of functional interface rather than towards the particular code expansion of the macros. (1) Someone asked whether or not the ordering of the items in the "plist" type arguments to ENSURE-CLASS was preserved from the ordering in the user's DEFCLASS form. But the real issue is whether or not the ordering in the plist makes any difference at all to the action of ENSURE-CLASS; if so, then the effects of that ordering must be specified. Now, *if* ordering does make a difference in any of these "plist" type arguments, then the actual effect that ordering has can be documented for ENSURE-CLASS as well as for DEFCLASS. Without ever *requiring* that DEFCLASS expands into a call to ENSURE-CLASS, we have parallel specifications that in the vanilla case would _adquately_ constrain any proposed macro expansion of one into the other. (2) There have been several questions about how the initforms for slots and for default-initargs are handled. I found the actual wording to be very confusing because it used terms like "evaluated one or more times"; but in fact what we all know to be going on is that the actual form is "effunctuated" precisely once (I believe that is Moon's terminology) , and then that function is "executed" zero or more times. EVAL is certainly irrelevant, but I noticed question or two wandered off into the (irrelevant) difference between evaluation of a macro and compilation of it. [I could give explicit pointers to these email conversation fragments to anyone who wants toe examine them further.] Now, if the functional interface specifies a function object as one of the arguments (or as part of a "plist" argument) that almost guarantees that the macroexpansion will have turned some into (FUNCTION (LAMBDA () )), but we need never get bogged down by trying to write a detailed specification for the actual code expansion. Furthermore, even if, yes even if, some implementation elects to use a non-portable (but more efficient?) construct in its actual expansion of DEFCLASS, still one is not precluded from using the FUNCTION form listed above in portable code. A gap in the current definition of ENSURE-GENERIC-FUNCTION? I must apologize for the following paragraphs; I'm certain that a problem is there, but I've not put the time into stating it more carefully than you can see below. It is related to Danny's comment: "reduced to a g-f lambda-list" is not defined here or in Chapter 1 or 2. If a method has a keyword argument, is that keyword one included in the generic function lambda-list? In the example on page 3-8, not only is there no &key color, but there is not even the &key in the lambda-list in the call to the ensure-generic-function. Also, Moon's comment on the same sentence indicates that he must have a similar trouble with it. As I will be out of town for about a week beginning tomorrow, I will not be able to read replies to this msg, nor make comments during that time. But I trust and hope that Moon and Cyphers have discovered the same difficulty independently, and will explicate it more thoroughly. I found in implementing the congruency rules that a single :lambda-list argument wasn't good enough to distinguish the case of "ensuring" the generic function de novo, and "ensuring" it on subsequent method definings. Basically, the call to ENSURE-GENERIC-FUNCTION from within DEFMETHOD needs the exact method-lambda-list, and needs to know that it is a method lambda list, so that it can do something slightly different in the two cases (i.e., "de novo" and subsequent). The suggestion about reducing the method lambda list to a g-f lambda list makes sense; but it just isn't good enough for the two cases. And of course explicit _user_ calls to ENSURE-GENERIC-FUNCTION want to specify exactly the g-f lambda list -- not some hypothetical method-lambda list that has to be reduced. The difficulty probably comes from the overloading of ENSURE-GENERIC-FUNCTION to serve both as a user-level defining function for Generic-Functions, and as a last-minute patch-up tool which must try to infer an implicit generic-function lambda-list at first method definition time, when the user hasn't done a DEFGENERIC before the first DEFMETHOD. As a result, Lucid's implementation has both the functional entry underlying DEFMETHOD and the function ENSURE-GENERIC-FUNCTION call another internal function, which explicitly has a keyword for the case of a method-lambda-list. -- JonL -- Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA25302; Fri, 27 Apr 90 18:07:47 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 27 APR 90 18:05:37 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 27 APR 90 18:05:18 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 786192; 27 Apr 90 21:05:13 EDT Date: Fri, 27 Apr 90 21:11 EDT From: David A. Moon Subject: user interface macros To: Jon L White Cc: mop.pa@Xerox.COM In-Reply-To: <9004280008.AA02801@ptl-club> Message-Id: <19900428011147.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No JonL, I think all your points here are well-taken. I just have one comment, which is that in specifying the metaobject protocol we need to be clear whether we're talking about how users can define new metaclass methods to be called from the existing facilities such as DEFCLASS, or about how users can define new facilities resembling DEFCLASS that call the existing functions. Of course both are important, but I think you and Gregor might be approaching this from opposite ends and thus not quite connecting. There's also a third thing we seem to be talking about, which is how users can extend the macros themselves (rather than writing their own macros that resemble the predefined ones). On the subject of ENSURE-GENERIC-FUNCTION, see the mail from Gregor from last September embedded in the comments Scott and I mailed out earlier tonight. Now we see the problem with private discussions: the information didn't get to everyone who needed to know it. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA21208; Mon, 30 Apr 90 09:35:26 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 30 APR 90 09:31:22 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 30 APR 90 09:27:13 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01055; Mon, 30 Apr 90 09:23:45 PDT Date: Mon, 30 Apr 90 09:23 PDT From: Gregor J. Kiczales Subject: Re: user interface macros To: David A. Moon , Patrick Dussud , Jon L White , Andreas Paepcke , David Gray , rivieres@parc.xerox.com, Cyphers@STONY-BROOK.SCRC.Symbolics.COM Cc: Danny Bobrow , Richard P. Gabriel , jkf@franz.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: <19900426154319.8.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <9004261722.AA02957@challenger>, <9004261911.AA01916@ptl-club>, <9004262017.AA04825@hplap.hpl.hp.com>, <9004270038.AA00272@black-monday>, <9004270124.AA05890@roo.parc.xerox.com>, <19900427215856.1.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <19900428011147.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <9004280008.AA02801@ptl-club> Message-Id: <19900430162306.8.GREGOR@SPIFF.parc.xerox.com> I will address all of these ui macro comments Wednesday. Right now I am working on another section which I would like to send out before I go back to hacking the macro section. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA14103; Tue, 1 May 90 14:17:56 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 01 MAY 90 12:59:59 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 01 MAY 90 12:58:55 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 787669; 1 May 90 15:58:12 EDT Date: Tue, 1 May 90 15:59 EDT From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM Sender: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: user interface macros To: Gregor J. Kiczales Cc: mop.pa@Xerox.COM In-Reply-To: <19900424043758.2.GREGOR@SPIFF.parc.xerox.com> Message-Id: <19900501195931.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No Comments from Moon and Cyphers on CLOS user interface macros section. Indented text is from the TeX source, to provide context. This is part 2 of our comments. Part 1 was mailed last Friday. Part 3, the final part, will be about Processing Method Bodies. >>> Attempts to add extensibility that don't work This document defines just enough of the compiler processing of the user interface macros to allow portable metaobject classes to determine whether instances are being created to represent definitions in the compile file environment. In such cases, the values of other keyword and initialization arguments may differ from the specified values so portable code must test for such cases to prevent encountering unexpected values. Testing for these cases is possible because compiler processing of the user-interface macros calls the functions {\bf ensure-class} and {\bf ensure-generic-function} with a non-null value for the {\bf :environment} keyword argument. Defining NULL to be the predicate that tests whether an environment is the run-time environment is not very abstract. This could run into serious problems with future extensions that unify this environment with the &environment argument to macros or that implement more than just the run-time and compilation environments. On the one hand, NIL might not be the only representation for the "ordinary" environment, and on the other hand, there might be several distinct environments that all have the property of containing classes that can be instantiated and methods that can be executed. I think we must choose either not to document any predicates on the environment, and require portable metaobject classes to operate some other way, or else to add one or more predicates that perform the specific tests on environments that are actually needed. I was unable to figure out what specific predicates are needed, nor what the specific problem is that needs to be solved (alluded to in "testing for these cases" above). As a strawman, I'll suggest (RUN-TIME-ENVIRONMENT-P env) => true if env is an environment that causes FIND-CLASS to return instantiable classes and causes ENSURE-GENERIC-FUNCTION to return callable generic functions. The term "run time environment" is from section 4.2 of the draft ANSI CL specification, revision 7.31 of 8/29/89. \itemitem{\bull} All other slot options appear as the values of properties with the same name as the slot option. Note that this includes not only the remaining specified slot options ({\bf :allocation} and {\bf :type}), but also any other options and values appearing in the slot specification. If one of these slot options appears more than once, the value of the property will be a list of the specified values. This is not workable for several reasons. First, it is unclear whether the value of the property is the value of the slot-option, or a list whose single element is the value of the slot-option, in the case of a slot-option that is allowed to appear more than once but appears only once in this particular slot specification. Second, there might be slot-options that, like :INITFORM, require processing such as capturing of the lexical environment. Third, there might be slot-options that, like :INITFORM and :ACCESSOR, must expand into multiple properties in the canonicalized slot specification. Fourth, there might be slot-options that, like :ACCESSOR and :WRITER, interact with each other, both contributing to a single property in the canonicalized slot specification. I think the only possible choice is to document the canonicalized slot specification format for every standard slot option, and to allow extended slot options (added either by an implementation or by a user) complete freedom in how they appear in the canonicalized slot specification, restricted only by what property names can be used. The appropriate generalization to extended slot options of the property name restrictions given for the standard slot options appears to be the following: The properties in the canonicalized slot specification must be named by either the symbol that names a related slot option, if the slot option can appear only once; or the symbol that is the plural form of the name of a related slot option, in the same home package and with the same export status, if the slot option can appear multiple times; or a symbol that is not accessible in the common-lisp-user package and is not exported by any package defined in the Common Lisp standard. If this pluralization rule is not adopted, then :READERS and :WRITERS should be renamed to :READER and :WRITER; but that would be both confusing and an incompatible change for implementations that followed 89-003. See below for a proposal for how users can add extended slot options and have them processed into canonicalized slot specifications by the DEFCLASS macro. \item{\bull} Any other class options become the value of keyword arguments with the same name. The value of the keyword argument is the tail of the class option. If any class option appears more than once in the {\bf defclass} form an error is signalled. This has much the same problem as noted for slot options. Also the part about "the tail of the class option" disagrees with figure 3-2 and our implementation for :metaclass and :documentation. There might be extended class options that can appear multiple times and/or that require processing such as capturing of the lexical environment. I think that :metaclass and :documentation should be canonicalized into just the class name or documentation string, not a list of it, and that extended class options should follow rules similar to the rules for extended slot options. See below for a proposal for how users can add extended class options and have them processed into ENSURE-CLASS arguments by the DEFCLASS macro. For {\bf defgeneric} forms, the generic function definition is obtained by calling {\bf ensure-generic function} with arguments derived from the macro form as described in the section ``The defgeneric Macro'' except that the {\bf :initial-methods} keyword argument is not included. If the {\bf defgeneric} form is being expanded by the file compiler, so that it can be executed later, the call to {\bf ensure-generic-function} also includes a non-null value for the {\bf :environment} keyword argument. This has a subtle bug. Suppose the defgeneric form is -not- being expanded by the file compiler, the generic function has been defined before with initial-methods, and the lambda-list is being changed incongruently. The new lambda-list will be installed before the new initial-methods are installed, causing a spurious congruency error. There could also be inconsistency between the old initial-methods and the new method-combination. Also there could be difficulties for programming environments, because if compiling a method body provokes an error and the execution of the defgeneric is aborted, the generic function will already have been partially redefined. It would be better to process the method bodies with a generic function instance that has not been installed as the actual definition of the generic function, and only modify the actual definition of the generic function after the initial-methods are available. In Genera, we use the class prototype of the generic function class as the generic function for processing the method bodies. Perhaps it would be better to make a new generic function instance with all the initialization arguments except the :initial-methods, but to make it with make-instance rather than ensure-generic-function so that it is not installed as the definition of its name. This would be true both in the file compiler and in ordinary macro expansion. >>> Proposed different ideas The rest of this message describes one possible way that the DEFCLASS macro could be made extensible by metaclasses, allowing new class options and new slot options to be added by users. There is also a proposed different idea about processing method bodies but it's not ready to mail yet. Processing of a DEFCLASS form: A DEFCLASS form is converted into two ENSURE-CLASS forms; one is evaluated at compile-file time and the other is evaluated at load time. The compile-file version is supplied with the :ENVIRONMENT keyword with a value having indefinite extent which reflects the "compile-fileness" of the environment of the DEFCLASS macro. The load-time version does not supply the environment keyword. Most of the conversion from a DEFCLASS form to an ENSURE-CLASS form is performed by methods specialized on the metaclass. These methods generate a canonic class specification. The canonic class specification will serve as the keyword and value forms for ENSURE-CLASS. Note that the canonic class specification is not a plist; it is a list of forms, which will be referred to as a forms-plist. If X is a forms-plist, then (MAPCAR #'EVAL X) is a plist. Typically the forms in a forms-plist are of the form (QUOTE value) or (FUNCTION value), and the examples will often assume this. Generic Function: CANONICALIZE-CLASS-OPTION Arguments: class -- An instance of the metaclass. option-name -- A symbol. option -- A symbol or a list. canonic-class-specification -- A forms-plist. environment -- An environment. Values: new-canonic-class-specification -- A forms-plist. Description: Verifies and interprets one class option. DEFCLASS processes class options in the order in which they appear in the DEFCLASS form. Class options are processed before superclasses and slots have been processed. The interpretation of the class option is accomplished by adding or modifying keywords and values to the returned canonic class specification. Methods are permitted to modify the canonic-class-specification argument, but implementations are not permitted to depend on this. All elements of the canonic class specification should be forms to be evaluated at definition time. Examples: ;;; Unspecialized method to handle all invalid class options. (DEFMETHOD CANONICALIZE-CLASS-OPTION ((CLASS STANDARD-CLASS) (OPTION-NAME T) (OPTION T) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) (WARN "~s is not a valid class option. It will be ignored." OPTION) CANONIC-CLASS-SPECIFICATION) (DEFMETHOD CANONICALIZE-CLASS-OPTION ((CLASS STANDARD-CLASS) (OPTION-NAME (EQL :METACLASS)) (OPTION CONS) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) (COND ((LOOP FOR (OPTION-FORM VALUE-FORM) ON CANONIC-CLASS-SPECIFICATION BY #'CDDR DOING (PROGN VALUE-FORM) THEREIS (AND (CONSP OPTION-FORM) (EQ (FIRST OPTION-FORM) 'QUOTE) (EQ (SECOND OPTION-FORM) OPTION-NAME))) (WARN "The ~s class option is specified twice. ~s will be ignored." OPTION-NAME OPTION) CANONIC-CLASS-SPECIFICATION) (T `(',OPTION-NAME (FIND-CLASS ',(SECOND OPTION)) ,@CANONIC-CLASS-SPECIFICATION)))) (DEFMETHOD CANONICALIZE-CLASS-OPTION ((CLASS STANDARD-CLASS) (OPTION-NAME (EQL :DEFAULT-INITARGS)) (OPTION CONS) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) (COND ((LOOP FOR (OPTION-FORM VALUE-FORM) ON CANONIC-CLASS-SPECIFICATION BY #'CDDR DOING (PROGN VALUE-FORM) THEREIS (AND (CONSP OPTION-FORM) (EQ (FIRST OPTION-FORM) 'QUOTE) (EQ (SECOND OPTION-FORM) OPTION-NAME))) (WARN "The ~s class option is specified twice. ~s will be ignored." OPTION-NAME OPTION) CANONIC-CLASS-SPECIFICATION) (T `(',OPTION-NAME `(,,@(LOOP FOR (KEYWORD VALUE) ON (CDR OPTION) BY #'CDDR COLLECT ``(,',KEYWORD ,',VALUE ,#'(LAMBDA () ,VALUE)))) ,@CANONIC-CLASS-SPECIFICATION)))) Generic Function: CANONICALIZE-SUPERCLASSES Arguments: class -- An instance of the metaclass. superclasses -- The list of metaclass names. canonic-slot-specification -- A forms-plist. environment -- An environment. Values: new-canonic-class-specification -- A forms-plist. Description: Verifies and interprets the class superclasses. Class options are processed before superclasses. Slots are processed after superclasses have been processed. The interpretation of the superclasses is accomplished by adding or modifying keywords and values to the returned canonic class specification. Methods are permitted to modify the canonic-class-specification argument, but implementations are not permitted to depend on this. All elements of the canonic class specification should be forms to be evaluated at definition time. Examples: (DEFMETHOD CANONICALIZE-SUPERCLASSES ((CLASS STANDARD-CLASS) (SUPERCLASSES NULL) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) `(':DIRECT-SUPERCLASSES '(STANDARD-OBJECT) ,@CANONIC-CLASS-SPECIFICATION)) (DEFMETHOD CANONICALIZE-SUPERCLASSES ((CLASS STANDARD-CLASS) (SUPERCLASSES CONS) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) `(':DIRECT-SUPERCLASSES ',SUPERCLASSES ,@CANONIC-CLASS-SPECIFICATION)) (DEFMETHOD CANONICALIZE-SUPERCLASSES ((CLASS FUNCALLABLE-STANDARD-CLASS) (SUPERCLASSES NULL) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) `(':DIRECT-SUPERCLASSES '(FUNCALLABLE-INSTANCE) ,@CANONIC-CLASS-SPECIFICATION)) Generic Function: CANONICALIZE-SLOT-SPECIFICATIONS Arguments: class -- An instance of the metaclass. slot-specifications -- The list of slot specifications appearing in the DEFCLASS form. canonic-class-specification -- A forms-plist. environment -- An environment. Values: new-canonic-class-specification -- A forms-plist. Description: Verifies and interprets the slot options. DEFCLASS processes slot options in the order in which they appear in the DEFCLASS form. Slot options are processed after class options and superclasses have been processed. The interpretation of the slot options is accomplished by adding or modifying keywords and values to the returned canonic class specification. Methods are permitted to modify the canonic-class-specification argument, but implementations are not permitted to depend on this. All elements of the canonic class specification should be forms to be evaluated at definition time. For the benefit of classes in which slot order is significant, the CANONICALIZE-SLOT-SPECIFICATIONS method specialized on STANDARD-CLASS puts the canonic slot descriptions in the same order in which they appear in the slot-specifications argument (which is the same order they appear in the DEFCLASS form). Example: (DEFMETHOD CANONICALIZE-SLOT-SPECIFICATIONS ((CLASS STANDARD-CLASS) (SLOT-SPECIFICATIONS LIST) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) (LET ((CANONIC-CLASS-SPECIFICATION CANONIC-CLASS-SPECIFICATION)) (DOLIST (SLOT-SPECIFICATION SLOT-SPECIFICATIONS) (SETQ CANONIC-CLASS-SPECIFICATION (CANONICALIZE-SLOT-SPECIFICATION CLASS SLOT-SPECIFICATION CANONIC-CLASS-SPECIFICATION ENVIRONMENT))) CANONIC-CLASS-SPECIFICATION)) Generic Function: CANONICALIZE-SLOT-SPECIFICATION Arguments: class -- An instance of the metaclass. slot-specification -- One slot specification appearing in the DEFCLASS form. canonic-class-specification -- A forms-plist. environment -- An environment. Values: new-canonic-class-specification -- A forms-plist. Description: Verifies and interprets one slot specification. The interpretation of the slot specification is accomplished by adding or modifying keywords and values to the returned canonic class specification. Methods are permitted to modify the canonic-class-specification argument, but implementations are not permitted to depend on this. All elements of the canonic class specification should be forms to be evaluated at definition time. Example: (DEFMETHOD CANONICALIZE-SLOT-SPECIFICATION ((CLASS STANDARD-CLASS) (SLOT-SPECIFICATION NULL) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) (WARN "~s is an invalid slot specification. It will be ignored." SLOT-SPECIFICATION) CANONIC-CLASS-SPECIFICATION) (DEFMETHOD CANONICALIZE-SLOT-SPECIFICATION ((CLASS STANDARD-CLASS) (SLOT-SPECIFICATION SYMBOL) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) (CANONICALIZE-SLOT-SPECIFICATION CLASS (LIST SLOT-SPECIFICATION) CANONIC-CLASS-SPECIFICATION ENVIRONMENT)) (DEFMETHOD CANONICALIZE-SLOT-SPECIFICATION ((CLASS STANDARD-CLASS) (SLOT-SPECIFICATION CONS) (CANONIC-CLASS-SPECIFICATION LIST) (ENVIRONMENT T)) (LET ((NAME (FIRST SLOT-SPECIFICATION))) (WHEN (NULL NAME) (WARN "~s is not a valid name for a slot." NAME) (RETURN-FROM CANONICALIZE-SLOT-SPECIFICATION CANONIC-CLASS-SPECIFICATION)) ;; Check to see if the slot is already defined (LET ((CANONIC-SLOT-SPECIFICATIONS (LOOP FOR (OPTION-FORM VALUE-FORM) ON CANONIC-CLASS-SPECIFICATION BY #'CDDR DOING (WHEN (AND (CONSP OPTION-FORM) (EQ (FIRST OPTION-FORM) 'QUOTE) (EQ (SECOND OPTION-FORM) ':DIRECT-SLOTS)) (RETURN (REST VALUE-FORM)))))) (DOLIST (CANONIC-SLOT-SPECIFICATION CANONIC-SLOT-SPECIFICATIONS) (WHEN (EQ (LOOP FOR (OPTION-FORM VALUE-FORM) ON (REST CANONIC-SLOT-SPECIFICATION) BY #'CDDR DOING (WHEN (AND (CONSP OPTION-FORM) (EQ (FIRST OPTION-FORM) 'QUOTE) (EQ (SECOND OPTION-FORM) ':NAME)) (RETURN (SECOND VALUE-FORM)))) NAME) (WARN "The slot name ~s is used for more than one slot.~@ The second slot will be ignored." NAME) (RETURN-FROM CANONICALIZE-SLOT-SPECIFICATION CANONIC-CLASS-SPECIFICATION))) (LET ((CANONIC-CLASS-SPECIFICATION CANONIC-CLASS-SPECIFICATION) (CANONIC-SLOT-SPECIFICATION `(':NAME ',NAME))) (LOOP FOR (OPTION VALUE) ON (REST SLOT-SPECIFICATION) BY #'CDDR DOING (MULTIPLE-VALUE-SETQ (CANONIC-CLASS-SPECIFICATION CANONIC-SLOT-SPECIFICATION) (CANONICALIZE-SLOT-OPTION CLASS CANONIC-CLASS-SPECIFICATION OPTION VALUE CANONIC-SLOT-SPECIFICATION ENVIRONMENT))) (COND (CANONIC-SLOT-SPECIFICATIONS ;; Add this canonic slot specification to the end of the list (SETF (CDR (LAST CANONIC-SLOT-SPECIFICATIONS)) `((LIST ,@CANONIC-SLOT-SPECIFICATION))) CANONIC-CLASS-SPECIFICATION) (T `(':DIRECT-SLOTS (LIST (LIST ,@CANONIC-SLOT-SPECIFICATION)) ,@CANONIC-CLASS-SPECIFICATION))))))) Generic Function: CANONICALIZE-SLOT-OPTION Arguments: class -- An instance of the metaclass. canonic-class-specification -- A forms-plist. option -- a keyword. value -- The value of the option. canonic-slot-specification -- A forms-plist. environment -- An environment. Values: new-canonic-class-specification -- A forms-plist. new-canonic-slot-specification -- A forms-plist. Description: Verifies and interprets one slot option. The interpretation of the slot option is accomplished by adding or modifying keywords and values to the returned canonic class specification and/or the returned canonic slot specification. Methods are permitted to modify the canonic specification arguments, but implementations are not permitted to depend on this. All elements of the canonic specification arguments should be forms to be evaluated at definition time. Examples: (DEFMETHOD CANONICALIZE-SLOT-OPTION ((CLASS STANDARD-CLASS) (CANONIC-CLASS-SPECIFICATION LIST) (OPTION T) (VALUE T) (CANONIC-SLOT-SPECIFICATION LIST) (ENVIRONMENT T)) (WARN "The slot option ~s is invalid" OPTION) (VALUES CANONIC-CLASS-SPECIFICATION CANONIC-SLOT-SPECIFICATION)) (DEFMETHOD CANONICALIZE-SLOT-OPTION ((CLASS STANDARD-CLASS) (CANONIC-CLASS-SPECIFICATION LIST) (OPTION (EQL :READER)) (VALUE T) (CANONIC-SLOT-SPECIFICATION LIST) (ENVIRONMENT T)) (LET ((READERS (LOOP FOR (OPTION-FORM VALUE-FORM) ON CANONIC-SLOT-SPECIFICATION BY #'CDDR DOING (WHEN (AND (CONSP OPTION-FORM) (EQ (FIRST OPTION-FORM) 'QUOTE) (EQ (SECOND OPTION-FORM) ':READERS)) (RETURN VALUE-FORM))))) (COND (READERS (SETF (CDR (LAST (SECOND READERS))) `(,VALUE)) (VALUES CANONIC-CLASS-SPECIFICATION CANONIC-SLOT-SPECIFICATION)) (T (VALUES CANONIC-CLASS-SPECIFICATION `(':READERS '(,VALUE) ,@CANONIC-SLOT-SPECIFICATION)))))) An example of DEFCLASS implemented using these generic functions is: (DEFMACRO DEFCLASS (NAME SUPERCLASSES SLOT-SPECIFICATIONS &REST CLASS-OPTIONS &ENVIRONMENT ENVIRONMENT) (LET* ((METACLASS-NAME (OR (LOOP FOR OPTION IN CLASS-OPTIONS DOING (WHEN (AND (CONSP OPTION) (EQ (FIRST OPTION) ':METACLASS)) (RETURN (SECOND OPTION)))) 'STANDARD-CLASS)) (METACLASS (FIND-CLASS METACLASS-NAME T NIL)) (PROTOTYPE (CLASS-PROTOTYPE METACLASS)) (CANONIC-CLASS-SPECIFICATION NIL)) (LOOP FOR CLASS-OPTION IN CLASS-OPTIONS DOING (SETQ CANONIC-CLASS-SPECIFICATION (CANONICALIZE-CLASS-OPTION PROTOTYPE (IF (ATOM CLASS-OPTION) CLASS-OPTION (FIRST CLASS-OPTION)) CLASS-OPTION CANONIC-CLASS-SPECIFICATION ENVIRONMENT))) (SETQ CANONIC-CLASS-SPECIFICATION (CANONICALIZE-SUPERCLASSES PROTOTYPE SUPERCLASSES CANONIC-CLASS-SPECIFICATION ENVIRONMENT)) (SETQ CANONIC-CLASS-SPECIFICATION (CANONICALIZE-SLOT-SPECIFICATIONS PROTOTYPE SLOT-SPECIFICATIONS CANONIC-CLASS-SPECIFICATION ENVIRONMENT)) `(PROGN (EVAL-WHEN (:COMPILE-FILE) (ENSURE-CLASS ',NAME :ENVIRONMENT ,(COMPILE-FILE-ENVIRONMENT ENVIRONMENT) ,@CANONIC-CLASS-SPECIFICATION)) (ENSURE-CLASS ',NAME ,@CANONIC-CLASS-SPECIFICATION)))) The function COMPILE-FILE-ENVIRONMENT takes an environment as an argument and returns an object with indefinite extent which has the same COMPILE-FILEness properties as its argument. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA25929; Wed, 2 May 90 18:47:19 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 02 MAY 90 16:21:53 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 02 MAY 90 16:17:38 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA13082; Wed, 2 May 90 16:14:12 PDT Date: Wed, 2 May 90 16:13 PDT From: Gregor J. Kiczales Subject: Re: user interface macros To: David A. Moon , David Gray , Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Jon L White Cc: Danny Bobrow , rivieres@parc.xerox.com, Richard P. Gabriel , Dussud@Lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: <19900426154319.8.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <9004270038.AA00272@black-monday>, <19900427215856.1.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <9004280008.AA02801@ptl-club>, <19900428011147.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <19900501195931.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Message-Id: <19900502231329.0.GREGOR@SPIFF.parc.xerox.com> Your messages raise a number of issues. In this message I attempt to address them all, with the exception of simple typos and other obvious screw-ups (I will correct those though). This message is divided into two parts. The first part addresses comments about the nature of the macroexpansion specification and tries to show my sense of what it is appropriate to be saying at this time. The second part deals with specific issues that were raised. ON THE NATURE OF THE GOALS (of this section as it relates to the whole) Date: Fri, 27 Apr 90 17:08:50 PDT From: Jon L White To what end specify the macro expansions exactly? These are good questions and ones I have spent some time wrestling with as well. In fact, as you yourself point out, the current draft attempts not to say anything about the expansions themselves. Instead, it tries to talk only about the various calls that result from evaluation or executing a macro. The question then becomes why even bother to do that. The main reason is to allow user-defined metaobject classes to be instantiated by the standard macros. You want DEFCLASS to be able to create instances of MY-CLASS, you want DEFMETHOD to be able to create instances of MY-METHOD etc. Rather, I think the only point of mentioning the expansion of the definer "user interface" macros is that our experience with metaobject creations over the past two years, via portable constructs, *had* to be limited to these macros. I don't have any idea what this sentence means. The goal of this document is to specify the behavior of the anonymous metaobjects -- that is what is powerful and interesting. But, to do so properly, requires that we say some things about the rest of the CLOS mechanisms. We need to talk about the macroexpansion layer for the reasons mentioned above. We need to talk about the name-->object mapping layer because many user metalevel programs want to blend with the name--> object mapping already used in `conventional' CLOS programs. These aren't the most interesting parts, but they are essential to the success of the whole. What is perhaps unfortunate is that this round of work is starting with macroexpansion -- that decision was made because that is the part of the old document that was in the worst shape. We just have to remember that this isn't the part we really care about. That we just need to do enough ui macro stuff to enable the kinds of things users need to do as mentioned above. For example, Scott proposes a full-featured mechanism for metaclass control over the parsing of DEFCLASS forms into calls to ENSURE-CLASS. I have experimented with things like this in the past, and the one Scott proposes is a nice one. But, I don't think we want to specify this sort of thing right now. I feel like it is more than we want to get into, especially given JonL's valid points that the uimacros are the least important part of this whole thing. I would rather do some combination of changing the specified behavior of the ui macros and explicitly allowing this kind of implementation specific extension. I could be argued out of this, especially if someone else wrote the relevant text (Scott has a start). So, on the subject of extending the syntax of DEFCLASS, I propose: - remove the part about what happens when an option (any option) is specified more than once. Just say it is not specified, that implementations are free to document their own behavior. - either - fix the :metaclass and :documentation class options and leave the stuff about the tail of the list (this is what I had in mind originally and failed to write) or - make the class options (other than :default-initargs) pass the CADR - explicitly mention that implementations are free to have specific mechanisms for extending the behavior of the ui macros. - fix the stuff about order to say only: - the order of :default-initargs is preserved - and possibly that for unspecified slot and class options, they the specified ones and their order is preserved ON SPECIFIC ISSUES Date: Thu, 26 Apr 90 11:43 EDT From: David A. Moon First fix the confusion of using "compile" both to mean "translate to machine code" and also to mean "write a file that can later be loaded and will produce similar objects." You'll know you've got it right when the specification does not admit any difference between EVAL and calling the result of COMPILE. You're concerned with the case of one Lisp or two (the compiling lisp and the loading/running Lisp), but you're not concerned with whether the representation of Lisp programs is S-expressions or machine code. I suggest eliminating all use of the word "compile" except in the compound form "compile-file." Yes, I was trying to head in this direction, but as we have all learned it isn't so easy. The part about allowing DEFGENERICs that appear in compiled files to affect the way DEFMETHOD forms are processed is, of course, what makes it hard. I will give this another go. Date: Thu, 26 Apr 90 17:38:26 PDT From: David Gray Rather than "evaluates the initform", I would prefer that the wording be modified to make it clear that it is permissible for the compiler to substitute something that has an equivalent effect. For example, :INITFORM (* 2 5) could result in :INITFUNCTION #'(LAMBDA () 10) How about "returns the result of evaluating the initform in the lexical environment of the DEFCLASS form"? Date: Fri, 27 Apr 90 17:58 EDT From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM User interface macro forms can be {\bit evaluated}, {\bit compiled}, or a compiled macro form can be {\bit executed}. This sentence is a bit confusing. I think it meant to say "User interface macro forms can be {\bit evaluated} or {\bit compiled} and {\bit executed}." Since that is true of all macros, I'm not really sure why it needs to be said at all. The purpose of the sentence was to define the three terms. I will try and fix this as mentioned above. In the arguments to ENSURE-CLASS, this document has :DIRECT-SUPERCLASSES and :DIRECT-SLOTS where 89-003 has :SUPERCLASSES and :SLOTS. Symbolics CLOS uses :DIRECT-SUPERCLASSES (based on mail with Gregor a few months ago) but :SLOTS. For consistency, :DIRECT-SLOTS would be better, but we've passed the point of being able to remove :SLOTS, although we could make :SLOTS mean :DIRECT-SLOTS. Similarly, :DIRECT-DEFAULT-INITARGS should replace :DEFAULT-INITARGS. Although no document and no implementation uses :DIRECT-DEFAULT-INITARGS currently, it would be more consistent. It's difficult for me to tell what you are asking for here. The change to :DIRECT-XXX was based on the mail you mention. I really think these are better names. Unless someone complains I would like to leave these as: :DIRECT-SLOTS :DIRECT-SUPERCLASSES :DIRECT-DEFAULT-INITARGS A canonicalized default initarg is a list of three elements. ... Symbolics CLOS and 89-003 put the form before the function. Why was the order gratuitously changed? Also, there needs to be provision for implementation additions (we use one), just as in the canonicalized slot specification. Just allow the list to have more than three elements, where elements after the first three are implementation dependent. I will change the order back and allow the lists to be longer. But, for reference: * I believe the order in draft 11 is better because it makes the implementation-specific `improvement' where you drop the form more straighforward. * I don't think making the lists longer is the most modular way to do the extension you mention. Instead, another keyword argument/initarg which parallels this one should be used. The name in 89-003 and in Symbolics CLOS is generic-function-method-class. Why the gratuitous change? Braino, I will change it back. \item{\bull} The value of the {\bf :specializers} initarg is a list of the specializer names for the method. For {\bf eql} specializers, this is a list in which the first element is the symbol {\bf setf} and the second element is the result of evaluating the eql specializer form in the lexical environment of the {\bf defmethod} form. For any other kind of specializer, this is the value from the {\bf defmethod} form with no special processing done. It's too weird to make this a list of elements that are parameter specializers in one case and parameter specializer names in the other case. 89-003 p.3-69 requires parameter specializers here, i.e. classes rather than class names. See also 89-003 p.3-16. So not only is this weird, it's also a gratuitous incompatibility. Actually, I don't think its weird, but I am willing to change it back. I believe, as I alluded to before, that there are three layers. 1) the macroexpansion layer 2) the name to metaobject mapping layer 3) the anonymous metaobjects (where the real CLOS behavior is) The way this worked in 89-003 and the way you have it puts stuff from layer 2 in layer 1, and that isn't modular. \item{\bull} The {\it direct superclasses} argument to {\bf defclass} becomes the value of the {\bf :direct-superclasses} keyword argument to {\bf ensure-class}. We do this differently. If the {\it direct superclasses} is NIL, then the metaclass is asked for the list of direct superclasses to be used, using class-default-direct-superclasses. For STANDARD-CLASS, (STANDARD-OBJECT) is used, for FUNCALLABLE-STANDARD-CLASS, (FUNCALLABLE-INSTANCE), etc. Thus ENSURE-CLASS receives the actual list of direct superclasses. In our way of defaulting these, it is possible for a metaclass to make classes which have no superclasses. The result of class-default-direct-superclasses is a list of class objects even though the :direct-superclasses is otherwise a list of class names; this might be a mistake, but does allow for anonymous classes as default direct superclasses. This is a similar issue. Defaulting the superclasses doesn't seem to me to be a macroexpansion issue. It seems to me that defaulting the superclasses is an essential part of the behavior of the raw object system. Once again though, I can live with it this way. Defining NULL to be the predicate that tests whether an environment is the run-time environment is not very abstract. This could run into serious problems with future extensions that unify this environment with the &environment argument to macros or that implement more than just the run-time and compilation environments. On the one hand, NIL might not be the only representation for the "ordinary" environment, and on the other hand, there might be several distinct environments that all have the property of containing classes that can be instantiated and methods that can be executed. I agree with all of these comments. What if we just added an argument :COMPILE-ENVIRONMENT-P or something. It would be true or false. In cases where it is true it would mean the some other information, passed in implementation-specific keyword arguments had the real compile environment. Date: Fri, 27 Apr 90 17:58 EDT From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM When defmethod calls ensure-generic-function, it must not supply the :lambda-list argument. ensure-generic-function has to know the difference between a call from defgeneric (which always replaces the lambda-list), and a call from defmethod (which never replaces the lambda-list). Symbolics CLOS works as outlined in this message: Date: Fri, 27 Apr 90 17:08:50 PDT From: Jon L White A gap in the current definition of ENSURE-GENERIC-FUNCTION? Based on the comments you have sent, here is a strawman. What if we have ENSURE-GENERIC-FUNCTION accept two keyword arguments: :LAMBDA-LIST and :METHOD-LAMBDA-LIST. The :LAMBDA-LIST argument will be passed in by DEFGENERIC. Its value will the the value specified in the macro form. Its presence (or non-nullness) will indicate the call was from DEFGENERIC. The :METHOD-LAMBDA-LIST argument will be passed in by DEFMETHOD. Its value will be the unspecialized lambda list from the macro form (what you get by calling extract-lambda-list). Its presence (or non-nullness) will indicate the call was from DEFMETHOD. This means that special processing will happen inside of ENSURE-GF and initialization when DEFMETHOD creates a generic function, but this scheme should make all the information each of you wants available. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA05797; Thu, 3 May 90 13:45:51 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 03 MAY 90 12:22:54 PDT Return-Path: Received: from lucid.com ([192.26.25.1]) by Xerox.COM ; 03 MAY 90 11:53:53 PDT Received: from black-monday ([192.31.212.62]) by heavens-gate.lucid.com id AA06330g; Thu, 3 May 90 11:48:40 PDT Received: by black-monday id AA06008g; Thu, 3 May 90 11:47:44 PDT Date: Thu, 3 May 90 11:47:44 PDT From: David Gray Message-Id: <9005031847.AA06008@black-monday> To: gregor@parc.xerox.com Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Cyphers@STONY-BROOK.SCRC.Symbolics.COM, jonl@lucid.com, bobrow@parc.xerox.com, rivieres@parc.xerox.com, rpg@lucid.com, Dussud@lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: Gregor J. Kiczales's message of Wed, 2 May 90 16:13 PDT <19900502231329.0.GREGOR@SPIFF.parc.xerox.com> Subject: user interface macros Cc: gray@lucid.com > Defining NULL to be the predicate that tests whether an environment is the > run-time environment is not very abstract. This could run into serious > problems with future extensions that unify this environment with the > &environment argument to macros or that implement more than just the run-time > and compilation environments. On the one hand, NIL might not be the only > representation for the "ordinary" environment, and on the other hand, there > might be several distinct environments that all have the property of > containing classes that can be instantiated and methods that can be executed. > I agree with all of these comments. What if we just added an argument > :COMPILE-ENVIRONMENT-P or something. It would be true or false. In > cases where it is true it would mean the some other information, passed > in implementation-specific keyword arguments had the real compile > environment. No, there should be just one environment argument. Perhaps there should be a function to test whether it is a compile-time environment (NULL is most certainly not that function), but I would want to see the need for that demonstrated first. For the metaclass writer, the point is to be consistent about passing the received environment on to FIND-CLASS, MACROEXPAND, ENSURE-GENERIC-FUNCTION, etc. I'm curious about Moon's phrase "future extensions that unify this environment with the &environment argument to macros"; isn't that unification already dictated by the current definition of FIND-CLASS? I have implemented such unified environments on the Explorer and found that it works very well, so this is not untested theory. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA07728; Thu, 3 May 90 14:40:10 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 03 MAY 90 12:58:37 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 03 MAY 90 12:25:03 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16320; Thu, 3 May 90 12:21:44 PDT Date: Thu, 3 May 90 12:21 PDT From: Gregor J. Kiczales Subject: Re: user interface macros To: David Gray Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Cyphers@STONY-BROOK.SCRC.Symbolics.COM, jonl@lucid.com, bobrow@parc.xerox.com, rivieres@parc.xerox.com, rpg@lucid.com, Dussud@lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: <9005031847.AA06008@black-monday> Message-Id: <19900503192101.6.GREGOR@SPIFF.parc.xerox.com> Date: Thu, 3 May 90 11:47:44 PDT From: David Gray No, there should be just one environment argument. Perhaps there should be a function to test whether it is a compile-time environment (NULL is most certainly not that function), but I would want to see the need for that demonstrated first. For the metaclass writer, the point is to be consistent about passing the received environment on to FIND-CLASS, MACROEXPAND, ENSURE-GENERIC-FUNCTION, etc. My idea was that the predicate would be the extra argument. User code would still be required to pass the argument on to the other functions (find-class etc.). User code would pass the value of the :environment argument, no other values. The other argument would just be a flag to user code that this was in the compile environment and things might be weird. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA25641; Mon, 7 May 90 06:29:36 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 07 MAY 90 06:28:37 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 07 MAY 90 06:26:42 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 789564; 4 May 90 17:57:47 EDT Date: Fri, 4 May 90 17:59 EDT From: David A. Moon Subject: user interface macros To: David Gray Cc: gregor@parc.xerox.com, Cyphers@STONY-BROOK.SCRC.Symbolics.COM, jonl@lucid.com, bobrow@parc.xerox.com, rivieres@parc.xerox.com, rpg@lucid.com, Dussud@lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: <9005031847.AA06008@black-monday> Message-Id: <19900504215904.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No Date: Thu, 3 May 90 11:47:44 PDT From: David Gray I'm curious about Moon's phrase "future extensions that unify this environment with the &environment argument to macros"; isn't that unification already dictated by the current definition of FIND-CLASS? I have implemented such unified environments on the Explorer and found that it works very well, so this is not untested theory. Here's the context of your quotation: Defining NULL to be the predicate that tests whether an environment is the run-time environment is not very abstract. This could run into serious problems with future extensions that unify this environment with the &environment argument to macros.... There is more than one macroexpansion environment that, regarded as a FIND-CLASS environment, represents the global runtime environment. Only one of them can be NIL, therefore NULL cannot be the test for whether an environment represents the global runtime environment. It's an argument for having a specific predicate for testing whether an environment has this property, instead of violating abstraction and using NULL as that predicate. There is the additional issue of whether such a predicate is needed at all. Moon and Cyphers said: I was unable to figure out what specific predicates are needed, nor what the specific problem is that needs to be solved (alluded to in "testing for these cases" above). Gray said: I would want to see the need for that demonstrated first. So I think we agree that we're not yet convinced such a predicate is needed. Gregor hasn't addressed this issue yet. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26488; Mon, 7 May 90 07:36:54 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 07 MAY 90 07:31:23 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 07 MAY 90 07:30:25 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 789979; 7 May 90 10:29:09 EDT Date: Mon, 7 May 90 10:30 EDT From: David A. Moon Subject: Re: user interface macros To: Gregor J. Kiczales Cc: David Gray , Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Jon L White , Danny Bobrow , rivieres@parc.xerox.com, Richard P. Gabriel , Dussud@Lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: <19900502231329.0.GREGOR@SPIFF.parc.xerox.com> Message-Id: <19900507143030.7.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No [Comments on excerpts from your message (actually written Friday, but mailed Monday). I'll comment on the environment issue separately.] Date: Wed, 2 May 90 16:13 PDT From: Gregor J. Kiczales For example, Scott proposes a full-featured mechanism for metaclass control over the parsing of DEFCLASS forms into calls to ENSURE-CLASS. I have experimented with things like this in the past, and the one Scott proposes is a nice one. But, I don't think we want to specify this sort of thing right now. I feel like it is more than we want to get into, especially given JonL's valid points that the uimacros are the least important part of this whole thing. I think that is a reasonable attitude. I think we mentioned that more as an example of what might be done than as a proposal for what should be done. The problem is that you opened the door to user-defined new class options and slot options by attempting to define how DEFCLASS would pass them through, and since what you defined didn't really work, we wanted to explore what it would take to make something that would work for all cases. Unless I'm missing something, I think it's been demonstrated that nothing really simple will do the job of allowing users to pass their own options through DEFCLASS in a satisfactory way. So, on the subject of extending the syntax of DEFCLASS, I propose: - remove the part about what happens when an option (any option) is specified more than once. Just say it is not specified, that implementations are free to document their own behavior. Okay. - either - fix the :metaclass and :documentation class options and leave the stuff about the tail of the list (this is what I had in mind originally and failed to write) or - make the class options (other than :default-initargs) pass the CADR I'm not sure I understand this, but if it means define what each of the standard class options turns into, and define that :metaclass and :documentation pass a symbol and a string (rather than a list), I agree. - explicitly mention that implementations are free to have specific mechanisms for extending the behavior of the ui macros. Okay. - fix the stuff about order to say only: - the order of :default-initargs is preserved - and possibly that for unspecified slot and class options, they the specified ones and their order is preserved I was unable to understand this, probably due to typos. To be specific, I think what you want to do about DEFCLASS is to define precisely how each of the standard options is passed through, and not to define at all whether and how nonstandard options are passed through, other than to mention that nonstandard options might be present and to discuss the naming restrictions (packages). In the arguments to ENSURE-CLASS, this document has :DIRECT-SUPERCLASSES and :DIRECT-SLOTS where 89-003 has :SUPERCLASSES and :SLOTS. Symbolics CLOS uses :DIRECT-SUPERCLASSES (based on mail with Gregor a few months ago) but :SLOTS. For consistency, :DIRECT-SLOTS would be better, but we've passed the point of being able to remove :SLOTS, although we could make :SLOTS mean :DIRECT-SLOTS. Similarly, :DIRECT-DEFAULT-INITARGS should replace :DEFAULT-INITARGS. Although no document and no implementation uses :DIRECT-DEFAULT-INITARGS currently, it would be more consistent. It's difficult for me to tell what you are asking for here. The change to :DIRECT-XXX was based on the mail you mention. I really think these are better names. Unless someone complains I would like to leave these as: :DIRECT-SLOTS :DIRECT-SUPERCLASSES :DIRECT-DEFAULT-INITARGS Your document says :DEFAULT-INITARGS, not :DIRECT-DEFAULT-INITARGS. We were suggesting :DIRECT- for all three of these things that get inherited. A canonicalized default initarg is a list of three elements. .... * I don't think making the lists longer is the most modular way to do the extension you mention. Instead, another keyword argument/initarg which parallels this one should be used. I don't think so, because then the thing that combines the direct default initargs to produce the complete list of default initargs would have to know about this other list and make sure to keep the two of them synchronized. Of course, the real error here is that the default initargs are materialized as lists rather than using a more abstract data type, and do not go through a stage of alternating keywords and values. If the default initargs were handled like the slots, none of these problems would arise. However, I am not advocating such a sweeping change. \item{\bull} The value of the {\bf :specializers} initarg is a list of the specializer names for the method. For {\bf eql} specializers, this is a list in which the first element is the symbol {\bf setf} and the second element is the result of evaluating the eql specializer form in the lexical environment of the {\bf defmethod} form. For any other kind of specializer, this is the value from the {\bf defmethod} form with no special processing done. It's too weird to make this a list of elements that are parameter specializers in one case and parameter specializer names in the other case. 89-003 p.3-69 requires parameter specializers here, i.e. classes rather than class names. See also 89-003 p.3-16. So not only is this weird, it's also a gratuitous incompatibility. Actually, I don't think its weird, but I am willing to change it back. I believe, as I alluded to before, that there are three layers. 1) the macroexpansion layer 2) the name to metaobject mapping layer 3) the anonymous metaobjects (where the real CLOS behavior is) The way this worked in 89-003 and the way you have it puts stuff from layer 2 in layer 1, and that isn't modular. This is hardly the only place where the macroexpansion layer uses metaobjects. I think a complete separation of the layers is simply not possible. Date: Fri, 27 Apr 90 17:58 EDT From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM When defmethod calls ensure-generic-function, it must not supply the :lambda-list argument. ensure-generic-function has to know the difference between a call from defgeneric (which always replaces the lambda-list), and a call from defmethod (which never replaces the lambda-list). Symbolics CLOS works as outlined in this message: Date: Fri, 27 Apr 90 17:08:50 PDT From: Jon L White A gap in the current definition of ENSURE-GENERIC-FUNCTION? Based on the comments you have sent, here is a strawman. What if we have ENSURE-GENERIC-FUNCTION accept two keyword arguments: :LAMBDA-LIST and :METHOD-LAMBDA-LIST. The :LAMBDA-LIST argument will be passed in by DEFGENERIC. Its value will the the value specified in the macro form. Its presence (or non-nullness) will indicate the call was from DEFGENERIC. The :METHOD-LAMBDA-LIST argument will be passed in by DEFMETHOD. Its value will be the unspecialized lambda list from the macro form (what you get by calling extract-lambda-list). Its presence (or non-nullness) will indicate the call was from DEFMETHOD. This means that special processing will happen inside of ENSURE-GF and initialization when DEFMETHOD creates a generic function, but this scheme should make all the information each of you wants available. I think it would be much cleaner to handle the meeting of the method lambda list and the generic function lambda list in ADD-METHOD, the same place where all other method-meets-generic-function processing is performed. Do you disagree with this, or did you just not consider it yet? Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA27271; Mon, 7 May 90 08:15:43 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 07 MAY 90 08:13:12 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 07 MAY 90 08:12:34 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 790061; 7 May 90 11:12:48 EDT Date: Mon, 7 May 90 11:14 EDT From: David A. Moon Subject: user interface macros: the environment issue To: Gregor J. Kiczales Cc: mop.pa@Xerox.COM In-Reply-To: <19900501195931.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <19900502231329.0.GREGOR@SPIFF.parc.xerox.com>, <9005031847.AA06008@black-monday>, <19900503192101.6.GREGOR@SPIFF.parc.xerox.com>, <9005032021.AA06121@black-monday>, <19900504215904.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Message-Id: <19900507151408.7.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No It might pay to read this message starting at the end, unless you don't remember all the context. Date: Tue, 1 May 90 15:59 EDT From: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM This document defines just enough of the compiler processing of the user interface macros to allow portable metaobject classes to determine whether instances are being created to represent definitions in the compile file environment. In such cases, the values of other keyword and initialization arguments may differ from the specified values so portable code must test for such cases to prevent encountering unexpected values. Testing for these cases is possible because compiler processing of the user-interface macros calls the functions {\bf ensure-class} and {\bf ensure-generic-function} with a non-null value for the {\bf :environment} keyword argument. Defining NULL to be the predicate that tests whether an environment is the run-time environment is not very abstract. This could run into serious problems with future extensions that unify this environment with the &environment argument to macros or that implement more than just the run-time and compilation environments. On the one hand, NIL might not be the only representation for the "ordinary" environment, and on the other hand, there might be several distinct environments that all have the property of containing classes that can be instantiated and methods that can be executed. I didn't include in this message my later message expanding on the previous two sentences. I hope they're clear now. I think we must choose either not to document any predicates on the environment, and require portable metaobject classes to operate some other way, or else to add one or more predicates that perform the specific tests on environments that are actually needed. I was unable to figure out what specific predicates are needed, nor what the specific problem is that needs to be solved (alluded to in "testing for these cases" above). As a strawman, I'll suggest (RUN-TIME-ENVIRONMENT-P env) => true if env is an environment that causes FIND-CLASS to return instantiable classes and causes ENSURE-GENERIC-FUNCTION to return callable generic functions. The term "run time environment" is from section 4.2 of the draft ANSI CL specification, revision 7.31 of 8/29/89. [from our example of how option parsing could be done:] The function COMPILE-FILE-ENVIRONMENT takes an environment as an argument and returns an object with indefinite extent which has the same COMPILE-FILEness properties as its argument. That function probably has the wrong name. The basic idea is that since Common Lisp does not allow a macro to incorporate its &environment argument into the expansion it returns, a macro that needs to do something like that (as DEFCLASS does), has to pass the &environment argument through a function that makes it into a sanitized argument with the same semnatics but indefinite extent. This is only needed as part of the protocol if users are making their own macros that resemble DEFCLASS or DEFMETHOD -and- if those macros need to play eval-when games. So I wouldn't worry too much about this right now. Date: Wed, 2 May 90 16:13 PDT From: Gregor J. Kiczales Defining NULL to be the predicate that tests whether an environment is the run-time environment is not very abstract. This could run into serious problems with future extensions that unify this environment with the &environment argument to macros or that implement more than just the run-time and compilation environments. On the one hand, NIL might not be the only representation for the "ordinary" environment, and on the other hand, there might be several distinct environments that all have the property of containing classes that can be instantiated and methods that can be executed. I agree with all of these comments. What if we just added an argument :COMPILE-ENVIRONMENT-P or something. It would be true or false. In cases where it is true it would mean the some other information, passed in implementation-specific keyword arguments had the real compile environment. Date: Thu, 3 May 90 11:47:44 PDT From: David Gray No, there should be just one environment argument. I agree 100%. I'd also like to add that any time you add more arguments rather than making the extsing argument more expressive, you are not adhering faithfully to the object-oriented religion. Perhaps there should be a function to test whether it is a compile-time environment (NULL is most certainly not that function), but I would want to see the need for that demonstrated first. For the metaclass writer, the point is to be consistent about passing the received environment on to FIND-CLASS, MACROEXPAND, ENSURE-GENERIC-FUNCTION, etc. Date: Thu, 3 May 90 12:21 PDT From: Gregor J. Kiczales My idea was that the predicate would be the extra argument. User code would still be required to pass the argument on to the other functions (find-class etc.). User code would pass the value of the :environment argument, no other values. The other argument would just be a flag to user code that this was in the compile environment and things might be weird. So "user code" would get information from one argument and "system code" would get the same information from a different argument? Since I don't believe there is any real difference between "user code" and "system code", and since specific pieces of code often migrate from one category to the other (in both directions, in fact), I don't think this will fly. Date: Thu, 3 May 90 13:21:20 PDT From: David Gray That still seems like an undesirable and unnecessary complication; I'd rather have a predicate function than a redundant argument. Date: Fri, 4 May 90 17:59 EDT From: David A. Moon There is the additional issue of whether such a predicate is needed at all. Moon and Cyphers said: I was unable to figure out what specific predicates are needed, nor what the specific problem is that needs to be solved (alluded to in "testing for these cases" above). Gray said: I would want to see the need for that demonstrated first. So I think we agree that we're not yet convinced such a predicate is needed. Gregor hasn't addressed this issue yet. Let's start by addressing the question of whether any predicates on environments are needed at all, and if so, what exactly those predicates are testing for. My strawman proposal is that the metaobject protocol documents no operations on environments other than the ones that are already in 88-002R (such as the environment argument to FIND-CLASS) and obvious extensions of the same thing. Thus no run-time versus compile-time predicate at all. Let's look at where this breaks down, if at all, to see whether there is a need for anything else. I know it will break down for users writing their own macros that do what DEFCLASS does. I haven't yet been shown a case where it will break down for users writing methods that get called by the expansion of any of the defining macros. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA03059; Mon, 7 May 90 09:15:52 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 07 MAY 90 09:11:04 PDT Return-Path: Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by Xerox.COM ; 07 MAY 90 09:10:13 PDT Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 381134; 7 May 90 11:30:12 EDT Date: Mon, 7 May 90 11:31 EDT From: Scott Cyphers Subject: user interface macros: the environment issue To: Moon@STONY-BROOK.SCRC.Symbolics.COM, gregor@parc.xerox.com Cc: mop.pa@Xerox.COM In-Reply-To: <19900507151408.7.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Message-Id: <19900507153131.7.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Mon, 7 May 90 11:14 EDT From: David A. Moon Gray said: I would want to see the need for that demonstrated first. So I think we agree that we're not yet convinced such a predicate is needed. Gregor hasn't addressed this issue yet. Let's start by addressing the question of whether any predicates on environments are needed at all, and if so, what exactly those predicates are testing for. My strawman proposal is that the metaobject protocol documents no operations on environments other than the ones that are already in 88-002R (such as the environment argument to FIND-CLASS) and obvious extensions of the same thing. Thus no run-time versus compile-time predicate at all. Let's look at where this breaks down, if at all, to see whether there is a need for anything else. I know it will break down for users writing their own macros that do what DEFCLASS does. I haven't yet been shown a case where it will break down for users writing methods that get called by the expansion of any of the defining macros. A DEFCLASS expands into a compile-file time ENSURE-CLASS and a load time ENSURE-CLASS. If the class has slots with :CLASS allocation, then their initforms get evaluated when the class is instantiated (probably by a SHARED-INITIALIZE method). The compile-time ENSURE-CLASS shouldn't call the initfunctions, so the SHARED-INITIALIZE method is going to have to look at the environment argument to determine whether or not to call any initfunctions. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA17842; Mon, 7 May 90 11:42:41 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 07 MAY 90 10:48:44 PDT Return-Path: Received: from lucid.com ([192.26.25.1]) by Xerox.COM ; 07 MAY 90 10:48:20 PDT Received: from black-monday ([192.31.212.62]) by heavens-gate.lucid.com id AA06273g; Mon, 7 May 90 10:47:32 PDT Received: by black-monday id AA11029g; Mon, 7 May 90 10:46:44 PDT Date: Mon, 7 May 90 10:46:44 PDT From: David Gray Message-Id: <9005071746.AA11029@black-monday> To: Moon@STONY-BROOK.SCRC.Symbolics.COM Cc: gregor@parc.xerox.com, mop.pa@Xerox.COM In-Reply-To: David A. Moon's message of Mon, 7 May 90 10:30 EDT <19900507143030.7.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Subject: user interface macros > To be specific, I think what you want to do about DEFCLASS is to define > precisely how each of the standard options is passed through, and not to > define at all whether and how nonstandard options are passed through, > other than to mention that nonstandard options might be present and to > discuss the naming restrictions (packages). That would be sufficient for implementation-defined options, but non-standard options should also include user-defined options. In order for the metaclass writer to be able to define new options, there needs to be a standard correspondence between the DEFCLASS form and the arguments to ENSURE-CLASS-USING-CLASS. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA00998; Mon, 7 May 90 18:38:04 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 07 MAY 90 13:58:44 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 07 MAY 90 13:24:54 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA28505; Mon, 7 May 90 13:07:51 PDT Date: Mon, 7 May 90 13:07 PDT From: Gregor J. Kiczales Subject: Re: user interface macros To: David A. Moon , David Gray Cc: Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Jon L White , Danny Bobrow , rivieres@parc.xerox.com, Richard P. Gabriel , Dussud@Lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: <19900507143030.7.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>, <9005071746.AA11029@black-monday> Message-Id: <19900507200704.4.GREGOR@SPIFF.parc.xerox.com> Just to comment quickly on this one little issue: Date: Mon, 7 May 90 10:46:44 PDT From: David Gray > To be specific, I think what you want to do about DEFCLASS is to define > precisely how each of the standard options is passed through, and not to > define at all whether and how nonstandard options are passed through, > other than to mention that nonstandard options might be present and to > discuss the naming restrictions (packages). That would be sufficient for implementation-defined options, but non-standard options should also include user-defined options. In order for the metaclass writer to be able to define new options, there needs to be a standard correspondence between the DEFCLASS form and the arguments to ENSURE-CLASS-USING-CLASS. I agree with David (Gray) that we need to do a little more than what David (Moon) suggests. My proposal (admittedely cluttered by typos) was to specify a minimal, simple behavior for DEFCLASS and DEFGENERIC processing of non-standard options. Enough to get some power out of it, but by no means fully featured. We would also say explictly that an implementations are free to extend or modify this behavior. Single appearance options which simply quote their value would be supported by the minimal, specified behavior. For anything else you would need to use your own macro or implementation-specific tools. I believe This will get enough more than saying nothing about how non-standard options are passed through that it is worth doing. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01327; Mon, 7 May 90 19:51:09 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 07 MAY 90 15:57:50 PDT Return-Path: Received: from lucid.com ([192.26.25.1]) by Xerox.COM ; 07 MAY 90 15:53:29 PDT Received: from ptl-club ([192.31.212.51]) by heavens-gate.lucid.com id AA08824g; Mon, 7 May 90 15:52:25 PDT Received: by ptl-club id AA05025g; Mon, 7 May 90 15:51:53 PDT Date: Mon, 7 May 90 15:51:53 PDT From: Jon L White Message-Id: <9005072251.AA05025@ptl-club> To: gray@lucid.com Cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, gregor@parc.xerox.com, mop.pa@Xerox.COM In-Reply-To: David Gray's message of Mon, 7 May 90 10:46:44 PDT <9005071746.AA11029@black-monday> Subject: user interface macros re: > To be specific, I think what you want to do about DEFCLASS is to define > precisely how each of the standard options is passed through, and not to > define at all whether and how nonstandard options are passed through, > other than to mention that nonstandard options might be present and to > discuss the naming restrictions (packages). That would be sufficient for implementation-defined options, but non-standard options should also include user-defined options. In order for the metaclass writer to be able to define new options, there needs to be a standard correspondence between the DEFCLASS form and the arguments to ENSURE-CLASS-USING-CLASS. I hope nothing prevents the "metaclass writer" from calling ENSURE-CLASS and ENSURE-CLASS-USING-CLASS directly; nothing should require all class creations to go through DEFCLASS. At some level, we have to be interested in how DEFCLASS, etc expand; but not necessarily in a specification level. Rather, as one of Scott's notes shows, we need to be able to assure ourselves that the underlying functional layer is good enough to do what any portable definition of DEFCLASS would want it to do. [As we found with ENSURE-GENERIC-FUNCTION, there was a gap.] So a fundamental question would first be: "How does ENSURE-CLASS treat non-standard options in its arguments that specify slot or class options?" A typical answer could be something like "implementations are free to extend ...". Or, these options might even be specified to be passed along to the required initialization methods that ENSURE-CLASS would call [see my previous note about the good steps taken in this direction by the the "Rainy Day" PCL.] In order to re-use the name DEFCLASS for non-standard class definitions, the macroexpansion handling of non-standard options -- both as class options and slot options -- would have to be assured. But this ought to be an easy task, and one not particularly important to the overriding task at hand, namely a user-visible metaobject protocol. I fear the discussion has tended to veer away from the original goal of a meta-object protocol, and wandered too much into the realm of previously unsolved, related compilation problems which are essentially irrelevant to this overriding goal; an overemphasis on the particulars of the ui expansions could have the same bad effect. Other than using our current expectations about what the various ui macros mean (when evaluated), I don't see much gained towards the metaobject protocol by discussing them now. There is a reason why only these macros -- as opposed to the underlying functional layger -- appear in the spec, but it is *not* due to their preeminent importance; note the explanation from my not of a week or so ago. Date: Fri, 27 Apr 90 17:08:50 PDT From: Jon L White To: gregor.PA@Xerox.COM . . . Rather, I think the only point of mentioning the expansion of the definer "user interface" macros is that our experience with metaobject creations over the past two years, via portable constructs, *had* to be limited to these macros. So it's natural that we would tend to think of the issues involved in terms of the exterior interface syntax. Some of you who have been on the Common-Lisp-Object-System mailing list for a long time may remember that precisely this question arose several years ago. And someone (who? maybe Dave Moon) suggested that while we indeed needed the functional interface for class, method, and generic function creations, the predominate usage by end users would be in terms of the succinct definer macros like DEFCLASS and DEFMETHOD. Thus we *had* to have syntax and semantics for these macros defined in the basic document; but the definitions for the functional interface, while logically more primitive, could be postponed until the metaboject layer became more fully defined. Indeed the need by an end-user for the functional layer would only really come into play when his application became involved in "meta" manipulations. From a later reply, it looks like Gregor missed the point of that paragraph by stumbling over the first sentence. Maybe reading the last two sentences first will make it clearer. -- JonL -- Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01331; Mon, 7 May 90 19:51:15 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 07 MAY 90 16:06:42 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 07 MAY 90 16:06:10 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 790791; 7 May 90 19:05:04 EDT Date: Mon, 7 May 90 19:06 EDT From: David A. Moon Subject: user interface macros To: Jon L White Cc: gray@lucid.com, gregor@parc.xerox.com, mop.pa@Xerox.COM In-Reply-To: <9005072251.AA05025@ptl-club> Message-Id: <19900507230639.0.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No Date: Mon, 7 May 90 15:51:53 PDT From: Jon L White So a fundamental question would first be: "How does ENSURE-CLASS treat non-standard options in its arguments that specify slot or class options?" A typical answer could be something like "implementations are free to extend ...". Or, these options might even be specified to be passed along to the required initialization methods that ENSURE-CLASS would call [see my previous note about the good steps taken in this direction by the the "Rainy Day" PCL.] Quite right. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01370; Mon, 7 May 90 19:53:33 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 07 MAY 90 14:53:03 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 07 MAY 90 14:52:22 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 790687; 7 May 90 17:51:12 EDT Date: Mon, 7 May 90 17:52 EDT From: David A. Moon Subject: Re: user interface macros To: Gregor J. Kiczales Cc: David Gray , Cyphers@STONY-BROOK.SCRC.Symbolics.COM, Jon L White , Danny Bobrow , rivieres@parc.xerox.com, Richard P. Gabriel , Dussud@Lucid.com, jkf@franz.com, paepcke@hplap.hpl.hp.com, jutta@ztivax.siemens.com, mop.pa@Xerox.COM In-Reply-To: <19900507200704.4.GREGOR@SPIFF.parc.xerox.com> Message-Id: <19900507215243.2.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No Date: Mon, 7 May 90 13:07 PDT From: Gregor J. Kiczales My proposal (admittedely cluttered by typos) was to specify a minimal, simple behavior for DEFCLASS and DEFGENERIC processing of non-standard options. Enough to get some power out of it, but by no means fully featured. We would also say explictly that an implementations are free to extend or modify this behavior. Single appearance options which simply quote their value would be supported by the minimal, specified behavior. For anything else you would need to use your own macro or implementation-specific tools. I believe This will get enough more than saying nothing about how non-standard options are passed through that it is worth doing. I guess I need to see a version that is not cluttered with typos, since it seems to me that if you specify something and say that implementations are free to modify it, you have not specified anything. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA21823; Tue, 8 May 90 13:07:48 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 08 MAY 90 11:56:11 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 08 MAY 90 11:54:12 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA03361; Tue, 8 May 90 11:54:38 PDT Date: Tue, 8 May 90 11:53 PDT From: Gregor J. Kiczales Subject: Re: user interface macros To: Jon L White Cc: mop.pa@Xerox.COM In-Reply-To: <9005072251.AA05025@ptl-club> Message-Id: <19900508185349.0.GREGOR@SPIFF.parc.xerox.com> Date: Mon, 7 May 90 15:51:53 PDT From: Jon L White Date: Fri, 27 Apr 90 17:08:50 PDT From: Jon L White Rather, I think the only point of mentioning the expansion of the definer "user interface" macros is that our experience with metaobject creations over the past two years, via portable constructs, *had* to be limited to these macros. From a later reply, it looks like Gregor missed the point of that paragraph by stumbling over the first sentence. Maybe reading the last two sentences first will make it clearer. I must have been unclear about my comment on this sentence. What I didn't understand was why you thought "our experience" had been limited in this way. I believe that there is lots of experience with direct manipulation of anonymous metaobjects. If you read the rest of my reply to your original message, you will see that I agree with most of what you said. I said that we are only starting with macroexpansion to get it out of the way. I also said that the much more interesting stuff is the behavior of the anonymous metaobjects, and that is on its way. Also note that the behavior of the anonymous metaobjects is even below the ENSURE-XXX functions and generic functions. So, like the ui macros, their behavior must be discussed, but isn't where the real power is. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA25798; Tue, 8 May 90 16:24:53 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 08 MAY 90 16:04:01 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 08 MAY 90 16:00:03 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04750; Tue, 8 May 90 16:00:54 PDT Date: Tue, 8 May 90 16:00 PDT From: Gregor J. Kiczales Subject: intro material To: mop.pa@Xerox.COM Message-Id: <19900508230004.3.GREGOR@SPIFF.parc.xerox.com> This message includes more new MOP material for review. Included are the Introduction (which will need more work later), the overview of metaobjects, the specified class structure and constraints on user specialization and implementation flexibility. This material goes at the beginning of the full document and the macroexpansion section immediately follows it. The file arisia.xerox.com: /pcl/mop/intro.ps is a postscript version of this material. This message contains the TeX source. Comments please. ---------------- \beginSection{Introduction} The first two chapters of this specification describe the standard Programmer Interface for the Common Lisp Object System (CLOS). This chapter presents the CLOS Metaobject Protocol: a description of CLOS as an extensible CLOS program. In this description, the fundamental components of CLOS programs (classes, generic functions, methods and method combinations) are represented by first-class objects. The behavior of CLOS is provided by these objects, or more precisely by methods specialized to the classes of these objects. Because these objects represent pieces of CLOS programs, and because their behavior provides the behavior of the CLOS language itself, they are considered meta-level objects. In this document, the term {\bit metaobject} is used to refer precisely to an object which represent a CLOS class, slot definition, generic function, method or method combination. The protocol followed by the metaobjects to provide the behavior of CLOS is called the {\bit CLOS Metaobject Protocol}. \endSection%{Introduction} \beginSection{Metaobjects} For each kind of program element there is a corresponding {\bit basic metaobject class}. These are the classes: {\bf class}, {\bf slot-definition}, {\bf generic-function}, {\bf method} and {\bf method-combination}. Any metaobject must be an instance of a subclass of exactly one of these classes. The results are undefined if an attempt is made to define a class which is a subclass of more than one basic metaobject class. Each metaobject represents one program element. Associated with each metaobject is the information required to serve its role. This includes information that might be provided directly in a user interface macro such as {\bf defclass} or {\bf defmethod}. Also included is indirect information such as that computed from class inheritance or the full set of methods associated with a generic function. Much of the information associated with a metaobject is represented using other metaobjects. This interconnected structure of metaobjects parallels that of the directed acyclic class graph and associated methods and generic functions. This section provides an overview of this structure by presenting a partial enumeration of the kinds of information associated with each kind of metaobject. \beginSubsection{Classes} A class metaobject determines the structure and behavior of its instances. Associated with a class metaobject is its name, information describing its place in the directed acyclic graph of classes, its slots, its options, its documentation and information about the methods which mention this class as a specializer. \beginlist \item{\bull} The name is available as a symbol. \item{\bull} The direct subclasses, direct superclasses and class precedence list are available as lists of class metaobjects. \item{\bull} The slots defined directly in the class are available as a list of direct slot definition metaobjects. The slots which are accessible in instances of the class are available as a list of effective slot definition metaobjects. \item{\bull} The documentation is available as a string. \item{\bull} The methods which use the class as a specializer, and the generic functions associated with those methods are available as lists of method and generic function metaobjects respectively. \endlist \endSubsection%{Classes} \beginSubsection{Slot Definitions} A slot definition metaobject contains information about the definition of a slot. There are two kinds of slot definition metaobjects. A direct slot definition metaobject is used to represent the direct definition of a slot in a class. This corresponds roughly to the slot specifiers found in {\bf defclass} forms. An effective slot definition metaobject is used to represent information, including inherited information, about a slot which is accessible in instances of a particular class. Associated with each class metaobject is a list of direct slot definition metaobjects representing the slots defined directly in the class. Also associated with each class metaobject is a list of effective slot definition metaobjects representing the set of slots accessible in instances of that class. Certain kinds of information is associated with both direct and effective slot definitions. \beginlist \item{\bull} The name, allocation, and type are available as forms that could appear in a {\bf defclass} form. \item{\bull} The initform, if there is one, is available as a form that could appear in a {\bf defclass} form. The initform together with its lexical environment is available as a function of no arguments which, when called, returns the result of evaluating the initform in its lexical environment. This is called the initfunction of the slot. \item{\bull} The slot filling initialization arguments are available as a list of symbols. \item{\bull} The documentation is available as a string. \endlist Certain other information is only associated with direct slot definition metaobjects. This information applies only to the direct definition of the slot in the class, it is not inherited. \beginlist \item{\bull} The function specifiers of those generic functions for which there are automatically generated reader and writer methods. This information is available as lists of function specifiers. The so-called accessors specified in the {\bf defclass} form are broken down into their equivalent readers and writers in the direct slot definition. \endlist Information, including inherited information, which applies to the definition of a slot in a particular class in which it is accessible is associated with effective slot definition metaobjects. \beginlist \item{\bull} Limited information about the location of the slot in instances of the class. \item{\bull} A flag which permits optimization of slot access even in the presence of applicable user defined methods on the slot access generic functions. \endlist \endSubsection%{Slot Definitions} \beginSubsection{Generic Functions} Associated with each generic function metaobject is its name, a set of methods, a lambda list, a method combination type and information about options like documentation, argument precedence order and declarations. \beginlist \item{\bull} The name is available as a function specifier. \item{\bull} The methods associated with the generic function are available as a list of method metaobjects. \item{\bull} The lambda list is available as a list. \item{\bull} The method combination is available as a method combination metaobject. \item{\bull} The documentation is available as a string. \item{\bull} The argument precedence order is available as a permutation of those symbols from the lambda list which name the required arguments of the generic function. \item{\bull} The declarations are available as a list of declarations. \endlist \endSubsection%{Generic Functions} \beginSubsection{Methods} A method metaobject contains a list of qualifiers, a lambda list, a list of specializers, a function and a documentation string. \beginlist \item{\bull} The qualifiers are available as a list of of non-null atoms. \item{\bull} The lambda list is available as a list. \item{\bull} The specializers are available as a list whose elements are either class metaobjects, or lists of the form {\tt ({\bf eql} {\it object\/})}. \item{\bull} The function is available as a function. This function can be applied to arguments using the result of an appropriate call to the generic function {\bf method-function-applier}. \item{\bull} When the method is associated with a generic function, that generic function metaobject is available. A method can be associated with at most one generic function at a time. \item{\bull} The documentation is available as a string. \endlist \endSubsection%{Methods} \beginSubsection{Method Combinations} A method combination metaobject represents the information about the method combination being used by a generic function. A method combination metaobject contains information about both the type of method combination and the arguments being used with that type. \beginlist \item{\bull} The name of the method combination type is available as a symbol. This name may or may not be the same as the name of the class of the method combination metaobject. \item{\bull} The arguments to the method combination are available as a list. \item{\bull} The documentation is available as a string. \endlist \endSubsection%{Method Combinations} \endSection%{Metaobjects} \beginSection{Inheritance Structure of Metaobject Classes} The inheritance structure of the specified metaobject classes is shown in Figure~3-1. \boxfig {\dimen0=.5pc \tabskip \dimen0 plus .5 fil \halign to \hsize {#\hfil&#\hfil\cr \noalign{\vskip -9pt} \bf Metaobject Class&\bf Direct Superclasses\cr \noalign{\vskip 2pt\hrule\vskip 2pt} \bf structure-object&\bf (t)\cr \bf standard-object&\bf (t)\cr \bf metaobject&\bf (standard-object)\cr \bf dependee-mixin&\bf (standard-object)\cr \bf generic-function&\bf (metaobject function)\cr \bf standard-generic-function&\bf (generic-function dependee-mixin)\cr \bf method&\bf (metaobject)\cr \bf standard-method&\bf (method)\cr \bf standard-accessor-method&\bf (standard-method)\cr \bf standard-reader-method&\bf (standard-accessor-method)\cr \bf standard-writer-method&\bf (standard-accessor-method)\cr \bf method-combination&\bf (metaobject)\cr \bf slot-definition&\bf (metaobject)\cr \bf direct-slot-definition&\bf (slot-definition)\cr \bf effective-slot-definition&\bf (slot-definition)\cr \bf standard-slot-definition&\bf (slot-definition)\cr \bf structure-slot-definition&\bf (slot-definition)\cr \bf standard-direct-slot-definition&\bf (standard-slot-definition direct-slot-definition)\cr \bf standard-effective-slot-definition&\bf (standard-slot-definition effective-slot-definition)\cr \bf structure-direct-slot-definition&\bf (structure-slot-definition direct-slot-definition)\cr \bf structure-effective-slot-definition&\bf (structure-slot-definition effective-slot-definition)\cr \bf class&\bf (metaobject)\cr \bf built-in-class&\bf (class)\cr \bf structure-class&\bf (class)\cr \bf forward-referenced-class&\bf (class dependee-mixin)\cr \bf standard-class&\bf (class dependee-mixin)\cr \bf funcallable-standard-class&\bf (class dependee-mixin)\cr \noalign{\vskip -9pt} }} \caption{} \endfig Direct superclass relationships among the specified metaobject classes. The class of every class shown is {\bf standard-class} except for the class {\bf t} which is an instance of the class {\bf built-in-class} and the classes {\bf generic-function} and {\bf standard-generic-function} which are instances of the class {\bf funcallable-standard-class}. \newpage The basic metaobject classes ({\bf class}, {\bf slot-definition}, {\bf generic-function}, {\bf method} and {\bf method-combination}) capture the most basic behavior of each kind of metaobject. They are not themselves intended to be instantiated. The results are undefined if an attempt is made to make an instance of one of these classes with {\bf make-instance}. The classes {\bf standard-class}, {\bf standard-direct-slot-definition}, {\bf standard-effective-slot-definition}, {\bf standard-method}, and {\bf standard-generic-function} are called {\bit standard metaobject classes}. For each kind of metaobject, this is the class the user interface macros presented in Chapters 1 and 2 use by default. The default class of method combination objects is not specified, but is always the class {\bf method-combination} or one of its subclasses. The classes {\bf built-in-class}, {\bf structure-class}, {\bf funcallable-standard-class} and {\bf forward-referenced-class} are special purpose metaclasses described in the section ``Special Metaclasses''. The classes {\bf standard-object} and {\bf structure-object} capture default behavior for instances of {\bf standard-class} and {\bf structure-class} respectively. The class {\bf standard-object} is the the default superclass for standard classes; the class {\bf structure-object} is the default superclass for structure classes. \beginSubSection{Implementation and User Specialization} The purpose of the Metaobject Protocol is to provide users with a powerful mechanism for extending and customizing the basic behavior of the Common Lisp Object System. As an object-oriented description of the basic CLOS behavior, the Metaobject Protocol makes it possible to create these extensions by defining specialized subclasses of pre-existing metaobject classes. The Metaobject Protocol provides this capability without interfering with the implementor's ability to develop high-performance implementations. This balance between user extensibility and implementor freedom is mediated by placing explicit restrictions on each. These restrictions are presented in this section. The following additional terminology is used to present these restrictions: \beginlist \item{\bull} Class, generic function and method definitions are divided into three categories. Definitions included in this document are called {\bit specified}; definitions defined by an implementation but not mentioned in this document are called {\bit implementation-specific}; and definitions which are part of a portable program are called {\bit portable}. \item{\bull} A class $I$ is {\bit interposed} between two other classes $C\sub{1}$ and $C\sub{2}$ if and only if there is some path, following direct superclasses, from the class $C\sub{1}$ to the class $C\sub{2}$ which includes $I$. \item{\bull} A method is {\bit specialized to} a class if and only if that class is in the list of specializers associated with the method; and the method is in the list of methods associated with some generic function. \item{\bull} In a given implementation, a specified method is {\bit promoted} to an implementation-specific class if and only if one or more of the specializers of the method is an implementation-specific superclass of the class listed in this specification. \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit shadows} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and when $M\sub{2}$ is invoked, {\bf call-next-method} is called from within its body. \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit overrides} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and when $M\sub{2}$ is invoked, {\bf call-next-method} is not called from within its body. \endlist \beginsubsubsection{Restrictions on Implementations} Implementations are allowed to modify the structure of specified classes and methods. Typically, this will mean one or more of: the interposition of implementation-specific classes; the promotion of specified methods; and the consolidation of two or more specified methods into a single method specialized to interposed classes. But, this description permits any implementation modifications provided provided that for any portable class $C\sub{\hbox{p}}$ that is a subclass of one or more specified classes $C\sub{0} \ldots C\sub{i}$, the following are true: \beginlist \item{\bull} In the class precedence of $C\sub{\hbox{p}}$, the classes $C\sub{0} \ldots C\sub{i}$ appear in the same order as they would have had no implementation-specific modifications been made. \item{\bull} The method applicability of any specified generic function is the same in terms of behavior as it would had no implementation-specific changes been made. This includes specified generic functions which have had portable methods added. In this context, the expression ``the same in terms of behavior'' means that methods with the same behavior as those specified. \item{\bull} Implementations are always free to define implementation-specific {\bf :before} and {\bf :after} methods on specified generic functions. Implementations are also free to define implementation-specific {\bf :around} methods with shadowing behavior. \item{\bull} No portable class $C\sub{\hbox{p}}$ inherits from a specified class any slot with a name accessible in the {\bf common-lisp-user} package. \endlist \beginsubsubsection{Restrictions on Portable Programs} Portable programs are free to define subclasses of specified classes, and are permitted to define methods on specified generic functions, with the following restrictions. The results are undefined if any of these restrictions is violated. \beginlist \item{\bull} Portable programs must not redefine any specified classes, generic functions, methods or method combination. Any method, defined by a portable program on a specified generic function, must have at least one specializer which is not a specified class. \item{\bull} Specified methods can be shadowed unless the description of the method explicitly prohibits this. Any restrictions on the value the shadowing method must return are explicitly mentioned in the description of the generic function. \item{\bull} Specified methods can be overridden only when the description of the method explicitly allows this. Typically, when a method is allowed to be overridden, a small number of related will need to be overridden as well. An example of this is the specified methods on the generic functions {\bf add-dependent}, {\bf remove-dependent} and {\bf map-dependents}. Overriding a specified method on one of these generic functions requires that the corresponding method on the other two generic functions be overridden as well. \item{\bull} Methods on portable metaobject classes must be defined before any instances of those classes (or any subclasses) are created, either directly or indirectly by a call to {\bf make-instance}. Methods can be defined after instances are created by {\bf allocate-instance} however. Portable metaobject classes cannot be redefined. \beginImplNote The purpose of this last bullet is to permit implementations to provide performance optimizations by analyzing, at the time the first instance of a metaobject class is initialized, what portable Metaobject Protocol methods will be applicable to it. This can make it possible to elide calls to those Metaobject Protocol generic functions which will have no applicable portable methods. \endImplNote \endlist \endsubsubsection%{Restrictions on Portable Programs} \endSubSection%{Implementation and User Specialization} \endSection%{Inheritance Structure of Metaobject Classes} Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA07953; Wed, 9 May 90 00:09:05 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 09 MAY 90 00:06:41 PDT Return-Path: Received: from arisia.Xerox.COM ([13.1.100.206]) by Xerox.COM ; 09 MAY 90 00:05:12 PDT Received: from LUCID.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA07916; Wed, 9 May 90 00:05:25 -0700 Received: from ptl-club ([192.31.212.51]) by heavens-gate.lucid.com id AA21822g; Wed, 9 May 90 00:04:36 PDT Received: by ptl-club id AA06213g; Wed, 9 May 90 00:04:12 PDT Date: Wed, 9 May 90 00:04:12 PDT From: Jon L White Message-Id: <9005090704.AA06213@ptl-club> To: gregor@parc.xerox.com Cc: mop.pa@arisia.Xerox.COM In-Reply-To: Gregor J. Kiczales's message of Tue, 8 May 90 11:53 PDT <19900508185349.0.GREGOR@SPIFF.parc.xerox.com> Subject: user interface macros re: I must have been unclear about my comment on this sentence. What I didn't understand was why you thought "our experience" had been limited in this way. I believe that there is lots of experience with direct manipulation of anonymous metaobjects. Well, here is your full, exact comment: Date: Wed, 2 May 90 16:13 PDT From: Gregor J. Kiczales Date: Fri, 27 Apr 90 17:08:50 PDT From: Jon L White . . . Rather, I think the only point of mentioning . . . I don't have any idea what this sentence means. [which indeed looks more like a boggling than a rebuttal.] The relevant subclause in that first sentence, which you probably overlooked, is underlined here below: . . . is that our experience with metaobject creations over the past two years, via portable constructs, *had* to be limited ... -------- The only portable constructs -- i.e., the only ones in 88-002R -- are the ui macros. So, as you say, onwards to "the real power", down in the creation and initialization protocols for the various metaobjects. -- JonL -- Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA08225; Wed, 9 May 90 11:29:16 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 09 MAY 90 10:06:36 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 09 MAY 90 10:04:59 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 791873; 9 May 90 13:05:05 EDT Date: Wed, 9 May 90 13:06 EDT From: Moon@STONY-BROOK.SCRC.Symbolics.COM, Cyphers@STONY-BROOK.SCRC.Symbolics.COM Sender: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: intro material To: Gregor J. Kiczales Cc: mop.pa@Xerox.COM In-Reply-To: <19900508230004.3.GREGOR@SPIFF.parc.xerox.com> Message-Id: <19900509170637.2.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No Commenting on this went pretty quickly. Indented material is an excerpt from the TeX source, provided to give context. References to Symbolics CLOS in many cases refer to the undocumented and unsupported metaobject protocol in our implementation, so these aren't necessarily things that we would be extremely resistant to changing. Moon noticed some typos and garbled English, which it would be too much trouble to report. If you don't have a local copy editor, let me know and I'll mail you a marked up hardcopy. This implies that class names must be symbols, which contradicts 88-002R and current practice. This implies that class, generic function, method, method combination, and slot definition documentation must be a string, but documentation can be NIL or a string. What you call METAOBJECT, Symbolics CLOS calls META-OBJECT. We don't know which spelling is more correct English usage, but switching to METAOBJECT isn't a problem for us. This document consistently uses the term "function specifier" but X3J13 uses the term "function name" for the same thing. 88-002R uses "function name" under DEFCLASS but "function specifier" under DEFGENERIC and DEFMETHOD. When 88-002R's writeup for DEFMETHOD was put into chapter 6 of the ANSI CL draft, "function specifier" was changed to "function name", so the latter seems to be the preferred term. The inheritance structure table shows that STANDARD-GENERIC-FUNCTION is a subtype of STANDARD-OBJECT. This is true in Symbolics CLOS also, but Moon wonders if it's really right, since STANDARD-OBJECT is supposed to supply the methods for objects of metaclass STANDARD-CLASS, and generic functions do not have that metaclass. It seems like you would at least need a class analogous to STANDARD-OBJECT, which can override any unwanted methods inherited from STANDARD-OBJECT; in Symbolics CLOS there are classes named CLOS-INTERNALS::DISPATCHING-FUNCALLABLE-INSTANCE and CLOS-INTERNALS:FUNCALLABLE-INSTANCE which sort-of fill this role; there doesn't seem to be anything at all like this in the inheritance structure table. Perhaps there should be, I don't know. There was also some inconclusive X3J13 discussion of whether a class whose metaclass is a subclass of STANDARD-CLASS must get STANDARD-OBJECT as a superclass, or whether STANDARD-OBJECT is only a mandatory superclass when the metaclass is exactly STANDARD-CLASS. In any case this issue ought to be discussed in the document and the rationale for whatever is decided set forth. Is interposition of metaclasses allowed? I.e. when the document says the class of GENERIC-FUNCTION is FUNCALLABLE-STANDARD-CLASS, does this mean the class must be exactly FUNCALLABLE-STANDARD-CLASS, or can it be an implementation-specific subclass of FUNCALLABLE-STANDARD-CLASS? The document should say yes or no on this issue. The inheritance structure table shows DIRECT and EFFECTIVE subclasses of STRUCTURE-SLOT-DEFINITION, but these were not needed in Symbolics CLOS. I'm not positive of the reason, but it seems to be that structure classes do not have separate direct slots; because of the way DEFSTRUCT is specified, inheritance is finalized during the expansion of the DEFSTRUCT macro, and so a structure class only has effective slots. Also remember that structure slots don't have accessors in the same way that standard slots have them. I don't presently have a concrete suggestion here. It is a mistake that the base class of all CLOS methods is also the class used for things defined with DEFMETHOD. There should be a class like STANDARD-USER-METHOD which has STANDARD-METHOD as a superclass. Why? There are methods which are applicable to things defined with DEFMETHOD which aren't applicable to accessor methods. For example, what is METHOD-FUNCTION of an accessor method? In our implementation, it is meaningless (we return NIL). \item{\bull} The name, allocation, and type are available as forms that could appear in a {\bf defclass} form. These aren't forms. Remember, forms are things that get evaluated. Just a day or two ago I was wondering why the allocation isn't reflected in the class of the slot definition instead of as an attribute of the slot definition. \item{\bull} A flag which permits optimization of slot access even in the presence of applicable user defined methods on the slot access generic functions. Is "permits" the right word? Perhaps "controls" or "influences"? Need to see the documentation of what this is about, to know. \item{\bull} The methods associated with the generic function are available as a list of method metaobjects. Also need the list of initial methods (the ones that come from the defgeneric). The reason is that if the list of initial methods in a DEFGENERIC changes, the ones that are no longer in the DEFGENERIC should go away, unless they have been redefined with DEFMETHOD. \item{\bull} The function is available as a function. This function can be applied to arguments using the result of an appropriate call to the generic function {\bf method-function-applier}. What is method-function-applier? We can't evaluate this without seeing the documentation of that. \item{\bull} When the method is associated with a generic function, that generic function metaobject is available. A method can be associated with at most one generic function at a time. Mention that if the method is not associated with a generic function, then the method's generic function is NIL. \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit shadows} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and when $M\sub{2}$ is invoked, {\bf call-next-method} is called from within its body. \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit overrides} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and when $M\sub{2}$ is invoked, {\bf call-next-method} is not called from within its body. In "standard" usage, the word "shadow" is synonymous with "override", so it's dangerous to use the two words to mean two different things. See CLtL p.38 and the ANSI CL draft glossary (a document I only refer to when I agree with it, apparently!). You should find a different word for the first of the two bullets; the only word I was able to think of right now is "wrap". Also, these descriptions cannot be complete since they say nothing about the methods' parameter specializers. I think M2 can only override or (shadow) M1 when both methods are applicable and M2 is earlier in the applicable method precedence order. What I just said has a subtle bug, because when the specializers are equal and the qualifiers are different, the relative position in the method precedence order is explicitly unspecified. You'd need to say something like: if they had the same qualifiers then M2 would be earlier than M1 or at the same position as M1 in the applicable method precedence order. \item{\bull} No portable class $C\sub{\hbox{p}}$ inherits from a specified class any slot with a name accessible in the {\bf common-lisp-user} package. What if it inherits a slot from an interposed class? What if the slot name is in the keyword package, or otherwise exported by a specified package but not accessible in the COMMON-LISP-USER package? For example, suppose the slot is named IF, the implementation has two versions of IF, one in COMMON-LISP and another implementation dependent one, and COMMON-LISP-USER uses the implementation dependent one. Then a user program in its own package that doesn't :use the implementation-dependent package would get shafted by the slot named IF, but your restriction would not be violated by the implementation. It would be better to use the standard wording for symbol package restrictions (see our comments on the previous MOP installment) instead of inventing new wording that has subtle bugs. \item{\bull} Methods on portable metaobject classes must be defined before any instances of those classes (or any subclasses) are created, either directly or indirectly by a call to {\bf make-instance}. Methods can be defined after instances are created by {\bf allocate-instance} however. Portable metaobject classes cannot be redefined. \beginImplNote The purpose of this last bullet is to permit implementations to provide performance optimizations by analyzing, at the time the first instance of a metaobject class is initialized, what portable Metaobject Protocol methods will be applicable to it. This can make it possible to elide calls to those Metaobject Protocol generic functions which will have no applicable portable methods. \endImplNote Any development-oriented implementation needs to allow for patching of metaclasses and metaclass methods. Certainly we've done extensive patching of that type in Symbolics CLOS. However, it's true that for programs to be portable to delivery-oriented implementations they shouldn't depend on being able to change metaclasses and metaclass methods. Should they even be allowed to change non-meta classes and methods in delivery situations? Is the caveat about ALLOCATE-INSTANCE because the implementation might call it too soon? I don't see why the user should be allowed to call it before all the methods are defined. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10360; Wed, 9 May 90 12:47:36 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 09 MAY 90 12:39:57 PDT Return-Path: Received: from piglet.parc.xerox.com ([13.1.100.229]) by Xerox.COM ; 09 MAY 90 12:38:39 PDT Received: from spiff.parc.Xerox.COM by piglet.parc.xerox.com with SMTP (5.61+/IDA-1.2.8/gandalf) id AA08341; Wed, 9 May 90 12:38:51 PDT Date: Wed, 9 May 90 12:38 PDT From: Gregor J. Kiczales Subject: Re: intro material To: Moon@STONY-BROOK.SCRC.Symbolics.COM, Cyphers@STONY-BROOK.SCRC.Symbolics.COM Cc: mop.pa@Xerox.COM In-Reply-To: <19900509170637.2.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Message-Id: <19900509193801.0.GREGOR@SPIFF.parc.xerox.com> Date: Wed, 9 May 90 13:06 EDT From: Moon@STONY-BROOK.SCRC.Symbolics.COM, Cyphers@STONY-BROOK.SCRC.Symbolics.COM Thanks for getting comments back so quickly. This is not a complete response to your message. I am only responding to fix a glaring editing I made which you pointed out. I wanted other people to have this fix before they sent their comments later today :-) ... TeX source for definitions of override and shadow ... Also, these descriptions cannot be complete since they say nothing about the methods' parameter specializers. The glory of text editors is that I was able to make the same mistake consistently. In each definition, insert the clause: "and for that set of arguments M2 is more specific than M1;" so, the definitions should be: \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit shadows} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and for that set of arguments $M\sub{2}$ is more specific than $M\sub{1}$; and when $M\sub{2}$ is invoked, {\bf call-next-method} is called from within its body. \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit overrides} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and for that set of arguments $M\sub{2}$ is more specific than $M\sub{1}$; and when $M\sub{2}$ is invoked, {\bf call-next-method} is not called from within its body. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10629; Wed, 9 May 90 12:57:17 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 09 MAY 90 12:51:06 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 09 MAY 90 12:49:15 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 792077; 9 May 90 15:49:03 EDT Date: Wed, 9 May 90 15:50 EDT From: David A. Moon Subject: Re: intro material To: Gregor J. Kiczales Cc: mop.pa@Xerox.COM In-Reply-To: <19900509193801.0.GREGOR@SPIFF.parc.xerox.com> Message-Id: <19900509195037.2.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No Date: Wed, 9 May 90 12:38 PDT From: Gregor J. Kiczales This is not a complete response to your message. I am only responding to fix a glaring editing I made which you pointed out. In each definition, insert the clause: "and for that set of arguments M2 is more specific than M1;" OK. Somewhere in our comments it says why that doesn't quite work, don't overlook that. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA17640; Thu, 17 May 90 04:54:25 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 17 MAY 90 02:04:11 PDT Sender: "Nicolas_Graube.EuroPARC"@Xerox.COM Date: 17 May 90 02:03:36 PDT (Thursday) Subject: Re: intro material From: "Nicolas_Graube.EuroPARC"@Xerox.COM To: mop.PA@Xerox.COM In-Reply-To: Gregor.pa's message of 9 May 90 00:00 BST Message-Id: <900517-020411-11923@Xerox> Some comments about the ``intro material''. Section: Metaobjects. The limitation on metaobject basic classes seems that these are abstract classes (limitation expressed by ``Any metaobject must be an instance of a subclass of ...'').This becomes clear inside the section ``Inheritance Structure of Metaobject Classes''. Cannot you use the term abstract classes in order to qualify them directly at the beginning? SubSection: Classes. Is it possible to give a clear explanation of the term ``structure''. Is it only concerned with the number of slot? Nothing is said about the role of the class of the class. Furthermore the term class metaobject is very misleading as one can interpreted it as the metaclass... SubSection: Slot Definitions. I do not know if the following paragraph of the Subsection on Slot Definition is necessary as the information was already provided in the previous section: Associated with each class metaobject is a list of direct slot definition metaobjects representing the slots defined directly in the class. Also associated with each class metaobject is a list of effective slot definition metaobjects representing the set of slots accessible in instances of that class. SubSection: Methods. Omitting information about generic function in the first sentence is a little bit confusing at first, can you add something like, ``and a reference to a generic function if any'' to the sentence: A method metaobject contains a list of qualifiers, a lambda list, a list of specializers, a function and a documentation string. SubSection: Method Combinations. \item{\bull} The name of the method combination type is available as a symbol. This name may or may not be the same as the name of the class of the method combination metaobject. It seems that Method Combinations classes are viewed as classes with only one instance, which will be reinforce by the merging of the name associated to the method-combination (an instance) and the name of the class depicting this combination. Section: Inheritance Structure of Metaobject Classes. The class of every class shown is {\bf standard-class} except for the class {\bf t} which is an instance of the class {\bf built-in-class} and the classes {\bf generic-function} and {\bf standard-generic-function} which are instances of the class {\bf funcallable-standard-class}. Why {\bf Class} is not the root of the instantiation graph? It seems like this class is more primitive than {\bf Standard-class}. Considering {\bf Class} as the instantiation's root enables the consideration of a small kernel on top of which CLOS can be derived (supporting the idea that CLOS is only a possible paradigm inside the Common-Lisp Object System, and thus enabling the derivation of some other by inheriting from this kernel). The adjonction of the sentence "and for that set of arguments M2 is more specific than M1;" makes things clearer on the ``shadow'' and ``override''. Finally I do agree on Moon's comment about the unecessity of two slot-definition classes for Structure, one seems sufficient. Nicolas Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10425; Sun, 20 May 90 10:14:11 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 20 MAY 90 10:06:27 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 20 MAY 90 10:06:05 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA09445; Sun, 20 May 90 10:06:19 PDT Message-Id: <9005201706.AA09445@spade.parc.xerox.com> Date: Sun, 20 May 90 10:06:19 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: mop.pa@Xerox.COM Subject: mailer lossage Line-Fold: NO If you send mail to the MOP list anytime between Thursday PM and Sunday AM, you should resend it. Our Arpanet Gateway machine lost a disk drive. P.S. While I have your attention, if you send me mail directly in that time, please send it again too. Thanks Gregor Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26748; Tue, 22 May 90 08:40:03 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 22 MAY 90 08:35:40 PDT Return-Path: Received: from NSFnet-Relay.AC.UK ([128.86.8.6]) by Xerox.COM ; 22 MAY 90 08:34:51 PDT Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK via Janet with NIFTP id aa27634; 22 May 90 15:19 BST Received: from aldham.cl.cam.ac.uk by gnnt.Cl.Cam.AC.UK id aa05375; 22 May 90 15:14 BST Received: by uk.ac.cam.cl.aldham (5.57/SMI-3.0DEV3) id AA01536; Tue, 22 May 90 15:14:24 +0100 Date: Tue, 22 May 90 15:14:24 +0100 From: jac%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK Message-Id: <9005221414.AA01536@uk.ac.cam.cl.aldham> To: mop.PA@Xerox.COM Subject: Slot-definition-location From Richard Barber, Procyon Research Ltd, Cambridge, UK In the section in MOP draft number 10, 'readers for slot definition objects', slot-definition-location is specified as having a single argument, an effective-slot-definition. I would like to see this generic function have 2 arguments (in order to give implementors more flexibility in how they implement slot-definitions in a class). The first argument to the function should be an effective-slot-definition as before, and the second the class in which the effective-slot-definition occurs. This would make sense since effective-slot-definitions are closely tied in with the class in which they occur - no two appropriate effective slots in a single class being allowed to have the same location. This change would be of no extra cost to the user. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA27390; Tue, 22 May 90 09:09:23 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 22 MAY 90 09:08:42 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 22 MAY 90 09:07:39 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA10273; Tue, 22 May 90 09:07:42 PDT Message-Id: <9005221607.AA10273@spade.parc.xerox.com> Date: Tue, 22 May 90 09:07:42 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: jac%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK Cc: mop.PA@Xerox.COM In-Reply-To: jac%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK's message of Tue, 22 May 90 15:14:24 +0100 <9005221414.AA01536@uk.ac.cam.cl.aldham> Subject: Re: Slot-definition-location Line-Fold: NO Date: Tue, 22 May 90 15:14:24 +0100 From: jac%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK >From Richard Barber, Procyon Research Ltd, Cambridge, UK In the section in MOP draft number 10, 'readers for slot definition objects', slot-definition-location is specified as having a single argument, an effective-slot-definition. I would like to see this generic function have 2 arguments (in order to give implementors more flexibility in how they implement slot-definitions in a class). The first argument to the function should be an effective-slot-definition as before, and the second the class in which the effective-slot-definition occurs. It makes sense for me to answer this comment about the old draft now because I hope to send out the function pages including the slot inheritance protocol later today. These pages won't include slot-definition-location, but will include compute-slots and compute-effective-slot-definition. I don't think the change you propose is needed because effective slot definitions are already computed for one class only. That is, the effective slot definition represents the information about the slot as it appears in a particular class. So, the extra information you propose adding to the call to this accessor can already be in the effective slot definition object. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10821; Mon, 4 Jun 90 12:03:16 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 04 JUN 90 11:14:57 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 04 JUN 90 09:58:56 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA14111; Sun, 3 Jun 90 17:43:55 PDT Message-Id: <9006040043.AA14111@spade.parc.xerox.com> Date: Sun, 3 Jun 90 17:43:55 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: MOP.pa@Xerox.COM Subject: /ftp/pcl/mop --> /pcl/mop Line-Fold: NO On arisia, if you are using anonymous FTP, the directory is called /pcl/mop, not /ftp/pcl/mop. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10826; Mon, 4 Jun 90 12:03:23 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 04 JUN 90 11:16:52 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 04 JUN 90 09:58:59 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA14098; Sun, 3 Jun 90 17:37:41 PDT Message-Id: <9006040037.AA14098@spade.parc.xerox.com> Date: Sun, 3 Jun 90 17:37:41 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: MOP.pa@Xerox.COM Subject: status Line-Fold: NO My next message will have the subject field a-to-c, and will be the TeX source of the `FUNCTI' pages for the generic functions ADD-DEPENDENT to COMPUTE-SLOTS (alphabetically). This is pages 27 through 49 of the current draft of the MOP. The file arisia.xerox.com:/ftp/pcl/mop/a-to-c.ps is Postscript source for these pages. Together with the material I just sent about class initialization, this material represents the hardest parts of the functi pages. All that remains of the function pages is: REMOVE-XXX ADD-XXX is in what I am sending. If we can agree on those, the remove ones should be easy. `readers' These are simple generic functions which just fetch a value associated with a metaobject. SLOT-XXX-USING-CLASS These are easy to write given agreement on what to say. What to say in this document is probably more than in Sandra's cleanup issue. I think we mostly agree already. METHOD-FUNCTION-APPLIER This is a performance inspired change to the method invocation protocol. Details forthcoming. ENSURE-XXX Most of the issues here already came up when I sent out the stuff on macroexpansion. FINALIZE-INHERITANCE I think we agree on this now. And some odds and ends like EXTRACT-LAMBDA-LIST, VALIDATE-SUPERCLASS etc. Danny, Jim and I are still optimistic and still slugging away. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10830; Mon, 4 Jun 90 12:03:29 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 04 JUN 90 11:16:53 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 04 JUN 90 09:59:02 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA14070; Sun, 3 Jun 90 16:56:54 PDT Message-Id: <9006032356.AA14070@spade.parc.xerox.com> Date: Sun, 3 Jun 90 16:56:54 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: MOP.pa@Xerox.COM Subject: initialization of class metaobjects Line-Fold: NO Following is the section from the `functi' pages that deals with the initialization of class metaobjects. This covers the use of MAKE-INSTANCE and REINITIALIZE-INSTANCE with class metaobjects. The file arisia.xerox.com:/ftp/pcl/mop/init.ps contains postscript source for this material. When you read this, please review not only the specific material about class metaobjects, but also the framework used to present it. That is what has taken most of the work in preparing this section. If this framework works, cranking out initialization of generic functions, methods, slot definitions and method combinations is easy. ---------------- \begincom{Initialization of Class Metaobjects}\ftype{} A class metaobject can be created by calling {\bf make-instance}. The initialization arguments establish the definition of the class. A class metaobject can be reinitialized by calling {\bf reinitialize-instance}. Some classes of class metaobject do not support reinitialization; in these cases, {\bf reinitialize-instance} signals an error. Initialization of a class metaobject must be done by calling {\bf make-instance} and allowing it to call {\bf initialize-instance}. Reinitialization of a class metaobject must be done by calling {\bf reinitialize-instance}. Portable programs must not call {\bf intialize-instance} directly to initialize a class metaboject. Portable programs must not call {\bf shared-intialize} directly to initialize or reinitialize a class metaboject. A description of the interpretation of each initialization argument is presented first, this is followed by a description of the special behavior of each of the specified classes of class metaobject. In these descriptions, the phrase ``this argument defaults to {\it value}'' means that when the initialization argument is not supplied, initialization or reinitialization proceeds as if {\it value} had been supplied. Whether this is done through the use of default initialization arguments is not specified. Whether any specified class of class metaobjects has default initialization arguments is not specified. Implementations are free to do so. Portable programs are free to define default initialization arguments on portable subclasses of the class {\bf class}. \beginlist \item{\bull} The {\bf :direct-superclasses} argument is a list of class metaobjects. Classes which do not support multiple inheritance signal an error if the list contains more than one element. An error is signalled if this value is not a proper list; or if it is the empty list; or if {\bf validate-superclass} returns false for any element of the list. When the class is being initialized, and this argument is not supplied, an error is signalled. If this argument is supplied, the generic function {\bf add-direct-subclass} is called once for each element of the list. When the class is being reinitialized, and this argument is not supplied, it defaults to the result of calling {\bf class-direct-superclasses} with the class metaobject as the argument. If this argument is supplied, the generic function {\bf remove-direct-subclass} is called once for each class in the result of calling {\bf class-direct-superclasses} but not in the list; and the generic function {\bf add-direct-subclass} is called once for each class which is in the list but not in the result of {\bf class-direct-superclasses}. \item{\bull} The {\bf :direct-slots} argument is a list of direct slot definition metaobjects. An error is signalled if this value is not a proper list or; if any element of the list is not an instance of the class {\bf direct-slot-definition} or one of its subclasses. If the class is being initialized, this argument defaults to false. If the class is being reinitialized, this argument defaults to the result of calling {\bf class-direct-slots} with the class metaobject as the argument. \item{\bull} The {\bf :direct-default-initargs} argument is a list of canonicalized default initargs. An error is signalled if this value is not a proper list; or if any element of the list is not a canonicalized default initarg. If the class is being initialized, this argument defaults to the empty list. If the class is being reinitialized, this argument defaults to the result of calling {\bf class-direct-default-initargs} with the class metaobject as the argument. \item{\bull} The {\bf :documentation} argument is a string or false. An error is signalled if this value is not a string or false. If the class is being initialized, this argument defaults to the empty list. If the class is being reinitialized, this argument defaults to the result of calling {\bf documentation} with the class metaobject as the argument. \endlist \vskip 2pc After the processing and defaulting of initialization arguments described above, the value of each initialization argument is associated with the metaobject. These values can then be accessed by calling the corresponding generic function. The correspondences are as follows: \boxfig {\dimen0=.75pc \tabskip \dimen0 plus .5 fil \halign to \hsize {#\hfil&\quad#\hfil\cr \noalign{\vskip -9pt} \bf Initialization Argument&\bf Generic Function\cr \noalign{\vskip 2pt\hrule\vskip 2pt} \bf :direct-superclasses&\bf class-direct-superclasses\cr \bf :direct-slots&\bf class-direct-slots \cr \bf :direct-default-initargs&\bf class-default-initargs \cr \bf :documentation&\bf documentation \cr \noalign{\vskip -9pt}}} \endfig \label Standard Classes: Standard classes support multiple inheritance and reinitialization. \label Structure Classes: Structure classes support single-inheritance. An error is signalled if {\bf initialize-instance} is called to initialize a structure class metaobject and the length of the {\bf :direct-superclasses} argument is greater than one. It is not specified whether structure classes support reinitialization. The results are undefined if {\bf reinitialize-instance} is called to reinitialize a structure class metaobject. \label Built-in Classes: Built-in classes cannot be created by the user, and cannot be reinitialized. An error is signalled if {\bf initialize-instance} or {\bf reinitialize-instance} are called to initialize or reinitialize a built-in class metaobject. \label Methods: It is not specified what methods provide the initialization and reinitialization behavior described above. Instead, the information needed to allow portable programs to specialize this behavior is presented in terms of a set of restrictions on the methods a portable program can define. These restrictions govern the methods that a portable program can define on the generic functions {\bf initialize-instance}, {\bf reinitialize-instance}, and {\bf shared-initialize}. These restrictions apply only to methods on these generic functions for which the first specializer is a subclass of the class {\bf class}. Other portable methods on these generic functions are not affected by these restrictions. The results are undefined if any of these restrictions are violated. \beginlist \item{\bull} Portable programs must not define methods on {\bf shared-initialize}. \item{\bull} Portable programs must not define primary methods on the generic function {\bf initialize-instance}. \item{\bull} Portable programs must not define primary methods on the generic function {\bf reinitialize-instance}. \item{\bull} Portable programs may define around methods on the generic function {\bf initialize-instance}, but these must be shadowing, not overriding methods. \item{\bull} Portable programs may define around methods on the generic function {\bf reinitialize-instance}, but these must be shadowing, not overriding methods. \item{\bull} A portable before method on the generic function {\bf initialize-instance} must assume that when it is run, the class metaobject has not been initialized. \item{\bull} A portable after method on the generic function {\bf initialize-instance} must assume that when it is run, the class metaobject has been completely initialized. \item{\bull} A portable before method on the generic function {\bf reinitialize-instance} must assume that when it is run, no reinitialization of the class metaobject has been done. \item{\bull} A portable after method on the generic function {\bf reinitialize-instance} must assume that when it is run, the class metaobject has been completely reinitialized. \endlist \endcom Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10836; Mon, 4 Jun 90 12:03:37 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 04 JUN 90 11:18:57 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 04 JUN 90 09:59:07 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA14105; Sun, 3 Jun 90 17:42:07 PDT Message-Id: <9006040042.AA14105@spade.parc.xerox.com> Date: Sun, 3 Jun 90 17:42:07 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: MOP.pa@Xerox.COM Subject: a-to-c Line-Fold: NO \begingfcom{add-dependent} \label Syntax: \Defgen {add-dependent} {metaobject dependent} \label Arguments: The {\it metaobject} argument is a class or generic function metaobject. The {\it dependent} argument is an object. \label Values: The value returned by this generic function is unspecified. \label Purpose: The generic function {\bf add-dependent} updates the set of dependents of {\it metaobject} to include {\it dependent}. If {\it dependent} is already in the set of dependents it is not added again (no error is signalled). The generic function {\bf map-dependents} can be called to access the set of dependents of a class or generic function. The generic function {\bf remove-dependent} can be called to remove an object from the set of dependents of a class or generic function. The effect of calling {\bf add-dependent} or {\bf remove-depedent} while a call to {\bf map-dependents} is in progress is unspecified. When {\it metaobject} is reinitialized by {\bf reinitialize-instance} each of its dependents is updated. This is done by calling {\bf map-dependents} so that {\bf update-dependent} can be called on each dependent. The situations in which {\bf add-dependent} is called are not specified. \label Methods: \Defmeth {add-dependent} {({\it class\/} standard-class) {\it dependent\/}} No behavior is specified for this method beyond that specified for the generic function. This method cannot be overridden unless the following methods are overridden as well: \begingroup\advance\leftskip 2pc \method{remove-dependent}{standard-class t}\hfil\break \method{map-dependents}{standard-class t} \par\endgroup \newpage \Defmeth {add-dependent} {({\it generic-function\/} standard-generic-function) {\it dependent\/}} No behavior is specified for this method beyond that specified for the generic function. This method cannot be overridden unless the following methods are overridden as well: \begingroup\advance\leftskip 2pc \method{remove-dependent}{standard-generic-function t}\hfil\break \method{map-dependents}{standard-generic-function t} \par\endgroup \label Remarks: Portable code must not use metaobjects themselves as dependents. Instead, portable programs which need to record a metaobject as a dependent, should encapsulate that metaobject in some other kind of object, and record that object as the dependent. This requirement prevents two portable programs, or a portable program and the implementation from inadvertently removing dependents recorded by one another. \label Example: This example shows a general facility for encapsulating metaobjects before recording them as dependents. The facility defines a basic kind of encapsulating object: an updater. Specializations of the basic class can be defined with appropriate special updating behavior. In this way, information about the updating required is associated with each updater rather than with the metaobject being updated. \screen! ;;; ;;; Updaters are used encapsulate any metaobject which needs updating ;;; when a given class or generic function is modified. RECORD-UPDATER ;;; is called to both create an updater and add it to the dependents of ;;; the class or generic functions. Methods on the generic function ;;; UPDATE-DEPENDENT, specialized to the specific class of updater do ;;; the appropriate update work. ;;; (defclass updater () ((dependee :initarg :dependee :reader dependee) (dependent :initarg :dependent :reader dependent))) (defun record-updater (class dependee dependent &rest initargs) (let ((updater (apply #'make-instance class :dependee dependee :dependent dependent initargs))) (add-dependent dependee updater) updater)) ;;; ;;; A FLUSH-CACHE-UPDATER simply flushes the cache of the dependent ;;; when it is updated. ;;; (defclass flush-cache-updater (updater) ()) (defmethod update-dependent ((updater flush-cache-updater) &rest args) (declare (ignore args)) (flush-cache (dependent updater))) \endscreen! \label See Also: ``The Dependent Maintenance Protocol'' {\bf remove-dependent} {\bf map-dependents} {\bf update-dependent} \endcom \begingfcom{add-direct-method} \label Syntax: \Defgen {add-direct-method} {specializer method} \label Arguments: The {\it specializer\/} argument is a method specializer. The results are undefined if it is not one of the specializers of {\it method\/}. The {\it method} argument is a method metaobject. \label Values: The value returned by this generic function is unspecified. \label Purpose: The generic function {\bf add-direct-method} is called to maintain a set of backpointers from a specializer to the set of methods specialized to it. When called, if {\it method} is already in the set, it is not added again (no error is signalled). This set can be accessed as a list by calling the generic function {\bf specializer-direct-methods}. Methods can be removed from the set by calling {\bf remove-direct-method}. The effect of calling {\bf add-direct-method} or {\bf remove-direct-method} on previously returned values of {\bf specializer-direct-methods} is unspecified. The generic function {\bf add-direct-method} is called by {\bf add-method} whenever a method is added to a generic function. It is called once for each of the specializers of the method. \label Methods: \Defmeth {add-direct-method} {\vtop{\hbox{({\it specializer} class)} \hbox{({\it method} method)}}} No behavior is specified for this method beyond that which is specified for the generic function. This method cannot be overridden unless the following methods are overridden as well: \begingroup\advance\leftskip 2pc \method{remove-direct-method}{class method}\hfil\break \method{specializer-direct-methods}{class} \par\endgroup \newpage \Defmeth {add-direct-method} {\vtop{\hbox{({\it specializer} cons)} \hbox{({\it method} method)}}} This method implements the behavior of the generic function for {\bf eql} specializers. When {\it specializer} is a list of the form {\bf(eql {\it object})}, {\it method} is added to a list of methods associated with {\it object}. This list is returned by \method{specializer-direct-methods}{cons}. If {\it specializer} is not a list of the form {\bf(eql {\it object})}, the behavior of this method is unspecified. This method cannot be overridden unless the following methods are overridden as well: \begingroup\advance\leftskip 2pc \method{remove-direct-method}{cons method}\hfil\break \method{specializer-direct-methods}{cons} \par\endgroup \label See Also: {\bf remove-direct-method} {\bf specializer-direct-methods} \endcom \begingfcom{add-direct-subclass} \label Syntax: \Defgen {add-direct-subclass} {superclass subclass} \label Arguments: The {\it superclass} argument is a class metaobject. The {\it subclass} argument is a class metaobject. \label Values: The value returned by this generic function is unspecified. \label Purpose: The generic function {\bf add-direct-subclass} is called to maintain a set of backpointers from a class to its direct subclasses. This generic function adds {\it subclass} to the set of direct subclasses of {\it superclass}. If {\it subclass} is already in the set it is not added again (no error is signalled). The generic function {\bf class-direct-subclasses} returns the set as a list. A class can be removed from the set by calling {\bf remove-direct-subclass}. The effect of calling {\bf add-direct-subclass} or {\bf remove-direct-subclass} on previously returned values of {\bf class-direct-subclasses} is unspecified. When a class is initialized, this generic function is called once for each direct superclass of the class. When a class is reinitialized, this generic function is called once for each added direct superclass of the class. The generic function {\bf remove-direct-subclass} is called once for each deleted direct superclass of the class. \label Methods: \Defmeth {add-direct-subclass} {\vtop{\hbox{({\it superclass\/} class)} \hbox{({\it subclass\/} class)}}} No behavior is specified for this method beyond that which is specified for the generic function. This method cannot be overridden unless the following methods are overridden as well: \begingroup\advance\leftskip 2pc \method{remove-direct-subclass}{class class}\hfil\break \method{class-direct-subclasses}{class} \par\endgroup \newpage \label See Also: {\bf remove-direct-subclass} {\bf class-direct-subclasses} \endcom \begingfcom{add-method} \label Syntax: \Defgen {add-method} {generic-function method} \label Arguments: The {\it generic-function\/} argument is a generic function metaobject. The {\it method\/} argument is a method metaobject. The lambda-list of the method function must be congruent with the lambda-list of the generic function, or an error is signaled. \label Values: The modified generic function is returned. The result of {\bf add-method} is {\bf eq} to the {\it generic-function\/} argument. \label Purpose: The generic function {\bf add-method} adds a method to the set of methods associated with a generic function. After adding the method to this set, {\bf compute-discriminating-function} is called and its result is installed by calling {\bf set-funcallable-instance-function}. The {\it generic-function} argument is destructively modified and returned as the the result. If the method metaobject is already associated with a generic function an error is signalled. The set of methods associated with the generic function can be accessed as a list by calling {\bf generic-function-methods}. A method can be removed from the set by calling {\bf remove-method}. The effect of calling {\bf add-method} or {\bf remove-method} on previous results returned by {\bf generic-function-methods} is unspecified. The generic function {\bf add-method} can be called by the user or the implementation. It is called whenever a method must be added to a generic function. \label Methods: \Defmeth {add-method} {\vtop{\hbox{({\it generic-function\/} standard-generic-function)} \hbox{({\it method\/} method)}}} If the given method agrees with an existing method of the generic function on parameter specializers and qualifiers, the existing method is replaced. See the section of Chapter 1 called ``Agreement on Parameter Specializers and Qualifiers'' for a definition of agreement in this context. This method cannot be overridden unless the following methods are overridden as well: \begingroup\advance\leftskip 2pc \method{remove-method}{standard-generic-function method}\hfil\break \method{generic-function-methods}{standard-generic-function} \par\endgroup \label See Also: Chapter 1 section --- ``Agreement on Parameter Specializers and Qualifiers'' {\bf remove-method} {\bf generic-function-methods} {\bf compute-discriminating-function} \endcom \begingfcom{allocate-instance} \label Syntax: \Defgen {allocate-instance} {class {\tt \&rest} {\it initargs\/}} \label Arguments: The {\it class\/} argument is a class metaobject. The {\it initargs\/} argument consists of alternating initialization argument names and values. \label Values: The value returned by {\bf allocate-instance} is a newly allocated instance. \label Purpose: The generic function {\bf allocate-instance} is called to create a new, uninitialized instance of a class. The interpretation of the concept of an ``unitialized instance'' depends on the method. Before allocating the new instance, {\bf class-finalized-p} is called to see if {\it class} has been finalized. If it has not been finalized, {\bf finalize-inheritance} is called before the new instance is allocated. \label Methods: \Defmeth {allocate-instance} {({\it class\/} standard-class) {\rest} {\it initargs}} The instance returned by this method has slots which are unbound. \vskip 1.6pc \Defmeth {allocate-instance} {({\it class\/} structure-class) {\rest} {\it initargs}} The instance returned by this method has slots with undefined values. \vskip 1.6pc \Defmeth {allocate-instance} {({\it class\/} built-in-class) {\rest} {\it initargs}} This method signals an error. \endcom \begingfcom{compute-applicable-methods} \label Syntax: \Defgen {compute-applicable-methods} {generic-function arguments} \label Arguments: The {\it generic-function} argument is a generic function metaobject. The {\it arguments} argument is a list of objects. \label Values: This generic function returns a possibly empty list of method metaobjects. \label Purpose: The generic function {\bf compute-applicable-methods} determines the method applicability of a generic function given a list of required arguments for the generic function. The returned list of method metaobjects is sorted by precedence order with the most specific method is first. If no methods are applicable to the supplied arguments the empty list is returned. When a generic function is invoked, the discriminating function must determine the ordered list of methods applicable to the arguments. Depending on the generic function and the arguments, this is done in one of three ways: using a memoized value; calling {\bf compute-applicable-methods-using-classes}; or calling {\bf compute-applicable-methods}. Refer to the description of {\bf compute-discriminating-function} for the details of this process. For any given generic function and set of arguments, if {\bf compute-applicable-methods-using-classes} returns a second value of true, the first value must be equal to the value returned by a corresponding call to {\bf compute-applicable-methods}. The results are undefined if this is not the case. The {\it arguments} argument must have at least as many elements as the generic function accepts required arguments. If fewer arguments are supplied, an error is signalled. \label Methods: \Defmeth {compute-applicable-methods} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{{\it arguments\/}}}} This method signals an error if any method of the generic function has a specializer which is not either a class metaobject or a list of the form {\bf(eql {\it object})}. Otherwise, this method computes the sorted list of applicable methods according to the rules described in the section of Chapter 1 called ``Method Selection and Combination''. This method can be overridden. Because of the consistency requirements between this generic function and {\bf compute-applicable-methods-using-classes}, doing so may require also overidding \method{compute-applicable-methods-using-classes}{standard-generic-function t}. \label See Also: ``Method Lookup Protocol'' {\bf compute-applicable-methods-using-classes} {\bf compute-discriminating-function} \endcom \begingfcom{compute-applicable-methods-using-classes} \label Syntax: \Defgen {compute-applicable-methods-using-classes} {generic-function classes} \label Arguments: The {\it generic-function} argument is a generic function metaobject. The {\it classes} argument is a list of class metaobjects. \label Values: This generic function returns two values. The first is a possibly empty list of method metaobjects. The second is either true or false. \label Purpose: The generic function {\bf compute-applicable-methods-using-classes} is called to attempt to determine the method applicability given only the classes of the required arguments to the generic function. If it is possible to completely determine the ordered list of applicable methods based only on the supplied classes, this generic function returns that list as its first value and true as its second value. The returned list of method metaobjects is sorted by precedence order, the most specific method is first. If no methods are applicable to the specified arguments the empty list is returned. If it is not possible to completely determine the ordered list of applicable methods based only on the supplied classes, this generic function returns an unspecified first value and false as its second value. When a generic function is invoked, the discriminating function must determine the ordered list of methods applicable to the arguments. Depending on the generic function and the arguments, this is done in one of three ways: using a memoized value; calling {\bf compute-applicable-methods-using-classes}; or calling {\bf compute-applicable-methods}. Refer to the description of {\bf compute-discriminating-function} for the details of this process. For any given generic function and set of arguments, if {\bf compute-applicable-methods-using-classes} returns a second value of true, the first value must be equal to the value returned by {\bf compute-applicable-methods}. The results are undefined if this is not the case. \newpage \label Methods: \Defmeth {compute-applicable-methods-using-classes} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{({\it classes\/} t)}}} If any method of the generic function has a specializer which is neither a class metaobject nor a list of the form {\bf(eql {\it object})}, this method returns an unspecified first value and false as its second value. In cases where the generic function has no methods with {\bf eql} specializers, or has no methods with {\bf eql} specializers which could be applicable to arguments of the supplied classes, this method returns the ordered list of applicable methods as its first value and true as its second value. Otherwise this method returns an unspecified first value and false as its second value. This method can be overridden. Because of the consistency requirements between this generic function and {\bf compute-applicable-methods}, doing so may require also overidding \method{compute-applicable-methods}{standard-generic-function t}. \label Remarks: This generic function exists to support extensions which modify the rules of method applicability but which base the new, modified rules only on the classes of the arguments to the generic function. Such extensions can be implemented by two methods, one on this generic function and another on {\bf compute-applicable-methods}. An extension which bases method applicability on properties of the arguments to the generic function other than their class, as is the case with {\bf eql} specializers, can be implemented in one of two ways. The first involves two methods definitions. One method on this generic function which returns a second value of false as appropriate together with a method on {\bf compute-applicable-methods} which computes the ordered set of applicable methods using the desired method applicability rules. The second involves definining a method on {\bf compute-discriminating-function}. The discriminating function returned by this method implements the desired method applicability rules directly without making any calls to {\bf compute-applicable-methods} or {\bf compute-applicable-methods-using-classes}. \label See Also: ``Method Lookup Protocol'' {\bf compute-applicable-methods} {\bf compute-discriminating-function} \endcom \begingfcom{compute-class-precedence-list} \label Syntax: \Defgen {compute-class-precedence-list} {class} \label Arguments: The {\it class} argument is a class metaobject. \label Values: The value returned by this generic function is a list of class metaobjects. \label Purpose: The generic-function {\bf compute-class-precedence-list} is called to determine the class precedence list of a class. The result is a proper list which contains each of {\it class} and its superclasses once and only once. The first element of the list is {\it class} and the last element is the class named {\bf t}. All methods on this generic function must compute the class precedence list as a function of the ordered direct superclasses of the superclasses of {\it class}. The results are undefined if the rules used to compute the class precedence list depend on any other factors. This generic function can be called by the user or the implementation. When a class is finalized, {\bf finalize-inheritance} calls this generic function and associates the returned value with the class metaobject. The value can then be accessed by calling {\bf class-precedence-list}. \label Methods: \Defmeth {compute-class-precedence-list} {({\it class} class)} This method computes the class precedence list according to the rules described in the section of Chapter 1 called ``Determining the Class Precedence List''. If the specified class or any of its superclasses is a forward referenced class an error is signalled. This method can be overridden. \label See Also: Chapter 1 section --- ``Determining the Class Precedence List'' {\bf finalize-inheritance} {\bf class-precedence-list} \endcom \begingfcom{compute-discriminating-function} \label Syntax: \Defgen {compute-discriminating-function} {generic-function} \label Arguments: The {\it generic-function} argument is a generic function metaobject. \label Values: The value returned by this generic function is a function. \label Purpose: The generic function {\bf compute-discriminating-function} is called to determine the discriminating function for a generic function. When a generic function is called, the discriminating function is called to implement the behavior of calling the generic function: determining the ordered set of applicable methods, determining the effective method, and running the effective method. To determine the ordered set of applicable methods, the discriminating function first calls {\bf compute-applicable-methods-using-classes}. If {\bf compute-applicable-methods-using-classes} returns a second value of false, the discriminating function then calls {\bf compute-applicable-methods}. When {\bf compute-applicable-methods-using-classes} returns a second value of true, the discriminating function is permitted to memoize the first returned value as follows. If the generic function is called again with required arguments which are instances of the same classes; and the generic function has not been reinitialized; and no method has been added to the generic function; and no method has been removed from the generic function; and for all the specializers of all the generic function's methods which are classes the class precedence list has not changed; for any such memoized value, no class precedence list of the required argument classes has changed; then the discriminating function may reuse the list of applicable methods without calling {\bf compute-applicable-methods-using-classes} again. Determination of the the effective method is done by calling {\bf compute-effective-method}. When the effective method is run, each method's function is called using the result of calling {\bf method-function-applier}. The result of {\bf compute-discriminating-function} is intended to be used as the discriminating function for {\it generic-function} and is intended to replace all previous discriminating functions for {\it generic-function}. The result of {\bf compute-discriminating-function} cannot be called directly with {\bf apply} or {\bf funcall}. Instead, once it has been installed with {\bf set-funcallable-instance-function}, the generic function itself can be called. Once {\bf compute-discriminating-function} is called, the result must be installed before {\it generic-function} is called again. Moreover the installed discriminating function must not subsequently be replaced by a previous result of {\bf compute-discriminating-function}. This generic function is called, and the result is installed by {\bf add-method}, {\bf remove-method}, {\bf initialize-instance} and {\bf reinitialize-instance}. \label Methods: \Defmeth {compute-discriminating-function} {({\it generic-function} standard-generic-function)} This method returns a discriminating function as described above. This method can be shadowed. The shadowing method is permitted to call {\bf call-next-method} and return a result which itself calls the result of this method. This method can be overridden. \label See Also: ``The Method Lookup Protocol'' {\bf compute-applicable-methods} {\bf compute-applicable-methods-using-classes} {\bf compute-effective-method} {\bf make-method-lambda} {\bf method-function-applier} \endcom \begingfcom{compute-effective-method} \label Syntax: \Defgen {compute-effective-method} {generic-function method-combination methods} \label Arguments: The {\it generic-function} argument is a generic function metaobject. The {\it method-combination} argument is a method combination metaobject. The {\it methods} argument is a list of method metaobjects. \label Values: This generic function returns two values. The first is an effective method. The second is a list of effective method options. \label Purpose: The generic function {\bf compute-effective-method} is called to determine the effective method from a sorted list of method metaobjects. The first value returned by this generic function is the effective method. The second is a list of effective method options, these have the same syntax and interpretation as the options argument to the long form of define method combination. This generic function can be called by the user or the implementation. It is called whenever a sorted list of applicable methods must be converted to an effective method. It is called by the result of \method {compute-discriminating-function} {standard-generic-function}. Because neither method nor method combination metaobjects can be reinitialized, the results of this generic function may be memoized. \label Methods: \Defmeth {compute-effective-method} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{({\it method-combination} standard-method-combination)} \hbox{{\it methods}}}} This method computes the effective method according to the rules of the method combination type implemented by {\it method-combination}. This method can be overridden. \vskip 1.6pc \Defmeth {compute-effective-method} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{({\it method-combination} standard-simple-method-combination)} \hbox{{\it methods}}}} This method computes the effective method according to the rules of the method combination type implemented by {\it method-combination}. This method can be overridden. \label See Also: ``Method Lookup Protocol'' Chapter 1 section --- ``Applying Method Combination to the Sorted List of Applicable Methods'' {\bf define-method-combination} {\bf compute-discriminating-function} \endcom \begingfcom{compute-effective-slot-definition} \label Syntax: \Defgen {compute-effective-slot-definition} {class name direct-slot-definitions} \label Arguments: The {\it class} argument is a class metaobject. The {\it name} argument is a slot name. The {\it direct-slot-definitions} argument is a list of direct slot definition metaobjects. \label Values: The value returned by this generic function is an effective slot definition metaobject. \label Purpose: This generic function determines the effective slot definition for each slot in a class. It is called by {\bf compute-slots} once for each slot accessible in instances of {\it class}. This generic function uses the supplied list of direct slot definition metaobjects to compute the inheritance of slot properties for a single slot. The returned effective slot definition represents the result of computing the inheritance. The class of the effective slot definition metaobject is determined by calling {\bf effective-slot-definition-class}. The effective slot definition is then created by calling {\bf make-instance}. It is not specified what initialization arguments are passed in this call to {\bf make-instance}. All implementation initialization of the effective slot definition will be done by implementation methods on {\bf shared-initialize}. (With the exception of the slot location which is done by {\bf compute-slots}.) \label Methods: \Defmeth {compute-effective-slot-definition} {\vtop{\hbox{({\it class} standard-class)} \hbox{{\it name}} \hbox{{\it superclass-slot-definitions}}}} This method implements the inheritance and defaulting of slot options following the rules described in the ``Inheritance of Slots and Options'' section of Chapter 1. This method signals an error if the value returned by the {\bf effective-slot-definition-class} the class {\bf standard-effective-slot-definition} or one of its subclasses. This method cannot be overridden; it can be shadowed, but the value returned by the shadowing method must be the value returned by this method. \vskip 1.6pc \Defmeth {compute-effective-slot-definition} {\vtop{\hbox{({\it class} structure-class)} \hbox{{\it name}} \hbox{{\it superclass-slot-definitions}}}} This method implements the inheritance and defaulting of slot options following the rules described for {\bf defstruct}. This method signals an error if the value returned by the {\bf effective-slot-definition-class} the class {\bf structure-effective-slot-definition} or one of its subclasses. This method cannot be overridden; it can be shadowed, but the value returned by the shadowing method must be the value returned by this method. \label See Also: {\bf compute-slots} {\bf effective-slot-definition-class} \endcom \begingfcom{compute-slots} \label Syntax: \Defgen {compute-slots} {class} \label Arguments: The {\it class} argument is a class metaobject. \label Purpose: This generic function computes a set of effective slot definition metaobjects for the class {\it class}. The result is a list of effective slot definition metaobjects: one for each slot that will be accessible in instances of {\it class}. This generic function proceeds in 4 steps: The first step collects the full set of direct slot definitions from the superclasses of {\it class}. The direct slot definitions are then collected into individual lists, one list for each slot name associated with any of the direct slot definitions. The slot names are compared with {\bf eql}. Each such list is then sorted into class precedence list order. Direct slot definitions coming from classes earlier in the class precedence list of {\it class} appear before those coming from classes later in the class precedence list. For each slot name, the generic function {\bf compute-effective-slot-definition} is called to compute an effective slot definition. The result of {\bf compute-slots} is a list of these effective slot definitions, in unspecified order. In the final step, the location for each effective slot definition is set. For more information on the slot definition locations, see the section ``Accessing Slots Directly''. \label Methods: \Defmeth {compute-slots} {({\it class} standard-class)} This method implements the specified behavior of the generic function. This method can be overriden. \vskip 1.6pc \Defmeth {compute-slots} {({\it class} structure-class)} This method implements the specified behavior of the generic function. \label See Also: {\bf compute-effective-slot-definition} {\bf effective-slot-definition-class} \endcom Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA00403; Mon, 4 Jun 90 21:39:24 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 04 JUN 90 15:05:02 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 04 JUN 90 13:34:13 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 803911; 4 Jun 90 16:34:00 EDT Date: Mon, 4 Jun 90 16:37 EDT From: David A. Moon Subject: status To: Gregor J. Kiczales Cc: MOP.pa@Xerox.COM In-Reply-To: <9006040037.AA14098@spade.parc.xerox.com> Message-Id: <19900604203720.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No FYI, I expect I will not be reading any of this, nor the paper from Jim des Rivieres that I received in the mail today, until after the X3J13 meeting. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA25788; Thu, 7 Jun 90 11:19:40 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 07 JUN 90 10:31:30 PDT Return-Path: Received: from NSFnet-Relay.AC.UK ([128.86.8.6]) by Xerox.COM ; 07 JUN 90 10:30:21 PDT Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK via Janet with NIFTP id aa11178; 7 Jun 90 14:06 BST Received: from aldham.cl.cam.ac.uk by gnnt.Cl.Cam.AC.UK id aa12089; 7 Jun 90 9:22 BST Received: by uk.ac.cam.cl.aldham (5.57/SMI-3.0DEV3) id AA11973; Thu, 7 Jun 90 09:22:35 +0100 Date: Thu, 7 Jun 90 09:22:35 +0100 From: jac@computer-lab.cambridge.ac.uk Message-Id: <9006070822.AA11973@uk.ac.cam.cl.aldham> To: MOP.pa@Xerox.COM Subject: Re: a-to-c From Richard Barber, Procyon Research Ltd, Cambridge, UK The new specification for a-c looks fine to me with the exception of 2 areas: The new specification of compute-discriminating-function is extremely constraining on the way implementations manage method dispatch in generic functions. In particular it forces the implementation to cache lists of applicable methods. We at Procyon have experimented with doing this but found it makes for an intolerable space overhead on small machines. We found the previous specification of compute-discriminating-function on page 3-41 of MOP Draft No 10 to be quite satisfactory and have implemented that. It does not force cacheing applicable methods, and we have developed an alternative fast technique for method dispatch. The second area which I am unhappy with (again for space reasons) is that of effective-slot-definition creation. (I mentioned this in a message to this group about 2 weeks ago). The new specification of compute-effective-slot-definition states that on each call it creates a new effective slot definition (using make-instance). However, Procyon's current implementation of CLOS shares these objects between a class and those inheriting from it whenever the objects would be equal. Following the new specification and not doing this sharing results in a ***20%*** increase in the size of our complete system image!! With this in mind, compute-effective-slot-definition should be permitted to return an existing effective slot definition object where an identical one exists. A minor consequence is that slot-definition-location should take an extra argument, the class in which the slot definition occurs. The above comments stem from first-hand experience with a full-scale implementation - I hope we can come to an agreement over them. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA02205; Mon, 11 Jun 90 18:03:53 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 11 JUN 90 10:17:11 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 11 JUN 90 09:46:01 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA00659; Mon, 11 Jun 90 09:45:44 PDT Message-Id: <9006111645.AA00659@spade.parc.xerox.com> Date: Mon, 11 Jun 90 09:45:44 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: jac@computer-lab.cambridge.ac.uk Cc: MOP.pa@Xerox.COM In-Reply-To: jac@computer-lab.cambridge.ac.uk's message of Thu, 7 Jun 90 09:22:35 +0100 <9006070822.AA11973@uk.ac.cam.cl.aldham> Subject: Re: a-to-c Line-Fold: NO Date: Thu, 7 Jun 90 09:22:35 +0100 From: jac@computer-lab.cambridge.ac.uk >From Richard Barber, Procyon Research Ltd, Cambridge, UK Thanks for getting your comments back so soon. Along with some of the other members of this list, I have just been at an X3J13 meeting which is why I haven't responded sooner. I have questions about both of your comments. But, in order to phrase my questions more concisely, let me first talk about an important kind of optimization in implementing the MOP. For the purpose of this message, let the term "standard-metaobject" mean those metaobjects which are instances of one of the standard metaobject classes. That is a class which is an instance of standard-class, a method which is an instance of standard-method etc. Note that these are not instances of subclasses of the standard classes, they are instances of the standard classes themselves. For any standard-metaobject, the implementation of the metaobject protocol can be heavily optimized. For example, a standard generic function metaobject doesn't need to ever call compute-discriminating- function. The rules of user specialization prevent there being any user-defined applicable methods. Formally, this optimization can be phrased as: The implementation is permitted to elide a specified call to a specified generic function if no portable methods would be applicable to the arguments. With this optimization in mind, let me ask a few questions about your comments. The new specification of compute-discriminating-function is extremely constraining on the way implementations manage method dispatch in generic functions. In particular it forces the implementation to cache lists of applicable methods. We at Procyon have experimented with doing this but found it makes for an intolerable space overhead on small machines. The description of the method lookup protocol was specifically designed to avoid requiring that lists of applicable methods be cached. Can you explain how it requires this? Or perhaps you could say something about your alternative technique which would demonstrate the additional leeway you would like. The second area which I am unhappy with (again for space reasons) is that of effective-slot-definition creation. (I mentioned this in a message to this group about 2 weeks ago). The new specification of compute-effective-slot-definition states that on each call it creates a new effective slot definition (using make-instance). However, Procyon's current implementation of CLOS shares these objects between a class and those inheriting from it whenever the objects would be equal. Following the new specification and not doing this sharing results in a ***20%*** increase in the size of our complete system image!! With this in mind, compute-effective-slot-definition should be permitted to return an existing effective slot definition object where an identical one exists. A minor consequence is that slot-definition-location should take an extra argument, the class in which the slot definition occurs. As far as I can tell, there are three ways to address this concern: 1) Find a way to allow compute-effective-slot-definition to return an object not created by a call to make-instance. For standard class metaobjects, the optimization mentioned above can play, but it is a little weird in light of the protocol. That is, the protocol really strongly suggests that effective slot definition metaobjects will be unique. It would take a somewhat different protocol to make this seem natural, and I think that protocol would likely be much more difficult for users to understand how to extend. 2) Keep (almost) the same protocol, but on an implementation-specific basis make the effective slot-definition metaobjects much more space efficient. If, for example, compute-effective-slot-definition gets the class as an argument, then one way to implement effective slot definitions would be with just two slots: The class and the slot name. Each reader of the effective slot definition would just recompute its value by going down the class precedence list etc. This should provide most of the space savings you mention. Another way would be using a technique similar to the one you describe of having effective slot definitions share common values. In such a scheme, each effective slot definition might have only one slot. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA09790; Tue, 12 Jun 90 19:58:25 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 12 JUN 90 17:16:16 PDT Return-Path: Received: from roo.parc.xerox.com ([13.2.16.72]) by Xerox.COM ; 12 JUN 90 17:15:34 PDT Received: by roo.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA00774; Tue, 12 Jun 90 17:15:30 PDT Message-Id: <9006130015.AA00774@roo.parc.xerox.com> Date: Tue, 12 Jun 90 17:15:30 PDT From: Jim des Rivieres Sender: rivieres@parc.xerox.com To: gregor@parc.xerox.com Cc: mop.pa@Xerox.COM Subject: Indian givers, CLOS style Reply-To: rivieres@parc.xerox.com A suggestion concerning the status of lists returned from metaobject accessors: From the current draft of the function pages (a-to-c): > The generic function {\bf class-direct-subclasses} returns the set as a > list. A class can be removed from the set by calling {\bf > remove-direct-subclass}. The effect of calling {\bf > add-direct-subclass} or {\bf remove-direct-subclass} on previously > returned values of {\bf class-direct-subclasses} is unspecified. The motivation for the last sentence is obvious---to make it possible to cut down the amount of consing that needs to be done when direct subclass is removed (additions pose no real problem). Similar wording is found in several other places where metaobject accessor functions return lists. It's seems fine to tell the user that the result returned by the accessor must not be smashed. This permits the implementation to share structure with that result if it so chooses. It's seems fine to tell the user that the result returned by the accessor may share with other things the user provided (e.g., class-direct-slots may share with the :direct-slots initarg when the class what initialized). This too permits the implementation to share structure with the user-supplied source if it so chooses. It's seems fine to tell the user that the result returned by the accessor may be a different list every time. And if the list represents a set, maybe the order the order will vary. This permits the implementation to reconstruct the list using whatever means it has at its disposal. But that last sentence means that the user cannot trust that the list returned by the accessor will remain intact; a safely-conscious user would have to copy it before saving it away (or engaging in any computation that might end up sharing with that list); your average user will think that they can get away without copying it, and a small number of them will be saldy mistaken on that account and will end up saddled with a subtle bug ("Gee. My CLOS program seemed to be working until I reloaded the file."). I believe this is out of spirit for Common Lisp; I think it would make much more sense if the spec that the implementation could not take back the answers it returned earlier. Naturally, portable methods on MOP functions would be expected to live by the same rules. There are a few known places where the extra consing regularly gets out of hand (e.g., the direct methods of class t). It would be more in keeping with the rest of the language if implementions were asked to find ways to handle these problem cases within the normal framework. E.g., (defclass class-with-lots-of-direct-methods (standard-class) ((internal-direct-methods :initform ()) ; mutable list (copiedp :initform nil) ; up to date copy exists (exportable-direct-methods))) ; copy (immutable) (defmethod specializer-direct-methods ((class class-with-lots-of-direct-methods)) (unless (slot-value class 'copiedp) ;; Copy the internal list and save it (setf (slot-value class 'copiedp) t) (setf (slot-value class 'exportable-direct-methods) (copy-list (slot-value class 'internal-direct-methods)))) (slot-value class 'exportable-direct-methods)) (defmethod add-direct-method ((class class-with-lots-of-direct-methods) method) (pushnew class (slot-value class 'internal-direct-methods)) (when (slot-value class 'copiedp) (pushnew class (slot-value class 'exportable-direct-methods))) (values)) (defmethod remove-direct-method ((class class-with-lots-of-direct-methods)) method) (setf (slot-value class 'internal-direct-methods) (delete method (slot-value class 'internal-direct-methods))) (setf (slot-value class 'copiedp) nil) (values)) Of course, this is not the only way the performance tradeoffs could be made. But it should be clear that the implementor does have considerable room to manoeuvre without an "Indian giver" provision. ---Jim Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA13297; Thu, 14 Jun 90 04:52:38 -0700 Received: from Semillon.ms by ArpaGateway.ms ; 13 JUN 90 20:43:01 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 13 JUN 90 20:42:24 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA04139; Wed, 13 Jun 90 20:42:25 PDT Message-Id: <9006140342.AA04139@spade.parc.xerox.com> Date: Wed, 13 Jun 90 20:42:25 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: rivieres@parc.xerox.com Cc: mop.pa@Xerox.COM In-Reply-To: Jim des Rivieres's message of Tue, 12 Jun 90 17:15:30 PDT <9006130015.AA00774@roo.parc.xerox.com> Subject: Re: Indian givers, CLOS style Line-Fold: NO Date: Tue, 12 Jun 90 17:15:30 PDT From: Jim des Rivieres Reply-To: rivieres@parc.xerox.com But that last sentence means that the user cannot trust that the list returned by the accessor will remain intact; a safely-conscious user would have to copy it before saving it away (or engaging in any computation that might end up sharing with that list); your average user will think that they can get away without copying it, and a small number of them will be saldy mistaken on that account and will end up saddled with a subtle bug. OK, I give in on this point. I agree with you that it isn't in the spirit of the MOP to give users this value which can change at any time. Unless anyone objects, I will go back and change all of these in the way you mention. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA13304; Thu, 14 Jun 90 04:52:46 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 13 JUN 90 21:06:25 PDT Return-Path: Received: from nero.parc.xerox.com ([13.1.100.172]) by Xerox.COM ; 13 JUN 90 21:04:05 PDT Received: by nero.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA00543; Wed, 13 Jun 90 21:04:11 PDT Received: from Messages.7.14.N.CUILIB.3.45.SNAP.NOT.LINKED.nero.parc.xerox.com.sun4.40 via MS.5.6.nero.parc.xerox.com.sun4_40; Wed, 13 Jun 90 21:04:10 -0700 (PDT) Message-Id: <0aRkmuMB0KGgA1Zsso@nero.parc.xerox.com> Date: Wed, 13 Jun 90 21:04:10 -0700 (PDT) From: Danny Bobrow To: MOP.pa@Xerox.COM Subject: Alternative to compute-discriminating-function protocol References: <9006121818.AA22774@roo.parc.xerox.com>, This message suggests an slight alternative to the current set of generic functions that make up the protocol for computing the discriminating function and effective method of a generic function. It takes as a premise that systems will often do class-based caching of effective methods, and provides a direct interface for that functionality. I first describe the basic idea (worked out by Jim desRivieres and myself), and then provide an alternative set of proposed function pages. -- When a generic function is invoked, the discriminating function must determine an effective method created from the methods applicable to the arguments. Depending on the generic function and the arguments, this is done in one of three ways: using a cached value; calling {\bf compute-cacheable-method-using-classes}; or calling {\bf compute-effective-method} on the result of {\bf compute-applicable-methods}. The generic function {\bf compute-cacheable-method-using-classes} computes such an effective method using only the classes of the required arguments to the function. If it returns an effective method, this can be used and cached (see details below). If it returns nil, then the "classical" mechanism for computing the effective method for the specific arguments is used. The generic function {\bf compute-applicable-methods-using-classes} can be used by {\bf compute-cacheable-method-using-classes} in constructing the cacheble effective method. The former returns two values, an ordered list of methods with only class specializers, and a second list of other methods that might be applicable given only the classes of the required arguments. For standard-generic-functions, these would be all methods with EQL specializers of the given classes. More details below. ----- \begingfcom{compute-applicable-methods} \label Syntax: \Defgen {compute-applicable-methods} {generic-function arguments} \label Arguments: The {\it generic-function} argument is a generic function metaobject. The {\it arguments} argument is a list of objects. \label Values: This generic function returns a possibly empty list of method metaobjects. \label Purpose: The generic function {\bf compute-applicable-methods} determines the method applicability of a generic function given a list of required arguments for the generic function. The returned list of method metaobjects is sorted by precedence order with the most specific method is first. If no methods are applicable to the supplied arguments the empty list is returned. When a generic function is invoked, the discriminating function must determine an effective method to be applied to the arguments. Depending on the generic function and the arguments, this is done in one of three ways: using a cached value; calling {\bf compute-cacheable-method-using-classes}; or calling {\bf compute-effective-method} on the result of {\bf compute-applicable-methods}. Refer to the description of {\bf compute-discriminating-function} for the details of this process. For any given generic function and set of arguments, if {\bf compute-cacheable-method-using-classes} returns a non-nil value, this must be an effective method; the values returned and side-effects from calling this method must be identical to using those values and side effects from a corresponding call to {\bf compute-effective-method} on the result of a call to {\bf compute-applicable-methods}. The results are undefined if this is not the case. The {\it arguments} argument must have at least as many elements as the generic function accepts required arguments. If fewer arguments are supplied, an error is signalled. \label Methods: \Defmeth {compute-applicable-methods} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{{\it arguments\/}}}} This method signals an error if any method of the generic function has a specializer which is not either a class metaobject or a list of the form {\bf(eql {\it object})}. Otherwise, this method computes the sorted list of applicable methods according to the rules described in the section of Chapter 1 called ``Method Selection and Combination''. This method can be overridden. Because of the consistency requirements between this generic function and {\bf compute-cacheable-method-using-classes}, doing so may require also overidding \method{compute-cacheable-method-using-classes}{standard-generic-function t}. \label See Also: ``Method Lookup Protocol'' {\bf compute-cacheable-method-using-classes} {\bf compute-discriminating-function} \endcom \begingfcom{compute-applicable-methods-using-classes} \label Syntax: \Defgen {compute-applicable-methods-using-classes} {generic-function classes} \label Arguments: The {\it generic-function} argument is a generic function metaobject. The {\it classes} argument is a list of class metaobjects. \label Values: This generic function returns two values. Both are possibly empty lists of method metaobjects. The first is an ordered list of methods whose specializers are all classes. The second is a list of other methods that might be applicable knowing only the classes of the arguments (e.g. all the methods with EQL specializers in the same class). \label Purpose: The generic function {\bf compute-applicable-methods-using-classes} is called to attempt to determine the method applicability given only the classes of the required arguments to the generic function. If it is possible to completely determine the ordered list of applicable methods based only on the supplied classes, this generic function returns that list as its first value and nil as its second value. The returned list of method metaobjects is sorted by precedence order, the most specific method is first. If no methods are applicable to the specified arguments the empty list is returned. If it is not possible to completely determine the ordered list of applicable methods based only on the supplied classes, this generic function returns the rest of the methods in the second value, potentially unordered. This generic function is designed to be used with {\bf compute-cacheable-method-using-classes} which would use these two lists to compute code that would produce code to do run time discrimination to determine the applicability of methods on the second list. For any given generic function and set of arguments, if {\bf compute-applicable-methods-using-classes} returns a second value of nil, the first value must be equal to the value returned by {\bf compute-applicable-methods}. The results are undefined if this is not the case. \newpage \label Methods: \Defmeth {compute-applicable-methods-using-classes} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{({\it classes\/} t)}}} In cases where the generic function has no methods with {\bf eql} specializers, or has no methods with {\bf eql} specializers which could be applicable to arguments of the supplied classes, this method returns the ordered list of applicable methods as its first value and nil as its second value. This method can be overridden. Because of the consistency requirements between this generic function and {\bf compute-applicable-methods}, doing so may require also overidding \method{compute-applicable-methods}{standard-generic-function t}. \endcom \begingfcom{compute-cacheable-method-using-classes} \label Syntax: \Defgen {compute-cacheable-method-using-classes} {generic-function classes} \label Arguments: The {\it generic-function} argument is a generic function metaobject. The {\it classes} argument is a list of class metaobjects. \label Values: This generic function returns an effective method, or nil. The effective method is any Common Lisp form, allowing the addition of the locally defined special forms {\bf method-arg} plus those described with respect to method-combination. {\bf method-arg} provides a mechanism for the effective method code to refer to arguments of the method. It takes a single argument, n, a non-negative integer which must less than the number of required arguments to the generic function. \label Purpose: The generic function {\bf compute-cacheable-method-using-classes} is called to attempt to determine an effective method given only the classes of the required arguments to the generic function. How it does this is not specified, though it may call {\bf compute-effective-method} and {\bf compute-applicable-methods-using-classes}. When a generic function is invoked, the discriminating function must determine the ordered list of methods applicable to the arguments. Depending on the generic function and the arguments, this is done in one of three ways: using a cached value; calling {\bf compute-cacheable-method-using-classes}; or calling {\bf compute-effective-method} on the result of calling {\bf compute-applicable-methods}. Refer to the description of {\bf compute-discriminating-function} for the details of this process. The value returned by {\bf compute-cacheable-method-using-classes} is known to depend only on the definitions of the classes of the required arguments, and the contents of the generic function, and the system will be responsible for ensuring the consistency of any cache if these change in any way. If there are other dependencies, then the user is responsible for calling {\bf forget-cacheable-methods} on the generic function to ensure that any cache is cleared. \newpage \label Methods: \Defmeth {compute-cacheable-method-using-classes} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{({\it classes\/} t)}}} If any method of the generic function has a specializer which is neither a class metaobject nor a list of the form {\bf(eql {\it object})}, this method returns nil. Otherwise this method returns an effective method. This method can be overridden. Because of the consistency requirements between this generic function and {\bf compute-applicable-methods}, doing so may require also overidding \method{compute-applicable-methods}{standard-generic-function t}. \label Remarks: This generic function exists to support extensions which modify the rules of method applicability but which base the new, modified rules only on the classes of the arguments to the generic function. . An extension which bases method applicability on properties of the arguments to the generic function other than their class, as is the case with {\bf eql} specializers, can be implemented in one of two ways. The first involves a method on this generic function which returns an appropriate value. For example, it create a piece of code that discriminates on the values of the given arguments at run time (either using case for example, or a hash-table). The second involves definining a method on {\bf compute-discriminating-function}. The discriminating function returned by this method implements the desired method applicability rules directly without making any calls to {\bf compute-applicable-methods} or {\bf compute-cacheable-method-using-classes}. \label See Also: ``Method Lookup Protocol'' {\bf compute-applicable-methods} \{bf compute-applicable-methods-using-classes} {\bf compute-discriminating-function} \endcom \begingfcom{compute-discriminating-function} \label Syntax: \Defgen {compute-discriminating-function} {generic-function} \label Arguments: The {\it generic-function} argument is a generic function metaobject. \label Values: The value returned by this generic function is a function. \label Purpose: The generic function {\bf compute-discriminating-function} is called to determine the discriminating function for a generic function. When a generic function is called, the discriminating function is called to implement the behavior of calling the generic function: determining the ordered set of applicable methods, determining the effective method, and running the effective method. To determine the effective method, the discriminating function first calls {\bf compute-cacheable-method-using-classes}. If {\bf compute-cacheable-method-using-classes} returns a nil value, the discriminating function then calls {bf compute-effective-method} on the result of calling {\bf compute-applicable-methods}. When {\bf compute-cacheable-method-using-classes} returns a non-nil value, the discriminating function is permitted to memoize the value as follows. If the generic function is called again with required arguments which are instances of the same classes; and the generic function has not been reinitialized, {\bf forget-cacheable-methods} has not been called; and no method has been added to the generic function; and no method has been removed from the generic function; and for all the specializers of all the generic function's methods which are classes the class precedence list has not changed; for any such memoized value, no class precedence list of the required argument classes has changed; then the discriminating function may reuse the effective method without calling {\bf compute-cacheable-method-using-classes} again. When the effective method is run, each method's function is called using the result of calling {\bf method-function-applier}. The result of {\bf compute-discriminating-function} is intended to be used as the discriminating function for {\it generic-function} and is intended to replace all previous discriminating functions for {\it generic-function}. The result of {\bf compute-discriminating-function} cannot be called directly with {\bf apply} or {\bf funcall}. Instead, once it has been installed with {\bf set-funcallable-instance-function}, the generic function itself can be called. Once {\bf compute-discriminating-function} is called, the result must be installed before {\it generic-function} is called again. Moreover the installed discriminating function must not subsequently be replaced by a previous result of {\bf compute-discriminating-function}. This generic function is called, and the result is installed by {\bf add-method}, {\bf remove-method}, {\bf initialize-instance} and {\bf reinitialize-instance}. \label Methods: \Defmeth {compute-discriminating-function} {({\it generic-function} standard-generic-function)} This method returns a discriminating function as described above. This method can be shadowed. The shadowing method is permitted to call {\bf call-next-method} and return a result which itself calls the result of this method. This method can be overridden. \label See Also: ``The Method Lookup Protocol'' {\bf compute-applicable-methods} {\bf compute-cacheable-method-using-classes} {\bf compute-applicable-methods-using-classes} {\bf compute-effective-method} {\bf make-method-lambda} {\bf method-function-applier} \endcom \begingfcom{compute-effective-method} \label Syntax: \Defgen {compute-effective-method} {generic-function method-combination methods} \label Arguments: The {\it generic-function} argument is a generic function metaobject. The {\it method-combination} argument is a method combination metaobject. The {\it methods} argument is a list of method metaobjects. \label Values: This generic function returns two values. The first is an effective method. The second is a list of effective method options. \label Purpose: The generic function {\bf compute-effective-method} is called to determine the effective method from a sorted list of method metaobjects. The first value returned by this generic function is the effective method. The second is a list of effective method options, these have the same syntax and interpretation as the options argument to the long form of define method combination. This generic function can be called by the user or the implementation. It is called whenever a sorted list of applicable methods must be converted to an effective method. It is called by the result of \method {compute-discriminating-function} {standard-generic-function}. Because neither method nor method combination metaobjects can be reinitialized, the results of this generic function may be memoized. \label Methods: \Defmeth {compute-effective-method} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{({\it method-combination} standard-method-combination)} \hbox{{\it methods}}}} This method computes the effective method according to the rules of the method combination type implemented by {\it method-combination}. This method can be overridden. \vskip 1.6pc \Defmeth {compute-effective-method} {\vtop{\hbox{({\it generic-function} standard-generic-function)} \hbox{({\it method-combination} standard-simple-method-combination)} \hbox{{\it methods}}}} This method computes the effective method according to the rules of the method combination type implemented by {\it method-combination}. This method can be overridden. \label See Also: ``Method Lookup Protocol'' Chapter 1 section --- ``Applying Method Combination to the Sorted List of Applicable Methods'' {\bf define-method-combination} {\bf compute-discriminating-function} \endcom Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA07978; Thu, 14 Jun 90 21:28:33 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 14 JUN 90 11:38:16 PDT Return-Path: Received: from spade.parc.xerox.com ([13.1.100.26]) by Xerox.COM ; 14 JUN 90 11:37:36 PDT Received: by spade.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA04249; Thu, 14 Jun 90 11:37:36 PDT Message-Id: <9006141837.AA04249@spade.parc.xerox.com> Date: Thu, 14 Jun 90 11:37:36 PDT From: Gregor J. Kiczales Sender: gregor@parc.xerox.com To: Moon@STONY-BROOK.SCRC.Symbolics.COM Cc: bobrow@parc.xerox.com, MOP.pa@Xerox.COM In-Reply-To: David A. Moon's message of Thu, 14 Jun 90 11:53 EDT <19900614155300.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Subject: Re: Alternative to compute-discriminating-function protocol Line-Fold: NO Actually, this is part of a long-standing discussion we have been having here about ways to provide increased support for user extensions that use non-class specializers. One way of looking at this is how might the protocol be extended to make it easier for a user to implement EQL specializers if they weren't already there. Unfortunately, there aren't any examples of non-class specializers that work as well as EQL. I think the reason Danny didn't include this rationale is that he may have intended only to send this to those of us who have been working with this issue. I can't say for sure of course! This proposal, as we have noticed in discussion here this morning, doesn't really provide any more power than the mechanism that is already written up. Basically, the idea in this mechanism is that you can defer some of the method applicability testing to the body of the effective method. This is done by doing something like putting a discrimination net in the effective method. Unfortunately, as is demonstrated in the current PCL, discrimination nets like this don't work very well, and they scale even less well. Using the protocol already written up, the same thing can be achieved by a conspiracy of compute-effective-method, compute-applicable-methods, and compute-applicable-methods-using-classes. compute---using-classes simply returns the extra methods and then compute-effective-method adds the extra discrimination code to the effective method. This is essentially equivalent to the mechanism in Danny's message. The extra two things he mentioned are the method-arg lexical function, for which the :arguments option can be used, and flush-cacheable-methods which should can be done by recomputing the discriminating function. My personal opinion is that there is a pretty important piece of work to be done here, addressing one of the big problems with current OO languages. Specifically, figuring out the difference between the class-based discrimination most OOPLs support and other kinds of discrimination (like on the value in a slot) that we do with some explicit conditional construct. We all know the frustration of having to decide whether, for a given property of an object, we are going to encode it in its class or in the value of slot. Working this out would get a new kind of integration of OOP and existing language constructs. Once it gets worked out, one could imagine extending the MOP to support it. I don't expect that will happen in the near future. But, we keep discussing it. What would life be if we stopped thinking up new problems for ourselves :-) Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA11986; Fri, 15 Jun 90 03:22:35 -0700 Received: from Chardonnay.ms by ArpaGateway.ms ; 14 JUN 90 09:30:48 PDT Return-Path: Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 14 JUN 90 09:28:31 PDT Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 808622; 14 Jun 90 11:49:17 EDT Date: Thu, 14 Jun 90 11:53 EDT From: David A. Moon Subject: Alternative to compute-discriminating-function protocol To: Danny Bobrow Cc: MOP.pa@Xerox.COM In-Reply-To: <0aRkmuMB0KGgA1Zsso@nero.parc.xerox.com> Message-Id: <19900614155300.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-Fold: No What's the rationale for proposing this new, more complex way of doing things? I expected to find a discussion of why this is preferable to the old way in your message somewhere, but I couldn't find it. The message appears to pure description with no explanation of why one would want to use these facilities. Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA00290; Mon, 18 Jun 90 06:45:31 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 18 JUN 90 03:54:09 PDT Return-Path: Received: from NSFnet-Relay.AC.UK ([128.86.8.6]) by Xerox.COM ; 18 JUN 90 03:53:42 PDT Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK via Janet with NIFTP id aa08430; 18 Jun 90 11:31 BST Received: from aldham.cl.cam.ac.uk by gannet.cl.cam.ac.uk with SMTP (PP) id ; Mon, 18 Jun 1990 10:53:12 +0000 Received: by uk.ac.cam.cl.aldham (5.57/SMI-3.0DEV3) id AA21581; Mon, 18 Jun 90 10:52:59 +0100 Date: Mon, 18 Jun 90 10:52:59 +0100 From: jac@computer-lab.cambridge.ac.uk Message-Id: <9006180952.AA21581@uk.ac.cam.cl.aldham> To: gregor@parc.xerox.com Cc: MOP.pa@Xerox.COM Subject: Re: a-to-c Sender: jac@computer-lab.cambridge.ac.uk From Richard Barber, Procyon Research Ltd, Cambridge, UK >Date: Mon, 11 Jun 90 09:45:44 PDT >From: "Gregor J. Kiczales" > >For any standard-metaobject, the implementation of the metaobject >protocol can be heavily optimized. For example, a standard generic >function metaobject doesn't need to ever call compute-discriminating- >function. The rules of user specialization prevent there being any >user-defined applicable methods. > >Formally, this optimization can be phrased as: The implementation is >permitted to elide a specified call to a specified generic function if >no portable methods would be applicable to the arguments. Thanks for making this point more explicit. I had not realized the full implications of this phrase when I originally read it in the MOP spec. With this in mind I am now happy with the new spec. I would guess that users of the MOP might also trip over this, expecting compute-discriminating-function on a standard generic function to do the full protocol when in fact the implementor has special-cased away the calls to compute-applicable-methods and friends. I think perhaps there should be a warning in the spec for compute-discriminating-function and also for compute-applicable-methods, compute-applicable-methods-using-classes, compute-effective-method etc. to say that if the user specializes any of these functions then compute-discriminating-function may also need to be specialized. > The new specification of compute-discriminating-function is extremely > constraining on the way implementations manage method dispatch in > generic functions. In particular it forces the implementation to cache > lists of applicable methods. We at Procyon have experimented with doing > this but found it makes for an intolerable space overhead on small > machines. > >The description of the method lookup protocol was specifically designed >to avoid requiring that lists of applicable methods be cached. I intended my comment to say that an implementation which did not memoize for standard generic functions would probably be unacceptably slow. But this objection goes away given the special-casing in standard method dispatch that is allowed to implementors. > ... The new specification of > compute-effective-slot-definition states that on each call it creates > a new effective slot definition (using make-instance). However, Procyon's > current implementation of CLOS shares these objects between a class and > those inheriting from it whenever the objects would be equal. > >As far as I can tell, there are three ways to address this concern: > >1) Find a way to allow compute-effective-slot-definition to return an >object not created by a call to make-instance. >... At Procyon over the last few days we have worked out a way to simulate the intended uniqueness behaviour of standard effective slot definitions without actually calling make-instance every time. This solution preserves our current space savings; we are therefore happy. Thank you again for your clarifications, Gregor. Richard Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA02265; Sat, 23 Jun 90 17:40:47 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 22 JUN 90 22:51:24 PDT Return-Path: Received: from lucid.com ([192.26.25.1]) by Xerox.COM ; 22 JUN 90 22:50:48 PDT Received: from rose ([192.31.212.83]) by heavens-gate.lucid.com id AA03648g; Fri, 22 Jun 90 22:48:42 PDT Received: by rose id AA01542g; Fri, 22 Jun 90 22:49:06 PDT Date: Fri, 22 Jun 90 22:49:06 PDT From: Richard P. Gabriel Message-Id: <9006230549.AA01542@rose> To: MOP.pa@Xerox.COM Subject: Chapter 3 reading After a quick reading of the new stuff, here is what I came up with: Page 3-3 In this document, the term {\bit metaobject} is used to refer precisely to an object which represent a CLOS class, slot definition, generic function, method or method combination. represent => represents Page 3-4 Any metaobject must be an instance of a subclass of exactly one of these classes. That is, there cannot be direct instances of these or such instances are not metaobjects? I take it that the term ``available as'' is used to indicate that these things are observable and when observed have the representations stated? Because this construction is odd, you should explain it. Page 3-5 Certain kinds of information is associated with both direct and effective slot definitions. kinds ... is => kinds ... are Certain other information is only associated with direct slot definition metaobjects. only associated => associated only Page 3-9 \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit shadows} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and for that set of arguments $M\sub{2}$ is more specific than $M\sub{1}$; and when $M\sub{2}$ is invoked, {\bf call-next-method} is called from within its body. First, I think the word `shadow' will fake people out, defined like this. Second, I think all :around methods shadow primary methods regardless of specificity of argument, so you need to word this differently. \item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit overrides} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$ are both associated with the same generic function; and either $M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and $M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf :around} method and $M\sub{1}$ is a primary method; and for that set of arguments $M\sub{2}$ is more specific than $M\sub{1}$; and when $M\sub{2}$ is invoked, {\bf call-next-method} is not called from within its body. :around methods override primary ones regardless of specificity. But, this description permits any implementation modifications provided provided that for any portable class $C\sub{\hbox{p}}$ that is a subclass of one or more specified classes $C\sub{0} \ldots C\sub{i}$, the following are true: provided provided => provided What is a portable class? \item{\bull} The method applicability of any specified generic function is the same in terms of behavior as it would had no implementation-specific changes been made. Wow, do you mean to say that the same methods are applicable and do the same things? This is a sentence the gov'mint coulda written. Page 3-10 Typically, when a method is allowed to be overridden, a small number of related will need to be overridden as well. related will => related methods will Page 3-18 An error is signalled if this value is not a proper list; or if it is the empty list; or if {\bf validate-superclass} returns false for any element of the list. The construction ``; or'' is over-punctuated. Also, VALIDATE-SUPERCLASS takes two arguments. I would try this: An error is signaled under the following conditions: if this value is not a proper list, if it is the empty list, or if {\bf validate-superclass} applied the class and any element of this list returns false. This construction occurs elsewhere on this page and the next. An error is signalled if this value is not a proper list or; if any element of the list is not an instance of the class {\bf direct-slot-definition} or one of its subclasses. If the class is being initialized, this argument defaults to false. If it's a proper list, the default must be nil or (), not false. I might be wrong about this, but check all uses of nil, false, and empty list in this subsection. Page 3-21 The generic function {\bf map-dependents} can be called to access the set of dependents of a class or generic function. The generic function {\bf remove-dependent} can be called to remove an object from the set of dependents of a class or generic function. The effect of calling {\bf add-dependent} or {\bf remove-depedent} while a call to {\bf map-dependents} is in progress is unspecified. remove-depedent => remove-dependent Page 3-22 ;;; ;;; Updaters are used encapsulate any metaobject which needs updating ;;; when a given class or generic function is modified. RECORD-UPDATER ;;; is called to both create an updater and add it to the dependents of ;;; the class or generic functions. Methods on the generic function ;;; UPDATE-DEPENDENT, specialized to the specific class of updater do ;;; the appropriate update work. ;;; used encapsulate => used to encapsulate (defun record-updater (class dependee dependent &rest initargs) (let ((updater (apply #'make-instance class :dependee dependee :dependent dependent initargs))) (add-dependent dependee updater) updater)) Why isn't this a generic function or doesn't it use check-type to make sure CLASS is an updater? Page 3-24 Why isn't add-direct-method just part of some dependent protocol between classes and methods, instead of this more direct treatment, or is this typical of how dependent protocols are handled? Page 3-28 The generic function {\bf add-method} adds a method to the set of methods associated with a generic function. After adding the method to this set, {\bf compute-discriminating-function} is called and its result is installed by calling {\bf set-funcallable-instance-function}. The {\it generic-function} argument is destructively modified and returned as the the result. the the => the Page 3-29 Chapter 1 section --- ``Agreement on Parameter Specializers and Qualifiers'' section -- ``Agreement => section---``Agreement This same problem occurs elsewhere. Page 3-30 \Defmeth {allocate-instance} {({\it class\/} structure-class) {\rest} {\it initargs}} The instance returned by this method has slots with undefined values. I would very much prefer to leave out structures as much as possible from this protocol. Structures are very nice as they are, and I fear the possible slowdown of structures or incorrectness and complexity of implementation in order to accomodate the MOP. The complexity of implementation is not justified for the simple facility. Page 3-32 This method can be overridden. Because of the consistency requirements between this generic function and {\bf compute-applicable-methods-using-classes}, doing so may require also overidding \method{compute-applicable-methods-using-classes}{standard-generic-function t}. This phrasing is better than similar phrasings you have used for this situation. Replace the others with something like this. Page 3-35 Under compute-class-precedence-list If the specified class or any of its superclasses is a forward referenced class an error is signalled. There are two situations - when the user calls this and when it is called by the system (at finalize-inheritance time?). In the first case it should not signal an error, and in the second it should. Page 3-36 Under compute-discriminating-function \label Values: The value returned by this generic function is a function. and later on The result of {\bf compute-discriminating-function} cannot be called directly with {\bf apply} or {\bf funcall}. This means it isn't a function. If you cannot add to X nor subtract from it, it ain't a number, and if you cannot funcall or apply X, it ain't a function. Actually, I think it should not be a function at all, but an instance of a class that one could call DISCRIMINATOR (with the usual STANDARD-DISCRIMINATOR). This object is a thing such that when you SET-FUNCALLABLE-INSTANCE-FUNCTION on a generic function and it, a funcallable generic function is produced. I suppose this situation indicates some kind of initialization or reinitialization. Imagine this implementation: a generic function has a code sequence at its head which uses a table to determine applicability. The result of a call to compute-discriminating-function, then, produces some kind of table object, which is then combined with the code sequence to produce the funcallableness of the generic function. Okay, so that shows that this shouldn't be a function, and that there should be a discrimninator class. But the standard- version of this part of the protocol could use the rest of the protocol that you suggest (compute-applicable-methods etc) when subclasses of discriminators are made and user methods applied, though I feel a little uncomfortable about it. I prefer making this a whole lot more abstract, possibly not going this deep in the protocol. I will think about this more. Determination of the the effective method is done by calling {\bf compute-effective-method}. the the => the Page 3-38 This generic function returns two values. The first is an effective method. The second is a list of effective method options. You should specify ``effective method'' a bit, if even simply to state that it is some abstract, first class thing. Page 3-40 The class of the effective slot definition metaobject is determined by calling {\bf effective-slot-definition-class}. The effective slot definition is then created by calling {\bf make-instance}. Why isn't this just CLASS-OF? Also, on this page (compute-effective-slot-definition), you should mention that the list of superclass-slot-definitions are in CPL order. I would leave out the structure methods for this. Page 3-42 The direct slot definitions are then collected into individual lists, one list for each slot name associated with any of the direct slot definitions. The slot names are compared with {\bf eql}. Each such list is then sorted into class precedence list order. Direct slot definitions coming from classes earlier in the class precedence list of {\it class} appear before those coming from classes later in the class precedence list. I found this hard to understand because of the phrase ``associated with any of the direct slot definitions.'' I presume these are the direct slot definitions for the slot with that name in any of the classes this class inherits from. It's better to be a little wordy, but clear. -rpg- Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA18239; Tue, 24 Jul 90 13:04:41 -0700 Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUL 90 12:56:59 PDT Return-Path: Received: from NSFnet-Relay.AC.UK ([128.86.8.6]) by Xerox.COM ; 24 JUL 90 12:53:32 PDT Received: from sun.nsfnet-relay.ac.uk by vax.NSFnet-Relay.AC.UK via Janet with NIFTP id aa06022; 24 Jul 90 12:52 BST Received: from cl.cam.ac.uk by gannet.cl.cam.ac.uk with SMTP (PP) id ; Tue, 24 Jul 1990 11:27:57 +0000 Received: by uk.ac.cam.cl.aldham (5.57/SMI-3.0DEV3) id AA08349; Tue, 24 Jul 90 11:27:07 +0100 Date: Tue, 24 Jul 90 11:27:07 +0100 From: jac@computer-lab.cambridge.ac.uk Message-Id: <9007241027.AA08349@uk.ac.cam.cl.aldham> To: gregor@parc.xerox.com Cc: MOP.pa@Xerox.COM Subject: Details in a-to-c spec Sender: jac@computer-lab.cambridge.ac.uk From Richard Barber, Procyon Research Ltd, Cambridge, UK Thinking in more detail about the a-to-c spec: 1. What is an 'effective method option', in the description of compute-effective-method? 2. Further down in compute-effective-method, it says >Because neither method nor method combination metaobjects can be >reinitialized, the results of this generic function may be memoized. Does this mean that a method combination may not depend on side-effects (e.g. the value of a special variable)? If it could, then the results of this generic function may not be memoized. On the other hand, if a method combination may not depend on side-effects, then this needs to be stated near the beginning of the CLOS spec. 3. Have you gone through what happens when a slot-definition class is redefined? If the slot structure of the class changes, then update-instance-for-changed-class gets called on each slot-definition instance. Update-instance-for-changed-class in turn may call the standard-slot-definition method on shared-initialize. However, the section 'Initialization of Slot Definition Metaobjects' that I have here states that 'if the :name argument to this method is not specified an error is signalled'. Is this your understanding of what the behaviour should be? Surely it should be possible to redefine a slot-definition class without causing an error? 4. Finally a comment about the proposed MOP generic functions on structures: >"Richard P. Gabriel" , Fri, 22 Jun 90 22:49:06 PDT > >I would very much prefer to leave out structures as much as possible >from this protocol. Structures are very nice as they are, and I fear >the possible slowdown of structures or incorrectness and complexity of >implementation in order to accomodate the MOP. The complexity of >implementation is not justified for the simple facility. I agree. Structures should be left out of the protocol. Otherwise, users of the MOP get little more than an extra bit of syntactic sugar, and the implementor has a real struggle to get it working correctly. Richard Received: from Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA18511; Tue, 21 Aug 90 10:53:44 -0700 Received: from Salvador.ms by ArpaGateway.ms ; 21 AUG 90 10:43:14 PDT Sender: kanderso@DINO.BBN.COM Date: 21 Aug 90 10:31:02 PDT (Tuesday) Subject: [Jeff Morrill: Mop comments] From: kanderso@DINO.BBN.COM To: MOP.PA@Xerox.COM Message-Id: <900821-104314-6052@Xerox> Return-Path: Received: from DINO.BBN.COM ([128.89.3.8]) by Xerox.COM ; 21 AUG 90 10:30:56 PDT Original-Date: Tue, 21 Aug 90 13:55:04 -0400 ------- Forwarded Message Return-path: jmorrill@bbn.com Date: Tue, 21 Aug 90 12:35 EDT From: Jeff Morrill Subject: Mop comments To: kanderson@BBN.COM Cc: jmorrill@BBN.COM, delatizky@BBN.COM Message-ID: <19900821163502.1.JMORRILL@adams.bbn.com> Ken, I have looked over the draft CLOS Mop Specification, and here are a couple of comments you may want to pass along. What is the status of slot optimization? I lamented the removal of methods like deoptimize-slot-access, and I don't see any "specified" way to deoptimize now. Clearly the use of slot-value-using-class is very important to those who program at the meta level, and I have been accustomed to deoptimizing SLOT-VALUE as the accepted procedure for getting slot-value-using-class to run. Symbolics' current Mop implementation doesn't appear to have anything like deoptimize-slot-access either. This makes me concerned that each vendor will have their own twist to defining the relationship between slot-value, slot-value-using-class, and the compiler. It is useful if not necessary to portable programs to be able to control compiler optimizations using meta behavior. For now I have TWO versions of slot-value (in two different packages): 1) the "real" slot-value, that always gets optimized and only sometimes calls slot-value-using-class, and 2) my own slot-value, that always calls slot-value-using-class and never gets optimized. jeff ------- End of Forwarded Message Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10051; Tue, 30 Oct 90 13:22:04 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16198>; Tue, 30 Oct 1990 13:21:07 PST Received: from inria.inria.fr ([128.93.8.1]) by alpha.xerox.com with SMTP id <16165>; Tue, 30 Oct 1990 13:17:40 PST Received: by inria.inria.fr (5.64+/90.0.9) via Fnet-EUnet id AA21469; Tue, 30 Oct 90 19:56:14 +0100 (MET) Received: from barbes.ilog.fr by ilog.ilog.fr, Tue, 30 Oct 90 18:03:58 +0100 Received: by barbes.ilog.fr, Tue, 30 Oct 90 18:02:17 +0100 X-Ns-Transport-Id: 08002008D0FD0003A617 Date: Tue, 30 Oct 1990 09:02:17 PST From: davis@ilog.ilog.fr Subject: mop questions To: mop@arisia.Xerox.COM Cc: davis@barbes.ilog.fr Message-Id: <9010301702.AA22429@barbes.ilog.fr> Gregor & co., Here are my initial impressions of The Art of the Meta-Object Protocol (AMOP), based on a more-or-less complete single reading. A more detailed review will follow. It's quite well written; the exposition is clear and straightforward without many side distractions. It's a good example of good programming, which is something the world always needs. Within the limits of CLOSETTE and CLOS, the examples are well thought out and very well motivated. The approach in chapter 3 of discussing ways to implement some of the full power of CLOS in CLOSETTE was particularly interesting to me. On the other hand, what I was really hoping to see was more exploration of the space of potential MOPs (and reflective object systems in general) and some justification of the actual CLOS MOP. The principles elucidated in Chapter 3 and Chapter 4 are steps in the right direction. I like the sections dealing with general protocol design considerations and how they apply to the MOP. However, it is not a general presentation of protocol problems nor a complete discussion of the MOP. For instance, in section 3.5 there is a discussion of the difference between making SLOT-VALUE generic and using SLOT-VALUE-USING-CLASS. However, there is no explanation of why the CLOS MOP chose the latter approach, or of other alternatives for the slot access protocol. On the whole, this is a fine and much-needed book, but certainly not the last word on the subject. Now, I have a few questions about MOP details. I'm sure I could think of a thousand more, and maybe I will. 1. Why does DEFCLASS expand into ENSURE-CLASS instead of MAKE-INSTANCE? (Ditto for other defining macros.) 2. Why are slot readers/writers/accessors created and bound inside of INITIALIZE-INSTANCE instead of in their own defining forms (eg DEFREADER, DEFACCESSOR, etc.)? 3. When Danny was here some months ago, he mentioned the possibility of reifying specializers into "specializer metaobjects". Was anything more written or discussed about this? There seem to be hooks in the MOP, and one brief footnote in AMOP, but no explicit discussion. 4. Why does the function GENERIC-FUNCTION-NAME exist, aside from debugging? 5. Is CLOS supposed to detect when new methods are added to reader or writer generic functions, when those new methods do not access the same slot as the original generic function? This question arises from the existence of the function METHOD-SLOT-NAME. 6. Do you intend there to be any sort of correspondence between slot allocation as given by the :ALLOCATION slot option and the class of the slot definition metaobject? I don't think so, but is this at least a viable implementation approach? 7. Would the intended CLOS way to implement, for example, slot facets be with new class metaobjects as we see in section 3.3 of AMOP, or by defining new slot definition metaobject classes? If the answer is the former, what would be a good reason to do the latter? -- Harley PS I'll send my comments about the implementation and user extension restrictions in a separate message. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA19524; Tue, 30 Oct 90 18:00:55 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16210>; Tue, 30 Oct 1990 18:00:13 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16198>; Tue, 30 Oct 1990 17:58:51 PST Received: by spade.parc.xerox.com id <279>; Tue, 30 Oct 1990 17:58:53 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003A986 Date: Tue, 30 Oct 1990 17:58:50 PST From: Gregor Kiczales Subject: expected traffic increase To: mop.parc@xerox.com Message-Id: <90Oct30.175853pst.279@spade.parc.xerox.com> As many of you know, in addition to a final draft of the specification, we at PARC are also working on a large document (~ 200 pages) which describes the basic concepts underlying the MOP. I call it a narrated deriviation of the MOP. It starts with a (simplified) CLOS without a MOP. Then, by working through a series of examples, it derives a MOP. Issues of design for functionality and performance are treated. We have recently circulated a draft of this document for comments, and asked people to send their comments to this mailing list. Any of you on this list who don't already have a copy of this can ftp Postscript source from arisia.xerox.com:/pcl/mop/amop.ps.Z. Gregor Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA20311; Tue, 30 Oct 90 18:22:56 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16199>; Tue, 30 Oct 1990 18:22:13 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16198>; Tue, 30 Oct 1990 18:20:56 PST Received: by spade.parc.xerox.com id <284>; Tue, 30 Oct 1990 18:20:55 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003A9D3 Date: Tue, 30 Oct 1990 18:20:49 PST From: Gregor Kiczales Subject: Re: mop questions In-Reply-To: "davis@ilog.ilog.fr's message of Tue, 30 Oct 1990 09:02:17 PST <9010301702.AA22429@barbes.ilog.fr>" To: davis@ilog.ilog.fr Cc: mop.parc@xerox.com, davis@barbes.ilog.fr Message-Id: <90Oct30.182055pst.284@spade.parc.xerox.com> Thanks for your comments on the AMOP. As Jim has addressed most of them in his previous message, I will focus on your MOP comments. You can also expect that we will get back to you with questions about your AMOP comments in the coming weeks. Date: Tue, 30 Oct 1990 09:02:17 PST From: davis@ilog.ilog.fr 1. Why does DEFCLASS expand into ENSURE-CLASS instead of MAKE-INSTANCE? (Ditto for other defining macros.) There is an important layer of functionality between them that needs to be captured. (MAKE-INSTANCE creates and deals with anonymous metaobjects. DEFCLASS provides a nice syntax for creating/redefining named metaobjects. ENSURE-CLASS provide the naming functionality. Specifically, if there is no class with this name, create one (make-instance) otherwise reinitialize the existing one (reinitialize-instance). 2. Why are slot readers/writers/accessors created and bound inside of INITIALIZE-INSTANCE instead of in their own defining forms (eg DEFREADER, DEFACCESSOR, etc.)? I don't know what this means. CLOS doesn't have forms like DEFREADER. It could of course, but doesn't. In addition, CLOS requires redefinition of class with different accessors, readers or writers to remove the old ones and add the new ones. If, as you may be suggesting, DEFCLASS converted readers and writers to DEFREADER and DEFWRITER, it would require that defclass did all the work of keeping track of new and old definitions. This doesn't fit the conceptual model we are trying to use that the state of class definition is entirely in the metaobject. It would also prevent the functionality of readers and writers from being available in classes created anonymously by MAKE-INSTANCE. 3. When Danny was here some months ago, he mentioned the possibility of reifying specializers into "specializer metaobjects". Was anything more written or discussed about this? There seem to be hooks in the MOP, and one brief footnote in AMOP, but no explicit discussion. We should have done this, but there is language in chapters 1 and 2 of the CLOS spec which suggests that an eql specializer is a list of the form (EQL ). In order to conform to that, and because making specializers full-on objects introduces added complexity, we haven't done it. But, we could be pushed I suppose. 4. Why does the function GENERIC-FUNCTION-NAME exist, aside from debugging? Same reason as CLASS-NAME. Debugging, browsing, inspecting. 5. Is CLOS supposed to detect when new methods are added to reader or writer generic functions, when those new methods do not access the same slot as the original generic function? This question arises from the existence of the function METHOD-SLOT-NAME. I don't understand this question. When you add a new method to a generic function, you just add it. Whether the generic function previously had only automatically created reader or writer methods doesn't enter into it. There is no reason why two automatically generated readers methods, on the same generic function, can't read slots with different names. I think about this by viewing generic functions and slots as being at different layers of abstraction. What slot a given generic function happens to read is a secret---only the implementor of the relevant method knows. So, if two methods happen to read slots with different names, so what. The job of the generic function is to access certain information, and the job of the person who writes the method is to know how that maps onto slots of the instance. 6. Do you intend there to be any sort of correspondence between slot allocation as given by the :ALLOCATION slot option and the class of the slot definition metaobject? I don't think so, but is this at least a viable implementation approach? The MOP doesn't do this. It treats allocation as state associated with the slot definition metaobject rather than as determining the class of the slot definition metaobject. We could have done it differently, but the currents scheme works pretty well for now. Going the other way also gets too quickly into unresolved issues about programming with dynamically created classes. 7. Would the intended CLOS way to implement, for example, slot facets be with new class metaobjects as we see in section 3.3 of AMOP, or by defining new slot definition metaobject classes? If the answer is the former, what would be a good reason to do the latter? The AMOP does this by defining both a new class metaobject class and a new slot definition metaobject class. Conceptually, the new class of slot definition metaobject is to say "it's OK to have an allocation you haven't seen before." The new class of class metaobject is to say "here is a kind of class which implements its instances as having these new kinds of slots." So, both are needed, they serve complementary roles. You could of course imagine a different protocol. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA18955; Wed, 31 Oct 90 12:07:58 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16253>; Wed, 31 Oct 1990 09:42:09 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16251>; Wed, 31 Oct 1990 09:40:11 PST Received: by spade.parc.xerox.com id <279>; Wed, 31 Oct 1990 09:40:55 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003AED4 Date: Wed, 31 Oct 1990 09:40:55 PST From: Gregor Kiczales Subject: Re: mop questions In-Reply-To: "davis@ilog.ilog.fr's message of Wed, 31 Oct 1990 03:12:55 PST <9010311113.AA22962@barbes.ilog.fr>" To: davis@ilog.ilog.fr Cc: mop.parc@xerox.com, davis@barbes.ilog.fr Message-Id: <90Oct31.094055pst.279@spade.parc.xerox.com> Date: Wed, 31 Oct 1990 03:12:55 PST From: davis@ilog.ilog.fr So what I'd like to know primarily is if you think this is a reasonable approach. In particular, I'm not interested in challenging CLOS's decisions, just in figuring out the best way for EuLisp. It seems perfectly reasonable to me to have DEFREADER and DEFWRITER macros, and to remove the functionality from DEFCLASS of defining these. CLOS made one choice about the style of its UI macros, this would just reflect another. But, two comments. First, the reason to do so certainly isn't to help the compiler. Unless I am missing something, the compiler should be able to do just as well well with the CLOS form as with explicit DEFREADER/DEFWRITER forms. Second, I believe that if you were really going to do this right, the only thing you would define is the underlying functionality---the explicit metaobject manipulation layer. None of these macros, or the UI syntax in terms of Lispo forms would be defined. Doing this would of course require you to do a MOP for the underlying Lisp which is why no-one has done it yet. But then, instead of writing the specification in terms of forms the compiler understands, you would write it in terms of metaobjects the compiler can compile and the interpreter can run. There would be application metaobjects, lambda metaobjects, etc. etc. This would then put you in a much better situation to write the programming environment. You could use any interface you wanted. Text and text editors ala maclisp, structure and structure editors ala interlisp, or fancy graphical structures and editors ala Units. There would be no confusion about the language primitives being `forms' so things would be much easier. I apologize for this question. I made some bad assumptions based on some slightly obscure language in 88-002R page 2-28 and a stronger TELOS restriction on generic functions. Right, this is a bug in CLOS. We should have an option on DEFMETHOD that allows you to control the class of the method created, that would make it more clear than generic functions can have methods of different classes and that the role of the :method-class option to DEFGENERIC is just to set the default method class for the generic function. What issues are you thinking about here? These questions about slot definition metaobjects are particularly interesting to me, since it is one of the areas in which TELOS differs the most from CLOS. The kind of thing that comes up when you are about to create a (meta)object and different participants in that process are trying to alter the default class in different ways. In the class of slot definition metaobjects, imagine that the class is trying to say, use a class which is the default class plus this other mixin(A). At the same time one of the slot definitions is trying to say use the default class plus this other mixin(B). What you often end up wanting to do is cons up a new class, with a cpl of (#:new-class A B default ...). That works pretty well, but we don't have enough experience with programming with dynamically created classes that I wanted to put any language like that in the spec. The version of the AMOP that I have does not discuss slot definition metaobjects. Right, but when you see it defining new `accessors' for a slot definition "metaobject", read that as defining a new subclass of the std kind of slot definition metaobject. So do you see a class as having only one kind of slot definition for all of its slots? No, I don't. This move by Eulisp seems like a move in the right direction. As I said above, I think you should also be able to control the class of the method metaobject from the method defining form. PS I received two copies of each of your messages, as well as a message from the PARC postmaster with the following error: We are working on this. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04528; Wed, 31 Oct 90 04:25:17 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16208>; Wed, 31 Oct 1990 04:23:42 PST Received: from inria.inria.fr ([128.93.8.1]) by alpha.xerox.com with SMTP id <16211>; Wed, 31 Oct 1990 04:22:11 PST Received: by inria.inria.fr (5.64+/90.0.9) via Fnet-EUnet id AA04018; Wed, 31 Oct 90 13:22:06 +0100 (MET) Received: from barbes.ilog.fr by ilog.ilog.fr, Wed, 31 Oct 90 12:14:37 +0100 Received: by barbes.ilog.fr, Wed, 31 Oct 90 12:12:55 +0100 X-Ns-Transport-Id: 08002008D0FD0003AC6E Date: Wed, 31 Oct 1990 03:12:55 PST From: davis@ilog.ilog.fr Subject: mop questions In-Reply-To: "Gregor Kiczales's message of Tue, 30 Oct 1990 18:20:49 PST <90Oct30.182055pst.284@spade.parc.xerox.com>" To: mop.parc@xerox.com Cc: davis@barbes.ilog.fr Message-Id: <9010311113.AA22962@barbes.ilog.fr> Gregor and Jim, Thanks for your prompt replies. There are a couple of issues I wanted to ask about in some more depth. 2. Why are slot readers/writers/accessors created and bound inside of INITIALIZE-INSTANCE instead of in their own defining forms (eg DEFREADER, DEFACCESSOR, etc.)? I don't know what this means. CLOS doesn't have forms like DEFREADER. It could of course, but doesn't. In addition, CLOS requires redefinition of class with different accessors, readers or writers to remove the old ones and add the new ones. If, as you may be suggesting, DEFCLASS converted readers and writers to DEFREADER and DEFWRITER, it would require that defclass did all the work of keeping track of new and old definitions. This doesn't fit the conceptual model we are trying to use that the state of class definition is entirely in the metaobject. It would also prevent the functionality of readers and writers from being available in classes created anonymously by MAKE-INSTANCE. The reason I ask these questions, of course, is in the context of EuLisp and TELOS. In EuLisp we would like function bindings - and especially important ones like slot accessors - to be defined entities known to the compiler. There is also a large interest in factoring complex behavior like that provided by DEFCLASS into a composition of simpler but well-specified behaviors. Adding defining forms for these rather special functions seems like a natural way to achieve these goals. So what I'd like to know primarily is if you think this is a reasonable approach. In particular, I'm not interested in challenging CLOS's decisions, just in figuring out the best way for EuLisp. Also in EuLisp class redefinition is not such an important issue. The interactive case is seen as special, and special processing rules can apply. What we are largely concerned with (at least on this side of the Channel) is module compilation. 5. Is CLOS supposed to detect when new methods are added to reader or writer generic functions, when those new methods do not access the same slot as the original generic function? This question arises from the existence of the function METHOD-SLOT-NAME. I don't understand this question. When you add a new method to a generic function, you just add it. Whether the generic function previously had only automatically created reader or writer methods doesn't enter into it. There is no reason why two automatically generated readers methods, on the same generic function, can't read slots with different names. I apologize for this question. I made some bad assumptions based on some slightly obscure language in 88-002R page 2-28 and a stronger TELOS restriction on generic functions. In the CLOS specification, "The :method-class option is used to specify that all methods on this generic function are to have a different class from the default provided by the system..." I assumed that all methods on a generic function were intended to have the same class. This is a useful restriction for certain purposes, and it is embodied in TELOS. (The abstraction point is a good one and argues against the restriction.) However, I see in the latest MOP pages 3-74 to 3-76 language which implies that this is not in fact a CLOS restriction. Anyway, assuming the restriction, it makes sense to think about reader and writer generic functions, and not just reader and writer methods. The existence of METHOD-SLOT-NAME then prompted me to wonder if you intended it to be an error to have different methods on such a generic function access different slots. In fact, I found it unusual that there would be such an error, thus the question. 6. Do you intend there to be any sort of correspondence between slot allocation as given by the :ALLOCATION slot option and the class of the slot definition metaobject? I don't think so, but is this at least a viable implementation approach? The MOP doesn't do this. It treats allocation as state associated with the slot definition metaobject rather than as determining the class of the slot definition metaobject. We could have done it differently, but the currents scheme works pretty well for now. Going the other way also gets too quickly into unresolved issues about programming with dynamically created classes. What issues are you thinking about here? These questions about slot definition metaobjects are particularly interesting to me, since it is one of the areas in which TELOS differs the most from CLOS. 7. Would the intended CLOS way to implement, for example, slot facets be with new class metaobjects as we see in section 3.3 of AMOP, or by defining new slot definition metaobject classes? If the answer is the former, what would be a good reason to do the latter? The AMOP does this by defining both a new class metaobject class and a new slot definition metaobject class. The version of the AMOP that I have does not discuss slot definition metaobjects. Conceptually, the new class of slot definition metaobject is to say "it's OK to have an allocation you haven't seen before." The new class of class metaobject is to say "here is a kind of class which implements its instances as having these new kinds of slots." So, both are needed, they serve complementary roles. So do you see a class as having only one kind of slot definition for all of its slots? One of the goals of the TELOS MOP was the ability to mix-n-match slot definition metaobjects of different classes within the same class metaobject. I think this is only a partial success in the current version; the EuLisp community is working on refinements as I write. Thanks again for your thoughtful (dare I say `reflective'?) answers. -- Harley PS I received two copies of each of your messages, as well as a message from the PARC postmaster with the following error: A copy of your message is being returned to you because one or more of the addresses you specified could not be recognized as addresses that are understood by, or reachable from, this system. error: err.unresolvable: nori@kagaku.se.fujitsu.co.jp.ARPA error: err.unresolvable: jac@computer-lab.cambridge.ac.uk.ARPA error: err.unresolvable: ida@cc.aoyama.ac.jp.ARPA error: err.unresolvable: harlqn.mop@harlqn.co.uk.ARPA Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA22443; Wed, 31 Oct 90 13:28:30 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16263>; Wed, 31 Oct 1990 13:26:28 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16259>; Wed, 31 Oct 1990 13:19:57 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 866544; 31 Oct 1990 16:19:36-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0003B25D Date: Wed, 31 Oct 1990 13:25:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: Moon's comments on Draft 11 To: mop@arisia.Xerox.COM Message-Id: <19901031212511.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Moon's comments on Draft 11 of the CLOS Metaobject Protocol specification, dated July 30, 1990 COMMENTS ON THE CONTENT Page 1 says that the Standard Protocol section has not been revised and I shouldn't read it because it will only confuse me. The problem is that I can't read the function description pages without knowing what protocols they are supposed to implement. As a result, I am only able to comment on pages 5 through 22. The fact that only this small fraction of the specification has been written so far makes the schedule pretty implausible in my opinion (final comments November 15, go to press in January). As for the content of pages 5 through 22, on the whole it's pretty good. 3-9 "The declarations are available as a list of declarations" -- I was unsure whether you meant declarations or decl-specs, that is, a list ((DECLARE foo) (DECLARE bar)) or a list (foo bar). I was unable to find anything in the document that would clarify this, especially since there is no section on the expansion of the DEFGENERIC macro. My confusion is augmented by the fact that 88-002R says the syntax of DEFGENERIC involves (DECLARE {declaration}+) yet other places in 88-002R, e.g. the syntax of DEFMETHOD, use "declaration" the same as CLtL2 p.215, which says a declaration is a list whose car is DECLARE. CLOS's terminology is not consistent with CLtL's terminology, and is not even self-consistent. Neither KMP nor I think there is a well-defined official ANSI CL terminology here, however KMP is now leaning towards using "declaration" to mean what CLtL calls a "decl-spec" and using "DECLARE expression" to mean what CLtL calls a "declaration". This seems reasonable to me. This is not only a documentation terminology issue; on p.3-93 there is a function listed called GENERIC-FUNCTION-DECLARATIONS (although this is one of the unrevised pages that we are not supposed to read); this function also exists in Symbolics CLOS, although at present it does not have any methods, and exists in Lucid CLOS where it returns a list of decl-specs. It would be unfortunate if there was a function named GENERIC-FUNCTION-DECLARATIONS but it returned decl-specs rather than declarations. If this function does what I suspect it does, and KMP's terminology is adopted, then everything will be consistent, which would be nice. 3-10 There are a bunch of problems with the table of inheritance structure of metaobject classes: There are no subclasses of funcallable-standard-object; I suspect that standard-generic-function should be one. If it's true, as reported in the paragraph after the table, that generic-function is an instance of funcallable-standard-class, then generic-function should also be a subclass of funcallable-standard-object. However I question whether, as an abstract class, generic-function should be committed to being a funcallable-standard-class. I question whether standard-accessor-method should inherit from standard-method (although it does so in Symbolics CLOS); there is no place other than standard-method to attach behavior related to methods that have method-functions, yet accessor methods do not have method-functions (at least not in the same way that normal methods do), and thus should not be inheriting the behavior associated with them. The problem here is that standard-method is being used both as a concrete class (defmethod instantiates it) and as an abstract class (standard-accessor-method inherits from it); this is almost always a signal of incorrect modularity. I believe standard-accessor-method should be a direct subclass of method. My final two comments are of lesser importance: There is a sentence fragment in the paragraph after the table that may have been intended as a caption. In each of the three classes for which multiple direct superclasses are listed, the order seems backwards to me because the class that seems more specific to me is listed second. However, Symbolics CLOS agrees with the specification here. 3-11 "interposed" Does this imply that in any CPL that includes C1, the classes C1, I, and C2 must appear in that order? I think you intended that, and it's implied by the standard CPL rules, but since nothing says non-specified classes can't use different CPL rules, I think this should be stated explicitly if it's what you intend. 3-13 The last bullet on this page, the one with the implementation note, seems silly to me. I see no reason why that information can't be recomputed when something is redefined. The restriction should either be removed or convincingly motivated. 3-17 It seems like a crock for the value of :initform to be unspecified when :initfunction is missing. What's the harm in requiring that either both be present or both be missing? 3-17 As I think I have pointed out before, this scheme for extended slot options can't work. Saying that the value is the option if it appears once, but a list of the options if it appears twice, causes a syntactic ambiguity. More seriously, it is entirely outside the spirit of Lisp to have one mechanism for the builtin slot options such as :initform and an entirely different mechanism for user-defined slot options. If the extension mechanism is incapable of implementing the built-in facilities, that's a sure sign of bad design. What's wrong with a very simple protocol for expanding slot options, such as a generic function expand-slot-option of a class (actually the prototype of the metaclass), the slot-option keyword, the object following the slot-option keyword, and the canonicalized slot specification so far, returning an updated canonicalized slot specification? (The last argument and the value are each actually a list of forms, which when evaluated and collected into a list will construct the canonicalized slot specification.) Only people who think EQL specializers should be flushed could object to this. There can be a very similar expand-class-option function. Cyphers had a hairier proposal that allowed the class and slot options to interact, but since that isn't necessary to implement the built-in options I would leave out the hair. 3-17 How come the :direct-default-initargs keyword argument to ensure-class doesn't have the same name as the class-option it represents? 3-17 A canonicalized default initarg in Symbolics CLOS is a list of four elements, where the first three are as the specification says and the fourth is a summary of the side-effects of the form. This kind of extensibility should be allowed. Personally I think it's a crock that this isn't a property list like a canonicalized slot specification. 3-19 This is not actually anything explicit in the MOP, but the example of extended slot options and class options on this page shows what I have long regarded as a flaw in thinking of how to extend CLOS, namely an excessive concern with name conflicts as the only problem that might arise when using different extensions together. The result of this is that extensions aren't allowed to use keyword symbols, because there is an idea that putting everything in its own package will eliminate conflicts. But this is contrary to the spirit of Lisp, which says that user-defined extensions shouldn't look syntactically different from the base language. Another way of saying the same thing is that extension designers are not going to be happy being forbidden to use keywords when the CLOS designers refused to accept the same restriction themselves. Name conflicts aren't a big problem anyway compared to some of the other problems that could occur if you tried to use two CLOS extensions at the same time anyway. Lucy Berlin's paper at OOPSLA 90 touches on this. I think extensions should be allowed to use whatever symbols they want, and in fact encouraged to use keyword symbols for naming options, and that the MOP should not pretend to make it unnecessary for extension writers to coordinate with each other. That's really not a CLOS issue anyway, it's really a programming methodology issue, how do you write programs that are good citizens of the shared Lisp world, and should be addressed at that level. 3-21, 3-22 "a non-null value for the :environment keyword argument." This is no good, there should be specific predicates for environments, not this violation of abstraction. If the MOP can't figure out how to deal with the compile-file environment issue, it shouldn't say anything about it at all, not say something that will have to be repudiated later. 3-22 "all of the initialization argument values must have applicable methods for the generic function make-load-form" -- this is inaccurate, since the specification of make-load-form says it is only called for certain metaclasses. What you are really trying to say (and I'm not sure why it's only said under make-method-lambda and not in all the other places that generate stuff that gets dumped by compile-file) is that all of the initialization argument names and values must be objects that are allowed in compiled constants (CLtL2 p.691). EDITORIAL COMMENTS The Xerox DocuTech Publishing System does not do a very good job of keeping the pages in order. However, I did not discover any pages that were actually missing. 3-8: "The name, allocation, and type are available as forms" -- these are of course objects, not forms. 3-11 stray "bf" 3-12 "from from" appears twice 3-13 "a small number of related" what? Probably methods. 3-18 How come the last bullet under slot options ("An implementation is free to add...") isn't repeated for class options? 3-18 I think I understand what the paragraph about ordering of arguments to ensure-class is trying to say, and I agree that it's reasonable, however it needs to be rewritten in better English. Use simpler sentence structure and a list of prescriptive requirements rather than a general requirement, an exception, and an exception to the exception, and it will be a lot easier to follow. 3-19 "effected" -> "affected" 3-21 "generic-function-default-method-class" in the figure is probably supposed to be "generic-function-method-class". 3-22 In Fig 3-5 "" is mis-indented. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA23584; Wed, 31 Oct 90 13:52:17 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16251>; Wed, 31 Oct 1990 13:50:11 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16251>; Wed, 31 Oct 1990 13:30:25 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410030; 31 Oct 1990 16:29:55-0500 X-Ns-Transport-Id: 08002008D0FD0003B289 Date: Wed, 31 Oct 1990 13:30:00 PST From: Scott Cyphers Subject: Firs set of comments on TAOTMOP part 2 To: mop@arisia.Xerox.COM Message-Id: <19901031213030.8.CYPHERS@SEAR.SCRC.Symbolics.COM> Comments on Volume 2 of "The Art of the Metaobject Protocol..." 3-7 first paragraph of Classes section: A class metaobject determines the structure and Add default behavior of its instances. Reason: Methods can also be EQL specialized. 3-8: second paragraph directly Rem in Add by the class Reason: Sounds better to me. 3-8: third paragraph Certain kinds of information Rem is Add are Reason: Grammar. 3-8: 4th par. available as Rem forms Add objects 3-8: second bullet as a function of no arguments Add , Reason: Grammar 3-8: fifth bullet those generic functions Rem for which there are Add with Reason: Simpler 3-8: first bullet for generic functions section the name is available as a function name. What if the generic function is unnamed? 3-9: 4th bullet in Methods ... method-function-applier I can't find a definition for this, so I can't say whether or not I can go along with this. 3-10: I think that there should be a class STANDARD-DEFMETHOD-METHOD with direct superclasses STANDARD-METHOD. STANDARD-DEFMETHOD-METHOD is what DEFMETHOD would normally expand into. One reason is that accessor methods have no need of a METHOD-FUNCTION, but ones defined by defmethod do. 3-11: 3rd par described in the section "Special Metaclasses". The referred to section needs something in it before these classes can be evaluated. 3-11: 4th par the class Rem es standard-object is Reason: Grammar. 3-12: end of 2nd bullet and in fact call-next-method is Add always invoked Reason: Conditionals. Perhaps something should be said about extensions which signal an error when things are inconsistent being permitted. This whole area of extensions is getting way out beyond what I think we have a good grasp on. 3-13: We need some concept of extensions to method combinations. If method combination MC allows methods qualified on qualifiers from the set Q, then MC+, with accepted qualifiers Q+ is an extension of MC iff Q is a subset of Q+ and MC+ behaves identically to MC when methods are qualified with qualifiers only from Q, and adding methods qualified from elements of Q+ not in Q will not change the order in which those methods qualified from Q will execute. For example, the following would be an extension to STANDARD: (DEFINE-METHOD-COMBINATION STANDARD-ERROR-CHECKING () ((AROUND (:AROUND)) (BEFORE (:BEFORE)) (PRIMARY () :REQUIRED T) (ERROR-CHECK (ERROR-CHECK) :ORDER :MOST-SPECIFIC-LAST) (AFTER (:AFTER) :ORDER :MOST-SPECIFIC-LAST)) (FLET ((CALL-METHODS (METHODS) (MAPCAR #'(LAMBDA (METHOD) `(CALL-METHOD ,METHOD)) METHODS))) (LET ((FORM (IF (OR BEFORE AFTER ERROR-CHECK (REST PRIMARY)) `(MULTIPLE-VALUE-PROG1 (PROGN ,@(CALL-METHODS BEFORE) (CALL-METHOD ,(FIRST PRIMARY) ,(REST PRIMARY))) ,@(CALL-METHODS ERROR-CHECK) ,@(CALL-METHODS AFTER)) `(CALL-METHOD ,(FIRST PRIMARY) ())))) (IF AROUND `(CALL-METHOD ,(FIRST AROUND) (,@(REST AROUND) (MAKE-METHOD ,FORM))) FORM)))) All the generic functions use STANDARD method combination, or an extension of it. 3-13: Last bullet Portable metaclasses cannot be redefined. Why not? I can see why user code shouldn't go around redefining the standard metaclasses for the same reason they shouldn't be allowed to redefine CAR, but I can't think of any reason to disallow it for user-defined metaclasses. I think the CLOS implementation should just make this kind of thing happen automatically via inheritance. 3-17: I can not accept the section for parsing of DEFCLASS, since it prohibits compile-time checking for spelling mistakes in option names. 3-18: The figure is obsolete and inconsistent with page 3-17. If I define the PLANE class with documentation, and then redefine it without documentation, what makes the documentation go away? 3-19: As stated previously, I can not accept the macroexpansion for SST. 3-19: Methods -- I'd still like to let the method body be involved in choosing the method's class. For example, (DEFMETHOD FOO-X ((THING FOO)) (SLOT-VALUE THING 'X)) should be able to turn into a reader method. This helps while expanding method combinations, a topic which I hope to get into the CLOS report. I think I sent a proposal for how to make DEFMETHOD, etc. do this back in May. 3-21: The above excepted, this expansion looks about right. 3-21: third par of Processing Method Bodies ensure-generic-function's :environment keyword -- How about just saying that this is an allowed keyword, the details of which are implementation-dependent? Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA06916; Wed, 31 Oct 90 20:38:11 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16271>; Wed, 31 Oct 1990 20:36:18 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16289>; Wed, 31 Oct 1990 20:34:29 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA27324g; Wed, 31 Oct 90 20:26:46 PST Received: by caligula id AA18813g; Wed, 31 Oct 90 20:30:52 PST X-Ns-Transport-Id: 08002008D0FD0003B75E Date: Wed, 31 Oct 1990 20:30:52 PST From: Jon L White Subject: Moon's comments on Draft 11 In-Reply-To: "Moon@STONY-BROOK.SCRC.Symbolics.COM's message of Wed, 31 Oct 1990 13:25:00 PST <19901031212511.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.COM Cc: mop@arisia.Xerox.COM Message-Id: <9011010430.AA18813@caligula> [Preview of this msg. Much of it relates to specific points brought up by you (Moon) in your cited message; but a few comments apply directly to the mop proposal: (1) METHOD-FUNCTION is an ill-considered concept, for reasons having nothing to do with the optimized implementations that elide it for STANDARD-ACCESSOR-METHOD's; see comments below on "next methods" context and APPLY-METHOD. (2) Allow GENERIC-FUNCTION to be a "built in" class; i.e., do not do anything that would require it to be of the same metaclass as STANDARD-GENERIC-FUNCTION. (3) Users are telling us that extensible slot-option parsing and processing is a requirement for them; let's look at Cypher's proposal sent out a few days ago. (4) Avoid the compile-file environment issue; pass the buck from the MOP realm into the compiler realm. (5) FUNCALLABLE is still too "cutsy" a syllable to be incorporated into serious names. It's acceptable only because it isn't used. ] re: It would be unfortunate if there was a function named GENERIC-FUNCTION-DECLARATIONS but it returned decl-specs rather than declarations. . . . From the rest of your comments, I take it that the "unfortunate" thing would be in the assymetry of the names -- "DECLS-SPECS" as opposed to generic-function "DECLARATIONS"? Although Lucid's 4.0 release supports the declarations "slot", it probably doesn't do anything with it. The next release, however, is making serious use of that information for a wide-variety of optimizations. re: However I question whether, as an abstract class, generic-function should be committed to being a funcallable-standard-class. The "STANDARD" in "STANDARD-GENERIC-FUNCTION" might simply mean "Obeys a SLOT-VALUE protocol". I don't particularly like that interpretation, but that is the only consistent reading of the use of "STANDARD" I could come up with. Thus the relation between STANDARD-GENERIC-FUNCTION and GENERIC-FUNCTION needn't be that of concrete to abstract class, but rather one simply of the former having the "slotted mixin" and the latter not having it. The array of these metaclasses in Lucid's CLOS is that a "slotted mixin" is mixed with the built-in class FUNCTION to get a class STANDARD-FUNCTION-OBJECT of metaclass STANDARD-FUNCTION-CLASS -- i.e., functions which submit to some sort of SLOT-VALUE protocol. By the bye, I'm using the term "slotted mixin" conceptually here rather than referring to an actual superclass; in the case at hand, the "mixin" is provided by a shift in metaclass rather than by an additional superclass [and in fact the slotted capability is adequately lifted into the metaclass realm by virtue of SLOT-VALUE-ABUSING-CLASS.] STANDARD-FUNCTION-CLASS and its company more than cover the notion of FUNCALLABLE-. [Lucid's CLOS supports the latter only for compatibility -- but there is currently little utility to it.] However, if we view the "GENERIC" mixin as submitting to an ADD-METHOD protocol, then I'm beginning to agree with you that GENERIC-FUNCTION shouldn't be of metaclass STANDARD-FUNCTION-CLASS (or FUNCALLABLE- STANDARD-CLASS) because the "generic mixin" by itself needn't require the full SLOT-VALUE protocol. The easy way out for Lucid might be simply to tag GENERIC-FUNCTION as of metaclass BUILT-IN-CLASS [there is surely no requirement for the superclasses of STANDARD-GENERIC- FUNCTION to be all of the same metaclass.] re: I question whether standard-accessor-method should inherit from standard-method (although it does so in Symbolics CLOS); there is no place other than standard-method to attach behavior related to methods that have method-functions, yet accessor methods do not have method-functions (at least not in the same way that normal methods do), and thus should not be inheriting the behavior associated with them. The problem here is that standard-method is being used both as a concrete class (defmethod instantiates it) and as an abstract class (standard-accessor-method inherits from it); this is almost always a signal of incorrect modularity. I believe standard-accessor-method should be a direct subclass of method. I'll have to disagree here (politely, if you please). From the preceeding comments about a meaning for "STANDARD", then STANDARD-METHOD's simply submit to a SLOT-VALUE protocol -- the "STANDARD" in no way bears on the utility of a FUNCTION slot. Now, the fact that three implementations do not in fact support a FUNCTION slot (in the "usual" way) for STANDARD-ACCESSOR-METHOD -- Symbolics, Lucid, and TI -- suggests that this concept isn't well thought out. It does not, to me at least, suggest that STANDARD-ACCESSOR-METHOD is poorly modularized as a subclass (or extension) of STANDARD-METHOD. The reason why I say "to me" is that Lucid's upcoming versions of CLOS will have trouble supporting the METHOD-FUNCTION concept for just about any methods; the difficulty will not be limited to just the subset of accessor methods. To drive the point home even more forcefully, what is the meaning of METHOD-FUNCTION for standard, primary methods that use CALL-NEXT-METHOD? Where is the "next methods" context? what is the meaning of a "function" for these methods without such context? Recall how in mid 1989, Lucid had to supply APPLY-METHOD which works a bit like APPLY, except that it has an additional required argument for the "next methods" context. re: [extensible slot-option processing] Cyphers had a hairier proposal that allowed the class and slot options to interact, but since that isn't necessary to implement the built-in options I would leave out the hair. I rather liked Scott's proposal, but because of it's detail, I haven't been able study it well enough for a deeper reply. re: I think ... the MOP should not pretend to make it unnecessary for extension writers to coordinate with each other. That's really not a CLOS issue anyway, it's really a programming methodology issue, how do you write programs that are good citizens of the shared Lisp world, and should be addressed at that level. I couldn't agree more. Additionally, I would categorize the overconcern with "compilation environments" for DEFCLASS etc. as similar in nature. These "cross compilation" issues should not be confused with the MOP, nor with anything particularly CLOS'y; they should only be addressed in detail, *** if addressed at all ***, in the context of a complete solution for compile-time definitions such as DEFMACRO, DEFSTRUCT, as well as a compile-time relativization of the package system and *FEATURES* list. re: If the MOP can't figure out how to deal with the compile-file environment issue, it shouldn't say anything about it at all, not say something that will have to be repudiated later. Hear, hear!! -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA23182; Thu, 1 Nov 90 08:13:51 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16295>; Thu, 1 Nov 1990 08:11:59 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16300>; Thu, 1 Nov 1990 08:01:45 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 866840; 1 Nov 1990 10:47:09-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0003BACC Date: Thu, 1 Nov 1990 07:49:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: Moon's comments on Draft 11 In-Reply-To: <9011010430.AA18813@caligula> To: Jon L White Cc: mop@arisia.Xerox.COM Message-Id: <19901101154941.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> In this message I am just answering questions that JonL asked me directly, so lots of JonL's message is elided. Date: Wed, 31 Oct 1990 23:30 EST From: Jon L White re: It would be unfortunate if there was a function named GENERIC-FUNCTION-DECLARATIONS but it returned decl-specs rather than declarations. . . . From the rest of your comments, I take it that the "unfortunate" thing would be in the assymetry of the names -- "DECLS-SPECS" as opposed to generic-function "DECLARATIONS"? I would have said "inconsistency" rather than "assymetry", but yes. I certainly don't object to the existence of the function, I'm just trying to make sure Common Lisp's terminology is consistent so there is some hope of people being able to understand the definition of the language. re: However I question whether, as an abstract class, generic-function should be committed to being a funcallable-standard-class. The "STANDARD" in "STANDARD-GENERIC-FUNCTION" might simply mean "Obeys a SLOT-VALUE protocol". I don't particularly like that interpretation, but that is the only consistent reading of the use of "STANDARD" I could come up with. I had always assumed that in CLOS, standard-this and standard-that means "the class that is used by the programmer interface macros specified in the standard." I couldn't find this written down explicitly anywhere, but it's a sensible reading of CLtL2 p.800. I don't think it has anything to do with SLOT-VALUE. Thus the relation between STANDARD-GENERIC-FUNCTION and GENERIC-FUNCTION needn't be that of concrete to abstract class, but rather one simply of the former having the "slotted mixin" and the latter not having it. I can't figure out what you're getting at here. Are you claiming that GENERIC-FUNCTION is not an abstract class, that is, are you claiming that the MOP defines what it means to do (MAKE-INSTANCE 'GENERIC-FUNCTION ...)? The first paragraph on p.3-11 of the pink book directly contradicts that. And you can't be claiming that STANDARD-GENERIC-FUNCTION is not a concrete class or not a subclass of GENERIC-FUNCTION. Of course since neither the MOP, nor I, nor you, have defined the terms "abstract class" and "concrete class" we might not mean the same thing by them. By "abstract class" I mean a class that is not intended to be instantiated, only to be subclasses, and by "concrete class" I mean any class that is not abstract. You and I probably do not disagree here, since we both conclude that the metaclass of GENERIC-FUNCTION specified on p.3-10 is questionable. re: I question whether standard-accessor-method should inherit from standard-method (although it does so in Symbolics CLOS); there is no place other than standard-method to attach behavior related to methods that have method-functions, yet accessor methods do not have method-functions (at least not in the same way that normal methods do), and thus should not be inheriting the behavior associated with them. The problem here is that standard-method is being used both as a concrete class (defmethod instantiates it) and as an abstract class (standard-accessor-method inherits from it); this is almost always a signal of incorrect modularity. I believe standard-accessor-method should be a direct subclass of method. I'll have to disagree here (politely, if you please). From the preceeding comments about a meaning for "STANDARD", then STANDARD-METHOD's simply submit to a SLOT-VALUE protocol -- the "STANDARD" in no way bears on the utility of a FUNCTION slot. The FUNCTION slot is a red herring and I'm sorry I led you in that direction. Let me try again. "The class STANDARD-METHOD is the default class of methods that are defined by the forms [sic] DEFMETHOD, ..." (CLtL2 p.800, from 88-002R). Page 3-10 of the pink book lists three subclasses of STANDARD-METHOD. Nothing in the revised pages of the pink book says what these three classes are for, but from the names and from what we've seen in past MOPs we can assume that DEFCLASS uses them in implementing the :READER, :WRITER, and :ACCESSOR slot options. Presumably it instantiates two of them and the third serves as a common superclass to organize behavior common to readers and writers. My objection is to STANDARD-METHOD being used for two distinct purposes: as the default class of methods for DEFMETHOD, and as the superclass of several other classes. These purposes are distinct and should be served by separate classes. I see two ways to do that. One is to make STANDARD-ACCESSOR-METHOD a direct subclass of METHOD instead of a direct subclass of STANDARD-METHOD; the other is to make a new class that is a direct superclass of both STANDARD-METHOD and STANDARD-ACCESSOR-METHOD. I support the former because it's simpler and I can't see a reason for the latter, but I would certainly accept the latter if there is a reason for it, for example if there is common behavior between the default method class used by DEFMETHOD and the default method class used by DEFCLASS that should be captured on a common superclass. We can't make the default class for DEFMETHOD be a new subclass of STANDARD-METHOD because that would contradict 88-002R, otherwise this would be a third way out. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA23933; Thu, 1 Nov 90 08:41:17 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16297>; Thu, 1 Nov 1990 08:39:46 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16304>; Thu, 1 Nov 1990 08:35:10 PST Received: from rose (rose.lucid.com) by heavens-gate.lucid.com id AA02152g; Thu, 1 Nov 90 08:28:20 PST Received: by rose id AA05803g; Thu, 1 Nov 90 08:32:14 PST Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: Richard P.Gabriel ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0003BB33 Date: Thu, 1 Nov 1990 08:32:14 PST From: rpg@lucid.com Subject: Moon's comments on Draft 11 In-Reply-To: "Moon@STONY-BROOK.SCRC.Symbolics.COM's message of Thu, 1 Nov 1990 07:49:00 PST <19901101154941.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.COM Cc: jonl@lucid.com, mop@arisia.Xerox.COM Message-Id: <9011011632.AA05803@rose> I don't happen to own any books that are pink, aside from one about hermeneutics. To what do you refer with the expression ``the pink book''? -rpg- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA24060; Thu, 1 Nov 90 08:45:46 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16291>; Thu, 1 Nov 1990 08:42:00 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16317>; Thu, 1 Nov 1990 08:38:06 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 866895; 1 Nov 1990 11:37:34-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted Illegal-Object: Syntax error in To: address found on alpha.xerox.com: To: Richard P.Gabriel ^ ^-missing end of address \-extraneous tokens in address X-Ns-Transport-Id: 08002008D0FD0003BB3B Date: Thu, 1 Nov 1990 08:40:00 PST From: Moon@stony-brook.scrc.symbolics.COM Subject: Moon's comments on Draft 11 In-Reply-To: <9011011632.AA05803@rose> To: mop@arisia.Xerox.COM Cc: jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <19901101164009.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Date: Thu, 1 Nov 1990 11:32 EST From: Richard P. Gabriel I don't happen to own any books that are pink, aside from one about hermeneutics. To what do you refer with the expression ``the pink book''? Draft 11 metaobject protocol specification, handed out by Gregor at the CLOS Workshop that you weren't at with a pink cover. JonL was at the workshop briefly, perhaps he picked up a copy. It's the document on which we are all commenting. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA28721; Thu, 1 Nov 90 10:33:00 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16318>; Thu, 1 Nov 1990 10:31:19 PST Received: from nero.parc.xerox.com ([13.2.16.60]) by alpha.xerox.com with SMTP id <16313>; Thu, 1 Nov 1990 10:09:34 PST Received: by nero.parc.xerox.com (5.61+/IDA-1.2.8/gandalf) id AA02047; Thu, 1 Nov 90 10:10:19 PST Received: from Messages.7.14.N.CUILIB.3.45.SNAP.NOT.LINKED.nero.parc.xerox.com.sun4.40 via MS.5.6.nero.parc.xerox.com.sun4_40; Thu, 1 Nov 1990 10:10:18 -0800 (PST) X-Ns-Transport-Id: 08002008D0FD0003BC73 Date: Thu, 1 Nov 1990 10:10:18 PST From: Danny Bobrow Subject: Fwd: Returned mail: User unknown To: mop.parc@xerox.com Message-Id: <4bA6I_gB0V0wE7WbZs@nero.parc.xerox.com> References: <9011011750.AA01995@nero.parc.xerox.com> Excerpts from mail: 30-Oct-90 mop questions davis@ilog.ilog.fr (3091) > For instance, in section 3.5 there is a > discussion of the difference between making SLOT-VALUE generic and > using SLOT-VALUE-USING-CLASS. However, there is no explanation of why > the CLOS MOP chose the latter approach, or of other alternatives for > the slot access protocol. Gregor and Jim have answered many of the direct questions. I thought I would take a crack at this one. In Jim's answer, he talks about the PERSISTENT-OBJECT example, how the metaclass can be distributed over many disparate parts of the class space not connected bhas a different distribution than an inheritance hierarchy. On the other hand, in many examples, an inheritance hierarchy provides exactly the right handle for a change in how SLOT-VALUE should work. The argument for using SLOT-VALUE-USING-CLASS is therefore that both options are available since its arguments are . Cheers danny Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA05104; Thu, 1 Nov 90 11:56:22 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16319>; Thu, 1 Nov 1990 11:54:37 PST Received: from inria.inria.fr ([128.93.8.1]) by alpha.xerox.com with SMTP id <16318>; Thu, 1 Nov 1990 11:12:05 PST Received: by inria.inria.fr (5.64+/90.0.9) via Fnet-EUnet id AA11781; Thu, 1 Nov 90 20:11:14 +0100 (MET) Received: from barbes.ilog.fr by ilog.ilog.fr, Thu, 1 Nov 90 19:33:47 +0100 Received: by barbes.ilog.fr, Thu, 1 Nov 90 19:31:12 +0100 X-Ns-Transport-Id: 08002008D0FD0003BD81 Date: Thu, 1 Nov 1990 10:31:12 PST From: davis@ilog.ilog.fr Subject: Defining readers and writers in DEFCLASS or with separate forms In-Reply-To: "David A. Moon's message of Wed, 31 Oct 1990 16:45-0500 <19901031214541.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.COM Cc: gregor@parc.xerox.com, mop.parc@xerox.com, davis@barbes.ilog.fr Message-Id: <9011011831.AA00218@barbes.ilog.fr> Mopers, I didn't realize mop@xerox had such a wide distribution. Again I reiterate that I'm considering these questions in the light of EuLisp. I apologize to those reading who haven't had a chance to read the current version of the EuLisp definition. I can mail Latex sources of this (evolving) document to those who are interested. You should be very interested, because it is quite long and rather complicated to produce from what I can give you. I agree that it would have been a reasonable choice to remove readers and writers from DEFCLASS and do them separately. CLOS chose to include an abbreviation for this common programming cliche. In the current EuLisp definition, DEFCLASS and DEFSTRUCT are considered shorthand for a (potential) MAKE-INSTANCE + global binding + declaration and the accessor defining operations. I disagree that adding DEFREADER and DEFWRITER to the language is reasonable. I am not suggesting adding DEFREADER and DEFWRITER to CommonLisp. That decision is, in any case, already made. However, here we have this new language, EuLisp, whose object system is largely derived from CLOS, and so I want to see how much of pure CLOS makes sense in that context and how these other ideas might fit in. If readers and writers are going to be defined with separate forms, they can be defined with DEFMETHOD. There is no reason at all that DEFMETHOD should not be adequate for this. Even in CLOS, I don't see how the current version of DEFMETHOD can do the equivalent of the accessor definitions. Gregor suggested that DEFMETHOD be able to determine the class of the method metaobject produced, and I think that would do the trick. But, two comments. First, the reason to do so certainly isn't to help the compiler. Unless I am missing something, the compiler should be able to do just as well well with the CLOS form as with explicit DEFREADER/DEFWRITER forms. In CLOS the accessor slot options are defined to produce methods of particular classes on generic functions of constant names. In EuLisp, these options are guaranteed to do the same thing as equivalent DEFREADER/DEFWRITER/DEFACCESSOR defining forms. So in this sense the compiler can do the analysis in both languages. The point I was trying to make, perhaps badly expressed in my original note, is that if some defining form is going to make a definition, there should be a way for the user to do it explicitly as well. A related sidenote: The new MOP goes to great lengths to forbid the metalevel programmer from overriding the behavior provided by the STANDARD-CLASS methods for INITIALIZE-INSTANCE and SHARED-INITIALIZE. I am not entirely sure why it was done this way instead of the (perhaps more complicated) behavioral restrictions on what an overriding method can do. However, there is a large area of class initialization behavior outside the scope of those rules which can be completely overridden. For example, if I wanted to break the rules about what the accessor options do for a new class metaobject class and slot definition metaobject class, it would be easy to write a method for DIRECT-SLOT-DEFINITION-CLASS for the new class metaobject class and then an overriding method for SHARED-INITIALIZE for the new slot definition metaobject class. Did you mean for similar restrictions to apply to INIATILIZE-INSTANCE/SHARED-INITIALIZE for other metaobject classes as well? Second, I believe that if you were really going to do this right, the only thing you would define is the underlying functionality---the explicit metaobject manipulation layer. None of these macros, or the UI syntax in terms of Lispo forms would be defined. This is fine for implementors but ignores the issue what language programmers use to communicate with each other. It's nice to have a standard for the surface syntax of Lisp forms so that programmers can read each others' programs. I suppose you coudl argue that publication should be in a machine-readable form which each reader translates to their favorite surface syntax (using a program) before reading it. In fact, the EuLisp definition specifies the defining forms, the generic functions used to implement them, and the behavior of the kernel metaobject classes for these generic functions. I think this is what Gregor means, but perhaps I'm wrong. I agree (I think) with Moon that it is important to define both layers, but not just for programmer convenience, and not just because we are technologically impoverished. The defining form layer provides explicit compiler declarations which the underlying functions cannot since they do not refer to names. Thank you all again for participating in a discussion which is not necessarily directly relevant to your work. -- Harley Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA15684; Thu, 1 Nov 90 14:36:52 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16333>; Thu, 1 Nov 1990 14:35:12 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16329>; Thu, 1 Nov 1990 14:32:46 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA05628g; Thu, 1 Nov 90 14:25:33 PST Received: by caligula id AA20189g; Thu, 1 Nov 90 14:29:41 PST X-Ns-Transport-Id: 08002008D0FD0003C0C2 Date: Thu, 1 Nov 1990 14:29:41 PST From: Jon L White Subject: Moon's comments on Draft 11 In-Reply-To: "David A. Moon's message of Thu, 1 Nov 1990 10:49-0500 <19901101154941.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@STONY-BROOK.SCRC.Symbolics.COM Cc: mop@arisia.Xerox.COM Message-Id: <9011012229.AA20189@caligula> re: One is to make STANDARD-ACCESSOR-METHOD a direct subclass of METHOD instead of a direct subclass of STANDARD-METHOD; the other is to make a new class that is a direct superclass of both STANDARD-METHOD and STANDARD-ACCESSOR-METHOD. I support the former because it's simpler and I can't see a reason for the latter, but I would certainly accept the latter if there is a reason for it, for example if there is common behavior between the default method class used by DEFMETHOD and the default method class used by DEFCLASS that should be captured on a common superclass. We can't make Wait a minute -- isn't the default class used for DEFMETHOD the class in GENERIC-FUNCTION-METHOD-CLASS? (and the default for the corresponding argument to DEFGENERIC is STANDARD-METHOD class.) I liked Scott's idea of having a way to say to DEFMETHOD that you want it to make a method of a non-default class; Gregor seemd to support that too. As to whether the method class for accessor methods should NOT be a subclass of STANDARD-METHOD -- well, those accessor methods, as objects, certainly share a awful lot with STANDARD-METHOD's, with only a delta's worth of difference. That's the classic case for subclassing in order to maximize code reusability. Consider, for a moment, the task that an end user would have if he were to define a new method class; it would be very hard for him to do it without recourse to subclassing STANDARD-METHOD -- *almost* as hard as it would be to correctly define a new metaclass that isn't a subclass of STANDARD-CLASS. This isn't to say that it's a stumbling block for implementors, but rather to point out the value of code and class reusability. So I'd want to see very good semantic (or typological, or theological) reason before giving up on the commonality. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA19328; Thu, 1 Nov 90 15:24:16 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16400>; Thu, 1 Nov 1990 15:22:42 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16319>; Thu, 1 Nov 1990 14:50:28 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 867236; 1 Nov 1990 17:50:11-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0003C0FE Date: Thu, 1 Nov 1990 14:52:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: Moon's comments on Draft 11 In-Reply-To: <9011012229.AA20189@caligula> To: Jon L White Cc: mop@arisia.Xerox.COM Message-Id: <19901101225247.7.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> My only response to this message is that you do not appear to have read anything that I said in my message. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04551; Thu, 1 Nov 90 18:59:28 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16429>; Thu, 1 Nov 1990 18:57:38 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16431>; Thu, 1 Nov 1990 18:56:07 PST Received: by spade.parc.xerox.com id <285>; Thu, 1 Nov 1990 18:56:47 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003C412 Date: Thu, 1 Nov 1990 18:56:35 PST From: Gregor Kiczales Subject: Re: Moon's comments on Draft 11 In-Reply-To: "Jon L White's message of Wed, 31 Oct 1990 20:30:52 PST <9011010430.AA18813@caligula>" To: jonl@lucid.COM Cc: Moon@stony-brook.scrc.symbolics.COM, mop@arisia.Xerox.COM Message-Id: <90Nov1.185647pst.285@spade.parc.xerox.com> Date: Wed, 31 Oct 1990 20:30:52 PST From: Jon L White (1) METHOD-FUNCTION is an ill-considered concept, for reasons having nothing to do with the optimized implementations that elide it for STANDARD-ACCESSOR-METHOD's; see comments below on "next methods" context and APPLY-METHOD. Yes, this is true. It is one of the things I plan to fix in this final draft. Once it is fixed, method-function will be relevant to accessor methods as well as other methods. That is, accessor methods will be required to return a method that does the right thing. Most implementations, internally, probably won't ask for it though (unless of course they have reason to believe the user has mucked with it in some way). (3) Users are telling us that extensible slot-option parsing and processing is a requirement for them; let's look at Cypher's proposal sent out a few days ago. I would like to see the user comments in detail. The current draft of the MOP supports some slot option parsing. A little less than I might have liked, but others encouraged me to ramp it down. (4) Avoid the compile-file environment issue; pass the buck from the MOP realm into the compiler realm. The current draft has less than it used to. I would be glad to take what it there out, but I was pushed to try and include it a long time ago. I guess since then we have realized that we can't get it right. (5) FUNCALLABLE is still too "cutsy" a syllable to be incorporated into serious names. It's acceptable only because it isn't used. I am reluctant to make simple name changes at this late stage. The "STANDARD" in "STANDARD-GENERIC-FUNCTION" might simply mean "Obeys a SLOT-VALUE protocol". I don't particularly like that interpretation, but that is the only consistent reading of the use of "STANDARD" I could come up with. "STANDARD-" means the one that the user interface macros use by default. That is, what 88-002R says they do if you don't do any MOP stuff. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA05607; Thu, 1 Nov 90 19:14:14 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16431>; Thu, 1 Nov 1990 19:12:19 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16426>; Thu, 1 Nov 1990 19:09:43 PST Received: by spade.parc.xerox.com id <284>; Thu, 1 Nov 1990 19:10:33 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003C434 Date: Thu, 1 Nov 1990 19:10:21 PST From: Gregor Kiczales Subject: Re: Defining readers and writers in DEFCLASS or with separate forms In-Reply-To: 's message of Wed, 31 Oct 1990 13:45:00 PST <19901031214541.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> To: Moon@stony-brook.scrc.symbolics.COM Cc: davis@ilog.ilog.fr, mop.parc@xerox.com Message-Id: <90Nov1.191033pst.284@spade.parc.xerox.com> Date: Wed, 31 Oct 1990 13:45:00 PST From: This is fine for implementors but ignores the issue what language programmers use to communicate with each other. It's nice to have a standard for the surface syntax of Lisp forms so that programmers can read each others' programs. I suppose you coudl argue that publication should be in a machine-readable form which each reader translates to their favorite surface syntax (using a program) before reading it. I could and I would. In at least two ways. First, one of the best things about (well-done) structure editors is that they let each reader look at code formatted according to their personal preferences --- even code originally written by someone else. If you like your IF statements formatted the "other" way, you can see them that way, even in code you didn't write. If you edit code someone else wrote, then when they go back to look at it, they will see it in their preferred formatting. This can be carried forth to other kinds of things, like the number of semi-colons that introduce a comment (or for that matter whether comments are delineated with semi-colons or some other way entirely). (Just think of all the fights that preempts!) Second, except for the rare occasions when it appears in a paper or book, "publication" of code is already in a machine readable form. Its just that our familiarity with ASCII somehow makes us think of it as being somehow less encoded than format like the one I am suggesting. In some sense it is less encoded---the program that decodes it is probably simpler than the program that decodes the representation I am suggesting. But, we still need that program. A floppy disk without a machine and appropriate software to read it is pretty opaque. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA06051; Thu, 1 Nov 90 19:21:15 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16429>; Thu, 1 Nov 1990 19:19:53 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16429>; Thu, 1 Nov 1990 19:18:28 PST Received: by spade.parc.xerox.com id <288>; Thu, 1 Nov 1990 19:19:07 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003C446 Date: Thu, 1 Nov 1990 19:19:00 PST From: Gregor Kiczales Subject: Re: Moon's comments on Draft 11 In-Reply-To: "Moon@STONY-BROOK.SCRC.Symbolics.COM's message of Thu, 1 Nov 1990 07:49:00 PST <19901101154941.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.COM Cc: jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <90Nov1.191907pst.288@spade.parc.xerox.com> Date: Thu, 1 Nov 1990 07:49:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM My objection is to STANDARD-METHOD being used for two distinct purposes: as the default class of methods for DEFMETHOD, and as the superclass of several other classes. These purposes are distinct and should be served by separate classes. Yes, this is a problem. I favor the first solution. Trying to get the second solution to work would involve coming up with a name for the new interposed class. That leads very quickly, at least in my mind, to a reexamination of all the names we are using so far. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA13126; Thu, 1 Nov 90 21:14:35 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16431>; Thu, 1 Nov 1990 21:12:56 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16431>; Thu, 1 Nov 1990 21:11:05 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA09062g; Thu, 1 Nov 90 21:03:14 PST Received: by caligula id AA20847g; Thu, 1 Nov 90 21:07:23 PST X-Ns-Transport-Id: 08002008D0FD0003C506 Date: Thu, 1 Nov 1990 21:07:23 PST From: Jon L White Subject: Moon's comments on Draft 11 In-Reply-To: "David A. Moon's message of Thu, 1 Nov 1990 17:52-0500 <19901101225247.7.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@STONY-BROOK.SCRC.Symbolics.COM Cc: mop@arisia.Xerox.COM Message-Id: <9011020507.AA20847@caligula> re: My only response to this message is that you do not appear to have read anything that I said in my message. The trouble with this kind of public message is that it gives no one any clue at all as to what you are thinking about. Recall that I quoted part of your message in my reply, and inferred from it that one of your suggestions would *not* have STANDARD-ACCESSOR-METHOD be a subclass of STANDARD-METHOD: [moon]: ... make STANDARD-ACCESSOR-METHOD a direct subclass of METHOD instead of a direct subclass of STANDARD-METHOD; . . . [jonl]: As to whether the method class for accessor methods should NOT be a subclass of STANDARD-METHOD -- well, those accessor methods, as objects, . . . I made no comment on your other suggestion, although contrary to your surmise, I did read it. Maybe you'd like to take another shot at a reply or rebuttal now? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16399; Thu, 1 Nov 90 22:13:36 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16435>; Thu, 1 Nov 1990 22:11:34 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16435>; Thu, 1 Nov 1990 22:10:30 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA09570g; Thu, 1 Nov 90 22:03:37 PST Received: by caligula id AA20880g; Thu, 1 Nov 90 22:07:46 PST X-Ns-Transport-Id: 08002008D0FD0003C552 Date: Thu, 1 Nov 1990 22:07:46 PST From: Jon L White Subject: Continuing comments on Draft 11 In-Reply-To: "Gregor Kiczales's message of Thu, 1 Nov 1990 18:56:35 PST <90Nov1.185647pst.285@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: mop@arisia.Xerox.COM Message-Id: <9011020607.AA20880@caligula> [First, some points of continuing interchage with your recent message; then two new comments on Draft 11. I will have more new comments at a later time, hopefully before Nov 15.] re: Once it is fixed, method-function will be relevant to accessor methods as well as other methods. That is, accessor methods will be required to return a method that does the right thing. Most implementations, internally, probably won't ask for it though (unless of course they have reason to believe the user has mucked with it in some way). In fact, Lucid's implementations return a dumb function that does do a partially optimized SLOT-VALUE (mostly it does so in order to support the METHOD-FUNCTION that came out of the moon/cyphers/jonl/franz(?) manifesto last March for a de-facto metaobject protocol). Probably some other implementations do the same. But what's the point of having it if, as you say, no implementation would really use it? and if it is *only* supported for compatibility? In addition, as far as I know, no one has addressed the question of methods requireing "next methods" context yet. re: [Users requesting tailorable slot specification protocols] I would like to see the user comments in detail. Right. Andreas sent some out recently (to which email list? I can't remember). I have received some suggestions verbally from people who wanted to add an option which basically said "do type-checking on stores into this slot"; there's not much more to this except the need to be able to parse a user-specified option, and to store the result in a user-specified field of the slot-definition. I vaguely remember something in one of the CLOS workshop papers also, but . . . re: [compile-file environment issues] The current draft has less than it used to. Now that you mention it, I see you're quite right! It even has an apologetic paragraph mentioning the "significant variance" among implementations on the matter. Good show. Then I'm only echoing Moon's suggestion to remove the couple of remaining fuzzy statements. re: [FUNCALLABLE] I am reluctant to make simple name changes at this late ... Yup. Well, hey, we still have CAR and CDR despite FIRST and REST, no? re: "STANDARD-" means the one that the user interface macros use by default. That is, what 88-002R says they do if you don't do any MOP stuff. Well that's an interesting view. But you can change the default for DEFMETHOD by calling DEFGENERIC with a :method-class option, and that step alone isn't MOP'y. It's entirely another matter to say that you can't create any other method class without MOP, or to say that none of the specified metaobjects other than STANDARD-METHOD and its subclasses will be suitable. How about this view: ``STANDARD means "concrete"; otherwise "abstract"'', with only a coule of exceptions (METHOD-COMBINATION and STRUCTURE-CLASS come to mind as exceptions, but they are also exceptions to the rule of ``"standard" means "default"''). Probably it's only a coincidence that all three views mostly coincide [the third being that ``"standard" means "slotted"''.] Two point I want to bring up now, to get your feeling on them before I say more in detail. In an email discussion in the past, I recall discussing a fatal flaw in the design of ENSURE-GENERIC-FUNCTION -- namely the :lambda-list argument doesn't carry enough information to be able to distinguish the dual purposes of (a) a target of macroexpansion for DEFMETHOD and of (b) a target of macroexpansion for DEFGENERIC. The current draft, under the DEFMETHOD section "Processing Method Bodies" punts the issue to ``The section "The Defgeneric Macro"''; but I can't find this section. Did I overlook it somewhere, or is this an intentionalp lacuna? There are six metaobject classes at or under SLOT-DEFINITION? why? Implementationally, there isn't any need to make a class distinction between "direct" and "effective" -- this can be done by keeping separate lists. Admittedly, there is a need for a generic function that goes through the step of taking collected direct definitions and producing the effective definitions; but another class isn't needed. The alternative would have at most two classes. -- JonL -- P.S. Do we need a STANDARD-METHOD-COMBINATION? Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA20968; Fri, 2 Nov 90 08:03:18 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16463>; Fri, 2 Nov 1990 08:01:07 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16447>; Fri, 2 Nov 1990 07:50:27 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410388; 2 Nov 1990 10:48:54-0500 X-Ns-Transport-Id: 08002008D0FD0003C897 Date: Fri, 2 Nov 1990 07:49:00 PST From: Scott Cyphers Subject: Continuing comments on Draft 11 In-Reply-To: <9011020607.AA20880@caligula> To: jonl@lucid.COM, gregor@parc.xerox.com Cc: mop@arisia.Xerox.COM Message-Id: <19901102154943.7.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Fri, 2 Nov 1990 01:07 EST From: Jon L White In addition, as far as I know, no one has addressed the question of methods requireing "next methods" context yet. It turns out that I reimplemented how method combination works, and forgot to tell myself that things turned out simpler that time around. I no longer have any strong objections to the hierarchy of method classes. I am mildly wondering if we need accessor methods at all, but haven't had a chance to think about it yet. Internally, in our implementation, all the functions that implement methods (I'll avoid the word method-function), as well as those which implement the connecting glue of an effective method, take an extra argument. The second value returned form MAKE-METHOD-LAMBDA tells what the method's function expects to find in the extra argument. Our method combination code fills in the extra argument. Presumably an APPLY-METHOD-LAMBDA kind of thing would have to do the same thing. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA28861; Fri, 2 Nov 90 10:02:22 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16477>; Fri, 2 Nov 1990 09:55:52 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16477>; Fri, 2 Nov 1990 09:54:07 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA13844g; Fri, 2 Nov 90 09:47:04 PST Received: by caligula id AA21624g; Fri, 2 Nov 90 09:51:12 PST X-Ns-Transport-Id: 08002008D0FD0003C9B1 Date: Fri, 2 Nov 1990 09:51:12 PST From: Jon L White Subject: Continuing comments on Draft 11 In-Reply-To: "Scott Cyphers's message of Fri, 2 Nov 1990 10:49-0500 <19901102154943.7.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: gregor@parc.xerox.com, mop@arisia.Xerox.COM Message-Id: <9011021751.AA21624@caligula> re: Internally, in our implementation, all the functions that implement methods (I'll avoid the word method-function), as well as those which implement the connecting glue of an effective method, take an extra argument. Since you said this in the context of the comment: In addition, as far as I know, no one has addressed the question of methods requireing "next methods" context yet. I presume you are talking about your technique for implementing "next methods" contexts? I think that TI does it by passing a hidden argument to the function (the method-call protocol bashes it into a pre-arranged local var in the forming stackframe). But this isn't suitable for interpretation, nor is it practical for Lucid's implementaion. What you are talking about looks like "currying" on an extra formal parameter to the method-lambda. We had considered that at Lucid a long time ago, and decided that we couldn't tolerate the extra stack shuffling that would imply in certain circumstances where the extra "curry'd" argument caused the frame to be "off by one". But it is still a very attractive idea. So I wonder, is the vanilla definition of METHOD-FUNCTION really every going to be very useful? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01966; Fri, 2 Nov 90 10:49:04 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16464>; Fri, 2 Nov 1990 10:43:45 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16467>; Fri, 2 Nov 1990 10:30:55 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410431; 2 Nov 1990 13:29:29-0500 X-Ns-Transport-Id: 08002008D0FD0003CA20 Date: Fri, 2 Nov 1990 10:30:00 PST From: Scott Cyphers Subject: Continuing comments on Draft 11 In-Reply-To: <9011021751.AA21624@caligula> To: jonl@lucid.COM, Cyphers@JASPER.SCRC.Symbolics.COM Cc: gregor@parc.xerox.com, mop@arisia.Xerox.COM Message-Id: <19901102183017.1.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Fri, 2 Nov 1990 12:51 EST From: Jon L White re: Internally, in our implementation, all the functions that implement methods (I'll avoid the word method-function), as well as those which implement the connecting glue of an effective method, take an extra argument. Since you said this in the context of the comment: In addition, as far as I know, no one has addressed the question of methods requireing "next methods" context yet. I presume you are talking about your technique for implementing "next methods" contexts? I think that TI does it by passing a hidden argument to the function (the method-call protocol bashes it into a pre-arranged local var in the forming stackframe). But this isn't suitable for interpretation, nor is it practical for Lucid's implementaion. What you are talking about looks like "currying" on an extra formal parameter to the method-lambda. We had considered that at Lucid a long time ago, and decided that we couldn't tolerate the extra stack shuffling that would imply in certain circumstances where the extra "curry'd" argument caused the frame to be "off by one". But it is still a very attractive idea. The idea goes back at least to old flavors, probably about the time when instance variables stopped being specials. On the 386, if the compiler believes a generic function is being called, I think it leaves a hole for the extra argument (hence it helps performance to have your defgenerics appear early). The hole doesn't matter if it turns out not to have been a generic function. If a generic function gets called where the compiler didn't leave the hole, then the arguments get copied. This turned out to work pretty well. On Ivory, the start call instruction will push an extra argument if the data type of the function is one of several things, one of which is a generic function. On the 3600, function calls always copy the arguments, and the microcode knows to put the hole in for the extra argument. So I wonder, is the vanilla definition of METHOD-FUNCTION really every going to be very useful? I was wondering about that myself. I'd like to see a simple example of a proposed use of METHOD-FUNCTION; it may be doing something completely different from what we are thinking it does. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA03716; Fri, 2 Nov 90 11:07:29 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16490>; Fri, 2 Nov 1990 11:05:05 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16467>; Fri, 2 Nov 1990 10:59:59 PST Received: by spade.parc.xerox.com id <294>; Fri, 2 Nov 1990 10:57:20 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003CA8D Date: Fri, 2 Nov 1990 10:57:17 PST From: Gregor Kiczales Subject: Re: Continuing comments on Draft 11 In-Reply-To: "Jon L White's message of Thu, 1 Nov 1990 22:07:46 PST <9011020607.AA20880@caligula>" To: jonl@lucid.COM Cc: mop@arisia.Xerox.COM Message-Id: <90Nov2.105720pst.294@spade.parc.xerox.com> Date: Thu, 1 Nov 1990 22:07:46 PST From: Jon L White [First, some points of continuing interchage with your recent message; then two new comments on Draft 11. I will have more new comments at a later time, hopefully before Nov 15.] Note that the November 15th date is of particular importance for the gray volume (part 1). While the pink volume (part 2) is important---it delivers the details of (much of) one MOP design---part 1 is really more now. Given that we are no longer trying to establish a standard, but rather trying to deliver the results of a useful piece of work, the explanations of concepts and background in part 1 are of more lasting value than the details of a particular design. Which is not to say that I don't want to try and improve the existing design. I do, and I appreciate all the feedback people are giving. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA09424; Fri, 2 Nov 90 12:15:37 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16474>; Fri, 2 Nov 1990 12:10:19 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <16474>; Fri, 2 Nov 1990 12:03:39 PST X-Ns-Transport-Id: 08002008D0FD0003CB82 Date: Fri, 2 Nov 1990 12:20:06 PST From: kanderso@DINO.BBN.COM Subject: [Jeff Morrill: MOP hacks] To: mop@arisia.Xerox.COM Cc: jmorrill@DINO.BBN.COM, reinhard@DINO.BBN.COM Message-Id: <90Nov2.120339pst.16474@alpha.xerox.com> I asked some of our slot hackers to describe their experience to support this discussion. This is a response from Jeff Morrill. Tom Reinhardt also has some interesting experience with this, and described some of it in detail at a CLOS workshop at OPSLA 1989. k ------- Forwarded Message Date: Fri, 2 Nov 90 13:33 EST From: Jeff Morrill Subject: MOP hacks To: kanderson@BBN.COM cc: jmorrill@BBN.COM, delatizky@BBN.COM, treinhardt@BBN.COM Message-ID: <19901102183324.2.JMORRILL@adams.bbn.com> Ken, You asked for a description of what I have done with the mop. Here are the highlights. 1. Definition of SLOT-FILLER-MIXIN, a metaclass. In my expert system, a "slot-value" is really a structure containing (1) the "real" value, and (2) a pointer to the RULE responsible for inferring that value (used to construct explanations). Once uncertainty is supported, I should like to include a DISTRIBUTION OF BELIEF as the "value" of the slot. I have hacs to slot-value-using-class (:around methods) that get the structure and pull out the "real" value. I have added a method called slot-explanation-using-class that gets the structure and pulls out the rule pointer. I was very upset that Symbolics chose to hardcode the optimization of SLOT-VALUE, thus I have no recourse as I did in PCL to un-optimize calls for certain classes. Thus my code doesn't work unless I call slot-value-using-class directly. So I have my own version of slot-value in a different package that never gets optimized. 2. Definition of DOMAIN-SLOT-MIXIN, mixed with STANDARD-EFFECTIVE-SLOT-DEFINITION and STANDARD-DIRECT-SLOT-DEFINITION. Slot-definitions get extra slots. This should be easy, but: a) Obviously, it would have been nice if ENSURE-CLASS could be extended to parse user-defined slot options. b) Dumping a class has to "unparse" the slot definitions, such that reloading the dumped structure will completely restore the extra slots of the slot definitions. This has been a very difficult problem, solved in an ugly way with an :around method to MAKE-LOAD-FORM, which appends the "unparsed" slot definitions to the end of the form. This could be solved more elegantly if ENSURE-CLASS could parse my options, then the load form could somehow be the same as the macroexpansion of DEFCLASS. c) Slot inheritance still seems a littly sticky to me at times. It ought to be easy to modify a direct-slot-definition and then have some high-level method to update all the effective-slot-definitions that care. I have done it by writing an :around method to COMPUTE-EFFECTIVE-SLOT-DEFINITION that filters out the nonstandard options and does the right thing. To update slot-inheritance, I call REINITIALIZE-INSTANCE on the class, which always seemed like overkill to me. 3. Definition of SIMPLE-FUNCALLABLE-INSTANCE, an instance that is funcallable but has no methods or dispatch code and doesn't install the definition in the function cell of some symbol. This seemed relatively easy in Symbolics CLOS, however I had no hook on the function of the funcallable instance. The Symbolics hook is the function: clos-internals::%funcallable-instance-function This function takes an "extra arg" that took some time to figure out. It turns out that the extra arg is the environment of the closure, and I needed another hook to go from the environment object to the fin itself, so that the body of my function could access slots on the fin. clos-internals::%FUNCALLABLE-INSTANCE-EXTRA-ARGUMENT-FUNCALLABLE-INSTANCE [KRA: Let me clarify this paragraph somewhat. Jeff wanted to replace the fin's function, so he had to figure out how to do that, and also figure out what arguments the fin's function actually took. We had some sources, but most of what happens, is done in microcode. Our model is that fins are slightly different lexical-closures. Lexical closures consist of [environment, function], while a fin looks like [extra-arg, fin-function] (total asside to Symbolics: what is interesting is that on Ivory's a fin-function can be a lexical closure, but on 3600's they must be a function!?) The extra arg is a defstorage object describing the fin. Jeff also wanted some other slots, and wanted his fins to be anonymous so he couldn't specialize STANDARD-GENERIC-FUNCTION :RAK] Funcallable instances are an extremely powerful programming abstraction, beyond their utility as the basis for generic functions, and therefore I believe they should be standardized as a part of the language. jeff morrill ------- End of Forwarded Message Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA13640; Fri, 2 Nov 90 13:19:37 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16467>; Fri, 2 Nov 1990 13:14:07 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16475>; Fri, 2 Nov 1990 13:11:01 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410491; 2 Nov 1990 16:10:13-0500 X-Ns-Transport-Id: 08002008D0FD0003CC31 Date: Fri, 2 Nov 1990 13:11:00 PST From: Scott Cyphers Subject: [Jeff Morrill: MOP hacks] In-Reply-To: <90Nov2.120339pst.16474@alpha.xerox.com> To: kanderso@DINO.BBN.COM, mop@arisia.Xerox.COM Cc: jmorrill@DINO.BBN.COM, reinhard@DINO.BBN.COM Message-Id: <19901102211106.5.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Fri, 2 Nov 1990 15:20 EST From: kanderso@DINO.BBN.COM I asked some of our slot hackers to describe their experience to support this discussion. This is a response from Jeff Morrill. Tom Reinhardt also has some interesting experience with this, and described some of it in detail at a CLOS workshop at OPSLA 1989. k ------- Forwarded Message Date: Fri, 2 Nov 90 13:33 EST From: Jeff Morrill Subject: MOP hacks To: kanderson@BBN.COM cc: jmorrill@BBN.COM, delatizky@BBN.COM, treinhardt@BBN.COM Message-ID: <19901102183324.2.JMORRILL@adams.bbn.com> Ken, You asked for a description of what I have done with the mop. Here are the highlights. 1. Definition of SLOT-FILLER-MIXIN, a metaclass. In my expert system, a "slot-value" is really a structure containing (1) the "real" value, and (2) a pointer to the RULE responsible for inferring that value (used to construct explanations). Once uncertainty is supported, I should like to include a DISTRIBUTION OF BELIEF as the "value" of the slot. I have hacs to slot-value-using-class (:around methods) that get the structure and pull out the "real" value. I have added a method called slot-explanation-using-class that gets the structure and pulls out the rule pointer. I was very upset that Symbolics chose to hardcode the optimization of SLOT-VALUE, thus I have no recourse as I did in PCL to un-optimize calls for certain classes. Thus my code doesn't work unless I call slot-value-using-class directly. So I have my own version of slot-value in a different package that never gets optimized. You can't tell when not to do the optimization, since the method doesn't know the exact class. However, mapping tables have escape mechanisms in them for just this sort of thing, so this can be made to work, as long as only one value was to be returned. It would be impossible to make an optimized SLOT-VALUE return multiple values or no values (I also think that this would be an invalid thing to do in ANSI CL). Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA13888; Fri, 2 Nov 90 13:23:40 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16476>; Fri, 2 Nov 1990 13:18:18 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16476>; Fri, 2 Nov 1990 13:11:18 PST Received: by spade.parc.xerox.com id <284>; Fri, 2 Nov 1990 13:12:08 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003CC33 Date: Fri, 2 Nov 1990 13:11:55 PST From: Gregor Kiczales Subject: Re: Continuing comments on Draft 11 In-Reply-To: "Scott Cyphers's message of Fri, 2 Nov 1990 07:49:00 PST <19901102154943.7.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <90Nov2.131208pst.284@spade.parc.xerox.com> Here is an outline of a proposal for dealing with passing in extra information like next-methods to the bodies of methods when they are excecuting. This proposal is designed to allow methods body specializations which don't require additional dynamic information, but does not support method body specializations that do. So, for example, if we didn't already have the concept of next methods and call-next-method, you couldn't implement it with this protocol. I present this, using a naive implementation model. Needless to say, implementations can use the usual sorts of tricks to further optimize this in the absence of any user meta-level incursions. make-method-lambda takes a gf, method, lamba-expression, and environment as arguments. It returns a lambda expression which, when efunctuated, produces a function whose lambda-list is is (args next-methods). The args is a list of the arguments to the generic function. next-methods is a list of the next methods to the function. so, given a defmethod form like: (defmethod foo (a b c) (bazola a b c)) the standard method on make-method-lambda would return a value something like: (lambda (args next-methods) (apply #'(lambda (a b c) (flet ((call-next-method ..) (next-method-p () (not (null next-methods)))) (bazola a b c))) args)) If the user wanted to define a new class of method that added a lexical function binding FOO around the body they would define a method like: (defmethod make-method-lambda ((gf standard-generic-function) (method my-method-1) lambda environment) (call-next-method gf method `(,(car lambda) ,(cadr lambda) `(flet ((foo ..)) ,(cddr lambda))) environment)) (Note that this doesn't treat declarations properly. We can either say, look, its easy to get decls right in new Common Lisp, or we could split the lambda argument up into three args, lambda-list declarations, and body.) METHOD-FUNCTION, on a method, would return a function of two arguments (a list of args and a list of next methods). This is important to have for things like user-built steppers. The implementation-model would be that impls would call METHOD-FUNCTION, but, as usual, they don't have to call it if they know what they are going to get. That is, there are no relevant meta-level incursions. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA14438; Fri, 2 Nov 90 13:31:41 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16486>; Fri, 2 Nov 1990 13:26:47 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16502>; Fri, 2 Nov 1990 13:23:00 PST Received: by spade.parc.xerox.com id <284>; Fri, 2 Nov 1990 13:19:54 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003CC42 Date: Fri, 2 Nov 1990 13:19:50 PST From: Gregor Kiczales Subject: Re: Continuing comments on Draft 11 In-Reply-To: "Jon L White's message of Thu, 1 Nov 1990 22:07:46 PST <9011020607.AA20880@caligula>" To: jonl@lucid.COM Cc: mop@arisia.Xerox.COM Message-Id: <90Nov2.131954pst.284@spade.parc.xerox.com> Date: Thu, 1 Nov 1990 22:07:46 PST From: Jon L White Right. Andreas sent some out recently (to which email list? I can't remember). I have received some suggestions verbally from people who wanted to add an option which basically said "do type-checking on stores into this slot"; there's not much more to this except the need to be able to parse a user-specified option, and to store the result in a user-specified field of the slot-definition. I vaguely remember something in one of the CLOS workshop papers also, but . . . The current MOP supports this level of slot option parsing. What it doesn't support is saying whether a given slot option should be evaluated, efunctuated, collected into a list, or anything like that. Right now, all it does it carry extra slot options over, unevaluated. I like Scott's stuff, but I would rather see it written up as a paper that would be an improvement to this MOP than trying to get it into this MOP now. re: "STANDARD-" means the one that the user interface macros use by default. That is, what 88-002R says they do if you don't do any MOP stuff. Well that's an interesting view. But you can change the default for DEFMETHOD by calling DEFGENERIC with a :method-class option, and that step alone isn't MOP'y. It's entirely another matter to say that you can't create any other method class without MOP, or to say that none of the specified metaobjects other than STANDARD-METHOD and its subclasses will be suitable. Yes, but logically :method-class, :generic-function-class and :metaclass belong in the MOP. Even though they are mentioned in 88-002R, 88-002R doesn't by itself say enough about them that you could possible use them. How about this view: ``STANDARD means "concrete"; otherwise "abstract"'', with only a coule of exceptions (METHOD-COMBINATION and STRUCTURE-CLASS come to mind as exceptions, but they are also exceptions to the rule of ``"standard" means "default"''). Probably it's only a coincidence that all three views mostly coincide [the third being that ``"standard" means "slotted"''.] Right. In an email discussion in the past, I recall discussing a fatal flaw in the design of ENSURE-GENERIC-FUNCTION -- namely the :lambda-list argument doesn't carry enough information to be able to distinguish the dual purposes of (a) a target of macroexpansion for DEFMETHOD and of (b) a target of macroexpansion for DEFGENERIC. The current draft, under the DEFMETHOD section "Processing Method Bodies" punts the issue to ``The section "The Defgeneric Macro"''; but I can't find this section. Did I overlook it somewhere, or is this an intentionalp lacuna? No, the DEFGENERIC macro needs to be written, but I was planning to do it in the way we had decided to resolve this problem. There are six metaobject classes at or under SLOT-DEFINITION? why? Implementationally, there isn't any need to make a class distinction between "direct" and "effective" -- this can be done by keeping separate lists. But, direct slot definitions have readers and writers whereas effective slot definitions don't. Also, effective slot definitions will have the slot-definition--location stuff. They really are different, and that difference should be recognized in their classes. Admittedly, there is a need for a generic function that goes through the step of taking collected direct definitions and producing the effective definitions; but another class isn't needed. The alternative would have at most two classes. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA15078; Fri, 2 Nov 90 13:41:39 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16489>; Fri, 2 Nov 1990 13:36:46 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16475>; Fri, 2 Nov 1990 13:33:10 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410502; 2 Nov 1990 16:31:43-0500 X-Ns-Transport-Id: 08002008D0FD0003CC77 Date: Fri, 2 Nov 1990 13:32:00 PST From: Scott Cyphers Subject: Re: Continuing comments on Draft 11 In-Reply-To: <90Nov2.131208pst.284@spade.parc.xerox.com> To: gregor@parc.xerox.com, Cyphers@JASPER.SCRC.Symbolics.COM Cc: jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <19901102213234.6.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Fri, 2 Nov 1990 16:11 EST From: Gregor Kiczales If the user wanted to define a new class of method that added a lexical function binding FOO around the body they would define a method like: (defmethod make-method-lambda ((gf standard-generic-function) (method my-method-1) lambda environment) (call-next-method gf method `(,(car lambda) ,(cadr lambda) `(flet ((foo ..)) ,(cddr lambda))) environment)) This would work (if you fixed the bug) just as well if you didn't say that make-method-lambda returned a function which took two arguments, so I don't see why you should be saying it. METHOD-FUNCTION, on a method, would return a function of two arguments (a list of args and a list of next methods). This is important to have for things like user-built steppers. The implementation-model would be that impls would call METHOD-FUNCTION, but, as usual, they don't have to call it if they know what they are going to get. That is, there are no relevant meta-level incursions. If a function FUNCALL-METHOD-LAMBDA took arguments of a MAKE-METHOD-LAMBDA's first and second values, a list of next methods, a boolean of whether or not next methods were allowed, and the arguments to the function, I could write such a FUNCALL-METHOD-LAMBDA function. Is that good enough for a stepper? Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16764; Fri, 2 Nov 90 14:05:30 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16488>; Fri, 2 Nov 1990 14:00:39 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16490>; Fri, 2 Nov 1990 13:46:53 PST Received: by spade.parc.xerox.com id <230>; Fri, 2 Nov 1990 13:47:36 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003CCAA Date: Fri, 2 Nov 1990 13:47:35 PST From: Gregor Kiczales Subject: Re: Continuing comments on Draft 11 In-Reply-To: "Scott Cyphers's message of Fri, 2 Nov 1990 13:32:00 PST <19901102213234.6.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: Cyphers@JASPER.SCRC.Symbolics.COM, jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <90Nov2.134736pst.230@spade.parc.xerox.com> Date: Fri, 2 Nov 1990 13:32:00 PST From: Scott Cyphers Date: Fri, 2 Nov 1990 16:11 EST From: Gregor Kiczales If the user wanted to define a new class of method that added a lexical function binding FOO around the body they would define a method like: (defmethod make-method-lambda ((gf standard-generic-function) (method my-method-1) lambda environment) (call-next-method gf method `(,(car lambda) ,(cadr lambda) `(flet ((foo ..)) ,@(cddr lambda))) environment)) This would work (if you fixed the bug) just as well if you didn't say that make-method-lambda returned a function which took two arguments, so I don't see why you should be saying it. METHOD-FUNCTION, on a method, would return a function of two arguments (a list of args and a list of next methods). This is important to have for things like user-built steppers. The implementation-model would be that impls would call METHOD-FUNCTION, but, as usual, they don't have to call it if they know what they are going to get. That is, there are no relevant meta-level incursions. If a function FUNCALL-METHOD-LAMBDA took arguments of a MAKE-METHOD-LAMBDA's first and second values, a list of next methods, a boolean of whether or not next methods were allowed, and the arguments to the function, I could write such a FUNCALL-METHOD-LAMBDA function. Is that good enough for a stepper? I am not sure I understand either of your comments, but I have a question that may clarify them for me. Are you implicitly assuming that any user methods on make-method lambda would call CALL-NEXT-METHOD as in my example. That is, are you assuming that the ultimate value returned by MAKE-METHOD-LAMBDA would have been produced by an implementation method? If so, that would mean that I couldn't write call-next-method or next-method-p for myself. btw, I fixed the bug Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA18968; Fri, 2 Nov 90 14:32:37 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16497>; Fri, 2 Nov 1990 14:27:05 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16496>; Fri, 2 Nov 1990 14:24:26 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410534; 2 Nov 1990 17:22:30-0500 X-Ns-Transport-Id: 08002008D0FD0003CD08 Date: Fri, 2 Nov 1990 14:23:00 PST From: Scott Cyphers Subject: Re: Continuing comments on Draft 11 In-Reply-To: <90Nov2.134736pst.230@spade.parc.xerox.com> To: gregor@parc.xerox.com, Cyphers@JASPER.SCRC.Symbolics.COM Cc: jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <19901102222320.9.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Fri, 2 Nov 1990 16:47 EST From: Gregor Kiczales I am not sure I understand either of your comments, but I have a question that may clarify them for me. Are you implicitly assuming that any user methods on make-method lambda would call CALL-NEXT-METHOD as in my example. That is, are you assuming that the ultimate value returned by MAKE-METHOD-LAMBDA would have been produced by an implementation method? Yes. If so, that would mean that I couldn't write call-next-method or next-method-p for myself. Oh, so that's what you want to do. I'm not exactly sure how anyone would use that, but I guess it doesn't matter. The information about next methods is a cooperative effort between the stuff that makes a combined method (the thing that you really dispatch to) from an effective method and make-method-lambda. The way we have these two things communicate is with the second value returned by MAKE-METHOD-LAMBDA. Suppose one of the things returned is :NEXT-METHOD-TYPE. NIL would mean that the method doesn't want this information. Another value might be CLOS-INTERNALS::THE-WAY-I-DO-IT, for normal CALL-NEXT-METHOD. If you wanted to do it some other way, you'd return GREGOR::MY-WAY. I guess there'd have to be a macro (only defined in methods) of no arguments called something like NEXT-METHODS which let you get hold of the list of next methods that your method combiner was passing to you (since each implementation will probably have a different way to do pass the information into the method). We use a generic function like this: (DEFMETHOD METHOD-FUNCTION-NAME-AND-EXTRA-ARGUMENT ((GENERIC-FUNCTION STANDARD-GENERIC-FUNCTION) (METHOD STANDARD-METHOD) NEXT-METHOD-FUNCTION ARGUMENT-FUNCTION &REST KEYS) (DECLARE (IGNORE KEYS)) (VALUES METHOD (COND ((METHOD-NO-NEXT-METHOD-INFORMATION METHOD) (METHOD-MAPPING-TABLE METHOD ARGUMENT-FUNCTION)) (T (MULTIPLE-VALUE-BIND (NEXT-FUNCTION-NAME NEXT-EXTRA-ARGUMENT) (FUNCALL NEXT-METHOD-FUNCTION) (LIST* (METHOD-MAPPING-TABLE METHOD ARGUMENT-FUNCTION) (FDEFINITION NEXT-FUNCTION-NAME) NEXT-EXTRA-ARGUMENT)))))) to do help make the combined method. NEXT-METHOD-FUNCTION generates the information for the next step in the chain, I hope this isn't too cryptic for understanding. The cond would have to be generalized; perhaps the value of :NEXT-METHOD-TYPE would be the name of a function to be called with arguments, and the COND would be eliminated, or something like that. By the way, the argument function is a function of which you can ask questions about the provided arguments, such as their actual class or value. This is how we get the right mapping table. We'd have to change this a bit to handle other kinds of specializers, but that's a different can of worms. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA03073; Fri, 2 Nov 90 17:43:37 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16479>; Fri, 2 Nov 1990 17:38:19 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16479>; Fri, 2 Nov 1990 17:36:43 PST Received: by spade.parc.xerox.com id <275>; Fri, 2 Nov 1990 17:37:40 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003CEF2 Date: Fri, 2 Nov 1990 17:37:28 PST From: Gregor Kiczales Subject: Re: Continuing comments on Draft 11 In-Reply-To: "Scott Cyphers's message of Fri, 2 Nov 1990 14:23:00 PST <19901102222320.9.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: Cyphers@JASPER.SCRC.Symbolics.COM, jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <90Nov2.173740pst.275@spade.parc.xerox.com> The stuff you sent back was so implementation specific that I am not sure I understood it. Let me try to propose something like what you are suggesting. Add a new lexical function to the body of methods, this lexical function can be used to access the value passed in as the second argument when a method function is called. Add a second returned value from make-method-lambda. This value is a symbol which describes what the method expects to find in the second argument to method functions. But, what does this get me? How can I extend the space of what the second argument/value are for. Because the second value returned by make-method-lambda is a symbol, and it disappears into the bowels of the implementation, I can't use OOP to tailor what it means. I actually don't think that extending the space of what dynamic information can be passed into a method is going to be tractable given the current MOP. It depends on a lot of stuff. For example, I think you would want to attach to compute-applicable-xxx, otherwise you wouldn't have a basis for caching. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA08966; Sat, 3 Nov 90 13:09:42 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16530>; Sat, 3 Nov 1990 13:04:39 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16530>; Sat, 3 Nov 1990 13:02:18 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410575; 3 Nov 1990 15:59:09-0500 X-Ns-Transport-Id: 08002008D0FD0003D2F7 Date: Sat, 3 Nov 1990 13:00:00 PST From: Scott Cyphers Subject: Re: Continuing comments on Draft 11 In-Reply-To: <90Nov2.173740pst.275@spade.parc.xerox.com> To: gregor@parc.xerox.com, Cyphers@JASPER.SCRC.Symbolics.COM Cc: jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <19901103210009.3.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Fri, 2 Nov 1990 20:37 EST From: Gregor Kiczales The stuff you sent back was so implementation specific that I am not sure I understood it. Let me try to propose something like what you are suggesting. Add a new lexical function to the body of methods, this lexical function can be used to access the value passed in as the second argument when a method function is called. Not "as the second argument", but roughly equivalent to the second argument you were proposing. Add a second returned value from make-method-lambda. This value is a symbol which describes what the method expects to find in the second argument to method functions. make-method-lambda already returns a second value, a plist. I'm just defining one of the properties. But, what does this get me? How can I extend the space of what the second argument/value are for. Because the second value returned by make-method-lambda is a symbol, and it disappears into the bowels of the implementation, I can't use OOP to tailor what it means. No, the second argument isn't supposed to be something that disappears into the bowels. It's a message to a missing part of MOP to tell that part how the method is expecting to receive information like the next methods (one can imagine someone wanting to have a call-previous-method (maybe in some backtracking system) and a call-next-method in the same function, or maybe even a call-other-message to get into some other stream of methods, which your scheme can't support). By specifying things like method-functions this early, without having specified the rest of the method combination mechanism, I think we seriously risk losing future flexibility. My second implementation of method combination (not the one in 8.0) gave me hope that something like this could be done, preferably in a way that can express the approaches taken by the current CLOS implementations. November 15th is too soon for a description to be worked out (although I'd be glad to prototype one when I can find the time). I actually don't think that extending the space of what dynamic information can be passed into a method is going to be tractable given the current MOP. It depends on a lot of stuff. For example, I think you would want to attach to compute-applicable-xxx, otherwise you wouldn't have a basis for caching. Right, that's why I don't think we should be saying what the arguments to a method function are going to look like at this time. Let's make sure the whole generic function picture is going to work before pseudo-standardizing a part of it. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA22276; Sun, 4 Nov 90 14:02:50 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16553>; Sun, 4 Nov 1990 13:57:16 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16553>; Sun, 4 Nov 1990 13:55:59 PST Received: by spade.parc.xerox.com id <284>; Sun, 4 Nov 1990 13:56:44 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003D67C Date: Sun, 4 Nov 1990 13:56:42 PST From: Gregor Kiczales Subject: validate-xxx-class-change To: MOP.PARC@xerox.com Message-Id: <90Nov4.135644pst.284@spade.parc.xerox.com> I propose to replace all the validate-xxx-class-change generic functions with the following, simpler facility. I believe it is just as powerful, and conceptually easier to understand. It may even be that people will want to extend it to cover change-class in general. (It would be even simpler if CLOS were Self, but its a bit too late for that now!) This adds a before method to CHANGE-CLASS, specialized to (METAOBJECT T) which calls VALIDATE-CHANGE-CLASS on the object and the prototype of the new class. If VALIDATE-CHANGE-CLASS returns, the class change proceeds. A specified method on VALIDATE-CHANGE-CLASS, specialized to (METAOBJECT METAOBJECT), always returns. Here is the naive implementation model code: (defmethod change-class :before ((object metaobject) new-class &key) (validate-change-class object (class-prototype new-class))) (defmethod validate-change-class ((object metaobject) (prototype metaobject)) ()) A user program which wants to prevent a metaobject from changing its class defines appropriate methods on VALIDATE-CHANGE-CLASS. For example, suppose the user defines two class metaobject classes, MY-FAST-CLASS and MY-SLOW-CLASS. The idea is that the fast class compiles in a bunch of stuff in an irrevocable way. A fast class has to stay that way, it can't have its class changed. Also, the only way to make a fast class is to create it that way in the first place, you can't change something into a fast class. The following two methods would work: (defmethod validate-change-class ((o my-fast-class) (n t)) (error "Can't change ~S away from being a fast class." o)) (defmethod validate-change-class ((o t) (n my-fast-class)) (error "Can't change something into a fast class. The only way to~%~ to make a fast class is to create it that way in the first place.")) Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA22784; Sun, 4 Nov 90 14:52:57 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16548>; Sun, 4 Nov 1990 14:48:33 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16548>; Sun, 4 Nov 1990 14:47:03 PST Received: by spade.parc.xerox.com id <284>; Sun, 4 Nov 1990 14:47:57 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003D6A3 Date: Sun, 4 Nov 1990 14:47:53 PST From: Gregor Kiczales Subject: specializer metaobjects To: mop.PARC@xerox.com Message-Id: <90Nov4.144757pst.284@spade.parc.xerox.com> In the current metaobject protocol is that EQL specializers are not objects (with their own special class). Aside from being conceptually gross, this leads to a number of problems. There are several methods that, in a silly way, are specialized to CONS. It also means that the MOP doesn't point the way for users who want to add a new kind of specializer. It doesn't make it clear that they should add a new kind of object for the new specializers rather than, for example, further overloading CONS. This message is a proposal to try and fix this by making EQL specializers themselves be metaobjects. The general idea is to define a new kind of metaobject, called . Classes are specializers. There is a new class SPECIALIZER, of which CLASS is a subclass. Another new class EQL-SPECIALIZER, is a direct subclass of SPECIALIZER. In the past I have avoided doing this because I believed that 88-002R specifically said that the form of eql specializers (not specializer names) was a list of which the car was the symbol EQL etc. I know believe that 88-002R doesn't say that because it doesn't have the conceptual framework required to do so. The proposal presented here solves the problems outlined above and moreover it paves the way for adding a new lower layer to the method lookup protocol that would make it easier for users adding new kinds of specializers. The tricky point is in describing the conversion of the external format of specializers (what appears in DEFMETHOD forms) to specializer metaobjects. This conversion needs to be based on a notion of `interning'. That is two external forms which both describe the `same' specializer should in fact produce the same specializer metaobject. The definition of `same' depends on the specializer in question. For classes, the interning function is just FIND-CLASS. For EQL specializers, the interning predicate is EQL. And so on. Here is some naive model implementation code: (defclass class (specializer) ..) (defun intern-class-specializer (class-name) (find-class class-name)) (defclass eql-specializer (specializer) ((object :initarg :object :reader eql-specializer-object))) (defvar *eql-specializers* (make-hash-table :test #'eql)) (defun intern-eql-specializer (object) (or (gethash object *eql-specializers*) (setf (gethash object *eql-specializers*) (make-instance 'eql-specializer :object object)))) So, a defmethod form and expansion would be something like: (defmethod foo ((x foo) (y (eql bar))) ..) (... (make-instance 'standard-method :specializers (list (intern-class-specializer 'foo) (intern-eql-specializer bar)) . .) ...) Note that the intern-xxx functions will have to be specified in order to allow users to do anonymous creation of methods with EQL specializers. If the user wants to do something like the slot class specializers discussed at the CLOS workshop they would do: (defclass slot-class-specializer (specializer) ((slot-name :initarg :slot-name ..) (class :initarg :class ..))) (defvar *slot-class-specializers* (make-hash-table :test #'equal)) (defun intern-slot-class-specializer (slot-name class-name) (let ((class (find-class class-name))) (or (gethash (cons slot-name class) *slot-class-specializers*) (setf (gethash (cons slot-name class) *slot-class-specializers*) (make-instance 'slot-class-specializer :slot-name slot-name :class class))))) and a method definition and expansion would look like: (define-method foo ((x foo) (y (eql bar)) (z (slot a baz))) ;means that the value of the ;slot named A of this argument ;should have class BAZ ..) (... (make-instance 'my-method :specializers (list (intern-class-specializer 'foo) (intern-eql-specializer bar) (intern-slot-class-specializer 'a 'baz)) . .) ...) Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA23510; Sun, 4 Nov 90 16:00:30 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16556>; Sun, 4 Nov 1990 15:55:58 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16555>; Sun, 4 Nov 1990 15:54:13 PST Received: by spade.parc.xerox.com id <284>; Sun, 4 Nov 1990 15:55:03 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003D6EC Date: Sun, 4 Nov 1990 15:54:49 PST From: Gregor Kiczales Subject: Re: Continuing comments on Draft 11 In-Reply-To: "Scott Cyphers's message of Sat, 3 Nov 1990 13:00:00 PST <19901103210009.3.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: Cyphers@JASPER.SCRC.Symbolics.COM, jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <90Nov4.155503pst.284@spade.parc.xerox.com> Date: Sat, 3 Nov 1990 13:00:00 PST From: Scott Cyphers make-method-lambda already returns a second value, a plist. I'm just defining one of the properties. Oh, I see. November 15th is too soon for a description to be worked out (although I'd be glad to prototype one when I can find the time). Actually, I think getting a facility like this really right is much farther away than that. It will require reworking large parts of the method lookup protocol including method combination. But, there is an easy way to get it half right, using the method combination facility. We may not want to do it now, but it pays to at least think about it for a but now. This idea is an upward compatible extension from my recent method function proposal, which means its easy to go back and add it. (I believe we have to put method functions in, without them there are too many things people can't write (steppers, weird dynamic method combinations, etc.) The idea is to say that the 2nd, 3rd (and so on) `arguments' to CALL-METHOD become the 2nd, 3rd (and so on) arguments to method functions. (An extension from the current scheme where the second argument to CALL-METHOD is a list of next methods and the second argument to method function is the list of next methods.) Users who want to pass more dynamic information to methods can do so by altering MAKE-METHOD-LAMBDA and COMPUTE-EFFECTIVE-METHOD. Given that, lets look at a form of the idea you suggested, where methods could `backup' in the list of applicable methods as well as go forward. (defclass backup-gf (standard-generic-function) ()) (defmethod make-method-lambda ((gf my-gf) m lambda env) ;; ;; Return a lambda of three (instead of two arguments). ;; The first two are as usual, the third is a list of ;; previous methods. The first element of the list of ;; previous methods is the current method. ;; (flet ((add-bindings () ;; ;; Add the lexical functions CALL-PREVIOUS-METHOD and ;; PREVIOUS-METHOD-P. Also, override the implementation's ;; CALL-NEXT-METHOD and NEXT-METHOD-P. ;; `(lambda ,(cadr lambda) (flet ((call-next-method (&rest args) (funcall (method-function (car next-methods)) args (cdr next-methods) (cons (car next-methods) previous-methods))) (call-previous-method (&rest args) (funcall (method-function (cadr previous-methods)) args (cons (car previous) next-methods) (cdr previous-methods))) (next-method-p () next-methods) (previous-method-p () (cdr previous-methods))) ,@(cddr lambda))))) `(lambda (args next-methods previous-methods) (funcall ,(call-next-method gf m (add-bindings) env) args next-methods)))) (defmethod compute-effective-method ((gf backup-gf) (combin t) methods) `(call-method ,(car methods) ,(cdr methods) ,(list (car methods)))) Now, if you say (defclass a () ()) (defclass b (a) ()) (defclass c (b) ()) (defgeneric foo (x in/out) (:generic-function-class backup-gf)) (defmethod foo ((x a) &optional (in/out 'in)) (print 'a) (if (eq in/out 'in) (call-next-method x 'in) (values))) (defmethod foo ((x b) &optional (in/out 'in)) (print 'b) (if (eq in/out 'in) (call-next-method x 'in) (call-previous-method x 'out))) (defmethod foo ((x c) &optional (in/out 'in)) (print 'c) (call-previous-method x 'out)) now, saying (foo (make-instance 'c)) does: A B C B A (At least that is what I hope it does! Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA24155; Sun, 4 Nov 90 16:53:29 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16557>; Sun, 4 Nov 1990 16:49:05 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16559>; Sun, 4 Nov 1990 16:47:32 PST Received: by spade.parc.xerox.com id <275>; Sun, 4 Nov 1990 16:48:23 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003D724 Date: Sun, 4 Nov 1990 16:48:13 PST From: Gregor Kiczales Subject: Re: Firs set of comments on TAOTMOP part 2 In-Reply-To: "Scott Cyphers's message of Wed, 31 Oct 1990 13:30:00 PST <19901031213030.8.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: mop@arisia.Xerox.COM Message-Id: <90Nov4.164823pst.275@spade.parc.xerox.com> Date: Wed, 31 Oct 1990 13:30:00 PST From: Scott Cyphers 3-13: Last bullet Portable metaclasses cannot be redefined. Why not? I can see why user code shouldn't go around redefining the standard metaclasses for the same reason they shouldn't be allowed to redefine CAR, but I can't think of any reason to disallow it for user-defined metaclasses. I think the CLOS implementation should just make this kind of thing happen automatically via inheritance. For the same reason portable metaobject classes and applicable methods must all be defined before any instances are created. To simplify the standard sorts of optimization tricks based on advance detection of the possible range of meta-level incursions. An implementation, such as yours, that wants to allow this sort of redefinition is of course free to do so. It just seems to much to ask all implementations to handle it. 3-17: I can not accept the section for parsing of DEFCLASS, since it prohibits compile-time checking for spelling mistakes in option names. I don't understand this. It seems to me the current scheme lets you do compile-time checking, in one of two ways: Simple, minimally adequate way. When no :metaclass option is specified, you know the class metaobject class is STANDARD-CLASS and you can do simple textual checking of the options. When a :metaclass option is specified you can warn about options you don't recognize, but that might get annoying. Slightly less complicated, but works completely way. Instantiate the class metaobjects "in the compile time environment." This means all the options will end up getting processed (as initialization arguments to the class and direct slot definition metaobjects). Any illegal options will become illegal initialization arguments and an error will be signalled. Because that error is in fact siganlled by a pice of implementation code you should be able to make this as user-friendly as you like. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA27636; Sun, 4 Nov 90 21:46:33 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16553>; Sun, 4 Nov 1990 21:44:41 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16552>; Sun, 4 Nov 1990 21:37:28 PST Received: from rose (rose.lucid.com) by heavens-gate.lucid.com id AA03324g; Sun, 4 Nov 90 21:28:42 PST Received: by rose id AA12175g; Sun, 4 Nov 90 21:32:40 PST Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: Richard P.Gabriel ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0003D829 Date: Sun, 4 Nov 1990 21:32:40 PST From: rpg@lucid.com Subject: Minor Remarks To: gregor@parc.xerox.com Cc: mop@arisia.Xerox.COM Message-Id: <9011050532.AA12175@rose> I've sent a lot of comments on the ``pink book'' in the past, but I was glancing at it today and noticed a few things. These might be repeats of previous comments: Page 3-8: There is a sentence I can't understand. It is ``An effective slot definition metaobject is used to represent information...about a slot which is accessible in instances of a particular class.'' First, does ``which'' refer to ``an effective slot definition metaobject,'' ``information'' or ``a slot''? Second, if the meaning is best stated this way ``An effective slot definition metaobject is used to represent information...about a slot that is accessible in instances of a particular class,'' does this mean that there is or might be a different slot definition metaobject for the `same' slot in subclasses of the mentioned class? Figure on page 3-10: Even though you later state that there can be other classes in the picture, I think you ought not state in this figure that these are the direct superclasses. I think there is no need to limit the superclasses to these, and I see no particular reason why these should even be *direct* superclasses. Page 3-48: (A randomly selected page). Here I see some overspecification. If the function compute-discriminating-function is really to be used by an implementation, the value returned should be allowed to be anything that fits with the other constraints on its value - presumably the value is passed on to other functions, and those functions are the only ones that care [sic] about type of the object. A user should be able to write a method for it that returns a function and that influences the behavior of his system, but this type of value might not be what the implementation would normally do. Also, when you say the value is a function, do you allow it to be a generic function (which is a function, after all). -rpg- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04298; Mon, 5 Nov 90 07:42:50 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16459>; Mon, 5 Nov 1990 07:40:42 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16459>; Mon, 5 Nov 1990 07:37:28 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 868188; 5 Nov 1990 10:37:30-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0003DA39 Date: Mon, 5 Nov 1990 07:39:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: specializer metaobjects In-Reply-To: <90Nov4.144757pst.284@spade.parc.xerox.com> To: Gregor Kiczales Cc: mop.PARC@xerox.com Message-Id: <19901105153958.9.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Date: Sun, 4 Nov 1990 17:47 EST From: Gregor Kiczales This message is a proposal to try and fix this by making EQL specializers themselves be metaobjects. The general idea is to define a new kind of metaobject, called . Classes are specializers. There is a new class SPECIALIZER, of which CLASS is a subclass. Another new class EQL-SPECIALIZER, is a direct subclass of SPECIALIZER. This seems like a reasonable proposal to me. Perhaps it can also help rationalize the meaning of SPECIALIZER-DIRECT-METHODS. In the past I have avoided doing this because I believed that 88-002R specifically said that the form of eql specializers (not specializer names) was a list of which the car was the symbol EQL etc. I know believe that 88-002R doesn't say that because it doesn't have the conceptual framework required to do so. Well, 88-002R indubitably contains the words "denotes a parameter specializer as follows ... the type specifier (eql -object)". I think we should freely admit that this is an incompatible change to 88-002R. The question should be, is this an incompatible change for any programs written using only the standard language as currently accepted by X3J13 (i.e. not using "chapter 3"). The answer is almost no; there is one thing I found in 88-002R that can be used to tell the difference between EQL specializers as conses and EQL specializers as metaobjects, namely FIND-METHOD's specializers argument. Of course it could be given a compatibility feature where conses would be accepted and translated to specializers, but that's probably undesirable since in practice very few or no programs would be helped by doing that. So I think this change should be proposed as an incompatible change whose benefit to cost ratio is definitely high enough to justify it, and not try to pretend that it's just a clarification. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04922; Mon, 5 Nov 90 08:16:30 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16459>; Mon, 5 Nov 1990 08:14:30 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <16569>; Mon, 5 Nov 1990 08:12:19 PST X-Ns-Transport-Id: 08002008D0FD0003DA8D Date: Mon, 5 Nov 1990 08:25:24 PST From: kanderso@DINO.BBN.COM Subject: Re: specializer metaobjects In-Reply-To: "Your message of Sun, 04 Nov 90 14:47:53 -0800. <90Nov4.144757pst.284@spade.parc.xerox.com>" To: Gregor Kiczales Cc: mop.PARC@xerox.com Message-Id: <90Nov5.081219pst.16569@alpha.xerox.com> Fake-Sender: gregor@parc.xerox.com X-NS-Transport-ID: 08002008D0FD0003D6A3 Date: Sun, 4 Nov 1990 14:47:53 PST From: Gregor Kiczales Subject: specializer metaobjects To: mop.PARC@xerox.com In the current metaobject protocol is that EQL specializers are not objects (with their own special class). Aside from being conceptually gross, this leads to a number of problems. There are several methods that, in a silly way, are specialized to CONS. It also means that the MOP doesn't point the way for users who want to add a new kind of specializer. It doesn't make it clear that they should add a new kind of object for the new specializers rather than, for example, further overloading CONS. ... Here is some naive model implementation code: (defclass class (specializer) ..) (defun intern-class-specializer (class-name) (find-class class-name)) (defclass eql-specializer (specializer) ((object :initarg :object :reader eql-specializer-object))) (defvar *eql-specializers* (make-hash-table :test #'eql)) (defun intern-eql-specializer (object) (or (gethash object *eql-specializers*) (setf (gethash object *eql-specializers*) (make-instance 'eql-specializer :object object)))) So, a defmethod form and expansion would be something like: (defmethod foo ((x foo) (y (eql bar))) ..) (... (make-instance 'standard-method :specializers (list (intern-class-specializer 'foo) (intern-eql-specializer bar)) . .) ...) Defmethod should really by written in terms of a gf like: (intern-specialize specializer) (defmethod intern-specializer ((s symbol)) (find-class s)) right? Note that the intern-xxx functions will have to be specified in order to allow users to do anonymous creation of methods with EQL specializers. If the user wants to do something like the slot class specializers discussed at the CLOS workshop they would do: (defclass slot-class-specializer (specializer) ((slot-name :initarg :slot-name ..) (class :initarg :class ..))) (defvar *slot-class-specializers* (make-hash-table :test #'equal)) (defun intern-slot-class-specializer (slot-name class-name) (let ((class (find-class class-name))) (or (gethash (cons slot-name class) *slot-class-specializers*) (setf (gethash (cons slot-name class) *slot-class-specializers*) (make-instance 'slot-class-specializer :slot-name slot-name :class class))))) and a method definition and expansion would look like: (define-method foo ((x foo) (y (eql bar)) (z (slot a baz))) ;means that the value of the ;slot named A of this argument ;should have class BAZ ..) (... (make-instance 'my-method :specializers (list (intern-class-specializer 'foo) (intern-eql-specializer bar) (intern-slot-class-specializer 'a 'baz)) . .) ...) I like this idea. Of course, a lot of the mop now specialized on standard-class will have to specialized on specializer, which is probably a good thing, except for the editing. Question: (defmethod foo (z (slot a bar)) ...) is a method specialized for objects that have (eq (class-of (slot-value z 'a)) (find-class 'bar)). (intern-specializer '(slot a bar)) returns an instance of class 'slot-specializer. How to refer to this class to specialize methods on it? (defmethod ((s (eql (intern-specializer '(slot a bar))))) ...) ? or do we have a specializer for specializers: (defmethod ((s (specializer '(slot a bar)))) ...) k Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA05213; Mon, 5 Nov 90 08:34:29 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16459>; Mon, 5 Nov 1990 08:32:28 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16564>; Mon, 5 Nov 1990 08:23:23 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 868247; 5 Nov 1990 11:23:17-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0003DAA9 Date: Mon, 5 Nov 1990 08:25:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM Subject: Comments on the gray book To: mop@arisia.Xerox.COM Message-Id: <19901105162546.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> The gray book (Art of the Metaobject Protocol) is harder to criticize than the pink book (Metaobject Protocol Specification) because it says right up front that it isn't talking about the real MOP or even the real CLOS and it leaves lots of things out that were too hard to explain. Here's what I thought of after an initial reading. I found this generally pretty readable and about as understandable as can be expected. It seemed to me that it is pretty easy to read along in this book thinking you understand what it's saying, and then discover that in fact most of it went in one ear and out the other. This is because the concepts being set forth are fundamentally complicated and confusing because of their circular structure. It's easy to get lost. Don't take this as negative criticism, this presentation is still far better than any other MOP presentation I have seen. It's inherently a difficult subject. Maybe there should be a quiz, or exercises at the end of each chapter. One more specific comment is that although efficient implementability is mentioned as a design goal, I don't think the book really touches on what is necessary to achieve that, which in my opinion depends fundamentally on keeping the programmer at arm's length from the implementation through the use of abstraction. I got the impression that in this book, "efficient implementability" ends up meaning to take an incredibly inefficient toy implementation and make it incrementally better. That's fine as a pedagogical technique, but somewhere in there the other side of the coin, making protocols that are abstract enough to work in implementations based on fundamentally different architectural decisions, needs to be addressed. This is certainly not an easy thing to do, but if it isn't done the value of The Art of the Metaobject Protocol will be greatly diminished. It's possible that you think chapter 4 already addresses this question, but after reading it a couple of times I don't think so. I don't think chapter 4 even fully addresses the popular cop-out response: the standard metaclasses can do it a special efficient way that's completely different from the way it's done if any user-defined methods are applicable. And of course I would rather see protocols defined in a way sufficiently abstracted from the implementation that no cop-out is required. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA05387; Mon, 5 Nov 90 08:45:37 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16575>; Mon, 5 Nov 1990 08:43:09 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16564>; Mon, 5 Nov 1990 08:32:38 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410654; 5 Nov 1990 11:30:42-0500 X-Ns-Transport-Id: 08002008D0FD0003DAC1 Date: Mon, 5 Nov 1990 08:32:00 PST From: Scott Cyphers Subject: Re: Continuing comments on Draft 11 In-Reply-To: <90Nov4.155503pst.284@spade.parc.xerox.com> To: gregor@parc.xerox.com, Cyphers@JASPER.SCRC.Symbolics.COM Cc: jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <19901105163204.5.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Sun, 4 Nov 1990 18:54 EST From: Gregor Kiczales The idea is to say that the 2nd, 3rd (and so on) `arguments' to CALL-METHOD become the 2nd, 3rd (and so on) arguments to method functions. (An extension from the current scheme where the second argument to CALL-METHOD is a list of next methods and the second argument to method function is the list of next methods.) Users who want to pass more dynamic information to methods can do so by altering MAKE-METHOD-LAMBDA and COMPUTE-EFFECTIVE-METHOD. This extension would be okay, although I'm not sure about the okayness details of how the call-method arguments get passed to the method function. Users defining their own kinds of methods would pay a substantial price in performance. When not using anything in MOP, a call-method in my implementation consists of a couple cars and cdrs and a simple function call (I do all the METHOD-FUNCTION kind of stuff during method combination. I also know what the arguments look like at that time, which is important for things like mapping tables). The MOP user would have to check the list of next methods, and either call METHOD-FUNCTION or NO-NEXT-METHOD as appropriate, cons the method arguments into a list, etc. There's mo room for a valid CL compiler to do much optimization there either, since argument passing conventions are a cooperative effort between the caller and the method being called. I want MOP users to be able to get the same kind of performance they get from the non-MOP stuff. If METHOD-FUNCTION knew the method and the arguments and returned a function and some description about the kinds of arguments that the function could be used with, then I think we might be closer to agreement (Jonl might even start to agree with it) although I think it's also going to be necessary to call the method function with something other than funcall or apply. We'd still have the next method information to deal with; having methods in there is going to be slow. Having something like what method-function returns would be better, but, again, you really want the method combinations and the methods to come to an agreement about what's in there, since it's not the kind of thing you can optimize based on local information. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16515; Mon, 5 Nov 90 14:11:55 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16598>; Mon, 5 Nov 1990 14:10:37 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16696>; Mon, 5 Nov 1990 11:27:59 PST Received: by spade.parc.xerox.com id <275>; Mon, 5 Nov 1990 11:28:42 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003E266 Date: Mon, 5 Nov 1990 11:28:38 PST From: Gregor Kiczales Subject: Re: specializer metaobjects In-Reply-To: 's message of Mon, 5 Nov 1990 07:39:00 PST <19901105153958.9.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> To: Moon@STONY-BROOK.SCRC.Symbolics.COM Cc: mop.PARC@xerox.com Message-Id: <90Nov5.112842pst.275@spade.parc.xerox.com> Date: Mon, 5 Nov 1990 07:39:00 PST From: Line-Fold: No So I think this change should be proposed as an incompatible change whose benefit to cost ratio is definitely high enough to justify it, and not try to pretend that it's just a clarification. I agree. FIND-METHOD is somewhat shaky in 88-002R anyways since that document is in no position to say what the object it returns is, or what you can do with it. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16627; Mon, 5 Nov 90 14:16:28 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16572>; Mon, 5 Nov 1990 14:14:32 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16716>; Mon, 5 Nov 1990 11:35:19 PST Received: by spade.parc.xerox.com id <275>; Mon, 5 Nov 1990 11:36:14 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003E23F Date: Mon, 5 Nov 1990 11:36:07 PST From: Gregor Kiczales Subject: Re: specializer metaobjects In-Reply-To: "kanderso@DINO.BBN.COM's message of Mon, 5 Nov 1990 08:25:24 PST <90Nov5.081155pst.16565@alpha.xerox.com>" To: kanderso@DINO.BBN.COM Cc: mop.PARC@xerox.com Message-Id: <90Nov5.113614pst.275@spade.parc.xerox.com> Date: Mon, 5 Nov 1990 08:25:24 PST From: kanderso@DINO.BBN.COM Defmethod should really by written in terms of a gf like: (intern-specialize specializer) (defmethod intern-specializer ((s symbol)) (find-class s)) right? Yes, some extensible DEFMETHOD parsing facility would be better. As I said in my message to Scott, I think it would be better to handle that as part of a full-fledged UI macro processing facility. Question: (defmethod foo (z (slot a bar)) ...) is a method specialized for objects that have (eq (class-of (slot-value z 'a)) (find-class 'bar)). (intern-specializer '(slot a bar)) returns an instance of class 'slot-specializer. How to refer to this class to specialize methods on it? (defmethod ((s (eql (intern-specializer '(slot a bar))))) ...) ? or do we have a specializer for specializers: (defmethod ((s (specializer '(slot a bar)))) ...) I guess I don't understand what you are trying to do here. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16631; Mon, 5 Nov 90 14:16:35 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16598>; Mon, 5 Nov 1990 14:15:38 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <17147>; Mon, 5 Nov 1990 13:37:47 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410781; 5 Nov 1990 16:36:09-0500 X-Ns-Transport-Id: 08002008D0FD0003E2AB Date: Mon, 5 Nov 1990 13:37:00 PST From: Scott Cyphers Subject: Re: specializer metaobjects In-Reply-To: <90Nov5.112541pst.275@spade.parc.xerox.com> To: gregor@parc.xerox.com, Cyphers@JASPER.SCRC.Symbolics.COM Cc: mop.PARC@xerox.com Message-Id: <19901105213733.6.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Mon, 5 Nov 1990 14:25 EST From: Gregor Kiczales Date: Mon, 5 Nov 1990 07:39:00 PST From: Scott Cyphers Is there any reason for this other than to conserve space? Yes. Without this concept of `interning', SPECIALIZER-DIRECT-METHODS is a shaky concept. That's a good reason. It should be worded something like "If X is EQL to Y, then (SPECIALIZER-INTERN X) is EQL to (SPECIALIZER-INTERN Y)" so that X's value can be GC'd if there are no user-visible pointers to it. It's just as easy to say it's the method's duty to remember what the source of the specializers looked like in those implementations that support such things. You call yourself an MOP programmer?! There should be a specializer class, with subclasses class-specializer and eql-specializer. Specializer takes an initarg :SPECIALIZER-FORM. Class-specializer also takes :CLASS and eql-specializer takes :OBJECT (or or some better name). Hugh? This just seems like another instance of the oldest OOP question in the world. Mixin or delegate. Should a class specializer be an object that points to a class or should it be an object which is a class. I chose the latter because it seems more elegant to me, and because the former is a significant change from the current MOP. It was just too early in the morning. I'd like to see a parse-specializer generic function (two arguments, the form and the environment) and a parse-cons-specializer, three arguments, the car of the form, the cdr of the form, and the environment. I'm not sure if the environment is really needed; better safe than sorry. CLOS would come with two methods for parse-specializer, one specialized on symbol and one on cons. parse-cons-specializer would have one method, eql-specialized on EQL. Our CLIM would also add one eql-specialized on CLASS which provides an alternative syntax for a class specializer. I would rather defer this to a full-fledged proposal for extensible processing of the UI macros. That sounds like a good place for it. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16964; Mon, 5 Nov 90 14:30:57 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16528>; Mon, 5 Nov 1990 14:27:54 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16705>; Mon, 5 Nov 1990 11:32:54 PST Received: by spade.parc.xerox.com id <275>; Mon, 5 Nov 1990 11:33:43 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003E315 Date: Mon, 5 Nov 1990 11:33:29 PST From: Gregor Kiczales Subject: Re: Continuing comments on Draft 11 In-Reply-To: "Scott Cyphers's message of Mon, 5 Nov 1990 08:32:00 PST <19901105163204.5.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: Cyphers@JASPER.SCRC.Symbolics.COM, jonl@lucid.COM, mop@arisia.Xerox.COM Message-Id: <90Nov5.113343pst.275@spade.parc.xerox.com> Date: Mon, 5 Nov 1990 08:32:00 PST From: Scott Cyphers Users defining their own kinds of methods would pay a substantial price in performance. When not using anything in MOP, a call-method in my implementation consists of a couple cars and cdrs and a simple function call (I do all the METHOD-FUNCTION kind of stuff during method combination. I also know what the arguments look like at that time, which is important for things like mapping tables). The MOP user would have to check the list of next methods, and either call METHOD-FUNCTION or NO-NEXT-METHOD as appropriate, cons the method arguments into a list, etc. There's mo room for a valid CL compiler to do much optimization there either, since argument passing conventions are a cooperative effort between the caller and the method being called. I want MOP users to be able to get the same kind of performance they get from the non-MOP stuff. Mumble, meta-level incursions into the actual method dispatch runtime are bound to cause performance impact. The current generation of MOP technology can't do too much about that. In the next generation, I believe a more aggressive and explicity use of partial evalutation techniques will help with a lot of this---imagine doing a MOP for the current Self implementation. But, note that even in this proposal, I could have improved things a lot. I would just change the code slightly so that CALL-METHOD passed in a list of method functions instead of methods. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16976; Mon, 5 Nov 90 14:31:25 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16588>; Mon, 5 Nov 1990 14:30:27 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16616>; Mon, 5 Nov 1990 11:04:47 PST Received: by spade.parc.xerox.com id <294>; Mon, 5 Nov 1990 11:05:39 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003E396 Date: Mon, 5 Nov 1990 11:05:24 PST From: Gregor Kiczales Subject: Re: Comments on the gray book In-Reply-To: "Moon@STONY-BROOK.SCRC.Symbolics.COM's message of Mon, 5 Nov 1990 08:25:00 PST <19901105162546.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@STONY-BROOK.SCRC.Symbolics.COM Cc: mop@arisia.Xerox.COM Message-Id: <90Nov5.110539pst.294@spade.parc.xerox.com> Date: Mon, 5 Nov 1990 08:25:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM One more specific comment is that although efficient implementability is mentioned as a design goal, I don't think the book really touches on what is necessary to achieve that, which in my opinion depends fundamentally on keeping the programmer at arm's length from the implementation through the use of abstraction. This is a real concern, and one which is fundamental to the value of this work. Can you say a little more about what you would like us to say? Your comments seem to be about both the presention (AMOP) and the design (MOP), but I can't distinguish the two sets of comments clearly enough to see what you are asking for. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA17349; Mon, 5 Nov 90 14:44:35 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16528>; Mon, 5 Nov 1990 14:44:17 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16687>; Mon, 5 Nov 1990 11:24:50 PST Received: by spade.parc.xerox.com id <275>; Mon, 5 Nov 1990 11:25:41 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0003E3E3 Date: Mon, 5 Nov 1990 11:25:35 PST From: Gregor Kiczales Subject: Re: specializer metaobjects In-Reply-To: "Scott Cyphers's message of Mon, 5 Nov 1990 07:39:00 PST <19901105153931.4.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@JASPER.SCRC.Symbolics.COM Cc: mop.PARC@xerox.com Message-Id: <90Nov5.112541pst.275@spade.parc.xerox.com> Date: Mon, 5 Nov 1990 07:39:00 PST From: Scott Cyphers Is there any reason for this other than to conserve space? Yes. Without this concept of `interning', SPECIALIZER-DIRECT-METHODS is a shaky concept. You call yourself an MOP programmer?! There should be a specializer class, with subclasses class-specializer and eql-specializer. Specializer takes an initarg :SPECIALIZER-FORM. Class-specializer also takes :CLASS and eql-specializer takes :OBJECT (or or some better name). Hugh? This just seems like another instance of the oldest OOP question in the world. Mixin or delegate. Should a class specializer be an object that points to a class or should it be an object which is a class. I chose the latter because it seems more elegant to me, and because the former is a significant change from the current MOP. I'd like to see a parse-specializer generic function (two arguments, the form and the environment) and a parse-cons-specializer, three arguments, the car of the form, the cdr of the form, and the environment. I'm not sure if the environment is really needed; better safe than sorry. CLOS would come with two methods for parse-specializer, one specialized on symbol and one on cons. parse-cons-specializer would have one method, eql-specialized on EQL. Our CLIM would also add one eql-specialized on CLASS which provides an alternative syntax for a class specializer. I would rather defer this to a full-fledged proposal for extensible processing of the UI macros. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA18001; Mon, 5 Nov 90 15:10:12 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16578>; Mon, 5 Nov 1990 15:09:55 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16593>; Mon, 5 Nov 1990 15:02:15 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410817; 5 Nov 1990 18:00:35-0500 X-Ns-Transport-Id: 08002008D0FD0003E4E0 Date: Mon, 5 Nov 1990 15:01:00 PST From: Scott Cyphers Subject: Re: specializer metaobjects In-Reply-To: <19901105213733.6.CYPHERS@SEAR.SCRC.Symbolics.COM> To: Cyphers@JASPER.SCRC.Symbolics.COM, gregor@parc.xerox.com Cc: mop.PARC@xerox.com Message-Id: <19901105230157.9.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Mon, 5 Nov 1990 16:37 EST From: Scott Cyphers Date: Mon, 5 Nov 1990 14:25 EST From: Gregor Kiczales Date: Mon, 5 Nov 1990 07:39:00 PST From: Scott Cyphers Is there any reason for this other than to conserve space? Yes. Without this concept of `interning', SPECIALIZER-DIRECT-METHODS is a shaky concept. That's a good reason. Actually, it isn't a good reason. Consider: (DEFMETHOD SPECIALIZER-DIRECT-METHODS ((SPECIALIZER EQL-SPECIALIZER)) (LET ((RESULT NIL)) (MAP-OVER-GENERIC-FUNCTIONS #'(LAMBDA (GF) (DOLIST (METHOD (GENERIC-FUNCTION-METHODS GF)) (WHEN (FIND (SPECIALIZER-EQL-OBJECT SPECIALIZER) (METHOD-SPECIALIZERS METHOD)) (PUSH METHOD RESULT))))) RESULT)) where MAP-OVER-GENERIC-FUNCTIONS does the obvious thing. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA23501; Mon, 5 Nov 90 18:14:19 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16582>; Mon, 5 Nov 1990 18:13:44 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <16509>; Mon, 5 Nov 1990 18:11:52 PST Received: by DINO.BBN.COM id aa17440; 5 Nov 90 21:01 EST X-Ns-Transport-Id: 08002008D0FD0003E6E6 Date: Mon, 5 Nov 1990 18:20:31 PST From: kanderso@DINO.BBN.COM Subject: Re: Comments on the gray book In-Reply-To: "Your message of Mon, 05 Nov 90 11:05:24 -0800. <90Nov5.110539pst.294@spade.parc.xerox.com>" To: Gregor Kiczales Cc: Moon@stony-brook.scrc.symbolics.COM, mop@arisia.Xerox.COM Message-Id: <90Nov5.181152pst.16509@alpha.xerox.com> Fake-Sender: gregor@parc.xerox.com X-NS-Transport-ID: 08002008D0FD0003E396 Date: Mon, 5 Nov 1990 11:05:24 PST From: Gregor Kiczales Subject: Re: Comments on the gray book To: Moon@stony-brook.scrc.symbolics.com cc: mop@parc.xerox.com Date: Mon, 5 Nov 1990 08:25:00 PST From: Moon@STONY-BROOK.SCRC.Symbolics.COM One more specific comment is that although efficient implementability is mentioned as a design goal, I don't think the book really touches on what is necessary to achieve that, which in my opinion depends fundamentally on keeping the programmer at arm's length from the implementation through the use of abstraction. This is a real concern, and one which is fundamental to the value of this work. Can you say a little more about what you would like us to say? Your comments seem to be about both the presention (AMOP) and the design (MOP), but I can't distinguish the two sets of comments clearly enough to see what you are asking for. Although i've only read to page 67, let me add a comment about AMOP. I also got caught short trying to skim things, finding i have to go back and check things out more carefully. I don't consider it a flaw in the manuscript, however. I had missed the fact that method objects had body slots. I just assumed they have functions, i guess. Then in section 1.7.3 imaginary functions inside eval get called, and i start not to feel so good. Footnote 16 is encouraging, but it almost made we want to go read the software in Appendix B. I think it is OK to be a bit vague in this section since things start to get vague by the last paragraph of page 36 when it is clear that we are inside the funcalling mechanism when somehow apply-generic-function gets called. I'd rather see you defer discussion about applying a method than see you call eval and apologize for it. What will C++ and Self people think if we don't make it clear that CLOS can be implemented relatively efficiently? k Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA23519; Mon, 5 Nov 90 18:15:11 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16509>; Mon, 5 Nov 1990 18:14:48 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <16580>; Mon, 5 Nov 1990 18:11:54 PST X-Ns-Transport-Id: 08002008D0FD0003E6E7 Date: Mon, 5 Nov 1990 18:28:49 PST From: kanderso@DINO.BBN.COM Subject: Some minor comments on AMOP To: mop.parc@xerox.com Cc: kanderson@DINO.BBN.COM Message-Id: <90Nov5.181154pst.16580@alpha.xerox.com> Additional minor comments, while i'm thinking of them: P. 22. Perhaps you should say that local-slot-location complains if doesn't have . Anyway, some function should check, even in CLOSETTE. P. 31. "This completes our presentation of generic function metaobjects and how defgeneric is implemented." (Reminds me of something i'd hear at Church, sermon on the MOP, perhaps.) At this point i was very curious about how gf's got run. You might mention that this is developed later. P. 54. From what you say, it seems like the second NIL on the page should be T. By the way, i find AMOP quite valuable as it motivates the components of the MOP, even if they aren't quite right. k Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26305; Mon, 5 Nov 90 21:00:48 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16574>; Mon, 5 Nov 1990 21:00:23 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16585>; Mon, 5 Nov 1990 20:58:50 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA13928g; Mon, 5 Nov 90 20:51:49 PST Received: by caligula id AA26438g; Mon, 5 Nov 90 20:56:05 PST X-Ns-Transport-Id: 08002008D0FD0003E803 Date: Mon, 5 Nov 1990 20:56:05 PST From: Jon L White Subject: validate-xxx-class-change In-Reply-To: "Gregor Kiczales's message of Sun, 4 Nov 1990 13:56:42 PST <90Nov4.135644pst.284@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: MOP.PARC@xerox.com Message-Id: <9011060456.AA26438@caligula> I can appreciate that one VALIDATE-CHANGE-CLASS is much better than numerious VALIDATE-xxx-CLASS-CHANGE's. But the several of the details of this proposal don't seem as well motivated to me. For example: (1) Why is the checking method -- the :BEFORE method on CHANGE-CLASS -- placed at the point (METAOBJECT T) rather than at (T CLASS)? First, I say "CLASS" rather than "T" since it only makes sense for the second argument to CHANGE-CLASS to be a class. But also I'm suggesting extending this idea just like you said: If this level of checking is useful, then wouldn't it be suitable, and even desirable, for any contemplated use of CHANGE-CLASS, and not just those that are moving around methods, generic-functions, slot-definitions, and classes? [For example, I might use this technique to permit the changing of an instance (direct or derived!) of COLORLESS-TURTLE into an instance of GREEN-TURTLE, but at the same time prohibit changing a RED-TURTLE into a GREEN-TURTLE.] (2) Why is it "ok" to change a metaobject into any other metaobject? Your sample code has: (defmethod validate-change-class ((object metaobject) (prototype metaobject)) ()) Can you really change a standard-accessor-method object into a slot-definition object with impunity? I should think that the proposal would take the opposite tack of generally denying the ability to make such changes unless there is an explicit enabling method on VALIDATE-CHANGE-CLASS. The model I have in mind is more like VALIDATE-SUPERCLASS. [This also re-raises the question of what are the metaclasses for the various metaobject classes, since the absence of a method on CHANGE-CLASS is a kind of restriction. The only prescribed method on CHANGE-CLASS is for changing one STANDARD-OBJECT into another -- i.e., you can change the class of any standard object as long as you stay within the STANDARD-CLASS fold -- but there are no presrciptions for changing, say, a funcallable instance into a STRUCTURE-OBJECT. In particular, I have already asked that GENERIC-FUNCTION and it's descendents not be required to be standard classes; and I think I would like to ask that METHOD-COMBINATION also not be so required.] Now, regarding some more specific points. re: If VALIDATE-CHANGE-CLASS returns, the class change proceeds. I dislike the assymetry of action with VALIDATE-SUPERCLASS, and prefer the latter's semantics. Your :BEFORE method on (METAOBJECT T) could just as easily be defined to signal an error unless VALIDATE-CHANGE-CLASS returns "true". re: . . . suppose the user defines two class metaobject classes, MY-FAST-CLASS and MY-SLOW-CLASS. What's the difference between a "meta" class and a "class metaobject" class? [I was able to follow the remaining discussion only because of the common tradition of nameing metaclasses as -CLASS whereas vanilla classes are usually named like or -OBJECT.] -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA05791; Wed, 7 Nov 90 14:38:30 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16658>; Wed, 7 Nov 1990 14:36:59 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16654>; Wed, 7 Nov 1990 14:34:28 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 869901; 7 Nov 1990 17:34:25-0500 Resent-To: mop@arisia.Xerox.COM Illegal-Object: Syntax error in Resent-From: address found on alpha.xerox.com: Resent-From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted Resent-Date: Wed, 7 Nov 1990 14:37:00 PST Resent-Message-Id: <19901107223702.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Resent-Comments: Evidently I'm confused by the way Xerox address syntax has been changing lately X-Ns-Transport-Id: 08002008D0FD0003FC60 Date: Wed, 7 Nov 1990 13:44:00 PST Sender: Moon@STONY-BROOK.SCRC.Symbolics.COM From: Postmaster@STONY-BROOK.SCRC.Symbolics.COM Subject: Unable to deliver letter To: Moon@STONY-BROOK.SCRC.Symbolics.COM Message-Id: <19901107214439.6.FILE-SERVER@STONY-BROOK.SCRC.Symbolics.COM> Unable to deliver letter to the following recipient: mop.parc@xerox.com: After trying without success for 1 week to contact the relevant domain servers needed to resolve the domain name "xerox.com", the Mailer must presume that there probably is no such domain. ----- Text of letter follows ----- Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 866567; 31 Oct 1990 16:40:11-0500 Date: Wed, 31 Oct 1990 16:45-0500 From: David A. Moon Subject: Defining readers and writers in DEFCLASS or with separate forms To: Gregor Kiczales , davis@ilog.ilog.FR cc: mop.parc@xerox.com In-Reply-To: <90Oct31.094055pst.279@spade.parc.xerox.com> Message-ID: <19901031214541.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Line-fold: No Date: Wed, 31 Oct 1990 12:40 EST From: Gregor Kiczales Date: Wed, 31 Oct 1990 03:12:55 PST From: davis@ilog.ilog.fr So what I'd like to know primarily is if you think this is a reasonable approach. In particular, I'm not interested in challenging CLOS's decisions, just in figuring out the best way for EuLisp. It seems perfectly reasonable to me to have DEFREADER and DEFWRITER macros, and to remove the functionality from DEFCLASS of defining these. CLOS made one choice about the style of its UI macros, this would just reflect another. I agree that it would have been a reasonable choice to remove readers and writers from DEFCLASS and do them separately. CLOS chose to include an abbreviation for this common programming cliche. I disagree that adding DEFREADER and DEFWRITER to the language is reasonable. If readers and writers are going to be defined with separate forms, they can be defined with DEFMETHOD. There is no reason at all that DEFMETHOD should not be adequate for this. At present in all implementations I am familiar with (DEFMETHOD FOO ((X C)) (SLOT-VALUE X 'Y)) and (DEFCLASS C () ((Y :READER FOO))) have different performance characteristics; for example, in the Ivory version of Symbolics Genera the defmethod is optimized for speed while the reader is optimized for space, so the defmethod is 25% faster by my measurement. In some other implementations the defmethod is slower. However this is an artifact of implementation and not inherent in the language. One might reasonable expect the defmethod and the reader to be implemented exactly the same. But, two comments. First, the reason to do so certainly isn't to help the compiler. Unless I am missing something, the compiler should be able to do just as well well with the CLOS form as with explicit DEFREADER/DEFWRITER forms. I certainly agree with this. Second, I believe that if you were really going to do this right, the only thing you would define is the underlying functionality---the explicit metaobject manipulation layer. None of these macros, or the UI syntax in terms of Lispo forms would be defined. This is fine for implementors but ignores the issue what language programmers use to communicate with each other. It's nice to have a standard for the surface syntax of Lisp forms so that programmers can read each others' programs. I suppose you coudl argue that publication should be in a machine-readable form which each reader translates to their favorite surface syntax (using a program) before reading it. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA00368; Thu, 8 Nov 90 12:23:06 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16735>; Thu, 8 Nov 1990 11:49:37 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <16731>; Thu, 8 Nov 1990 11:45:32 PST X-Ns-Transport-Id: 08002008D0FD00040786 Date: Thu, 8 Nov 1990 12:04:16 PST From: kanderso@DINO.BBN.COM Subject: class-prototype To: mop.parc@xerox.com Cc: kanderson@DINO.BBN.COM Message-Id: <90Nov8.114532pst.16731@alpha.xerox.com> The description of class-prototoype seems refreshingly short. Is there anything more one should say about the prototype? I remember some discussion on the PCL list saying that the only thing you can count on about a prototype is (eq (class-of (class-prototype class)) class). Don't expect anything else like its slots being bound, or it having gone through any part of the make-instance protocol. Should this be clarified? k Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04187; Thu, 8 Nov 90 14:19:24 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16764>; Thu, 8 Nov 1990 14:17:54 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <16772>; Thu, 8 Nov 1990 14:13:58 PST Received: by DINO.BBN.COM id ab05338; 8 Nov 90 16:09 EST X-Ns-Transport-Id: 08002008D0FD00040980 Date: Thu, 8 Nov 1990 13:21:34 PST From: kanderso@DINO.BBN.COM Subject: COMPUTE-DISCRIMINATING-FUNCTION and friends To: mop.parc@xerox.com Cc: kanderson@DINO.BBN.COM Message-Id: <90Nov8.141358pst.16772@alpha.xerox.com> I'm having trouble following the description of building an "installed discriminating function" which uses the functions on pages 3-41 to 3-51. 1. I think the first 3 paragraphs "PURPOSE" section of COMPUTE-DISCRIMINATING-FUNCTION is confusing to anyone who wants to get some idea of how a discriminator is built. The first paragraph should state that a gf's "insalled descriminating function" is determined by calling COMPUTE-DISCRIMINATING-FUNCTION if that is the case. The second paragraph says "To determine the ordered set of applicable methods ...", but never says why one would want to do that. The reason of course is to compute the effective method (for a particular set of arguments?). Perhaps there should be a reiteration, or a reference to the secton "Determing the Effective Method" from section I. I'd like to see the first paragarph replace with something like: The gf compute-discriminating-function is called to determine the discriminating function for a generic function. The discriminating function implements the behavior of the generic function and it can be installed using set-funcallable-instance-function. The contract of the discriminationg function is to produce the proper behavior when the generic function is called with a set of arguments. This is done by invoking an appropriate effective method. The effective method is determined as described in section "Determining the Effective Method". The following metalevel generic functions aid in this process.... 2. What kinds of extentions does COMPUTE-APPLICABLE-METHODS-USING-CLASSES? help you build? Does it really make lots of neat extentions simpler? What happens to it if we adopt Gregor's specializer proposal? It seems like we'll have to add more metalevel support inside compute-applicable-methods. k Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04550; Thu, 8 Nov 90 14:26:28 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16742>; Thu, 8 Nov 1990 14:25:36 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16726>; Thu, 8 Nov 1990 14:23:07 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA13287g; Thu, 8 Nov 90 12:41:02 PST Received: by caligula id AA00675g; Thu, 8 Nov 90 12:45:20 PST X-Ns-Transport-Id: 08002008D0FD000409B4 Date: Thu, 8 Nov 1990 12:45:20 PST From: Jon L White Subject: class-prototype In-Reply-To: "kanderso@DINO.BBN.COM's message of Thu, 8 Nov 1990 12:04:16 PST <90Nov8.114532pst.16731@alpha.xerox.com>" To: kanderso@DINO.BBN.COM Cc: mop.parc@xerox.com Message-Id: <9011082045.AA00675@caligula> re: The description of class-prototoype seems refreshingly short. Time will tell whether shortness is "refreshing" or is indicative of a limited exposure to the consequences. re: Don't expect anything else like its slots being bound, or it having gone through any part of the make-instance protocol. Should this be clarified? The fact that a prototype cannot be "made" until the class's superclasses are defined means that it must submit to some kind of lazy creation. This fact alone has caused concern with end users who managed to observe the "birth" occuring at unexpected times [e.g., John Rose at Sun.] This *might* be why someone would want to relax the requirements on the properties of the object returned by CLASS-PROTOTYPE. An alternative is to create bogus objects that simply carry type information; they would at least obey the strictures you just quoted from the PCL mailing list. Unfortunately, this is a gross violation of the contract with data typing, so it's not clear that exposing such bogons to the end user via CLASS-PROTOTYPE serves any purpose, even though implementations might make efficient use of it in some circumstances. Because ALLOCATE-INSTANCE got accidentally left out of the 88-002R, I don't recall whether the restriction laid on MAKE-INSTANCE is also laid upon ALLOCATE-INSTANCE; it probably should be (i.e., you can't allocate an instance until the class and its supers are "defined"). Even though ALLOCATE-INSTANCE doesn't put values in slots, their presence is "first class" due to SLOT-EXISTS-P; thus the reasoning behind the restriction on MAKE-INSTANCE applies exactly here too. It's entirely another matter as to whether or not it makes sense to relax the restriction on MAKE/ALLOCATE INSTANCE -- I've had numerous question about this one from folks who are accustomed to the use of KEE. Implementationally, it is easy enough to do, but there are serious questions as to what the semantics for such bogons ought to be (other than their datatype, that is), especially with respect to signaling an error when the lack of defined superclasses is a clear impediment. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA28467; Sun, 11 Nov 90 03:51:03 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <17067>; Sun, 11 Nov 1990 03:50:12 PST Received: from relay.cc.u-tokyo.ac.jp ([192.41.197.3]) by alpha.xerox.com with SMTP id <17069>; Sun, 11 Nov 1990 03:48:41 PST Received: from ccut.cc.u-tokyo.ac.jp by relay.cc.u-tokyo.ac.jp (5.61/2.7W) id AA12822; Sun, 11 Nov 90 20:48:29 +0900 Received: by ccut.cc.u-tokyo.ac.jp (5.61/6.4J.6-ut2.126) id AA28583; Sun, 11 Nov 90 20:48:25 +0900 Received: by trla.trl.ibm.co.jp (5.51/6.4J.6-900124) id AA07183; Sun, 11 Nov 90 20:37:16+0900 Return-Path: X-Ns-Transport-Id: 08002008D0FD0004217B Date: Sun, 11 Nov 1990 21:37:14 PST From: TANAKA Tomoyuki Subject: my visit in December (2) To: Gregor Kiczales Cc: MOP , tanakat@trl.ibm.co.jp Message-Id: <9011111137.AA07183@trla.trl.ibm.co.jp> Hello. (I am CCing this to MOP---that way someone will read this even if you are away.) My tentative plan for visiting Palo Alto in December is as follows: ... 14 (Fri) late afternoon: Arrive in Palo Alto. ... 17 (Mon): Visit IBM Palo Alto Scientific Center ... 18 (Tues): Head back to Tokyo So I am hoping to visit Xerox PARC either ... late afternoon on 14 (Fri) and/or ... the next day, 15 (Sat). How does this sound? Is it the case that nobody is at the lab on Saturdays? I doubt this. Best wishes, Tomoyuki (Mr.) TANAKA Tomoyuki (Tanaka is my family name.) ;;; IBM Research, Tokyo Research Laboratory ;;; 5-19, Sanbancho, Chiyoda-ku, Tokyo 102, Japan ;;; ;;; If replying to this address (tanakat@trl.ibm.co.jp) doesn't ;;; work, please try this address: tanakat@jpntscvm.bitnet ;;; (Note it's tanakaT, not tanaka) Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16322; Mon, 12 Nov 90 08:23:06 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <17103>; Mon, 12 Nov 1990 08:22:47 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <17105>; Mon, 12 Nov 1990 07:58:06 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 411749; 12 Nov 1990 10:55:31-0500 Resent-To: mop@arisia.Xerox.COM Resent-From: Scott Cyphers Resent-Date: Mon, 12 Nov 1990 07:57:00 PST Resent-Message-Id: <19901112155751.5.CYPHERS@SEAR.SCRC.Symbolics.COM> Resent-Comments: Try again. X-Ns-Transport-Id: 08002008D0FD000426AA Date: Mon, 12 Nov 1990 07:47:00 PST Sender: Cyphers@JASPER.SCRC.Symbolics.COM From: Postmaster@JASPER.SCRC.Symbolics.COM Subject: Unable to deliver letter To: Cyphers@JASPER.SCRC.Symbolics.COM Message-Id: <19901112154736.8.FILE-SERVER@JASPER.SCRC.Symbolics.COM> Unable to deliver letter to the following recipient: mop.PARC@xerox.com: After trying without success for 1 week to contact the relevant domain servers needed to resolve the domain name "xerox.com", the Mailer must presume that there probably is no such domain. ----- Text of letter follows ----- Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 410632; 5 Nov 1990 10:38:10-0500 Date: Mon, 5 Nov 1990 10:39-0500 From: Scott Cyphers Subject: specializer metaobjects To: Gregor@parc.xerox.COM, mop.PARC@xerox.com In-Reply-To: <90Nov4.144757pst.284@spade.parc.xerox.com> Message-ID: <19901105153931.4.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Sun, 4 Nov 1990 17:47 EST From: Gregor Kiczales I think this is a step in the right direction. The tricky point is in describing the conversion of the external format of specializers (what appears in DEFMETHOD forms) to specializer metaobjects. This conversion needs to be based on a notion of `interning'. Is there any reason for this other than to conserve space? If it's just to preserve space, this seems like a job for the implementation, which may have access to things like weak tables to help it do the job. Just make the MOP say "An implementation is free to share specializers that behave the same" or something like that. That is two external forms which both describe the `same' specializer should in fact produce the same specializer metaobject. The definition of `same' depends on the specializer in question. For classes, the interning function is just FIND-CLASS. For EQL specializers, the interning predicate is EQL. And so on. We already preserce initforms for slots, why not specializer forms for specializers? For example, if *FOO* and *BAR* are EQL, then (EQL *FOO*) and (EQL *BAR*) do the same thing, but look different. For an implementation which saves initforms, saving the specializer form makes just as much sense. Here is some naive model implementation code: (defclass class (specializer) ..) You call yourself an MOP programmer?! There should be a specializer class, with subclasses class-specializer and eql-specializer. Specializer takes an initarg :SPECIALIZER-FORM. Class-specializer also takes :CLASS and eql-specializer takes :OBJECT (or or some better name). I'd like to see a parse-specializer generic function (two arguments, the form and the environment) and a parse-cons-specializer, three arguments, the car of the form, the cdr of the form, and the environment. I'm not sure if the environment is really needed; better safe than sorry. CLOS would come with two methods for parse-specializer, one specialized on symbol and one on cons. parse-cons-specializer would have one method, eql-specialized on EQL. Our CLIM would also add one eql-specialized on CLASS which provides an alternative syntax for a class specializer. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA00695; Tue, 13 Nov 90 06:43:45 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <17221>; Tue, 13 Nov 1990 06:43:14 PST Received: from relay.cc.u-tokyo.ac.jp ([192.41.197.3]) by alpha.xerox.com with SMTP id <17220>; Tue, 13 Nov 1990 06:42:11 PST Received: from ccut.cc.u-tokyo.ac.jp by relay.cc.u-tokyo.ac.jp (5.61/2.7W) id AA15815; Tue, 13 Nov 90 23:41:37 +0900 Received: by ccut.cc.u-tokyo.ac.jp (5.61/6.4J.6-ut2.126) id AA11699; Tue, 13 Nov 90 23:41:27 +0900 Received: by trla.trl.ibm.co.jp (5.51/6.4J.6-900124) id AA05452; Tue, 13 Nov 90 23:36:19+0900 Return-Path: X-Ns-Transport-Id: 08002008D0FD00043238 Date: Wed, 14 Nov 1990 00:36:18 PST From: TANAKA Tomoyuki Subject: My (possible) visit in December (3) To: Gregor Kiczales Cc: MOP , tanakat@trl.ibm.co.jp Message-Id: <9011131436.AA05452@trla.trl.ibm.co.jp> Hello. I changed my plan a bit: --- Arrive in SF: Dec 12 (Wed) night --- Leave SF: Dec 16 (Sun) afternoon I would like to visit you sometime during this interval. Tanaka Tomoyuki Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA09097; Tue, 13 Nov 90 13:53:00 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <17254>; Tue, 13 Nov 1990 13:52:32 PST Received: from hplms2.hpl.hp.com ([15.255.176.66]) by alpha.xerox.com with SMTP id <17248>; Tue, 13 Nov 1990 13:51:07 PST Received: from hplsny.hpl.hp.com by hplms2.hpl.hp.com with SMTP (16.5/15.5+IOS 3.20) id AA01038; Tue, 13 Nov 90 13:50:28 -0800 Received: from localhost by hplsny.hpl.hp.com with SMTP (15.11/15.5+IOS 3.14) id AA08103; Tue, 13 Nov 90 13:50:30 pst X-Mailer: mh6.5 X-Ns-Transport-Id: 08002008D0FD000436E9 Date: Tue, 13 Nov 1990 13:50:26 PST From: Alan Snyder Subject: comments on The Art of the Metaobject Protocol, Part 1 To: mop@arisia.Xerox.COM Reply-To: snyder@hplms2.hpl.hp.COM Message-Id: <8101.658533026@hplsny.hpl.hp.com> I have read through Part 1 of "The Art of the MetaObject Protocol". I think it is excellent! Well written. I have a few comments. On page 32, you might want to comment on why you are storing a form and an environment separately, instead of just a closure. Your examples would benefit from use of the :TYPE option to declare the types of slot values, wherever possible. In the same vein, how about using the package system to make explicit those things that are available to the user? For example, couldn't the package system be used to protect against (setf (class-direct-subclasses ... )), which is mentioned on page 48? In section 2.1, you mention introducing class objects as part of the MOP. However, if you were using a Scheme style, you would need class objects as part of the vanilla user language (e.g. as the argument to make-instance, instead of using a class name). However, the class object could just be an entity; it would not need any user-visible operations. So, I think it is more accurate to say that the class object is part of the vanilla user language and the operations on class objects are part of the enhancement provided by the MOP. Page 35, the undotted i trick is cute, but I don't like it. The problem is that the undotted i is not recognizable! Page 77: The phrase "creating class metaobjects" is misleading. It should be "creating instances of class metaobjects". 3.2.1: I've always felt that the "alternative class precedence lists" example was given more press than it deserves. It is so trivial. Perhaps you should omit it? The other examples are much deeper. Page 93: There is no space in the name "CommonObjects". Page 99: In a couple of places, you say that a method cannot be overriden or redefined. Wouldn't it be nice if CLOS let you declare that (and enforced the declaration)? Would it be a good example to use the MOP to implement such a declaration??? Page 73: Why must an entire class be a database-class? Why can't I define an "employee" class and have both ordinary employee objects and database employee objects? You don't even discuss this as a possibility... 4.2.3: Encapsulated methods. It's too bad that the generic function has to know that the methods are encapsulated. Why shouldn't one method be encapsulated and others be ordinary??? (For example, why can't I define a PRINT encapsulated method on a CommonObjects class? [where PRINT is some standard generic function] ) (Does the revision on page 128 allow this?) For anyone who is aware of how long it took to develop the MOP, it would be nice to have a summary somewhere of the things that were hard to get right. It would be nice if you discussed compilation issues. Alan Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26258; Wed, 14 Nov 90 09:18:28 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <17263>; Wed, 14 Nov 1990 09:16:43 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <17266>; Wed, 14 Nov 1990 09:12:54 PST X-Ns-Transport-Id: 08002008D0FD00043B56 Date: Wed, 14 Nov 1990 09:36:53 PST From: kanderso@DINO.BBN.COM Subject: Comments on AMOP To: mop@arisia.Xerox.COM Cc: kanderson@DINO.BBN.COM Message-Id: <90Nov14.091254pst.17266@alpha.xerox.com> Here are a couple more comments on AMOP. Page 32. I recommend redoing your treatment of method-functions slightly. In the Closette software, method-functions are compiled at runtime. The body of AMOP talks about some imaginary way of doing apply-method that calls eval. This way is then extended, later on. I believe things would be fine if you introduce method-functions immediately. You could mention the way Closette does it, which is late compilation, versus the way PCL does it during compile-file time, and leave the details until the appendix. Even keeping the body and the function around could lead to very interesting SELF like experimentation. Your metalevel extentions in section 4.2.3 would still work out well. An alternative would be to create the compiled method-function as a #'(lambda ...) in the call to ensure-method. This would let you side step the environment issue altogether. Clearly you want to make the factoring point on page 134 quite strongly. I don't think you need weak method functions to make the point. I found it a cruel joke to read up to page 138 to find that i wasn't going to get a clue of how a real CLOS implementation does this. Page 119, Line 3. Starts with a funny character. Basically, i think this is a wonderful work. It is probably even more valuable than finishing Chapter 3 of CLOS, because it motivates the issues of any MOP so well. I think Appendix A deserves to be a full fledged chapter. I love the term "metastability". Watching you construct the metabraid in Closette in 10 easy steps was extremely enjoyable. Thanks, k Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA09283; Wed, 14 Nov 90 19:12:14 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16189>; Wed, 14 Nov 1990 19:11:26 PST Received: from decpa.pa.dec.com ([16.1.240.23]) by alpha.xerox.com with SMTP id <16196>; Wed, 14 Nov 1990 19:10:02 PST Received: by decpa.pa.dec.com; id AA11881; Wed, 14 Nov 90 09:38:20 -0800 Received: from tle.enet; by decwrl.enet; Wed, 14 Nov 90 09:38:26 PST X-Ns-Transport-Id: 08002008D0FD00044144 Date: Wed, 14 Nov 1990 09:38:26 PST From: 14-Nov-1990 1238 Subject: 1st pass comments on Art of MOP To: mop@arisia.Xerox.COM Message-Id: <9011141738.AA11881@decpa.pa.dec.com> Hi. I still haven't finished reading the whole book, but I thought you might want to see my comments before it's too late. In general, the book is pretty good--it's reasonably clear and easy to read. I'm going to see if I can get some of the traditional-language compiler people around here to appreciate the issues, and this presentation is a good one. Although I've noticed that some of this is addressed in Chapter 4, which I haven't read yet, I'd like to state that compile-time/optimization issues are important and interesting, and that I'm disappointed that this book doesn't devote more time on that. The following is a log of all of my comments as I read. Some of the questions were answered later on, but I've left them in so you can consider adding some commentary that would make the exposition a little clearer. Intro: Why require explicit defgeneric before defmethod? I assume it's just because of simplicity of exposition, not because of difficulty of implementation. The rest of the restrictions seem pretty reasonable. 1.3 No justification for why cacheing class precedence list & all slots in standard-class, but not other information, such as all effective methods or the like 1.3 p11 & 1.5 p29 functions other than the defclass and defgeneric macro are not "available to users" -- but they are part of CLtL/X3J13 CLOS. Probably need to mention that some CLtL/X3J13 CLOS functions are really part of the MOP. p12 "that it true" should be "that is true" p13 Why bother confusing reader with "address" of standard-class instance? p17 Someone could ask "Well, gee, why use after method on initialize-instance for standard-class? Why not just insert in ensure-class?" Already starting the process of generalizing the implementation needs better justification. Maybe the implementation shouldn't use CLOS at all in Chapter 1? That would really drive the point home better. 1.3.4 To continue the "recursive descent" exposition, describe compute-class- precedence-list in detail before compute-slots, rather than the other way around p22 How to associate slot-name <==> location? Is local-slot-location really part of std-instance definition? p26 Stylistic issue: '() to indicate empty list instead of just () would be clearer p31 Mention that you're ignoring the case that a regular function is already defined for the function name p32 Missing (BLOCK 'PAINT ...) around body in fig 1.5 p34 Mention that there's no checking that lambda lists agree Why separate the lambda-list, body, &environment, when storing #'(lambda (...) ...) would avoid the problem? p41 [p34 comment continued, as it turns out] Adding call-next-method & next-method-p is part of the justification; but couldn't this have been done another way? (e.g. FLET and special variables) EVALHOOK could be used instead of a mythical EVAL with environment arg p43 "The classed named" should be "The classes named" p50 "==>" looks too much like the "evaluates to" symbol of CLtL, rather than like a prompt p51 Why is convert-to-string needed? isn't class-name always a string? p57 "latter label a" should be "latter labels a" p59 "the presense of" should be "the presence of" p62 "each generic function has at least one method" ? no p69 Two periods after "don't provide.." should have only one period p72-73 Another goal: avoidance of duplication of mechanisms--encourages using standard CLOS for implementing itself p81 Last paragraph--why not depend on whether it's a rainy Tuesday? p82 "with the class metaobject for standard-object and t coming at the end" should be plural: "class metaobjects" p86 Where did it say that users couldn't redefine system-defined classes? Sure, one can easily outlaw defmethod compute-class-precendence-list on standard-class, but how is new programmer supposed to know where the line is? "standard" in the name? p88 "non-empty list of ... metaobject" should be plural: "metaobjects" general: Does every function that is in the "public" metaobject protocol need to be a method? What about internal functions? Of course not, but how does one decide? [maybe this is discussed in Chapter 4...] I'd hope there were some specific principles rather than responses to the needs of individual applications as they came along. p103 "by not replaced" should be "but not replaced" p108 allocate-instance on standard-class: why no override? But that's what we want! "Slots marks with" should be "Slots marked with" p111 Gotta setf (gethash ...) with value of delete p112 Missing spaces in "make-instanceandinitialize-instance" "information this is" should be "information that is" [haven't read Chapter 4 yet] p143 evalhook allows use of env for eval another reason why not: overhead: time & space I tried the Closette implementation on VAX LISP V3.1 and have a few comments: (1) It basically seemed to work (2) The address of an allocated object can be determined by (SYS::ADDRESS-OF x) It can be read-time conditionalized by #+:VAXLISP (3) The compiler blew up trying to evaluate the call to (EXPORT EXPORTS), because EXPORTS wasn't defined. I put an EVAL-WHEN (COMPILE LOAD EVAL) around the DEFVAR of EXPORTS. (4) The compiler blew up because CANONICALIZE-DIRECT-SUPERCLASSES wasn't defined. So I gave up and loaded the source file first, and then compiled closette. This worked, so the change I made in (3) isn't needed. A comment to the effect that you might need to load the code before compiling would be welcome. (5) There were a lot of warning messages from the compiler about variables being bound but not used, during bootstrapping. ---Walter BTW, note that my address is now @tle.enet.dec.com, not @aitg.enet.dec.com. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA07661; Thu, 15 Nov 90 15:52:07 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16255>; Thu, 15 Nov 1990 15:51:40 PST Received: from rice.edu ([128.42.5.1]) by alpha.xerox.com with SMTP id <16252>; Thu, 15 Nov 1990 15:47:42 PST Received: from titan.rice.edu by rice.edu (AA14046); Thu, 15 Nov 90 17:47:07 CST Received: by titan.rice.edu (AA24463); Thu, 15 Nov 90 17:47:17 CST X-Ns-Transport-Id: 08002008D0FD00044BE2 Date: Thu, 15 Nov 1990 15:47:17 PST From: mcw@rice.edu (Michael Wirth) Subject: Feedback on "The Art of the MOP" To: mop@arisia.Xerox.COM Cc: D0966@applelink.apple.com, mcw@titan.rice.edu Message-Id: <9011152347.AA24463@titan.rice.edu> First of all, thanks for producing the document. I spent an hour or two with it on my flight back from Ottawa and found it to be very informative and delightful reading. I'm looking forward to a quiet moment or two when I can resume my examination of the document. But I though I'd better give you some initial comments now. (I have too many partially read books stacked up!) These comments are entirely on issues of "style", not substantive content. Applying these suggestions throughout the document would, I hope, improve the reader's ease of comprehension. In Fig. 1.1 on page 10: * Add arrowheads to the links. * Use some visual cue to distinguish backstage objects (e.g., font, shaded background, etc.) in the figures. Visually distinguish blocks of code from the text (e.g., by indentation, smaller point size, shaded background, etc.). See page 24 for an example of where this is needed. In Fig. 1.4 on page 29: * Move this figure to after the start of section 1.5 * Distinguish figures somehow (e.g., box, white-space, shaded area, etc.) Thanks for the opportunity to review "The Art of the MOP". If you issue a new version, please send me a copy. I'll promise to try to float it to the top of my reading stack. Mike Wirth Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA15770; Thu, 15 Nov 90 20:26:25 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16259>; Thu, 15 Nov 1990 20:26:00 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16259>; Thu, 15 Nov 1990 20:24:41 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA26814g; Thu, 15 Nov 90 20:16:57 PST Received: by caligula id AA09221g; Thu, 15 Nov 90 20:21:33 PST X-Ns-Transport-Id: 08002008D0FD00044EEA Date: Thu, 15 Nov 1990 20:21:33 PST From: Jon L White Subject: Comments on AMOP To: bobrow@parc.xerox.com, gregor@parc.xerox.com, desrivieres.PARC@xerox.com Cc: mop@arisia.Xerox.COM Message-Id: <9011160421.AA09221@caligula> [Always cramped for time -- at least it's only the 15'th!] I have a number of comments, ranging all the way from little nit pickings to overall design directions. For sake of brevity (ha!) I'll not point out typos etc that other reviewers must have already noticed; and one of the design issues is so large that I'll compose it into a separate message (slot-specifications versus slot-definitions). However, this does raise the issue of what good these comments can do now. I think some of the metaobject protocol design points are not "cast in concrete" yet, because only a relatively small part of them have been implemented by the several vendors with CLOS's in the field, or about to be in the field (of course, I mean the stuff in additon to the X3J13 document 88-002R and subsequent "cleanups" of that.) In addition to the relatively small set of "introspective" functions and types that Dave Moon, Scott Cyphers, myself, and Franz agreed upon last March, I might count VALIDATE-SUPERCLASS in this category too. Although Symbolics has not documented VALIDATE-SUPERCLASS, they provide it internally, and seem to be willing to talk to people about it's existence as long as it is understood that all the not-yet standardized stuff is subject to change. Lucid provides "on line" documentation (sometimes of dubious quality) for such facilities. So I hope you all can take my comments in the right spirit -- namely, the positivie praise is not just "stroking", but sincere; the negative comments are not just carping, but are trying to point out troublesome spots, in case there is time to amend them somehow. And the "constructive suggestions" and not just off-the-wall, but re-directions for design points that will definitely cause some unnecessary degree of trouble *** and for which it isn't too late yet to alter them ***. You must realize, that with the final publication of this document/book, it will be infinitely harder to make corrections to poorly designed or overlooked points; witness the difficulties we may have with the premature descriptions found in CLtL/II now (as opposed to the corrected versions that will eventually and hopefully come out in a final ANSI proposal.) . . . . . . . . . . . . . . . . . . . . First the praise. The world will definitely be better off for the publication of this book. At present, only a handfull of cognescenti have mastered CLOS internals. One can hardly see any of the important implications of the rigorous specification (X3J13/88-002R) merely by being astute about computer languages and reading the specification. There is no doubt that the widespread dissemination of the PCL sources has had a signal impact on making CLOS acceptable to the "cognescenti" who have managed to grasp its beauty. But frankly, those sources are virtually impenetrable; only the most dedicated hacker with lots of time on his hands can effectively understand them and manipulate them constructively. But more. The overall organization of this "book" is very good; it presents the topics in a very logical, step-by-step order, and will, _I think_, be understandable by any reasonable computer scientist. In particular, I like the breakdown of the example code; good cutting into bite-sized pieces, good use of succinct programming paradigms! [I always *knew* the inclusion of all those APL-inspired sequence functions into Common Lisp was good for something! Quux Redux! Of course, a completely functional style in this presentation doesn't mean that this is a good way to actually implement the intermediate CLOS functionality presented; it just makes it more reasonable not to have to worry about efficiency considerations and programming hacks when you are tyring to understand the basic algorithms. Also, the kinds of efficiency considerations I am thinking of aren't something that can be compensated mechanically from the functional style code, so let's not use this time and space for the continuing arguments about what an SSC ("Sufficiently-Smart-Compiler") could do.] I especially liked the Class-With-Attributes example; I've heard comments and questions about CLOS from many people who have used KEE in the past, and this section may actually help them in coding up some of their former concepts. It would also be nice to see a bit more attention given to a route that is susceptible to optimization. For example you might multiply the number of actual slots by the number of attributes and "interpolate" some slots corresponding to the attribute storage by giving them internally generated names. So a class with slots A, B and C and with attribute CHARM could be automatically extended to have slots #:A-CHARM, #:B-CHARM, and #:C-CHARM (don't take these names too seriously), and then it would be trivial to add optimizations for forms like (SLOT-ATTRIBUTE 'A 'CHARM). The examples in sections 3.5 and 3.6 of "monitored" slots and "dynamic" slots are really quite nice! I hope someone can actually use them. Section 3.5 on "Slot Access" does a good job clearing up why the function SLOT-VALUE isn't generic. The straw-man you offer (on the middle of page 102) is, however, just a bit weak. Just as there is STANDARD-OBJECT as a "maximal" class for STANDARD-CLASS, so it is possible to have DATABASE-OBJECT as a "maximal" class for DATABASE-CLASS, even when DATABASE-CLASS is a sublcass of STANDARD-CLASS [I know that Andreas Paepcke has addressed just this point in work related to his PCLOS. By the bye, my use of "maximal" here is clear, no?] Knocking down this house of cards is a bit more tedious since you have to draw the comparison between SLOT-VALUE and SLOT-VALUE-USING-CLASS for other metaclasses that don't have "maximal" elements. But still, this is a good section to have. . . . . . . . . . . . . . . . . . . . . Now, time for some critiques. If this note seems to be lengthy on the critique side and shorter on the praise side, I do not mean to be harsh; rather it is only because I wanted to mention some thoughts I've had while reading the AMOP *** before *** they become totally moot by its widespread dissemination. There is one general downside to the overall presentation, even though it isn't by any means a showstopper. I had been expecting, based on previous comments from you all (the authors), a rationale behind some of the CLOS components; in particular, the WHY's of why you would want some of these otherwise unmotiveated metaobject thingies. I know, you could argue that the reasoning is implicit after you have an overall understanding of the presentation and why it all hangs together; I just think it would be better to make these reasonings and comments more explicit, and to do so at a very explicit level (i.e., the level that says "user-control over programming constructs is good" or "extensibility is better" or "motherhood and apple pie" doesn't cut it.) I won't take time/space to make detailed suggestions on this matter, because it goes too deep for casual contributions (and the effort to flesh it out this way might be too great at this late a time in your publication cycle). I just wanted to point out what I consider a serious lacuna. In truth, I've only had the time to read Chapters 1-3 carefuly, and skim chapter 4; but the disappointment is that the first half of the book is page after page after page of details of an implementation, with few if any hints at the expected rationales. Now, a minor nit. The first chapter's title is "How CLOS *is* Implemented" [emphasis mine]. This is bit much. It is about how CLOSETTE is implemented, and I can recognize how closely CLOSETTE parallels a re-worked and abbreviated version of PCL. So maybe a title like "Implementing CLOS" would be more neutral? You surely mean the code to be illustrative and not mandatory. For example, how much of the functionality on pages 12 and 13 is: (1) required by X3J13/002R and CLtL/II? (2) included in the "de-facto, introspective metaboject protocl" abstracted by Symbolics, Lucid, and Franz and included in their products? (3) mentioned in the continuing saga of the "Chapter 3" proposal? (4) a PCL'ism probably not included in the foregoing? Consider each point in turn for PRINT-OBJECT, CLASS-PRECEDENCE-LIST, ENSURE-CLASS, and DIRECT-METHODS or CANONICALIZE-DIRECT-SUPERCLASSES. This is clearly a presentation of CLOSETTE -- a workable implementation of a small subset of CLOS -- not a critical study of what functionality is logically required, or of what may eventually be desirable. A more serious point is the substitution of novel terminology for what are likely already standardly acceptable terms. Page 11 introduces the term "Class metabojects"; how is this different from "Class objects? Page 74 introduces "metaobject classes"; how different is this from "metaclasses"? Further, the term "metaobject" is badly blurred by (p.74) "a metaobject is an instance of some metaobject class"; does this mean that the totally useless object I get by randomly calling (ALLOCATE-INSTANCE 'STANDARD-METHOD) is a metaobject? That doesn't fit with the general direction of metaobjects as objects used in the definition of the basic system (and which the user needs to know about in order to tailor the system to his own desires). With bated breath I was awaiting the introductions of "meta classobjects" and "object metaclasses"; it just looked like a case of picking three wordlets and combining them all ways. I can't believe that avoidance of the word "metaclass" has any value -- and your declaration of intent to do so, on page 74, offered no justification. [SmallTalkers, and researchers familiar with Pierre Cointe's and Patti Maes' works will likely not be confused by it either; so that can't be the justification.]. I found that playing the "three wordlet" game was quite frustrating, and definitely would have preferred simpler and more conventional terms. This is not a question of *consistency* of terminology, but rather the invention of novel terms where standard ones would have sufficed. In _many_ places, all the extra "objectology" could simply have been dropped. Just say "class". In context, it is ususally easy to tell if "class" refers to an abstract concept, or to an actual data object (or, as the current AMOP say "Class metaobject"); this is particularly true of prose that is describing the actions of a sample piece of code. On the other hand, the terms on page 74 of "regular methods" (and "specialized methods"?) work quite well. "Regular" is always up for grabs as a locally-redefined adjective. Even "Regular metaclasses" and "Specialized metaclasses" would work. As I read the sample code on page 51 -- ALL-CLASSES -- I wondered why you didn't just expose the hash table documented on page 14? Of course it would be infinitely more efficient to maphash across the table than to descend a "bushy" class hierarchy, but that isn't why I bring up the question. Rather, I am wondering if you are afraid to call the hash table found in the closure of FIND-CLASS a metaobject? Is it the case that the only things you are willing to call "metaobjects" are of metaclass Standard-Class (such as the class named by T?). At least on page 46 you point out that every Lisp object has class. So this anonymous hash-table has some class, and is very pertinent to the implementation of the system. [By the bye, the entitlement of "class" to everything brings up the question of the missing BUILT-IN-CLASS, but ...] Does it have to be of a completely new datatype to be a metaobject? The section on encapsulated classes -- Section 3.3.4 -- has some conceptual difficulties. It says that encapsulation "defines a subclass that assigns unique names to ***direct slots***" [emphasis added]. But what is a "direct slot"? is it one whose composition includes no inherited components? or is it one that simply has *some* components attributable to the slot specifiers given directly to the class creation functions? If the latter and not the former, then how can the slot be considered "encapsulated" if it is exposed to inheritance? But if the former, then the definition is circular, since it is precisely "inheritance" that you are trying to block. Since "encapsulated" mostly implies name inaccessibility, then why not just use the package system for this purpose? (well, that is why it was invented.) You could make a new, unique package for every encapsulated class, and the accessibility of the private slots would be controlled by package accessibility (which would just happen to coincide with the internals of that class.) Further, you would use IMPORT and EXPORT to control the modular concepts that other languages call "import" and "export". Interesting. Also the section on Discriminating functions and Method Functions has some difficulties if it is targeted towards a mandatory piece of CLOS functionality. Dick Gabriel has already argued against the notion of "discriminating function" as being basic; rather, he proposed a design that would create a "discriminating object" which a most-general disptach function could operate upon in order to make the actual dispatch code for a generic function. And I have (in other forums) brought up some of the difficulties with forcing every method to support a single Method-Function component. For effective methods, it is clear that a single "function" could easily be generated; but it is not at all clear that COMPUTE-EFFECTIVE-METHOD must compose its resultant function merely by pulling out the Method-Functions of the various methods. So what good is Method-Function? Having a component which is some sort of generator usable by method combination would be fine, but the Method-Function as currently mentioned isn't it. . . . . . . . . . . . . . . . . . . . . In the next few paragraphs, I want to make a couple of short-but-specific constructive suggestions. I'm sure each of these isn't too late in the release cycle of existing CLOS implementations, nor are they constrained yet by X3J13 standards. Page 41 introduces APPLY-METHOD. This is a good concept. Unfortunately the ordering of arguments is pessimal. By analogy to APPLY, APPLY-METHOD's signature should be like: (APPLY ... ) In the case where all the arguments to the method/generic-function have been enlisted, this just becomes: (APPLY ) The format currently in AMOP doesn't allow for the obvious analogy with APPLY (and that's bad enough), but Lucid's implementation has already supplied an APPLY-METHOD function with the preferable signature as an extension (that was actually needed by two different end users). Why not follow precedent here? and follow the good analogoue to APPLY. Section 2.4 "Programmatic Creation of New Classes" is belaboring under the pressure to have a symbol to name every class. Why not just go for it and permit anonymous classes? Unfortunatley, the X3J13 specification implies this constraint also (no anonymous classes); but we all have been expecting it to be relaxed when the metaobject protocol is available. And Dave Moon has been using some sort of anonymous classes in CLIM work (I think); so Lucid had to modify some part of it's implementataion *not* to enforce the 88-002R semantics, and not to depend upon every class having a name (note: "name", not "propoer name"). Can we nip this in the bug? this propensity to name everything. Besides, I really didn't see how enforced name assignments helped the CLOSETTE presentation in any way. Following below are comments about a few more minor problems, which could easily be corrected. -- page 21 uses STD-INSTANCE. Recent mailings to the X3J13 list show the undesirability (and unnecessity) of using 1960's style abbreviations, especially where hard-to-remember names are concerned. So why not STANDARD-INSTANCE. If vowel-less abbreviations are such a good idea, then why not use STD-INST-LCL-SLTS? (I'll be I don't have to fill in the vowels or other missing particles for you here.) If they aren't such a great idea in general, then why stoop to them on STANDARD? -- page 23 has ALLOCATE-INSTANCE as a regular non-generic function; but even the page 25 code implies that it must be generic. So why not name the defun'd function ALLOCATE-STANDARD-INSTANCE, and later show that the generic function could simply dispatch to that function in the case of a standard-class request. Or maybe even rewrite the defun as a defmethod. -- page 26 says that SHARED-INITIALIZE can set a value "From an existing binding". One can ask "What does this mean?" perhaps it would be good to mention a case or two in which you wind up inside SHARED-INITIALIZE and there are "existing bindings" to look at (e.g., redefinitions, :BEFORE methods and the like.) -- page 37 defines COMPUTE-APPLICABLE-METHODS-USING-CLASSES; this is a very misleading name to someone familiar with the nomenclature style of "Chapter 3" -- such as functions like SLOT-VALUE-USING-CLASS, ENSURE--USING-CLASS, and so on. Let me suggest instead COMPUTE-APPLICABLE-METHODS-FROM-CLASSES. -- page 51 calls CONVERT-TO-STRING on the CLASS-NAMES; but haven't you already restricted the class NAME slots to being symbols? (not necessarily proper names, but certainly not random objects). And despite it's name, STRING-LESSP accepts symbols; so the symbol which is the name of a class is acceptable for the comparison. -- page 52 -- section 2.2.6 -- introduces the concept of "Well-Ordered Classes". This is a misuse of the mathematical concept of a well order; what you are really discussing is the concept of consistency of partial orders. You could say "Consistently Ordered", without having unwanted implications. Or, "Consistently Ordered by subclasses." [By the bye, I was seriously disappointed that you just presented this concept and didn't refer either to its utility in method combination, nor to the very common misunderstanding that the non-cognescenti have about the partial orderings induced by the CPL algorithm.] -- page 74 defines "exactly three system-supplied" metaclasses; what happened to STANDARD-SLOT-DEFINITION? shortly thereafter, the example of Class-With-Attributes uses slot-definition objects all over the place. -- Sections 2.2.7 and 2.3.1 -- about "regenerating" definitions for classes, generic-funtions, and method -- implies that virtually all the source code is stored (e.g., the :INITFORM's, as well as the code bodies for methods). I wouldn't like this to be taken as a revival of the "residential Lisp" versus "text files for sources" debate. Can't you somehow "tone it down"? at least a word to the wise that the source code for some parts *** might not *** be available after file compilation, but that the other parts of the regeneration are still accessible? -- Chapter 3 uses terms for method definitions like "overridden" and "redefined" (and "shadowed"?); but I don't recall seeing these defined in AMOP. I know they are carefully defined elsewhere, but that doesn't help if the definitions aren't available in AMOP too. [or, maybe I just forgot where they were defined?] -- Section 3.3 might try drawing a parallel between a hypothetical VALUE attribute and the functionality of the SLOT-VALUE function; that way, SLOT-ATTRIBUTE could more easily been seen as a conceptual generalization of SLOT-VALUE. -- page 99 says that "the regular method [on Finalize-Inheritance], which is specialized to Standard-Class, *cannot* be overridden or redefined" [emphasis in original]. Don't you mean "must not" rather than "cannot"? in CLtL parlance, "it is an error ...". -- On the same topic, you later say that the specialized method must call CALL-NEXT-METHOD (in order to get the side-effects, or whatever.) This might be a good place to point out, even if only in a footnote, that CALL-NEXT-METHOD is the right thing, and putting an :AROUND method would be wrong. I know you don't have :AROUND's in CLOSETTE; but end users so often make the mistake of sledge-hammering in an :AROUND method when all they really needed was a specialized method that called CALL-NEXT-METHOD. This just seemed like a good place to point out some examples of good style. -- page 103 mentions that "a class C1 can be a subclass of C2 without requiring that (CLASS-OF C1) be a subclass of (CLASS-OF C2), and conversely." A meaningful example might be good here. For example, in most real CLOS implementations, you would expect class FUNCTION to be of BUILT-IN-CLASS, but its subclass STANDARD-GENERIC-FUNCTION to be of another, incomparable metaclass. This seems to be a tough point for many otherwise well-read but CLOS-naive people to understand, since in SmallTalk the metaclass hierarchy is (I guess) just a dual of the regular class hierarchy. This would also be a good place to mention the relevancy of a concept like VALIDATE-SUPERCLASS. . . . . . . . . . . . . . . . . . . . . Well, that's about enough for now. High order bit? Its a net win! Keep at it. -- Jon -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA19875; Thu, 15 Nov 90 23:06:17 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16218>; Thu, 15 Nov 1990 23:05:29 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16218>; Thu, 15 Nov 1990 23:03:41 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA28158g; Thu, 15 Nov 90 22:56:29 PST Received: by caligula id AA09350g; Thu, 15 Nov 90 23:01:06 PST X-Ns-Transport-Id: 08002008D0FD00044FC0 Date: Thu, 15 Nov 1990 23:01:06 PST From: Jon L White Subject: Mopping up after the fact To: mop@arisia.Xerox.COM Message-Id: <9011160701.AA09350@caligula> [Hmmm, "cleanup" issues for the Meta Object Protocol must be what we mean by "mopping up"] There's one point of development in the emerging MOP that is very confusing, and needlessly so. Since the AMOP also follows this line of design, it is sort of necessary to bring it up now before a confusing paradigm is cast in concrete. There is surely time to correct it now. Let me illustrate it with reference to the :DEFAULT-INITARGS option to DEFCLASS. Consider: (defclass foo () ((slot1 :initarg :slot1) (slot2 :initarg :slot2) (slot3 :initarg :slot3 :initform 0 :type (and number (not syzygy)))) (:default-initargs :slot1 1 :slot2 2)) (defclass bar (foo) ((slot3 :initarg hue :type (or symbol integer))) (:default-initargs :slot1 'one :slot3 (call-three))) Question: what are the default initarg definitions for class BAR? It might suffice to characterize them with the list: ((:SLOT1 . ) (:SLOT3 . ) (:SLOT2 . )) or maybe even like: (:SLOT1 :SLOT3 :SLOT2 ) the point being that each such definition is a resolution of the possibly many direct specifications found in the given class and in its superclassess. (In this case the resolution doesn't involve any compound compositions -- just selection based on precedence; but it could have been otherwise). Yet it has been suggested that the alist format of the definition isn't satisfactory since one might conceivably want to write metaobject protocols that treat different categories of initial value fetchings differently, *** and even want to attach methods at certain points in their construction or application ***. [The proplist format would be even worse.] Thus the format for a single initializer: (:SLOT1 . ) or: (:SLOT3 . ; Mon, 19 Nov 1990 15:22:41 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16415>; Mon, 19 Nov 1990 15:20:52 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 875273; 19 Nov 1990 18:10:32-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD000471C7 Date: Mon, 19 Nov 1990 15:14:00 PST From: Moon@stony-brook.scrc.symbolics.com Subject: Mopping up after the fact In-Reply-To: <9011160701.AA09350@caligula> To: Jon L White Cc: mop@arisia.Xerox.COM Message-Id: <19901119231436.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Could you send a 10 to 15 line, no longer, summary of what exactly you are proposing here, please? I couldn't even figure out whether the default initarg stuff was part of your proposal or not. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA16487; Tue, 20 Nov 90 02:18:32 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16457>; Tue, 20 Nov 1990 02:17:40 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16460>; Tue, 20 Nov 1990 02:15:36 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA02921g; Tue, 20 Nov 90 02:06:50 PST Received: by caligula id AA13475g; Mon, 19 Nov 90 22:41:20 PST X-Ns-Transport-Id: 08002008D0FD000475D7 Date: Mon, 19 Nov 1990 22:41:20 PST From: Jon L White Subject: Mopping up after the fact In-Reply-To: "Moon@stony-brook.scrc.symbolics.com's message of Mon, 19 Nov 1990 15:14:00 PST <19901119231436.6.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.com Cc: mop@arisia.Xerox.COM Message-Id: <9011200641.AA13475@caligula> re: Could you send a 10 to 15 line, no longer, summary of what exactly ... The following two paragraphs lifted from the longer message are about 15 lines total, and hit at the essence of what I was saying. The upshot is that no change is implied for default initargs (since we aren't using "Initializer" objects); but the extra kinds of -SLOT-DEFINITIONS could go away (leaving primarily one) if we chose not to recode the storage of canonicalized slot _specifications_ from lists into standard-object instances. The rest of the message was rebutting the hypothetical argument that it could be useful somewhere, someday, to have done the recoding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . *** Only the one function *** -- COMPUTE-CLASS-DEFAULT-INITARGS -- ever looks at the "direct" default initarg specifications; and in some cases it would be premature to classify them into Initializer classes until FINALIZE-INHERITANCE is called on that class. The natural course is to leave the "specifications" in their list-structure original format, and to let the function invoked at inheritance finalization time be the sole one responsible for collecting the pieces of spec into a full, effective "definition." Just as in the case of the :DEFAULT-INITARGS specifications, *** only the one function *** -- COMPUTE-SLOTS -- ever looks at the "direct" slot specifications and in some cases it might be premature to classify them into final SLOT-DEFINITION sub-classes until FINALIZE-INHERITANCE is called on that class. The natural course is to leave the "specifications" in their list-structure original format, and to let the function invoked at inheritance finalization time be the sole one responsible for collecting the pieces of spec into a full, effective "definition." . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA07378; Wed, 21 Nov 90 22:12:12 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16549>; Wed, 21 Nov 1990 22:11:49 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16548>; Wed, 21 Nov 1990 22:10:20 PST Received: by spade.parc.xerox.com id <275>; Wed, 21 Nov 1990 22:09:29 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD000488C5 Date: Wed, 21 Nov 1990 22:09:18 PST From: Gregor Kiczales Subject: Re: Mopping up after the fact In-Reply-To: "Jon L White's message of Mon, 19 Nov 1990 22:41:20 PST <9011200641.AA13475@caligula>" To: jonl@lucid.com Cc: Moon@stony-brook.scrc.symbolics.com, mop@arisia.Xerox.COM Message-Id: <90Nov21.220929pst.275@spade.parc.xerox.com> It seems to me that your proposal actually has two implicit parts. The first is that the protocol use to deal with effective slot definitions metaobjects (and default initargs, but I won't talk about them explicitly in this message), be enriched so that the implementation could ask them about things like the kind of of initform they have specially. At least that is what I infer from the suggestion that there would be "contant initform" and "eval initform" classes. I agree that this could and should be done, in a substantially more eleborate MOP. The second part of your proposal is that the access protocol for getting information from direct slot definition metaobjects be, essentially, GETF rather than a set of generic functions. You say that COMPUTE-SLOTS is the only function that looks at these, so there is no need for them to have the more sophisticated accessor protocol they have. COMPUTE-SLOTS isn't the only function that looks at direct slot definition metaobjects, any browser type of tool like the ones shown in chapter two of the AMOP also have to look at these metaobjects. But, that is neither here nor there; if we were to document that GETF was the way to access them, then any code could access them that way. My concern is that I can think of examples where having the accessors to direct slot definition metaobjects be generic functions lets me do things I can't do if the accessor is GETF. For example, in the following code, I define a special kind of class, MY-CLASS; it has its own special kind of direct slot definition metaobject MY-SLOT. These special direct slot definition metaobjects don't store the value of any of the usual "fields" except name. All the other fields have a special default, unique to this class of class metaobject. (defclass my-class (standard-class) ()) (defmethod direct-slot-definition-class ((class my-class) ignore) (find-class 'my-slot)) (defclass my-slot (direct-slot-definition) ((name :initarg :name :reader slot-definition-name))) (defmethod slot-definition-type ((s my-slot)) 'fixnum) (defmethod slot-definition-initform ((s my-slot)) '0) (defmethod slot-definition-initfunction ((s my-slot)) #'(lambda () 0)) (defmethod slot-definition-initargs ((s my-slot)) ()) (defmethod slot-definition-readers ((s my-slot)) ()) (defmethod slot-definition-writers ((s my-slot)) ()) This example is, perhaps, a bit contrived. But I think it illustrates the point that make the extensible OO protocol surrounding direct slot definition metaobjects back into a non-extensible functional protocol is troubling. What I would rather do, actually, is change all the metaobjects (direct and effective) associated with default initargs, into real objects with a generic function based access protocol. But that will have to be for a fancier MOP. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA07619; Wed, 21 Nov 90 22:41:52 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16560>; Wed, 21 Nov 1990 22:41:37 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16560>; Wed, 21 Nov 1990 22:39:54 PST Received: by spade.parc.xerox.com id <275>; Wed, 21 Nov 1990 22:37:53 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD000488E0 Date: Wed, 21 Nov 1990 22:37:40 PST From: Gregor Kiczales Subject: Re: validate-xxx-class-change In-Reply-To: "Jon L White's message of Mon, 5 Nov 1990 20:56:05 PST <9011060456.AA26438@caligula>" To: jonl@lucid.com Cc: MOP.PARC@xerox.com Message-Id: <90Nov21.223753pst.275@spade.parc.xerox.com> Date: Mon, 5 Nov 1990 20:56:05 PST From: Jon L White I can appreciate that one VALIDATE-CHANGE-CLASS is much better than numerious VALIDATE-xxx-CLASS-CHANGE's. But the several of the details of this proposal don't seem as well motivated to me. For example: (1) Why is the checking method -- the :BEFORE method on CHANGE-CLASS -- placed at the point (METAOBJECT T) rather than at (T CLASS)? I agree that it should be either (METAOBJECT CLASS) or (T CLASS). I can put the first in the MOP description; the second is for X3J13 to decide. (2) Why is it "ok" to change a metaobject into any other metaobject? Right, I'll fix this. re: If VALIDATE-CHANGE-CLASS returns, the class change proceeds. I dislike the assymetry of action with VALIDATE-SUPERCLASS, and prefer the latter's semantics. Your :BEFORE method on (METAOBJECT T) could just as easily be defined to signal an error unless VALIDATE-CHANGE-CLASS returns "true". If someone who knows how to program with the condition system will tell me what works best, I will do it consistently with all these generic functions. My conern is for the quality of the error message signalled; by having VALIDATE-XXX return true/false, I was hoping to make it easier to do a good error message. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA14940; Thu, 22 Nov 90 13:02:00 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16573>; Thu, 22 Nov 1990 13:01:22 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16573>; Thu, 22 Nov 1990 12:59:58 PST Received: by spade.parc.xerox.com id <275>; Thu, 22 Nov 1990 12:59:27 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD00048B86 Date: Thu, 22 Nov 1990 12:59:24 PST From: Gregor Kiczales Subject: change to instance structure protocol To: MOP.PARC@xerox.com Message-Id: <90Nov22.125927pst.275@spade.parc.xerox.com> The current instance structure protocol specifies that the slot access functions (e.g. SLOT-VALUE) are implemented in terms of slot acccess generic functions (i.e. SLOT-VALUE-USING-CLASS). The generic functions dispatch on the (class of) the class and the (class of) the object. This protocol has always had a problem, specifically if you want to specialize access to some but not all of a class's slots, it is a bit awkward. You have to write a method on the generic function which first tests to see if the slot in question is a special one; if it is, special code is run, otherwise you do a CALL-NEXT-METHOD. This problem gets even worse when we consider the problem of retaining the implementations ability to do optimized slot access. If the user defines a method on a slot access generic function, the implementation has to call that method (it must deoptimize slot access); but even if in fact only some of the class's slots are affected, the performance of the access to all of them will be affected. The problem is the same one of resolution, the current protocol only specializes on the class and the object, not on individual slots. The solution we have been using is to have a generic function called SLOT-DEFINITION-ELIDE-PORTABLE-ACCESS-METHOD-P which allows the to test whether it can retain its optimization in some cases. But, this is a hack, it distinguishes "compiled" and "interpreted" code in a weird way, and is just plain blecherous. (For reference, the part of the newest MOP which describes this is included at the end of this message.) There is an elegant solution, but I have refrained from proposing it for some time. Now, it really seems worth proposing. The basic idea is to change the last (slot-name) argument to all of the SLOT-XXX-USING-CLASS generic functions. The new value would be the actual effective slot definition metaobject rather than the slot name. The slot access functions would be specified to lookup the effective slot definition object using CLASS-SLOTS, SLOT-DEFINITION-NAME and EQL. Model code: (defun slot-value (object slot-name) (let* ((class (class-of object)) (slot-definition (find slot-name (class-slots class) :key #'slot-definition-name :test #'eql))) (if (null slot-definition) (slot-missing object slot-name 'slot-value) (slot-value-using-class class object slot-definition)))) (defmethod slot-value-using-class ((class standard-class) (object standard-object) (slotd standard-effective-slot-definition)) ..) Given this, a user that wants to specialize the access to some but not all slots of a class can do so by controlling the class of the effective slot definition metaobjects. (defclass my-class (standard-class) ()) (defmethod effective-slot-definition-class ((class my-class) direct-slots) (if (find-class 'special-slot) (call-next-method))) (defclass special-slot (standard-effective-slot-definition) ()) (defmethod slot-value-using-class ((class my-class) object (slotd special-slot)) ) In effect, what has happened is that we have increased the "resolution" of the specialization in the slot access protocol. It is now possible to specialize on a set of slots whereas before it was only possible to specialize on the class and object. With this new protocol, the implementation's ability to elide calls to specified generic functions (and portable methods) arises the same way it does in other parts of the protocol. An advance test of method applicability (`snooping' is what JonL would call it I guess) can see that no portable methods are applicable and then retain the inline call. This change is incompatible in syntax and the like, but my guess is that any implementation technique that used to work still works. Does anyone object to this change? *** For reference, the part of the MOP (draft) which describes *** *** the way things work currently. *** \beginSubsection{Instance Structure Protocol} The instance structure protocol is a three layer protocol. The upper layer is responsible for implementing the behavior of the slot access functions like {\bf slot-value} and {\bf (setf slot-value)}. The middle layer controls the interaction between portable specializations of slot access behavior and any implementation-specific optimizations of slot access. The lowest layer controls the implementation of instances, providing limited mechanisms for direct access to the storage associated with an instance. For each CLOS slot access function, there is a corresponding generic function which actually provides the behavior of the function. When called, the slot access function simply calls the corresponding generic function, and returns its result. The arguments passed on to the generic function include one additional value, the class of the {\it object} argument, which always immediately precedes the {\it object} argument The correspondences between slot access function and underlying slot access generic function are as follows: \boxfig {\dimen0=.5pc \def\slotargs{}%{(\it object slot-name\bf)} \def\gfslotargs{}%{(\it class object slot-name\bf)} \tabskip \dimen0 plus .5 fil \halign to \hsize {#\hfil&#\hfil\cr \noalign{\vskip -9pt} \bf Slot Access Function &\bf Corresponding Slot Access Generic Function\cr \noalign{\vskip 2pt\hrule\vskip 2pt} \bf slot-boundp \slotargs &\bf slot-boundp-using-class \gfslotargs\cr \bf slot-exists-p \slotargs &\bf slot-exists-p-using-class \gfslotargs\cr \bf slot-makunbound \slotargs &\bf slot-makunbound-using-class \gfslotargs\cr \bf slot-value \slotargs &\bf slot-value-using-class \gfslotargs\cr \bf (setf slot-value) \slotargs &\bf (setf slot-value-using-class) \gfslotargs\cr \noalign{\vskip -9pt} }} \caption{} \endfig While not actually specified, it is expected that most implementations will have some mechanism for optimizing slot access. At the time this document is being written, most implementations optimize calls to {\bf slot-value} and {\bf (setf slot-value)} which occur in the body of {\bf defmethod} forms, and which appear implicitly in automatically generated slot accessors. The effect of these optimizations is to elide the actual call to the corresponding slot access generic function by ``in-lining'' the behavior of the generic function's specified method. In the presence of applicable portable methods on slot access generic functions, any such optimization must ensure that these methods are called; just as if no optimization had been done in the first place. But, in many cases, portable methods on the slot access generic functions do not actually affect the behavior of access to all the slots of instances. Often, only a small number of an instance's slots are affected. In such cases, it is desirable to allow the implementation's optimization mechanism to avoid the call to the portable method, if it can be determined in advance that the slot in question is not affected by any of the portable methods. For any given class, this interaction between the implementation's optimization mechanism and portable slot access methods is controlled on a per-slot basis, by the corresponding effective slot definition metaobject. When the class is finalized, the generic function {\bf slot-definition-elide-portable-access-method-p} is called on each of the effective slots. If this generic function returns true, the implementation is permitted (but not required) to elide the call to any applicable portable methods on the slot access generic functions---the implementation is free to run its optimized slot access code. If this generic function returns false, applicable portable methods on the slot access generic functions must be called. The only specified method on the generic function {\bf slot-definition-elide-portable-access-method-p} always returns false. Thus, the default behavior is for applicable portable methods on slot access generic functions to always be called. \beginExample The following code demonstrates a typical use of this mechanism. The class metaobject class {\bf my-class} supports the normal {\bf :instance} and {\bf :class} allocated slots. In addition, {\bf my-class} supports a variant kind of slot for which the access must be done in a special way. For any variant slot, the predicate {\bf my-magic-slot-p} returns true when called on the corresponding effective slot definition metaobject. The example shows the method on {\bf slot-value-using-class} which would be defined to implement the behavior of the variant slots. When the slot with the given name is not a variant slot, {\bf call-next-method} is called to invoke the normal implementation of slot access. The method on {\bf slot-definition-elide-portable-access-method-p} can be read as an ``up-front'' guarantee about whether or not the method on {\bf slot-value-using-class} will end up calling and returning the result of {\bf call-next-method}. \screen! (defmethod slot-value-using-class ((class my-class) object slot-name) (let ((slotd (find slot-name (class-slots class) :key #'slot-definition-name))) (if (my-magic-slot-p slotd) <> (call-next-method)))) (defmethod slot-definition-elide-portable-access-method-p ((class my-class) effective-slot-definition) (null (my-magic-slot-p effective-slot-definition))) \endscreen! \endExample Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA15123; Thu, 22 Nov 90 13:21:04 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16573>; Thu, 22 Nov 1990 13:20:46 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16578>; Thu, 22 Nov 1990 13:19:24 PST Received: from rose (rose.lucid.com) by heavens-gate.lucid.com id AA26500g; Thu, 22 Nov 90 13:11:45 PST Received: by rose id AA09952g; Thu, 22 Nov 90 13:16:32 PST Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: Richard P.Gabriel ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD00048B9A Date: Thu, 22 Nov 1990 13:16:32 PST From: rpg@lucid.com Subject: change to instance structure protocol In-Reply-To: "Gregor Kiczales's message of Thu, 22 Nov 1990 12:59:24 PST <90Nov22.125927pst.275@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: MOP.PARC@xerox.com Message-Id: <9011222116.AA09952@rose> I believe you are proposing the Telos (EuLisp) solution. -rpg- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA17099; Thu, 22 Nov 90 17:23:49 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16582>; Thu, 22 Nov 1990 17:23:22 PST Received: from inria.inria.fr ([128.93.8.1]) by alpha.xerox.com with SMTP id <16582>; Thu, 22 Nov 1990 17:21:34 PST Received: by inria.inria.fr (5.65+/90.0.9) via Fnet-EUnet id AA04195; Fri, 23 Nov 90 02:20:09 +0100 (MET) Received: from barbes.ilog.fr by ilog.ilog.fr, Fri, 23 Nov 90 01:27:18 +0100 Received: by barbes.ilog.fr, Fri, 23 Nov 90 01:24:17 +0100 X-Ns-Transport-Id: 08002008D0FD00048C39 Date: Thu, 22 Nov 1990 16:24:17 PST From: davis@ilog.ilog.fr Subject: change to instance structure protocol In-Reply-To: "rpg@lucid.com's message of Thu, 22 Nov 1990 13:16:32 PST <9011222116.AA09952@rose>" To: rpg@lucid.com Cc: gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <9011230024.AA15079@barbes.ilog.fr> From: rpg@lucid.com I believe you are proposing the Telos (EuLisp) solution. -rpg- Almost, but there is at least one important difference. In TELOS, the slot access protocol has one more level than in CLOS. SLOT-VALUE is defined as follows: (defun slot-value (object slot-name &optional no-error-p) ;; Returns the value of the slot named SLOT-NAME in the object. If ;; NO-ERROR-P is () and the value is the unbound slot value, ;; SLOT-UNBOUND will be called with the object and slot name as ;; arguments. If NO-ERROR-P is true, the value will always be ;; returned, even if it is unbound. If the slot does not exist, ;; SLOT-MISSING will be called with the object and slot name as ;; arguments, irrespective of NO-ERR-FLAG. (let* ((slotd (find-slot (class-of object) slot-name)) (original-value (slot-description-reader slotd object))) (if no-error-p original-value (if (eq original-value (unbound-slot-value)) (slot-unbound object slot-name) original-value)))) FIND-SLOT is responsible for reporting SLOT-MISSING. It is a generic function discriminating on the object's metaclass. SLOT-DESCRIPTION-READER is a generic function whose methods normally discriminate on the class of the slot definition object. In typical cases, it calls EuLisp's equivalent of SLOT-VALUE-USING-CLASS, METACLASS-SLOT-READER. (I don't like the names either.) This generic function is handed the class of the object, the object, and a third object which indicates the position of the slot in the object. In typical implementations, this third object is an integer. The point of this scheme is that the slot definition object has a chance to get a handle on the slot access before the metaclass, and can ignore the metaclass's normal slot access behavior. A typical example of the use of the two levels is shared slots: (defmethod slot-description-reader ((slotd local-slot-description) object) ;; This is the typical case where we let the metaclass take control ;; using METACLASS-SLOT-READER. (metaclass-slot-reader (class-of object) object (slot-description-position slotd))) (defmethod slot-description-reader ((slotd shared-slot-description) object) ;; This is for shared slots. In this case, the slot description ;; holds a pointer to a vector of shared slot values for the class ;; which defined the slot. METACLASS-SLOT-READER is not called. (vector-ref (slot-description-shared-values slotd) (slot-description-position slotd))) So the metaclass only comes into play when the slot description decides it's appropriate. At first glance, you might think that giving the slot description class priority over the metaclass can be accomplished using Gregor's scheme as well by respecifying the argument precedence order. However, the advantage of the EuLisp scheme is not just the order in which things are done, but the fact that you can write methods for slot description classes and metaclasses separately. Mix-n-match, as it were. To go along with this upgrade of the slot description status (compared to CLOS), there is an additional slot option in DEFCLASS which permits the author to specify the class of the slot description for that slot. This is more fine-grained than CLOS's EFFECTIVE-SLOT-DEFINITION-CLASS, although I suppose it wouldn't be hard to write a metaclass in CLOS which handled this option. But STANDARD-CLASS's behavior does not encourage the development of new slot description classes. EuLisp also defines the function INDEXED-SLOT-VALUE, which skips the SLOT-DESCRIPTION-READER phase of the access and goes directly to METACLASS-SLOT-READER. This can be used for homogenous objects of arbitrary size, a case difficult to do properly in CLOS. It is defined as follows: (defun indexed-slot-value (object position &optional no-error-p) ;; Retrieves the POSITION'th component of OBJECT using ;; METACLASS-SLOT-READER. (let ((original-value (metaclass-slot-reader (class-of object) object position))) (if no-error-p original-value (if (eq original-value (unbound-slot-value)) (slot-unbound object position) original-value)))) So there is a wide variety of object access possible for the user. As with Gregor's method, standard optimization tricks are feasible in TELOS. -- Harley Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA24552; Fri, 23 Nov 90 09:35:37 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16489>; Fri, 23 Nov 1990 09:35:14 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16474>; Fri, 23 Nov 1990 09:33:52 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA00735g; Fri, 23 Nov 90 09:26:12 PST Received: by caligula id AA16405g; Fri, 23 Nov 90 09:30:59 PST X-Ns-Transport-Id: 08002008D0FD00048DE3 Date: Fri, 23 Nov 1990 09:30:59 PST From: Jon L White Subject: Mopping up after the fact In-Reply-To: "Gregor Kiczales's message of Wed, 21 Nov 1990 22:09:18 PST <90Nov21.220929pst.275@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: Moon@stony-brook.scrc.symbolics.com, mop@arisia.Xerox.COM Message-Id: <9011231730.AA16405@caligula> re: This example is, perhaps, a bit contrived. Certainly. re: But I think it illustrates the point that make the extensible OO protocol surrounding direct slot definition metaobjects back into a non-extensible functional protocol is troubling. But does it? The intent of this example would be more clearly covered if the class metaobjects involved kept a slot for the common, defaulted tail of a slot *specification*, which CANONICALIZE-SLOT-SPECIFICATION would look at. Either way, of course, damages the referential transparancy of the specification. So in a sense it might be better not to be led into a usage that uses the re-coding of the specifications purely in a way that demonstrates how a discrimination can be performed upon the induced class distinction. re: What I would rather do, actually, is change all the metaobjects (direct and effective) associated with default initargs, into real objects with a generic function based access protocol. The CLOS spec (88-002R and subsequent "cleanups")) leaves the content and type of the metaobjects unspecified; it uses "specification" or "option" generally rather than implying a a subclassing of the resultant "effective" metaobjects. So I would not suggest refining the concepts found in 88-002R except where it serves a real purpose. Thus I am not now pushing for a distinction to be made for class :default-initargs specifications. Someday, it might turn out to be a nice idea for some usage, but I don't feel strongly about it now. At this time, none of the proposed nor contemplated metaobject protocols benefit from the re-coding of slot specifications into standard objects; and I don't think you even wanted to rebut the charge that the re-coding makes the code and design overly complex (when seen from the viewpoint of the proposed and contemplated protocols.) So I'm only proposing the application of Occam's razor. -- JonL -- P.S. [Gee, you've even gotten me saying "class metaobjects" now] Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA24695; Fri, 23 Nov 90 09:55:17 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16474>; Fri, 23 Nov 1990 09:55:02 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16474>; Fri, 23 Nov 1990 09:53:45 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA00839g; Fri, 23 Nov 90 09:46:19 PST Received: by caligula id AA16428g; Fri, 23 Nov 90 09:51:08 PST X-Ns-Transport-Id: 08002008D0FD00048DF2 Date: Fri, 23 Nov 1990 09:51:08 PST From: Jon L White Subject: change to instance structure protocol In-Reply-To: "Gregor Kiczales's message of Thu, 22 Nov 1990 12:59:24 PST <90Nov22.125927pst.275@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: MOP.PARC@xerox.com Message-Id: <9011231751.AA16428@caligula> [This looks like an excellent use of the somewhat nascent ability to make new (effective) SLOT-DEFINITION classes.] I'd be a bit concerned about slowdown in regular (non-inlined) SLOT-VALUE because of it -- whereas now a SLOT-VALUE has to do a CLASS-OF, followed by some kind of table lookup, it will (under this proposal) have to do an additional lookup of the named SLOT-DEFINITION object from the class object. I don't suppose this is a critical flaw, but just one more thing to worry about. There's no doubt, whatsoever, in my mind that the goal you are striving for in this proposal is critical. The several papers at OOPSLA show precisely this need. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26017; Mon, 26 Nov 90 17:23:12 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16279>; Mon, 26 Nov 1990 17:22:51 PST Received: from inria.inria.fr ([128.93.8.1]) by alpha.xerox.com with SMTP id <16281>; Mon, 26 Nov 1990 17:20:46 PST Received: by inria.inria.fr (5.65+/90.0.9) via Fnet-EUnet id AA10049; Tue, 27 Nov 90 01:10:39 +0100 (MET) Received: from barbes.ilog.fr by ilog.ilog.fr, Tue, 27 Nov 90 00:18:24 +0100 Received: by barbes.ilog.fr, Tue, 27 Nov 90 00:15:22 +0100 X-Ns-Transport-Id: 08002008D0FD00049D63 Date: Mon, 26 Nov 1990 15:15:22 PST From: davis@ilog.ilog.fr Subject: change to instance structure protocol In-Reply-To: "Richard P. Gabriel's message of Thu, 22 Nov 90 17:57:17 PST <9011230157.AA09996@rose>" To: rpg@lucid.com Cc: gregor@parc.xerox.com, mop@arisia.Xerox.COM, davis@barbes.ilog.fr Message-Id: <9011262315.AA18741@barbes.ilog.fr> Gabriel writes: I haven't studied it (because I'm sitting down to eat a turkey) but I think the extra level is merely a convenience rather than a significant feature. A user writes: (defmethod slot-value-using-class ((class standard-class) (object standard-object) (slotd standard-effective-slot-definition)) (let ((original-value (slot-description-reader slotd object))) (if no-error-p original-value (if (eq original-value (unbound-slot-value)) (slot-unbound object slot-name) original-value)))) (defmethod slot-description-reader ((slotd local-slot-description) object) ...) (defmethod slot-description-reader ((slotd shared-slot-description) object) ...) and users of this system are able to have the slot description class have precedence or not, as he wishes. Sure. And in EuLisp I could write: ... a bunch of defclasses... (defmethod slot-description-reader ((slotd standard-effective-slot-definition) (object standard-object)) (slot-value-using-class (class-of object) object slotd)) (defmethod slot-value-using-class ...) and get the CLOS behavior. But neither of these are in each others' respective specifications. The question to me is, which way, if either, better meets the goals of MOPpiness. And, more generally, what are those goals? For example, if we want slot definitions and metaclasses to be relatively independent, how does that affect the inheritance protocol? -- Harley Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA08928; Tue, 27 Nov 90 09:26:08 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16297>; Tue, 27 Nov 1990 09:25:40 PST Received: from inria.inria.fr ([128.93.8.1]) by alpha.xerox.com with SMTP id <16297>; Tue, 27 Nov 1990 09:23:18 PST Received: by inria.inria.fr (5.65+/90.0.9) via Fnet-EUnet id AA23859; Tue, 27 Nov 90 18:22:49 +0100 (MET) Received: from barbes.ilog.fr by ilog.ilog.fr, Tue, 27 Nov 90 18:09:26 +0100 Received: by barbes.ilog.fr, Tue, 27 Nov 90 18:06:24 +0100 X-Ns-Transport-Id: 08002008D0FD0004A239 Date: Tue, 27 Nov 1990 09:06:24 PST From: davis@ilog.ilog.fr Subject: find my slot To: mop@arisia.Xerox.COM Message-Id: <9011271706.AA19385@barbes.ilog.fr> Of the 5 major CLOS metaobject types (classes, generic functions, methods, method combinations, and slot definitions), three have retrieval functions (FIND-CLASS, FIND-METHOD, FIND-METHOD-COMBINATION), and one doesn't need one (generic functions). What happened to FIND-SLOT-DEFINITION? -- Harley Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA08940; Tue, 27 Nov 90 16:14:56 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16333>; Tue, 27 Nov 1990 16:14:07 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16389>; Tue, 27 Nov 1990 15:21:48 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA02727g; Tue, 27 Nov 90 15:13:52 PST Received: by caligula id AA21524g; Tue, 27 Nov 90 15:18:46 PST X-Ns-Transport-Id: 08002008D0FD0004A6C0 Date: Tue, 27 Nov 1990 15:18:46 PST From: Jon L White Subject: find my slot In-Reply-To: "davis@ilog.ilog.fr's message of Tue, 27 Nov 1990 09:06:24 PST <9011271706.AA19385@barbes.ilog.fr>" To: davis@ilog.ilog.fr Cc: mop@arisia.Xerox.COM Message-Id: <9011272318.AA21524@caligula> re: What happened to FIND-SLOT-DEFINITION? Good point. Lucid's implementation has a sub-primitive that is almost that (for its own internal use.) But it needs to be interfaced in the same way that the other FIND- are. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26267; Thu, 29 Nov 90 12:37:46 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16505>; Thu, 29 Nov 1990 12:37:19 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16527>; Thu, 29 Nov 1990 12:35:05 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 878861; 29 Nov 1990 15:30:28-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0004BBA0 Date: Thu, 29 Nov 1990 12:35:00 PST From: Moon@stony-brook.scrc.symbolics.com Subject: change to instance structure protocol In-Reply-To: <90Nov22.125927pst.275@spade.parc.xerox.com> To: Gregor Kiczales Cc: MOP.PARC@xerox.com Message-Id: <19901129203530.2.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Date: Thu, 22 Nov 1990 15:59 EST From: Gregor Kiczales .... There is an elegant solution, but I have refrained from proposing it for some time. Now, it really seems worth proposing. The basic idea is to change the last (slot-name) argument to all of the SLOT-XXX-USING-CLASS generic functions. The new value would be the actual effective slot definition metaobject rather than the slot name. In my opinion your proposal is clearly the right thing. By the way, I verified that adopting this proposal would not slow down SLOT-VALUE in the inline optimized case nor in the notinline optimized case in Symbolics' implementation. I'm not sure why JonL thought it would slow down the notinline case, although Lucid's implementation may work differently. In Symbolics' implementation notinline SLOT-VALUE does not call SLOT-VALUE-USING-CLASS for the standard metaclass. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA28195; Thu, 29 Nov 90 13:18:08 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16532>; Thu, 29 Nov 1990 13:17:41 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16491>; Thu, 29 Nov 1990 12:19:56 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 878854; 29 Nov 1990 15:14:36-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0004BB5C Date: Thu, 29 Nov 1990 12:19:00 PST From: Moon@stony-brook.scrc.symbolics.com Subject: find my slot In-Reply-To: <9011271706.AA19385@barbes.ilog.fr> To: davis@ilog.ilog.fr Cc: mop@arisia.Xerox.COM Message-Id: <19901129201934.1.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Date: Tue, 27 Nov 1990 12:06 EST From: davis@ilog.ilog.fr Of the 5 major CLOS metaobject types (classes, generic functions, methods, method combinations, and slot definitions), three have retrieval functions (FIND-CLASS, FIND-METHOD, FIND-METHOD-COMBINATION), and one doesn't need one (generic functions). What happened to FIND-SLOT-DEFINITION? It isn't necessary, because CLASS-DIRECT-SLOTS and CLASS-SLOTS are specified to return lists, therefore the existing FIND function can be used (with :KEY #'SLOT-DEFINITION-NAME). Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA00013; Thu, 29 Nov 90 13:48:05 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16510>; Thu, 29 Nov 1990 13:47:41 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16497>; Thu, 29 Nov 1990 13:42:46 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 414445; 29 Nov 1990 16:25:08-0500 X-Ns-Transport-Id: 08002008D0FD0004BC59 Date: Thu, 29 Nov 1990 13:23:00 PST From: Scott Cyphers Subject: change to instance structure protocol In-Reply-To: <19901129203530.2.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> To: Moon@stony-brook.scrc.symbolics.com, gregor@parc.xerox.com Cc: MOP.PARC@xerox.com Message-Id: <19901129212321.0.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Thu, 29 Nov 1990 15:35 EST From: Moon@stony-brook.scrc.symbolics.com Date: Thu, 22 Nov 1990 15:59 EST From: Gregor Kiczales .... There is an elegant solution, but I have refrained from proposing it for some time. Now, it really seems worth proposing. The basic idea is to change the last (slot-name) argument to all of the SLOT-XXX-USING-CLASS generic functions. The new value would be the actual effective slot definition metaobject rather than the slot name. In my opinion your proposal is clearly the right thing. By the way, I verified that adopting this proposal would not slow down SLOT-VALUE in the inline optimized case nor in the notinline optimized case in Symbolics' implementation. I'm not sure why JonL thought it would slow down the notinline case, although Lucid's implementation may work differently. In Symbolics' implementation notinline SLOT-VALUE does not call SLOT-VALUE-USING-CLASS for the standard metaclass. In all this, remember that SLOT-VALUE-USING-CLASS can also have its first argument EQL specialized on a particular class. We don't handle that case correctly, but I think our optimizations could work around it if they bothered to check for it. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01114; Thu, 29 Nov 90 14:42:01 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16213>; Thu, 29 Nov 1990 14:41:38 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16548>; Thu, 29 Nov 1990 14:39:48 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA25992g; Thu, 29 Nov 90 14:31:59 PST Received: by caligula id AA01467g; Thu, 29 Nov 90 14:36:57 PST X-Ns-Transport-Id: 08002008D0FD0004BCF9 Date: Thu, 29 Nov 1990 14:36:57 PST From: Jon L White Subject: change to instance structure protocol In-Reply-To: "Moon@stony-brook.scrc.symbolics.com's message of Thu, 29 Nov 1990 12:35:00 PST <19901129203530.2.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.com Cc: gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <9011292236.AA01467@caligula> re: In Symbolics' implementation notinline SLOT-VALUE does not call SLOT-VALUE-USING-CLASS for the standard metaclass. I thought it was supposed to, so that the user could hang hooks. Or, are you simly referring to an optimization of the notinline case when there are no user-defined methods? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01630; Thu, 29 Nov 90 15:06:00 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16543>; Thu, 29 Nov 1990 15:05:26 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16529>; Thu, 29 Nov 1990 15:01:43 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA26257g; Thu, 29 Nov 90 14:53:40 PST Received: by caligula id AA01506g; Thu, 29 Nov 90 14:58:36 PST X-Ns-Transport-Id: 08002008D0FD0004BD3C Date: Thu, 29 Nov 1990 14:58:36 PST From: Jon L White Subject: find my slot In-Reply-To: "Moon@stony-brook.scrc.symbolics.com's message of Thu, 29 Nov 1990 12:19:00 PST <19901129201934.1.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.com Cc: davis@ilog.ilog.fr, mop@arisia.Xerox.COM Message-Id: <9011292258.AA01506@caligula> re: Date: Tue, 27 Nov 1990 12:06 EST From: davis@ilog.ilog.fr Of the 5 major CLOS metaobject types (classes, generic functions, methods, method combinations, and slot definitions), three have retrieval functions (FIND-CLASS, FIND-METHOD, FIND-METHOD-COMBINATION), and one doesn't need one (generic functions). What happened to FIND-SLOT-DEFINITION? It isn't necessary, because CLASS-DIRECT-SLOTS and CLASS-SLOTS are specified to return lists, therefore the existing FIND function can be used (with :KEY #'SLOT-DEFINITION-NAME). If Harley's question is only about introspective capabilities, then we don't need FIND-METHOD either -- because of the documentation for GENERIC-FUNCTION-METHODS, METHOD-QUALIFIERS, and METHOD-SPECIALIZERS. However, FIND-CLASS and FIND-METHOD are "Chapter 2" facilities. Would you now propose to remove FIND-METHOD? or would the uniformity of interface resulting from the addition of FIND-SLOT-DEFINITION be better than trying to retrench into a minimal kernal language? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA06564; Thu, 29 Nov 90 18:57:09 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16543>; Thu, 29 Nov 1990 18:56:41 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16544>; Thu, 29 Nov 1990 18:52:26 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 879126; 29 Nov 1990 21:46:45-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0004BF8E Date: Thu, 29 Nov 1990 18:51:00 PST From: Moon@stony-brook.scrc.symbolics.com Subject: find my slot In-Reply-To: <9011292258.AA01506@caligula> To: Jon L White Cc: davis@ilog.ilog.fr, mop@arisia.Xerox.COM Message-Id: <19901130025147.3.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Date: Thu, 29 Nov 1990 17:58 EST From: Jon L White re: Date: Tue, 27 Nov 1990 12:06 EST From: davis@ilog.ilog.fr Of the 5 major CLOS metaobject types (classes, generic functions, methods, method combinations, and slot definitions), three have retrieval functions (FIND-CLASS, FIND-METHOD, FIND-METHOD-COMBINATION), and one doesn't need one (generic functions). What happened to FIND-SLOT-DEFINITION? It isn't necessary, because CLASS-DIRECT-SLOTS and CLASS-SLOTS are specified to return lists, therefore the existing FIND function can be used (with :KEY #'SLOT-DEFINITION-NAME). If Harley's question is only about introspective capabilities, then we don't need FIND-METHOD either -- because of the documentation for GENERIC-FUNCTION-METHODS, METHOD-QUALIFIERS, and METHOD-SPECIALIZERS. It's true that FIND-METHOD doesn't do anything you can't do yourself given those other facilities. It also doesn't do anything that's useful, as far as I can see, if all you have is the standard part of CLOS (chapter 2). I imagine FIND-METHOD exists because the translation into FIND is quite complicated. I notice that FIND-METHOD is generic, so maybe it exists so users can define other methods for it. However, I can't imagine what one could accomplish, other than perhaps a minor speedup, by writing specialized methods for FIND-METHOD. However, FIND-CLASS and FIND-METHOD are "Chapter 2" facilities. Would you now propose to remove FIND-METHOD? or would the uniformity of interface resulting from the addition of FIND-SLOT-DEFINITION be better than trying to retrench into a minimal kernal language? I'm not proposing anything. I will comment that attempting such uniformity of interface in CLOS is pretty much a lost cause; CLOS just shows too well that it is the work of many hands. The absence of FIND-SLOT-DEFINITION is one of the few things about the most recent draft of the metaobject protocol I have (July 30, 1990) that doesn't bother me one little bit. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA06578; Thu, 29 Nov 90 18:58:18 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16539>; Thu, 29 Nov 1990 18:57:55 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16539>; Thu, 29 Nov 1990 18:56:35 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 879128; 29 Nov 1990 21:51:37-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0004BF93 Date: Thu, 29 Nov 1990 18:56:00 PST From: Moon@stony-brook.scrc.symbolics.com Subject: change to instance structure protocol In-Reply-To: <9011292236.AA01467@caligula> To: Jon L White Cc: gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <19901130025639.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Date: Thu, 29 Nov 1990 17:36 EST From: Jon L White re: In Symbolics' implementation notinline SLOT-VALUE does not call SLOT-VALUE-USING-CLASS for the standard metaclass. I thought it was supposed to, so that the user could hang hooks. Or, are you simly referring to an optimization of the notinline case when there are no user-defined methods? From p.13 of the July 30, 1990 metaobject protocol specification draft: "Any method, defined by a portable program on a specified generic function, must have at least one specializer which is not a specified class." So "the standard metaclass" implies "no user-defined methods". Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA06583; Thu, 29 Nov 90 18:59:00 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16548>; Thu, 29 Nov 1990 18:58:37 PST Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by alpha.xerox.com with SMTP id <16548>; Thu, 29 Nov 1990 18:57:08 PST Received: from KENNETH-WILLIAMS.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 879129; 29 Nov 1990 21:52:19-0500 Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: David A.Moon ^ ^-illegal period in phrase \-phrases containing '.' must be quoted Supersedes: <19901130025639.4.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Comments: spoke too soon X-Ns-Transport-Id: 08002008D0FD0004BF94 Date: Thu, 29 Nov 1990 18:57:00 PST From: Moon@stony-brook.scrc.symbolics.com Subject: change to instance structure protocol In-Reply-To: <9011292236.AA01467@caligula> To: Jon L White Cc: gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <19901130025720.5.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM> Date: Thu, 29 Nov 1990 17:36 EST From: Jon L White re: In Symbolics' implementation notinline SLOT-VALUE does not call SLOT-VALUE-USING-CLASS for the standard metaclass. I thought it was supposed to, so that the user could hang hooks. Or, are you simly referring to an optimization of the notinline case when there are no user-defined methods? From p.13 of the July 30, 1990 metaobject protocol specification draft: "Any method, defined by a portable program on a specified generic function, must have at least one specializer which is not a specified class." So "the standard metaclass" implies "no user-defined methods" (except for the bug with EQL specialized methods that Cyphers pointed out, which I imagine is one of the banes of Gregor's existence too). Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA24518; Fri, 30 Nov 90 11:18:16 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16561>; Fri, 30 Nov 1990 11:11:30 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16551>; Fri, 30 Nov 1990 11:09:45 PST Received: by spade.parc.xerox.com id <168>; Fri, 30 Nov 1990 11:09:29 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0004C5DA Date: Fri, 30 Nov 1990 11:09:25 PST From: Gregor Kiczales Subject: Re: change to instance structure protocol In-Reply-To: "Moon@stony-brook.scrc.symbolics.com's message of Thu, 29 Nov 1990 18:57:00 PST <19901130025720.5.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.com Cc: jonl@lucid.com, MOP.PARC@xerox.com Message-Id: <90Nov30.110929pst.168@spade.parc.xerox.com> Date: Thu, 29 Nov 1990 18:57:00 PST From: Moon@stony-brook.scrc.symbolics.com "Any method, defined by a portable program on a specified generic function, must have at least one specializer which is not a specified class." So "the standard metaclass" implies "no user-defined methods" (except for the bug with EQL specialized methods that Cyphers pointed out, which I imagine is one of the banes of Gregor's existence too). Yes, it is this "bane" which led me down the path of questioning the EQL methods concept. I came to see that without EQL methods, code that reasons about method applicability is simple and elegant. But, with EQL methods, it is a mess. I eventually concluded that EQL methods (should) have nothing to do with CLOS; whereas other kinds of methods are about applicability and inheritance, EQL methods are just about applicability. The functionality provided by EQL methods is useful. While it might make sense to merge it with the method lookup functionality in prototype languages (Object Lisp, Self), it should be part of a separate facility in class/instance languages like CLOS. Alas, EQL methods seem to be in to stay now. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA24762; Fri, 30 Nov 90 11:29:59 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16565>; Fri, 30 Nov 1990 11:23:06 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16574>; Fri, 30 Nov 1990 11:20:51 PST Received: by spade.parc.xerox.com id <299>; Fri, 30 Nov 1990 11:19:18 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0004C601 Date: Fri, 30 Nov 1990 11:19:15 PST From: Gregor Kiczales Subject: Re: find my slot In-Reply-To: "Jon L White's message of Thu, 29 Nov 1990 14:58:36 PST <9011292258.AA01506@caligula>" To: jonl@lucid.com Cc: Moon@stony-brook.scrc.symbolics.com, davis@ilog.ilog.fr, mop@arisia.Xerox.COM Message-Id: <90Nov30.111918pst.299@spade.parc.xerox.com> Date: Thu, 29 Nov 1990 14:58:36 PST From: Jon L White However, FIND-CLASS and FIND-METHOD are "Chapter 2" facilities. Would you now propose to remove FIND-METHOD? or would the uniformity of interface resulting from the addition of FIND-SLOT-DEFINITION be better than trying to retrench into a minimal kernal language? Just to agree with (part of) what David said. FIND-METHOD may appear in 88-002R, but it is pretty clear to me that it is really a (simple) MOP facility. 88-002R mentions a few things that lets users get their hands on metaobjects, and says that there are things called metaobjects. But, it doesn't say enough, by itself, to do anything with them. This isn't a proposal to change anything about 88-002R. I just want to point out that I don't believe the "88-002R"/"MOP Document" distinction lines up perfectly with the "CLOS (The Base Language)"/"MOP (The Meta Language)" distinction. As an aside, I think we should add FIND-SLOT-DEFINITION. Sure, it is simple to write, but so is UNION. Also, I think it and FIND-METHOD should be/remain generic. As David pointed out, this makes it possible to have them be more efficient in certain cases, which is, I believe, not negligible. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26022; Fri, 30 Nov 90 12:21:54 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16569>; Fri, 30 Nov 1990 12:15:16 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16569>; Fri, 30 Nov 1990 12:10:40 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA06509g; Fri, 30 Nov 90 12:02:17 PST Received: by caligula id AA02966g; Fri, 30 Nov 90 12:07:15 PST X-Ns-Transport-Id: 08002008D0FD0004C6AE Date: Fri, 30 Nov 1990 12:07:15 PST From: Jon L White Subject: find my slot In-Reply-To: "Gregor Kiczales's message of Fri, 30 Nov 1990 11:19:15 PST <90Nov30.111918pst.299@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: Moon@stony-brook.scrc.symbolics.com, davis@ilog.ilog.fr, mop@arisia.Xerox.COM Message-Id: <9011302007.AA02966@caligula> re: As an aside, I think we should add FIND-SLOT-DEFINITION. Sure, it is simple to write, but so is UNION. Also, I think it and FIND-METHOD should be/remain generic. As David pointed out, this makes it possible to have them be more efficient in certain cases, which is, I believe, not negligible. I'm willing to buy Dave's argument that F-S-D isn't very important from a language point of view. The one observation I could make is that since Lucid's implementation has almost exactly that functionality inside it internally -- and it is noticeably more efficient, mostly in terms of "footprint" of code -- then why not let the user have access to this one- liner rather than haveing to reproduce it himself (and probably getting it wrong the first time!). But I'm not seriously concerned about it. Incidentally, a revised version of CLOS documentation might do a better job of shifting to the MOP chapters the functions that a vanilla user will probably never use. ADD-METHOD, FIND-METHOD, etc come to mind. But note: ALLOCATE-INSTANCE *doesn't* come to mind in this regard; copping an "uninitialized" instance isn't just MOP'ping, but it is usually "wizarding" (like, methods for MAKE-LOAD-FORM, which surely is basic rather than meta). -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA26720; Fri, 30 Nov 90 12:55:16 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16573>; Fri, 30 Nov 1990 12:48:29 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16560>; Fri, 30 Nov 1990 12:47:08 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA06891g; Fri, 30 Nov 90 12:39:13 PST Received: by caligula id AA02986g; Fri, 30 Nov 90 12:44:09 PST X-Ns-Transport-Id: 08002008D0FD0004C706 Date: Fri, 30 Nov 1990 12:44:09 PST From: Jon L White Subject: change to instance structure protocol In-Reply-To: "Gregor Kiczales's message of Fri, 30 Nov 1990 11:09:25 PST <90Nov30.110929pst.168@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: Moon@stony-brook.scrc.symbolics.com, MOP.PARC@xerox.com Message-Id: <9011302044.AA02986@caligula> re: Alas, EQL methods seem to be in to stay now. There's even a paper in the CLOS workshop comparing them to sliced bread. Isn't Danny the prime instigator of them? how does he feel? Danny, you there? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA28852; Fri, 30 Nov 90 14:21:26 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16574>; Fri, 30 Nov 1990 14:14:42 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16585>; Fri, 30 Nov 1990 14:12:57 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA07740g; Fri, 30 Nov 90 14:04:41 PST Received: by caligula id AA03202g; Fri, 30 Nov 90 14:09:38 PST Comments: spoke too soon, but by how much? X-Ns-Transport-Id: 08002008D0FD0004C803 Date: Fri, 30 Nov 1990 14:09:38 PST From: Jon L White Subject: change to instance structure protocol In-Reply-To: "David A. Moon's message of Thu, 29 Nov 1990 21:57-0500 <19901130025720.5.MOON@KENNETH-WILLIAMS.SCRC.Symbolics.COM>" To: Moon@stony-brook.scrc.symbolics.com Cc: gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <9011302209.AA03202@caligula> re: >From p.13 of the July 30, 1990 metaobject protocol specification draft: "Any method, defined by a portable program on a specified generic function, must have at least one specializer which is not a specified class." So "the standard metaclass" implies "no user-defined methods" (except for the bug with EQL specialized methods that Cyphers pointed out, which I imagine is one of the banes of Gregor's existence too). (defclass moons-loophole () (some-slot)) (defmethod slot-value-using-class ((meta standard-class) (x moons-loophole) slot-name) (squosh-it-around (call-next-method))) However, I'm still in the dark as to what you mean by "the standard metaclass"? Are you simply referring to STANDARD-CLASS, or to STANDARD-CLASS and all possible subclasses thereof (whose methods for SLOT-VALUE-USING-CLASS might inherit, override, or extend the "specified" ones)? Now, regarding the quoted section of "Chap 3, draft 11" -- it isn't clear to me just what it is trying to accomplish. Does it imply that it is illegal to define an :AFTER method on ALLOCATE-INSTANCE specialized to, say, FUNCALLABLE-STANDARD-CLASS? If so, then I don't see the point of it; but if not, then just what is it trying to say? By the bye, is it a bug in draft 11, page 3-115, that the specified methods don't specialize the second argument the same way as the other SLOT--USING-CLASS functions do? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA00723; Fri, 30 Nov 90 15:21:37 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16603>; Fri, 30 Nov 1990 15:14:52 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <16595>; Fri, 30 Nov 1990 15:13:00 PST Received: by spade.parc.xerox.com id <297>; Fri, 30 Nov 1990 15:12:37 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0004C8C0 Date: Fri, 30 Nov 1990 15:12:29 PST From: Gregor Kiczales Subject: Re: change to instance structure protocol In-Reply-To: "Jon L White's message of Fri, 30 Nov 1990 14:09:38 PST <9011302209.AA03202@caligula>" To: jonl@lucid.com Cc: Moon@stony-brook.scrc.symbolics.com, MOP.PARC@xerox.com Message-Id: <90Nov30.151237pst.297@spade.parc.xerox.com> Date: Fri, 30 Nov 1990 14:09:38 PST From: Jon L White Comments: spoke too soon, but by how much? Now, regarding the quoted section of "Chap 3, draft 11" -- it isn't clear to me just what it is trying to accomplish. Does it imply that it is illegal to define an :AFTER method on ALLOCATE-INSTANCE specialized to, say, FUNCALLABLE-STANDARD-CLASS? If so, then I don't see the point of it; but if not, then just what is it trying to say? I thought I had answered this before, perhaps not. Think of this as the natural analog of the Lisp Symbol Redefinition issue. It is trying to make the method definition you propose illegal, and it is doing it because that method is a "reserved word." There are two problems with letting users define methods like it: 1) They could bash a system method. 2) Two users could remove each other's methods; in this sense, defining a method like the one you propose is like programming with advice rather than metaobject programming. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01807; Fri, 30 Nov 90 15:52:01 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16585>; Fri, 30 Nov 1990 15:45:10 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16589>; Fri, 30 Nov 1990 15:43:45 PST Received: from rose (rose.lucid.com) by heavens-gate.lucid.com id AA08745g; Fri, 30 Nov 90 15:35:39 PST Received: by rose id AA20751g; Fri, 30 Nov 90 15:40:38 PST Illegal-Object: Syntax error in From: address found on alpha.xerox.com: From: Richard P.Gabriel ^ ^-illegal period in phrase \-phrases containing '.' must be quoted X-Ns-Transport-Id: 08002008D0FD0004C8FB Date: Fri, 30 Nov 1990 15:40:38 PST From: rpg@lucid.com Subject: change to instance structure protocol In-Reply-To: "Gregor Kiczales's message of Fri, 30 Nov 1990 15:12:29 PST <90Nov30.151237pst.297@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: jonl@lucid.com, Moon@stony-brook.scrc.symbolics.com, MOP.PARC@xerox.com Message-Id: <9011302340.AA20751@rose> There are two problems with letting users define methods like it: 1) They could bash a system method. 2) Two users could remove each other's methods; in this sense, defining a method like the one you propose is like programming with advice rather than metaobject programming. There are problems with your problems, which will lead to my main point. 1. Even with all the caveats you can think of, a user's program could still bash a system method. 2. Two users can always remove each other's methods regardless of the limitations you put on what methods can be defined (unless you rule them all out). 3. An important class of metaobject programming is instrumentation and history keeping. This is naturally captured by auxiliary methods. Are you trying to say that method combination is a bad idea because a lot of it is like advice programming? The real problem is that you are trying to specify what can only be specified with difficulty or possibly not at all. You really want to say that MOP acts as specified by the statement S, and you are not allowed to do anything that changes S much. Your approach is to provide some heuristic rules that approximate the two parts of this: namely, the part that specifies what S is and the part that defines `much'. -rpg- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA03103; Fri, 30 Nov 90 16:33:13 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16589>; Fri, 30 Nov 1990 16:26:26 PST Received: from hulk.cisco.com ([192.31.7.22]) by alpha.xerox.com with SMTP id <16564>; Fri, 30 Nov 1990 16:24:49 PST X-Ns-Transport-Id: 08002008D0FD0004C96C Date: Fri, 30 Nov 1990 16:23:28 PST From: Rachel Goldeen Subject: missing file To: mop@arisia.Xerox.COM Cc: goldeen@hulk.cisco.com Message-Id: <12642160817.23.GOLDEEN@hulk.cisco.com> Hi Gregor, I am missing amopa3.tex. Could you please send it to me? Thanks, Rachel ------- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA19070; Mon, 3 Dec 90 08:56:14 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16604>; Mon, 3 Dec 1990 08:55:54 PST Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by alpha.xerox.com with SMTP id <16644>; Mon, 3 Dec 1990 08:54:06 PST Received: from SEAR.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via INTERNET with SMTP id 415080; 3 Dec 1990 11:50:10-0500 X-Ns-Transport-Id: 08002008D0FD0004D6D8 Date: Mon, 3 Dec 1990 08:49:00 PST From: Scott Cyphers Subject: change to instance structure protocol In-Reply-To: <9011292236.AA01467@caligula> To: jonl@lucid.com, Moon@stony-brook.scrc.symbolics.com Cc: gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <19901203164904.4.CYPHERS@SEAR.SCRC.Symbolics.COM> Date: Thu, 29 Nov 1990 17:36 EST From: Jon L White re: In Symbolics' implementation notinline SLOT-VALUE does not call SLOT-VALUE-USING-CLASS for the standard metaclass. I thought it was supposed to, so that the user could hang hooks. Or, are you simly referring to an optimization of the notinline case when there are no user-defined methods? That's right. When SLOT-VALUE gets an instance, it loads a special slot in the instance information. This slot contains a special table of slot names which can be accessed quickly in the instance. We do a blindingly fast linear search for the slot name in the table. If it is found, the offset in the table is the offset of the slot in the instance (or something like that). If a class has shared slots, the shared slots are left out of the table. The bug (which could be fixed easily enough) is that you also have to leave out slot names for any slots which are affected by a method on SLOT-VALUE-USING-CLASS. There are a number of simple ways that this mechanism could be extended. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA01223; Mon, 3 Dec 90 19:19:54 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16672>; Mon, 3 Dec 1990 19:19:38 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16640>; Mon, 3 Dec 1990 19:18:19 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA04182g; Mon, 3 Dec 90 19:09:58 PST Received: by caligula id AA07278g; Mon, 3 Dec 90 19:15:00 PST X-Ns-Transport-Id: 08002008D0FD0004DDC6 Date: Mon, 3 Dec 1990 19:15:00 PST From: Jon L White Subject: change to instance structure protocol In-Reply-To: "Scott Cyphers's message of Mon, 3 Dec 1990 08:49:00 PST <19901203164904.4.CYPHERS@SEAR.SCRC.Symbolics.COM>" To: Cyphers@jasper.scrc.symbolics.com Cc: Moon@stony-brook.scrc.symbolics.com, gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <9012040315.AA07278@caligula> re: We do a blindingly fast linear search for the slot name in the table. Ditto. Except that from monitoring things, I wouldn't have called it "blindingly" fast; it isn't anywhere near as fast, for example, as the (hashed-access) permutation-table indirection used for the "inline" case. In our case the specialized method on SLOT-VALUE-ABUSING-CLASS implements the optimization; but I can see that pulling it back into SLOT-VALUE for "the standard metaclass" case could be worthwhile. re: The bug (which could be fixed easily enough) is that you also have to leave out slot names for any slots which are affected by a method on SLOT-VALUE-USING-CLASS. There are a number of simple ways that . . . But in general it's impossible to know what a random method on SLOT-VALUE-USING-CLASS will affect, since one almost never specializes the third argument (although you might specialize the second). Since the _likely_ candidates for SLOT-VALUE-USING-CLASS methods will be sublcasses of Standard-Class, then a less aggressive approach to optimization might be good enough. That is, the "less aggressive" approach would permit full speed on Standard-Class (where there would be no user-defined methods), moderately fast speed on subclasses of Standard-Class for which inapplicable methods exist, and of course "correct, but slower" speed when the methods are applicable. Now, the point of Gregor's original proposal (about which we are now carrying on peripheral discussion?) was to alter the semantics of the third argument so that the _unusual_ case would be more likely to have methods specialized on something [e.g., DATABASE-SLOT-DEFINITION as opposed to STANDARD-SLOT-DEFINITION]. This way, whatever optimization winds up being used for "the standard case" would not be affected at all by the presence of user-defined methods (ahem, presuming of course that the loser didn't just leave the third argument totally unspecialized!) Anyway, this kind of benefit make the proposal look even more attractive. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA02724; Mon, 3 Dec 90 21:23:16 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16629>; Mon, 3 Dec 1990 21:22:42 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <16629>; Mon, 3 Dec 1990 21:20:49 PST Received: from caligula (caligula.lucid.com) by heavens-gate.lucid.com id AA05317g; Mon, 3 Dec 90 21:12:48 PST Received: by caligula id AA07385g; Mon, 3 Dec 90 21:17:51 PST X-Ns-Transport-Id: 08002008D0FD0004DE6D Date: Mon, 3 Dec 1990 21:17:51 PST From: Jon L White Subject: change to instance structure protocol In-Reply-To: "Gregor Kiczales's message of Fri, 30 Nov 1990 15:12:29 PST <90Nov30.151237pst.297@spade.parc.xerox.com>" To: gregor@parc.xerox.com Cc: Moon@stony-brook.scrc.symbolics.com, MOP.PARC@xerox.com Message-Id: <9012040517.AA07385@caligula> re: [the point of the restriction from p.13 of the July 30, 1990 metaobject protocol specification draft ??] I thought I had answered this before, perhaps not. Think of this as the natural analog of the Lisp Symbol Redefinition issue. It is trying to make the method definition you propose illegal, and it is doing it because that method is a "reserved word." [You may have discussed this before, in the time period between OOPSLA '90 and your November 15 deadline for AMOP Part I comments; if so, then I probably didn't read all that mail in detail.] OK, I see what you are getting at -- it isn't just to enable the kinds of optimizations for which the MOONS-LOOPHOLE class is a "breaker". However, "Lisp Symbol Redefinition" may not be the the best design against which to make an analogue. I don't feel comfortable at all with it, for much the same reasons espoused earlier by Dick. For example, I can't see any point at all to saying that the semantics of: (DEFSTRUCT POSITION . . . ) must be undefined, just because POSITION is in the COMMON-LISP package (because of its functional value). How, for example, does that help the end user any more than saying that he cannot portably do: (DEFSTRUCT USER::UPOSITION . . . ) ?? There an always an implicit assumption that some other "portable" program might want to define a structure on USER::UPOSITION so should this symbol be off limits?? More precisely, adding cumbersome restrictions to the "Language" in order to accomplish a goal for which the package system was invented (i.e., end-user control over "imports" and "exports"), seems like a totally misdirected effort. [Note that none of this bears on the issue of forbidding a conforming implementation from making an extension whereby COMMON-LISP:POSITION is given a defstruct definition.] But AMOP Part II seems, to me, to begin a much more fruitful approach towards setting up a true "protocol" (namely, saying when and under what conditions such-and-such a definition is legal, and what it "means".) I refer to the notions of "extending" and "overriding", and to the concept of "interposed classes" and "promoted" methods for specified metaobjects. Note that "extension" and "overriding", as "protocols", are not mechanically checkable at definition time; but I don't see that as a problem. I *would* see it as an stupid barrier if some implementation prevented me from defining an :AFTER method on ALLOCATE-INSTANCE for standard-objects simply because it is easy to implement that check. -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA14078; Tue, 4 Dec 90 10:38:08 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <16688>; Tue, 4 Dec 1990 10:37:38 PST Received: from apple.com ([130.43.2.2]) by alpha.xerox.com with SMTP id <16688>; Tue, 4 Dec 1990 10:35:02 PST Received: from [90.1.0.10] by apple.com with SMTP (5.61/25-eef) id AA08410; Tue, 4 Dec 90 10:34:54 -0800 for MOP.PARC@xerox.com Received: from cambridge.apple.com (ministry.cambridge.apple.com) by goofy.apple.com with SMTP (5.61/25-eef) id AA16030; Tue, 4 Dec 90 10:34:48 -0800 for MOP.PARC@xerox.com Received: from [90.223.0.23] by cambridge.apple.com with SMTP (5.64/25-eef) id AA13720; Tue, 4 Dec 90 13:29:29 -0500 X-Ns-Transport-Id: 08002008D0FD0004E2EF Date: Tue, 4 Dec 1990 03:49:22 PST From: moon@cambridge.apple.com (David Moon) Subject: Re: change to instance structure protocol To: Jon L White Cc: Cyphers@jasper.scrc.symbolics.com, gregor@parc.xerox.com, MOP.PARC@xerox.com Message-Id: <9012041829.AA13720@cambridge.apple.com> > Date: Mon, 3 Dec 1990 19:15:00 PST > From: Jon L White > re: We do a blindingly fast linear search for the slot name in the table. > > Ditto. Except that from monitoring things, I wouldn't have called it > "blindingly" fast; it isn't anywhere near as fast, for example, as the > (hashed-access) permutation-table indirection used for the "inline" case. Ours (now theirs) is more blinding than yours since the Ivory and the 3600 have architectural and hardware support for pipelined memory searches. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA08442; Thu, 10 Jan 91 07:10:22 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <17891>; Thu, 10 Jan 1991 07:09:31 PST Received: from cheops.cis.ohio-state.edu ([128.146.8.62]) by alpha.xerox.com with SMTP id <17074>; Thu, 10 Jan 1991 07:07:11 PST Received: from sacral.cis.ohio-state.edu by cheops.cis.ohio-state.edu (5.61-kk/5.910105) id AA17289; Thu, 10 Jan 91 10:07:07 -0500 Received: by sacral.cis.ohio-state.edu (5.61-kk/5.900430) id AA06581; Thu, 10 Jan 91 10:07:55 -0500 X-Ns-Transport-Id: 08002008D0FD0005FA35 Date: Thu, 10 Jan 1991 07:07:55 PST From: Arun Welch Subject: quoted keyword arguments To: mop.PARC@xerox.com Message-Id: <9101101507.AA06581@sacral.cis.ohio-state.edu> Figures 3-2 and 3-3 show the expansion of defclass forms into ensure-class forms. In the expansion, the keyword arguments are quoted as in ':direct-superclasses. Since keywords evaluate to themselves, why the quote? What am I missing? ...arun ---------------------------------------------------------------------------- Arun Welch Lisp Systems Programmer, Lab for AI Research, Ohio State University welch@cis.ohio-state.edu Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA13329; Thu, 10 Jan 91 09:47:22 -0800 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <17965>; Thu, 10 Jan 1991 09:47:02 PST Received: from spade.parc.xerox.com ([13.1.100.26]) by alpha.xerox.com with SMTP id <17965>; Thu, 10 Jan 1991 09:44:12 PST Received: by spade.parc.xerox.com id <277>; Thu, 10 Jan 1991 09:42:50 -0800 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0005FBBA Date: Thu, 10 Jan 1991 09:42:39 PST From: Gregor Kiczales Subject: Re: quoted keyword arguments In-Reply-To: "Arun Welch's message of Thu, 10 Jan 1991 07:07:55 PST <9101101507.AA06581@sacral.cis.ohio-state.edu>" To: welch@cis.ohio-state.edu Cc: mop.PARC@xerox.com Message-Id: <91Jan10.094250pst.277@spade.parc.xerox.com> Yes, keyword arguments do evaluate to themselves so, strictly speaking, the quote is superfluous. It is there to emphasize that the processing of unrecognized options just blindly quotes them. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA10614; Tue, 29 Jan 91 03:22:17 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <20076>; Tue, 29 Jan 1991 03:19:29 PST Received: from unido.informatik.uni-dortmund.de ([129.217.64.60]) by alpha.xerox.com with SMTP id <20076>; Tue, 29 Jan 1991 03:17:58 PST Received: from ernohb by unido.informatik.uni-dortmund.de with UUCP (UNIDO-2.0.3.e) via EUnet for xerox.com id AA08731; Tue, 29 Jan 91 11:18:44 GMT Received: by ernohb.uucp; Tue, 29 Jan 91 10:10:40 +0100 X-Ns-Transport-Id: 08002008D0FD0006B265 Date: Tue, 29 Jan 1991 01:10:40 PST From: Frank Plassmeier Subject: CLOS Info To: MOP.PARC@xerox.com Message-Id: <9101290910.AA00648@ernohb.uucp> Dear Mr. Kiczales, as Dr. Graube told me you could send me information concerning the Metaobject Protocol of CLOS. I am particularly interested in a copy of "Art of the MetaObject Protocol". Mail can be sent to: ERNO Raumfahrttechnik GmbH P. O. Box 10 59 09 2800 Bremen 1 Federal Republic of Germany Electronic Mail can be sent to: fp@ernohb.uucp Kind regards, Frank Plassmeier Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA04580; Mon, 11 Feb 91 14:23:25 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <18069>; Mon, 11 Feb 1991 14:22:51 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <18067>; Mon, 11 Feb 1991 14:21:11 PST Received: from kolyma (kolyma.lucid.com) by heavens-gate.lucid.com id AA10308g; Mon, 11 Feb 91 14:19:18 PST Received: by kolyma id AA21364g; Mon, 11 Feb 91 14:21:32 PST X-Ns-Transport-Id: 08002008D0FD00074BC8 Date: Mon, 11 Feb 1991 14:21:32 PST From: Jon L White Subject: CLASS-DIRECT-INSTANCES? To: mop.PARC@xerox.com Message-Id: <9102112221.AA21364@kolyma> The following reply to a query on comp.lang.clos give one more inch of evidence for the utility of the phrases "direct instances" and "indirect" or "derived" instances. Date: Mon, 11 Feb 91 14:08:44 MST From: egdorf@zaphod.lanl.gov (Skip Egdorf) To: mikeb@ford-wdl1.ARPA Cc: commonloops@cis.ohio-state.edu In-Reply-To: (Michael H Bender's message of 11 Feb 91 18:18:40 GMT Subject: RE: accessing clos objects . . . I have implemented such a metaclass using the accessors for class name-object mapping as a model. This scheme allows (class-direct-instances class), (instance-name object), (find-instance obect), and (setf (instance-name object) ...) on any instances of classes of this new metaclass. . . . Out of curiosity, is this email disucssion list "dead" now? Is there going to be any further discussion of the "pink" book? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA06909; Mon, 11 Feb 91 17:26:05 -0800 Received: from Mercury.Parc.Xerox.xns by alpha.xerox.com via XNS id <18014>; Mon, 11 Feb 1991 17:25:42 PST Received: from DINO.BBN.COM ([128.89.3.8]) by alpha.xerox.com with SMTP id <18115>; Mon, 11 Feb 1991 17:22:04 PST X-Ns-Transport-Id: 08002008D0FD00074EA2 Date: Mon, 11 Feb 1991 17:08:01 PST From: kanderso@dino.bbn.com Subject: Re: CLASS-DIRECT-INSTANCES? In-Reply-To: "Your message of Mon, 11 Feb 91 14:21:32 -0800. <9102112221.AA21364@kolyma>" To: Jon L White Cc: mop.PARC@xerox.com Message-Id: <91Feb11.172204pst.18115@alpha.xerox.com> X-NS-Transport-ID: 08002008D0FD00074BC8 Date: Mon, 11 Feb 1991 14:21:32 PST From: Jon L White Subject: CLASS-DIRECT-INSTANCES? To: mop.PARC@xerox.com The following reply to a query on comp.lang.clos give one more inch of evidence for the utility of the phrases "direct instances" and "indirect" or "derived" instances. Date: Mon, 11 Feb 91 14:08:44 MST From: egdorf@zaphod.lanl.gov (Skip Egdorf) To: mikeb@ford-wdl1.ARPA Cc: commonloops@cis.ohio-state.edu In-Reply-To: (Michael H Bender's message of 11 Feb 91 18:18:40 GMT Subject: RE: accessing clos objects . . . I have implemented such a metaclass using the accessors for class name-object mapping as a model. This scheme allows (class-direct-instances class), (instance-name object), (find-instance obect), and (setf (instance-name object) ...) on any instances of classes of this new metaclass. . . . Out of curiosity, is this email disucssion list "dead" now? Is there going to be any further discussion of the "pink" book? -- JonL -- I've only hurd rumors about the "pink" book. What is it, and how do i borrow a copy i can read? Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA06924; Mon, 11 Feb 91 17:27:30 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <18116>; Mon, 11 Feb 1991 17:27:14 PST Received: from lucid.com ([192.31.212.72]) by alpha.xerox.com with SMTP id <17855>; Mon, 11 Feb 1991 17:25:12 PST Received: from kolyma (kolyma.lucid.com) by heavens-gate.lucid.com id AA10890g; Mon, 11 Feb 91 17:23:19 PST Received: by kolyma id AA21647g; Mon, 11 Feb 91 17:25:33 PST X-Ns-Transport-Id: 08002008D0FD00074EB3 Date: Mon, 11 Feb 1991 17:25:33 PST From: Jon L White Subject: CLASS-DIRECT-INSTANCES? In-Reply-To: "kanderso@dino.bbn.com's message of Mon, 11 Feb 91 20:08:01 -0500 <9102120120.AA10878@lucid.com>" To: kanderso@dino.bbn.com Cc: mop.PARC@xerox.com Message-Id: <9102120125.AA21647@kolyma> re: I've only hurd rumors about the "pink" book. What is it, and how do i borrow a copy i can read? I guess it is primarily a minor updating of Gregor's "Chapter 3" draft metaobject proposal dated roughly 11-July-90? -- JonL -- Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA08008; Tue, 12 Feb 91 17:15:46 -0800 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <20022>; Tue, 12 Feb 1991 17:15:07 PST Received: from brazil.cambridge.apple.com ([134.149.2.3]) by alpha.xerox.com with SMTP id <20372>; Tue, 12 Feb 1991 15:21:16 PST Received: from [90.223.0.23] by brazil.cambridge.apple.com with SMTP (5.64/25-eef) id AA18276; Tue, 12 Feb 91 11:50:57 -0500 for mop.PARC@xerox.com X-Ns-Transport-Id: 08002008D0FD000754EB Date: Tue, 12 Feb 1991 03:40:31 PST From: moon@brazil.cambridge.apple.com (David A. Moon) Subject: Re: CLASS-DIRECT-INSTANCES? To: Jon L White Cc: mop.PARC@xerox.com, KMP@symbolics.com Message-Id: <9102121650.AA18276@brazil.cambridge.apple.com> > Date: Mon, 11 Feb 1991 14:21:32 PST > From: Jon L White > To: mop.PARC@xerox.com > > The following reply to a query on comp.lang.clos give one more inch > of evidence for the utility of the phrases "direct instances" and > "indirect" or "derived" instances. > .... If you look at the glossary in the X3J13 draft Kent recently made available, it looks like he has settled on the terms "direct instance", "indirect instance", and "generalized instance." Perhaps we can regard this issue as closed. Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA02029; Tue, 16 Apr 91 13:12:27 -0700 Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <16297>; Tue, 16 Apr 1991 13:07:11 PDT Received: from maui.cs.ucla.edu ([131.179.128.11]) by alpha.xerox.com with SMTP id <16193>; Tue, 16 Apr 1991 13:04:12 PDT Received: by maui.cs.ucla.edu (Sendmail 5.61a+YP/3.07) id AA09833; Tue, 16 Apr 91 13:03:59 -0700 X-Ns-Transport-Id: 08002008D0FD0009FAB3 Date: Tue, 16 Apr 1991 13:03:59 PDT From: steven@cs.ucla.edu (Steven Berson) To: mop.PARC@xerox.com Message-Id: <9104162003.AA09833@maui.cs.ucla.edu> I have a verson of the Metaobject Protocol draft dated July 30, 1990. Is this the current one? Where can I get a newer one if it exists? Thanks. Steve Received: from alpha.Xerox.COM by arisia.Xerox.COM with SMTP (5.61+/IDA-1.2.8/gandalf) id AA03949; Tue, 16 Apr 91 14:50:34 -0700 Received: from Clayvin.Parc.Xerox.xns by alpha.xerox.com via XNS id <16506>; Tue, 16 Apr 1991 14:47:49 PDT Received: from tracer-bullet.parc.xerox.com ([13.2.18.12]) by alpha.xerox.com with SMTP id <16496>; Tue, 16 Apr 1991 14:36:38 PDT Received: by tracer-bullet.parc.xerox.com id <29186>; Tue, 16 Apr 1991 14:25:48 -0700 Fake-Sender: gregor@parc.xerox.com X-Ns-Transport-Id: 08002008D0FD0009FBFF Date: Tue, 16 Apr 1991 14:25:35 PDT From: Gregor Kiczales In-Reply-To: "Steven Berson's message of Tue, 16 Apr 1991 13:03:59 PDT <9104162003.AA09833@maui.cs.ucla.edu>" To: steven@cs.ucla.edu Cc: mop.PARC@xerox.com Message-Id: <91Apr16.142548pdt.29186@tracer-bullet.parc.xerox.com> Date: Tue, 16 Apr 1991 13:03:59 PDT From: steven@cs.ucla.edu (Steven Berson) I have a verson of the Metaobject Protocol draft dated July 30, 1990. Is this the current one? Where can I get a newer one if it exists? Thanks. Steve There is a newer version, which will appear in our "Art of the Metaobject Protocol" book. The electronic source (LaTeX) for this version will be publicly available shortly. We are in the processing of removing its dependencies on a proprietary macro package.