perm filename CLOOPS.1[COM,LSP] blob sn#845326 filedate 1987-08-31 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00545 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00048 00002	Received: from SAIL.STANFORD.EDU by AI.AI.MIT.EDU 14 Oct 86 11:00:22 EDT
C00051 00003	   We see this as a separate document.   We have not yet discussed
C00053 00004			Class Precedence List (S)
C00055 00005			remove-class (L) [under discussion]
C00057 00006
C00059 00007	Date: 13 Oct 86  2206 PDT
C00062 00008	in my note had DESCRIBE-GENERIC for DEFGENERIC, then would you agree
C00065 00009	manual we agreed that SETQ was a bad historical holdover, and that by
C00068 00010	    won't fly.
C00071 00011
C00073 00012
C00075 00013
C00078 00014	       we go.
C00080 00015	Subject: Computing the class precedence list
C00083 00016
C00086 00017	Received: from Xerox.COM by AI.AI.MIT.EDU  9 Oct 86 21:10:31 EDT
C00089 00018
C00092 00019
C00095 00020	functions.
C00098 00021
C00100 00022	pg. 32-There is a typo at the top of the page. The
C00103 00023	in my note had DESCRIBE-GENERIC for DEFGENERIC, then would you agree
C00106 00024	manual we agreed that SETQ was a bad historical holdover, and that by
C00109 00025	    won't fly.
C00112 00026
C00114 00027	Cc: snyder%hplabsc@hplabs.HP.COM
C00117 00028	combination be done using macros? If the latter, then obviously
C00120 00029	TYPEP to work correctly?
C00123 00030	pg. 15-For the :ARGUMENT-PRECEDENCE-ORDER, what happens if not
C00126 00031
C00128 00032	Redistributed: commonloopscore↑.pa
C00131 00033	is what you do when your intention is to `get a new generic-function
C00134 00034	    Date: 8 Oct 86 15:50 PDT
C00136 00035	for it none of the other slot options allow NIL.  As with the
C00139 00036
C00142 00037	(SATISFIES (MEMBER arg '(X)) is not a valid CL type specifier
C00145 00038
C00148 00039
C00151 00040	Received: from Xerox.COM by AI.AI.MIT.EDU  8 Oct 86 21:16:24 EDT
C00153 00041	may influence modification of Common Lisp.
C00156 00042	In-reply-to: Bobrow.pa's message of 8 Oct 86 13:50 PDT
C00158 00043	            (<slot-name> <init-value-form> 
C00160 00044	DEFCLASS OPTIONS
C00162 00045	(initialize <instance> &rest)
C00164 00046	REQUIRED argument may be replaced by (arg-name arg-specializer).
C00167 00047
C00169 00048
C00172 00049	(:method-class class-name)
C00174 00050	:class class-name
C00176 00051
C00178 00052	Message-ID: <861008-145402-6443@Xerox>
C00180 00053	compute the precedence list in New Flavors, stripped down to make it
C00183 00054	 The values returned by MAP-COMPONENTS-DEPTH-FIRST are meaningless to the outside caller.
C00186 00055					     Construct the union of everything preceding this flavor
C00189 00056				  (CDR (ASSOC FLAVOR-NAME ALIST)))
C00192 00057	(DEFCLASS1 C4 (C1 C2))
C00194 00058
C00197 00059
C00199 00060	For some reason, the file excl-low.l was missing from the /pub/pcl
C00202 00061	DALY@IBM.COM
C00204 00062
C00207 00063
C00209 00064	   A Proposed Specification
C00211 00065	Return-Path: <luis@ingres.Berkeley.EDU>
C00213 00066
C00215 00067
C00218 00068	            operation on a superclass, and finds then happening differently
C00220 00069	should have been declared explicitly, possibly using the
C00223 00070	        subclass has the classes in a different order than a super. 
C00225 00071	Received: from Semillon.ms by ArpaGateway.ms  25 SEP 86 12:53:27 PDT
C00228 00072	affect behavior.  If so, signal an error.  This extension would ensure that
C00231 00073	normal case.  This seems a low enough level of issue that it shouldn't
C00234 00074	Let me give a less "off-the-cuff" reply:
C00237 00075
C00240 00076
C00242 00077	From: masinter.PA@Xerox.COM
C00245 00078	cc: commonloopscore↑.PA@Xerox.COM
C00248 00079	Received: from Xerox.COM by AI.AI.MIT.EDU 23 Sep 86 16:53:58 EDT
C00251 00080	get-slot of a vector doesn't matter, as long as it doesn't slow down the
C00254 00081	of the superclass.  It might use the next argument to choose a method,
C00257 00082	    the only alternative would be to allow (class-name (class-of (make-array
C00259 00083	"symbol-class" but that is pretty hopeless, and the class isn't a
C00262 00084	I do not believe that the argument limits (minimum, maximum, optional,
C00265 00085	(define-function-interface name argument-shape values-shape
C00268 00086	Line-fold: No
C00271 00087	    and methods discriminate only on those arguments.  However, methods can
C00274 00088		    Case 1b.
C00277 00089	ready for standardization.  We should tread carefully in this area.
C00280 00090	OK.
C00283 00091
C00286 00092	From the last meeting:
C00290 00093
C00293 00094	Received: from EUPHRATES.SCRC.Symbolics.COM by
C00296 00095	can say #'FOO instead of (GENERIC-FUNCTION-NAMED 'FOO).  Perhaps there
C00299 00096	of flavors that don't always appear in the same order.  It found 1830
C00302 00097	inline as a method-invocation on class-of. For that reason, the leaves
C00305 00098
C00308 00099	Date: 22 Sep 86 11:19 PDT
C00311 00100	Message-ID: <860922135659.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
C00314 00101	    This new scheme has not yet been discussed on this list though.  This
C00317 00102	    A recursive rule that computes class precedence lists locally.
C00319 00103	F3       A B          F3 A B Object
C00321 00104
C00324 00105	preparing things in advance of instantiation would have a higher cost
C00327 00106
C00330 00107
C00333 00108	that makes them implementation-dependent.  My intuition is that this will
C00336 00109	    Third, I don't think that bit, fixnum and bignum should be defined to be
C00339 00110	    and saying that a "vector" is first an array and secondly a sequence
C00342 00111	My reasons for excluding other built-in types listed in CLtL Table 4-1:
C00345 00112	Message-ID: <860922111626.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
C00347 00113	From: MASINTER.PA@Xerox.COM
C00350 00114	discriminate on removing "simple-array" would do most of the cleanup,
C00353 00115
C00355 00116	lists is changed by the merge. And the first element of each sublist
C00357 00117
C00360 00118	                                 &optional (width 1)) ...)
C00363 00119	optionals that it fills in.  The contract between the generic and the
C00366 00120
C00368 00121	methods and having to keep in my head that someone can call DRAW with 1
C00371 00122	implementations causes a macro expansion cache to become invalidated
C00373 00123	Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 19:11:37 EDT
C00376 00124	The CommonLoops paper used only two short names, viz "make" and "with". 
C00378 00125	In the existing CommonLoops papers and code, there is an object called
C00381 00126	Received: from Cabernet.ms by ArpaGateway.ms  21 SEP 86 15:35:27 PDT
C00384 00127
C00387 00128
C00391 00129	or another is required to get around this.
C00394 00130	Received: from EUPHRATES.SCRC.Symbolics.COM by
C00396 00131	    FUNCALL, etc. However, they are immutable. add-method, remove-method
C00399 00132
C00402 00133	to the first someone.  In example 1, the behavior of the saved-away foo
C00405 00134	makes all books written about Common Lisp have to say less. 
C00408 00135
C00410 00136	Pro & Cons:
C00413 00137	Subject: Short Names   
C00416 00138	Received: from Cabernet.ms by ArpaGateway.ms  19 SEP 86 10:45:24 PDT
C00419 00139	Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
C00421 00140	    We need to discuss which of these allocation options belong in
C00424 00141	                  allocated then.   If the first access is a read, then
C00427 00142	    The names :accessor and :read-accessor do not go together well.
C00430 00143	Message-ID: <860919105557.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
C00432 00144	    someone else can.
C00434 00145	The names :accessor and :read-accessor do not go together well.  If
C00437 00146	Precedence: priority-mail
C00440 00147	Message-ID: <860918-141159-9040@Xerox>
C00443 00148	create a cloud of
C00445 00149	I think that your characterization of the early CommonLoops proposal as
C00448 00150	user←ftp:   -rw-r--r--  1 270      41          10366 May 30 11:01 defsys.l
C00450 00151
C00452 00152
C00455 00153	I would suggest these three keywords:
C00457 00154	Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:45:30 EDT
C00460 00155	    (defclass point () ((x 0) (y 0)) (accessors-with-prefix point-))
C00462 00156	ensure that the accessor generic function is run -- which might include
C00464 00157
C00467 00158	From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
C00470 00159	Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
C00473 00160
C00476 00161	    After the ACM Conference there was a meeting of the Common Lisp
C00479 00162	    Lucid began work on a draft specification of the standard.  This working
C00482 00163			    straightforward object-oriented programming.
C00484 00164	    can
C00486 00165
C00488 00166	cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.pa@Xerox.COM
C00491 00167	 message of Thu, 18 Sep 86 08:17 EDT
C00493 00168	The syntax of with-slots is:
C00496 00169	to reference a single variable.  But with-slots is very convenient if
C00499 00170
C00502 00171	In-Reply-To: <860917-132658-7944@Xerox>
C00505 00172	Received: from EUPHRATES.SCRC.Symbolics.COM by
C00508 00173	To: CommonLoopsCore↑.pa@Xerox.COM
C00511 00174	Lisp that incorporates the best features of both systems.
C00514 00175	up and initialization. Into the conversation for a couple of days, I've
C00516 00176			lookup. This is the kind I described above.  
C00519 00177	    (defmethod foo ((x c1) &optional ((y c2)) (z *v1* my-supplied-z))) ..)
C00522 00178	    by the variety of things which people claimed would be natural or
C00525 00179	      ..)
C00528 00180	    to have access to the supplied-p information for the optional argument.
C00530 00181	    
C00533 00182	up the auxiliary name draw-internal, which is confusing because
C00536 00183
C00538 00184
C00541 00185	In-Reply-To: <860917-101441-7733@Xerox>
C00544 00186	To: CommonLoopsCore↑.pa@Xerox.COM
C00547 00187	This seems to be an issue that remains to be worked out about defclass.
C00550 00188
C00553 00189	are in the standard as long as there is something with equivalent
C00556 00190		 method-combination fit together, which is:
C00559 00191	"daemon", but I'm not attached to that name.  We don't actually need a
C00563 00192	to spend time thinking about this until after OOPSLA, but for now I'm
C00566 00193			(T
C00569 00194	∨
C00572 00195	can work out all the basic language details you included at the end of
C00574 00196	this.
C00577 00197	Many people in the Common Lisp community now see a need for defining a
C00580 00198	group started with the basic programmer interface for defining new
C00583 00199
C00585 00200	                need not fit into a rigid hierarchy.
C00587 00201	Received: from Cabernet.ms by ArpaGateway.ms  17 SEP 86 09:24:43 PDT
C00590 00202	of its contract with the world.  I think of any argument defaulting done
C00593 00203
C00595 00204	(defgeneric shape (thing &optional &key width height &allow-other-keys))
C00598 00205	lists and vectors can be made and accessed in a uniform manner
C00601 00206	(DEFINE-METHOD-COMBINATION :SUPER-DAEMON ()
C00604 00207	Message-ID: <860917-092458-7674@Xerox>
C00606 00208	For me, the question about supplied-p arguments comes down to deciding
C00609 00209
C00611 00210	eventually work out.  If, by friday, we have settled on a scheme that
C00614 00211						  COLLECT `(GET-FLAVOR-MAPPING-TABLE-FOR-INSTANCE
C00617 00212	Finally, I would want to describe the method combination language that allows 
C00620 00213	not pay any efficiency cost, while code that does use run-super will be
C00623 00214
C00625 00215			      COLLECT METHOD
C00628 00216	this method
C00631 00217	 This works by calling some machine-dependent facilities.
C00634 00218	this method
C00636 00219	(DEFGENERIC SDTEST (X Y)
C00638 00220	Message-ID: <860916205006.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
C00641 00221	    "general" syntax, with space left for "classical" syntax
C00643 00222
C00645 00223
C00647 00224
C00649 00225	In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
C00652 00226	One issue to be addressed is the following.  If we insist on the EQUALS
C00655 00227
C00658 00228	 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 104483 Tue
C00661 00229	Many people in the Common Lisp community see a need for defining a standard
C00664 00230	and generic functions.  This work is ongoing, but it has not yet reached a
C00667 00231	                hardware as well as specialized machines.
C00670 00232	                declaratively, making it easier to construct programs from
C00673 00233	Message-ID: <860915235743.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
C00676 00234	always called with the same number of arguments.
C00679 00235	The lambda-lists of all methods for a given generic function must be
C00682 00236	lambda-lists and in the case of keyword parameters the parameter
C00685 00237	Received: from EUPHRATES.SCRC.Symbolics.COM by
C00688 00238	SKeene@STONY-BROOK.SCRC.Symbolics.COM
C00691 00239	    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
C00694 00240	    of the CommonLos spec.
C00697 00241	deffunction	(I know this is longer, but it emphasizes the "function"
C00699 00242	    before a defmethod.  I don't want to make up my mind about having to do
C00702 00243	    Moon's variant of generic function defaulting, in which the defaulted
C00705 00244	why programs that can tell the difference between GFD #1 and GFD #2 should
C00708 00245
C00711 00246	intuitively I think it means that they are equal except for the names of
C00714 00247	One can claim that Common Lisp itself is a poorer language because
C00717 00248	To quote from my message of 2 Sep, which your message is a reply to:
C00720 00249	∨
C00722 00250
C00725 00251	    Date: 14 Sep 86 18:31 PDT
C00727 00252	Received: from Semillon.ms by ArpaGateway.ms  14 SEP 86 18:06:04 PDT
C00730 00253	(defgeneric draw (thing place &optional (clip-mask *clip-mask*)) ..)
C00732 00254
C00734 00255	Line-fold: no
C00737 00256	     rule:
C00739 00257	that we are going to be able to take advantage of the travel we are going to
C00741 00258	    {form}*)
C00744 00259
C00747 00260
C00750 00261	    {form}*)
C00752 00262	    {form}*)
C00754 00263	(defmethod (foo c1) (b)
C00756 00264	from other symbols in the car of a list, i.e. the cdr of the list is not
C00759 00265	     From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
C00762 00266
C00765 00267	    This is what flavors does now and is what I think we should do.  It
C00767 00268	From: Stan Lanning <Lanning.pa@Xerox.COM>
C00769 00269	shouldn't get bit by this.  We just have to be sure to fill our messages
C00772 00270	    in Palo Alto.  This will give us enough time to actually get some work
C00775 00271	∨
C00778 00272	user with nice convenience.
C00781 00273
C00784 00274	     instead of "message passing".
C00787 00275	Received: from Salvador.ms by ArpaGateway.ms  12 SEP 86 09:39:22 PDT
C00790 00276	believe that we can take care of this by the organization and phrasing
C00793 00277	right that it is a mistake to opt for the latest, greatest at the
C00796 00278
C00799 00279		    From: Bobrow.pa@Xerox.COM
C00802 00280	always sounds good, even to me, but historically it has almost always
C00805 00281
C00807 00282	on that generic-function.  For reasons which are complicated, doing
C00810 00283	Message-ID: <860911150805.2.GREGOR@AVALON.XEROX-PARC>
C00812 00284	default methods.  A :around default method is the canonical example.
C00815 00285	I do think we should be providing support in the standard so that an
C00818 00286	 11:42 PDT
C00820 00287	    Date: 11 Sep 86 10:03 PDT
C00823 00288		 Whoppers (and wrappers) are different from regular methods
C00826 00289	Subject: Whoppers and Phenomenology
C00829 00290	    types?
C00832 00291	understood methods with a particular method-option to behave just like
C00835 00292
C00838 00293	removed? 
C00840 00294	a
C00843 00295
C00845 00296
C00847 00297
C00850 00298	    Is the name of the type of method combination a symbol for some deep
C00853 00299	Message-ID: <860910-154308-2286@Xerox>
C00856 00300
C00858 00301	      :accessor generic-function-name
C00861 00302	reason or just to keep it a simple name as in other named things?
C00864 00303	(Danny, I'm referring to the current West Coast proposal).
C00866 00304	We can probably go along with this, but it ought to be
C00868 00305	The way you omit the initial value form when giving slot-options
C00870 00306
C00873 00307	the standard.  Maybe only a subset of them.
C00875 00308	    Each option-name is a keyword that names an option the
C00877 00309	"things we basically agree on" in the minutes of that meeting we
C00879 00310	The second reason is that these aren't just error-checking.
C00882 00311	  
C00885 00312	  stored?  In the silver book it talks about extensions to the
C00887 00313	    Each option is one of:
C00889 00314	it would be a method of the discriminator, rather than
C00891 00315	  
C00894 00316	  me, and if it can be defined with the stronger
C00897 00317	  
C00899 00318
C00901 00319	 Xerox.COM  09 SEP 86 21:34:51 PDT
C00904 00320	instance?  
C00906 00321	In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 08 Sep 86
C00909 00322	indentation.
C00911 00323	   Each slot-spec is one of:
C00913 00324	given, then SETF may NOT be used with this accessor. If
C00915 00325	this particular issue.
C00917 00326	can appear only once.  The arguments for this way of doing
C00919 00327
C00921 00328	  of this method.  Some examples of method-options are:
C00923 00329	      body...))
C00925 00330	the restriction.
C00927 00331		   (:documentation string)
C00929 00332
C00931 00333	used much more than daemon combination.  Hence my attempt to
C00933 00334
C00934 00335	-- danny
C00937 00336	    users to remmber that this is a generic function and others may define
C00940 00337	but now I think it's actually impossible. 
C00943 00338
C00946 00339	cc: Bobrow.pa@Xerox.COM, CommonLoopsCore↑.PA@Xerox.COM
C00949 00340	-- danny
C00952 00341	necessary.
C00955 00342	that "it's like intern" the first mention causes an automatic creation,
C00957 00343	     
C00960 00344	expands to the equivalent of both a defgeneric and a default defmethod.
C00963 00345	arglist.
C00965 00346	rather than on implementation considerations, which considerations Moon
C00968 00347		     in detail.
C00971 00348	Subject: Class versus Type System
C00974 00349
C00977 00350	     in methods to be a whole different type system from the regular
C00980 00351	set of guarded clauses. The nesting is determined by subtypep
C00982 00352
C00985 00353	implementation of SUBTYPEP is more inefficient than those that are judged
C00988 00354	    From: Bobrow.pa@Xerox.COM
C00991 00355
C00993 00356	In general syntax at least one must be specifed if you are using
C00996 00357	I would say that all Lisp Objects are instances of some class.  For
C00999 00358	predication, equality to a constant (EQL, I presume).  If we're going to
C01002 00359	  (OR (AND class1 test1)
C01005 00360	both predications must be evaluated, and if both are true an error must
C01008 00361
C01010 00362	        (slot-name initial-value-form)
C01013 00363	initial
C01015 00364	         option-name
C01017 00365	OK   
C01019 00366
C01021 00367	     type-specifier).
C01023 00368	       method-lambda-list setf-lambda-list
C01025 00369	     option.
C01027 00370	              (:generic-function-class class-name)
C01029 00371	     
C01032 00372
C01034 00373	starting
C01036 00374	To: commonloopscore↑.pa@Xerox.COM
C01039 00375
C01041 00376	     name-or-name-and-options = name|
C01044 00377	From: Bobrow.pa@Xerox.COM
C01047 00378	Subject: Re: Message selection, continued 
C01050 00379	5) Discrimination is done on the basis of all provided and filled
C01053 00380	only var-names for the optional arguments that is, NIL will be provided
C01056 00381
C01059 00382	    ATOM and COMMON from that lattice (vector is an atom). Therefore, a cons
C01062 00383	    information within itself. It has no name but can be associated with
C01065 00384
C01068 00385	  They aren't keywords.  You got fooled by looking at existing examples
C01070 00386	 name-or-name-and-options = name|
C01073 00387	cell is not the class CLASS (but is BUILT-IN-CLASS or some such) its
C01076 00388	new subpart to an existing thing. It seems odd to me that adding a new
C01078 00389	 Xerox.COM  04 SEP 86 21:47:42 PDT
C01081 00390
C01084 00391	    method.  If run-super is invoked in the method, it does:
C01087 00392	    Does this make sense?  It seems to provide a single coherent story. 
C01089 00393			  (MAPCAR #'CALL-COMPONENT-METHOD PRIMARY))
C01091 00394	following example, which has been taken from a real-life program:
C01094 00395
C01097 00396		     METHOD-ARGLIST))
C01099 00397	    ARGS))
C01101 00398	:method-transformer, it should be possible to scan the body of the
C01105 00399	In-Reply-To: <860903164956.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
C01108 00400	Smalltalk-80, you can only inherit from one class, but in Common Lisp,
C01111 00401	Issue 2: RPG proposes that default forms for function parameters that
C01115 00402	a default form in a method gives the impression that the form is evaluated
C01118 00403	 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74496
C01121 00404	Also I don't think there is anything in Common Lisp that says the name of
C01124 00405
C01126 00406	                :accessor generic-function-name
C01129 00407	    (:initable-slots slot-name...)
C01131 00408	variable may be used.  However, type-qualified-variables cannot be used for
C01133 00409
C01135 00410	    (:documentation string)
C01137 00411
C01139 00412	    remove-class
C01141 00413
C01143 00414	Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 17:20:10 EDT
C01146 00415	    the same shape as each of the methods [or it is NIL.  No methods can be
C01149 00416	    Then the function parameters of the generic function do not figure into
C01151 00417	    invoked, then every argument that had a argument specifier attached to it
C01154 00418	defgeneric every time they say defmethod, especially if the defgeneric
C01156 00419	    (defmethod paint (clr &optional ((bldg office-building) *default-bldg*)) ...)
C01159 00420	    parameters with defgeneric (or one of the other specific means of doing
C01162 00421			    :default-method-function 
C01165 00422	    method combination.] 
C01168 00423	    We agree with the problems you describe with the defmethod syntax
C01171 00424	    programmatic interface (i.e. creating the objects and calling the right
C01174 00425	Received: from EUPHRATES.SCRC.Symbolics.COM by
C01177 00426	    2) for setf we propose a top level form
C01180 00427	syntax is (defmethod (generic option...) lambda-list body...) I don't
C01182 00428	Received: from Salvador.ms by ArpaGateway.ms  03 SEP 86 23:04:00 PDT
C01185 00429
C01187 00430	(2) is not considered, because it discriminates on the second argument.
C01190 00431	requires us to frequently say, as the NewFlavors documentation frequently
C01192 00432
C01194 00433		 This function is spread out for commenting
C01196 00434
C01199 00435	In-Reply-To: <860903-140440-1246@Xerox>
C01202 00436
C01205 00437	  1) Options like :before and :after that are part of the name of the
C01208 00438	classical flavors syntax can be distinguished from this new Common Lisp
C01211 00439
C01214 00440	 the first time.
C01217 00441	is an instance of <class> regardless of whether it was supplied or defaulted.
C01220 00442
C01223 00443	    embed a program counter into the optional argument defaulting mechanism.
C01227 00444	I apologize for misleading you about the contents of my proposal by side-tracking
C01230 00445	    value would be supplied by the default <default>. However, if a value for
C01233 00446	arguments.  I am not proposing that anything in step 3 be any different, when there
C01236 00447	    (2) (defmethod ring (&optional ((x <class-2>) <instance of class-3>))...)
C01239 00448	By the way, what would happen if the same forms were executed in your
C01242 00449	Redistributed-date: Wed, 3 Sep 86 17:29 EDT
C01245 00450	objects that aren't primitive and have slots.  I see four possible
C01248 00451			  slots of the class.  A slot is a place where you can store data
C01251 00452
C01254 00453
C01256 00454
C01258 00455	From: Bobrow.pa@Xerox.COM
C01261 00456	argument specifiers, c1 and c2.
C01263 00457
C01266 00458		...&optional ((x office-building) *default-building*)...  (1)
C01269 00459
C01271 00460	If we allowed side effects in the default for optionals, we could probably
C01274 00461	nested class definitions.  CommonLoops is often presented in terms of
C01277 00462	To: commonloopscore↑.pa@Xerox.COM
C01280 00463	generic function objects one such mapping is established each time you
C01284 00464	Assuming you propose that the meta-object that represents a generic
C01287 00465	    to adopt the following rule:
C01290 00466	you're thinking that the error is "method inconsistent with itself" rather
C01293 00467	Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
C01295 00468	methods exist:
C01298 00469	∨
C01301 00470	for the discriminator function.  Another scenario might be that generic
C01303 00471	When the fragment
C01305 00472	Received: from Cabernet.ms by ArpaGateway.ms  02 SEP 86 22:17:36 PDT
C01308 00473	       (b 2))
C01310 00474	This is rather odd, because the interpretation of :accessor-prefix with one
C01313 00475
C01316 00476	      (:accessor-prefix xxx)
C01319 00477	    By the way, do we really want to introduce a new feature for :read-only
C01322 00478	To: CommonLoopsCore↑.PA@Xerox.COM
C01325 00479	 Xerox.COM  02 SEP 86 21:35:47 PDT
C01328 00480
C01331 00481
C01334 00482	None of these declarations would be common in code written by the average
C01337 00483	The problems with this are:
C01340 00484
C01343 00485	The set of possible method-types should be extensible.  In Flavors, a
C01347 00486	the remaining descriptors so that all positional arguments precede all
C01350 00487	value form taken from a defmethod or defgeneric.  It is an error for the
C01354 00488	Received: from Cabernet.ms by ArpaGateway.ms  02 SEP 86 19:40:50 PDT
C01357 00489	∨
C01360 00490	   (primary "primary" :every :base-flavor-last (:primary))
C01363 00491	Subject: Re: [Guy Steele <gls@THINK-AQUINAS.ARPA>: Common LOOPS]
C01366 00492	Received: from CHICOPEE.SCRC.Symbolics.COM by
C01369 00493	Subject: Let's define our terminology
C01372 00494		      program modularity.  A typical mode of use is to define several
C01375 00495	Return-Path: <dmaclaug@j.bbn.com>
C01378 00496	"the Common Lisp object-oriented programming standard".   This will make
C01381 00497	Instance  Every object is an instance of some class.  The term instance is
C01384 00498	          function.  The discriminator contains the code that performs the
C01387 00499
C01389 00500	Received: from Salvador.ms by ArpaGateway.ms  02 SEP 86 12:34:24 PDT
C01392 00501	Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 12:23:29 EDT
C01395 00502	have a slot named x and an accessor for it named foo-y, unless you code
C01398 00503	Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM  29 AUG 86
C01401 00504	We are making a pass through the declarative method combination
C01404 00505	altered, and it must be kept clear how a customized discimination
C01407 00506	binding in the compile-time environment, and does have a binding in the
C01410 00507	    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
C01413 00508	Date: Thu, 28 Aug 86 16:42 EDT
C01416 00509	function must have the same shape is quite important for
C01419 00510	discrimination.  I see two approaches to fixing this.  One is to require
C01422 00511	    work fine.  I feel less comfortable with &rest.  It gets into a whole
C01425 00512	the method on it, and have the metaclass keep track of classes
C01428 00513	behavior is somehow inadequate.
C01430 00514	argument is specialized to the undefining type, with the method
C01433 00515	to pick a name.
C01436 00516	Message-ID: <860828-113956-2368@Xerox>
C01438 00517	The :non-setfable-accessor-prefix option works the same way, but
C01441 00518	Redistributed: commonloopscore↑.pa
C01443 00519	∨
C01445 00520	Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 14:23:56 EDT
C01447 00521	I am delighted to learn that there will be a meeting during IJCAI-85 to
C01449 00522
C01451 00523	Subject: Defclass should be approximately upwards compatible with
C01454 00524	explaining defclass to a student I don't want to have to get into
C01457 00525	   FOO's first argument should be a moving-object, the second
C01459 00526	Date: 26 Aug 86 13:08 PDT
C01462 00527
C01464 00528	    :default-init-plist (..)
C01466 00529	  Contentious:  (Danny didn't see why these were needed)
C01468 00530	  with and with* are direct and via-accessor interface to instance
C01470 00531	class,
C01473 00532	around.
C01475 00533	Mon 25-Aug-86 22:35:09 EDT
C01478 00534	One possible way:
C01480 00535	"readable and writable".  (The experiences I'm thinking about are
C01482 00536	cc: DLW@STONY-BROOK.SCRC.Symbolics.COM, Bobrow.PA,
C01484 00537	      ()
C01486 00538	      ()
C01488 00539
C01491 00540	Subject: [David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>: First
C01493 00541	      . <options>)
C01495 00542	    (:dispatch . arg-names)
C01497 00543	I had to read it twice.  The last word is a Lisp symbol, I assume.  More
C01499 00544
C01502 00545	Received: from Xerox.COM by AI.AI.MIT.EDU 26 Aug 86 13:04:04 EDT
C01503 ENDMK
C⊗;
Received: from SAIL.STANFORD.EDU by AI.AI.MIT.EDU 14 Oct 86 11:00:22 EDT
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Oct 86  07:53:39 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 132678; Tue 14-Oct-86 10:17:10 EDT
Date: Tue, 14 Oct 86 10:15 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Summary of Object Standard Discussions (Repeat of last
         week) 
To: Bobrow.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <861013-183034-1785@Xerox>
Message-ID: <861014101523.7.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No

    Date: 13 Oct 86 18:31 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    DOCUMENTATION
      When are pieces of the Symbolics document appearing on SAIL?   Can 
    someone summarize for me what agreements on writing and combining were
    reached.

    -- danny

Sure.   Here's a summary of what we decided will happen with the 
documentation.   There will be 3 documents that will go together.  The
title and authors are as you noted in an earlier message.  The outline
of the first document follows, and you'll see that the writing is split 
up more or less evenly between Lucid (L) and Symbolics (S).  

Part I:  Progammer's Interface 

Part II:  Meta Object Protocol
  
   We see this as a separate document.   We have not yet discussed
   anything specific about this document, except that it needs to be
   written.  

Part III:  Design Rationale

   This is another separate document.  It will include the reasons
   underlying certain design decisions.   

   We will all be adding to this document as we go along.   To start,
   I'm going to put in sections from the "Classes" document.

----------------------------------------------

Part I:  Progammer's Interface 

	  1  Introduction (brief, no history) (L)
	  2  Concepts
		Classes (L)
		  -Defining classes
		  -Structure of class objects (slots)
		  -Creating instances
		  -Superclasses
		  -Inheritance
		  -Class precedence (brief)
		  -Accessing slots
		  -Types and Classes
		Generic Functions and Methods (S)
		  -Compare g-f's and ordinary functions
		  -Defining generic functions
		  -Defining methods
		Method Selection (S)
		Method Combination (S)
		Class Precedence List (S)
		Meta Objects (L)
		   -Metaclass
		   -Method class
		   -Generic function class

	   3  Alphabetic List of Functions 
		
[Each function page has the following fields:  Purpose, Syntax,
Arguments, Example, Remarks, See Also] 
 
[We are going to merge existing documentation from both the Lucid
and the Symbolics documents.   Some of the documentation must be revised
according to the discussions we had.] 

		add-method (L)
		argument-precedence-order (L)
		call-next-method (S)
		change-class (L)
		class-of (L)
		defclass (S)
		defgeneric (S)
		defgeneric-setf (S)
		define-method-combination (S) (and related functions)
		defmethod (S)
		defmethod-setf (S)
		function-parameters (L)
		generic-function-p (L)
		get-method (L)
		lambda-list-argument-specifiers (L)
		make-generic (L)	
		make-instance (L)
		method-combination (L)
		remove-class (L) [under discussion]
		remove-method (L)
		remove-setf-method (L)
		slot-value (L) 
		with-slots (S)

	   4  Existing CL Functions that Need to Change 

		describe (S)
		documentation (L)
		print-object (S)
		
	   5  Glossary 


∨
Received: from SAIL.STANFORD.EDU by AI.AI.MIT.EDU 14 Oct 86 02:35:32 EDT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 86  23:33:18 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 86 23:29:27 PDT
Return-Path: <@SAIL.STANFORD.EDU:SMITCHELL@USC-ECL.ARPA>
Redistributed: CommonLoopsInternal↑.x
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 13 OCT 86
 23:28:22 PDT
Received: from USC-ECL.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 86
 23:09:23 PDT
Date: Mon, 13 Oct 86 23:08:58 PDT
From: "Steve Mitchell" <SMITCHELL@USC-ECL.ARPA>
Subject: Mailing list addition
To: cl-object-oriented-programming@SU-AI.ARPA
cc: ailist-request@SRI-STRIPE.ARPA, nl-kr-request@ROCHESTER.ARPA,
 smitchell@USC-ECL.ARPA
Message-ID: <12246648417.53.SMITCHELL@USC-ECL.ARPA>


Please add me to your mailing list.  Thanks in advance!

Steven Mitchell
smitchell@usc-ecl.arpa
-------

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 14 Oct 86 02:30:12 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 86 23:29:27 PDT
Return-Path: <@SAIL.STANFORD.EDU:SMITCHELL@USC-ECL.ARPA>
Redistributed: CommonLoopsInternal↑.x
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 13 OCT 86
 23:28:22 PDT
Received: from USC-ECL.ARPA by SAIL.STANFORD.EDU with TCP; 13 Oct 86
 23:09:23 PDT
Date: Mon, 13 Oct 86 23:08:58 PDT
From: "Steve Mitchell" <SMITCHELL@USC-ECL.ARPA>
Subject: Mailing list addition
To: cl-object-oriented-programming@SU-AI.ARPA
cc: ailist-request@SRI-STRIPE.ARPA, nl-kr-request@ROCHESTER.ARPA,
 smitchell@USC-ECL.ARPA
Message-ID: <12246648417.53.SMITCHELL@USC-ECL.ARPA>


Please add me to your mailing list.  Thanks in advance!

Steven Mitchell
smitchell@usc-ecl.arpa
-------

∨
Received: from SAIL.STANFORD.EDU by AI.AI.MIT.EDU 14 Oct 86 01:08:25 EDT
Date: 13 Oct 86  2206 PDT
From: Linda DeMichiel <LGD@SAIL.STANFORD.EDU>
Subject: new object system spec files 

There is a new version of functi.tex and all files derived from it on
[CLS,LSP] on SAIL. The old tex source file has been renamed to functi.1.  

Linda

∨
Received: from SAIL.STANFORD.EDU by AI.AI.MIT.EDU 13 Oct 86 21:38:29 EDT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Oct 86  18:31:49 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 OCT 86 18:30:34 PDT
Date: 13 Oct 86 18:31 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: Summary of Object Standard Discussions (Repeat of last
 week) 
To: common-lisp-object-system@SAIL.STANFORD.EDU
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <861013-183034-1785@Xerox>

(Response to RPG)
    About DEFGENERIC.

    I certainly did not agree that a defgeneric was not required
    before any DEFMETHODs. What I agreed to, and what I carefully
    restated every time someone tried to tranform my statement into an
    agreement statement, was that the first step in convincing me to
    not require a defining statement for a generic function to appear
    before any DEFMETHODs is to rename DEFGENERIC to something else.

We certainly agreed to disagree about the name of this.  How about
the name DESCRIBE-GENERIC.  If all the things said about DEFGENERIC 
in my note had DESCRIBE-GENERIC for DEFGENERIC, then would you agree
DESCRIBE-GENERIC was done implicily by each DEFMETHOD, and the user 
could give a DESCRIBE-GENERIC to obtain a non-default generic function?

(Response to Moon)
    If you make the generic function FOO f-unbound and then do a
    DEFMETHOD or DEFGENERIC for FOO, you get a new generic-function
    object that doesn't know about any of the methods for the old FOO. 
    Those methods are gone (except in the PCL meta-object protocol
    class-direct-methods would still know about those methods, so the
    data structure would be inconsistent).

What data structure is inconsistent.  If one did
(DEFMETHOD FOO ((X c1))...)
(DEFMETHOD FOO ((X c2))...)
(SETQ ZZ (SYMBOL-FUNCTION FOO))
(SETF (SYMBOL-FUNCTION 'FOO) NIL) 
   or (FMAKUNBOUND 'FOO)  ;; I don't understand the difference
Then ZZ is bound to a funcallable object (a generic function) that will
indeed call the first method on an instance of c1. It is also be the
case that a "name" generated for the user for the first method may be
confusing. Doing the two DEFMETHODS again will indeed create a new
generic-function object stored in the symbol function cell of FOO.
The methods will be different, and both stored in the
class-direct-methods of the class c1. This implies perhaps that we need
some protocol for destroying generic-function objects that removes
things from class-direct-methods.

    My notes don't say that.  They say we agreed after discussing
    this and other similar topics that we weren't writing a
    prescriptive style manual for Common Lisp.

My memory was that although we were not writing a prescriptive style
manual we agreed that SETQ was a bad historical holdover, and that by
example we were going to encourage the other style.

     <slot-spec> = <slot-name> | 
                  (<slot-name> <init-value-form>) | (<slot-name>
                  {<slot-option> <option-value>}*)
    with a :default-value <slot-option>.  Any objections?

I don't like those nasty four words (it is an error) about
non-initialized variables.  If we want uninitialized variables, then
this syntax is fine with me.

        :initable <key or nil>  if NIL then not initable

    We did not discuss allowing NIL here.  I don't see any reason
    for it; none of the other slot options allow NIL.  As with the
    accessors the default should be that it's not initable unless you
    say something to make it initable.

How about programs generating structures.  For them, a NIL might be
appropriate. But the initialization protocol should be worked out.  I
prefer slot names to be used as keys rather than keywords in any event
if we have any default.

    I don't like the term "name-qualifier"; the word "name" here is
    just a noise word.  My notes just say "qualifier".  Plain
    "qualifier", with "method qualifier" used when method context is
    not obvious, would be better than "name-qualifier".

"qualifier" is fine -- both are better than "option"

    My notes say we agreed that the funny Common Loops exception to
    the normal argument-precedence-order for methods on individuals
    won't fly.

Agreed.

        If a DEFGENERIC specifies a contract that is not
        congruent with the current contract, it signals an error.  

    We didn't discuss this, if my notes are complete.  I assume you
    mean it only signals an error if there are methods whose parameters
    are not congruent with the new defgeneric's parameters.  That's
    okay; at this point the program development environment comes into
    play, so we shouldn't say any more.
There may be other problems between DESCRIBE-GENERICs.  Should users be
able to change method-combination or generic-function class?  Perhaps.

        WITH-SLOTS
        (with-slots ({var-name}|
                 (var-name (keyword arg)*)) form*)

    Change <var-name> to <instance>, an expression that evaluates
    to an instance.  No reason to limit the possible expressions to
    variables. The expression is evaluated exactly once.  According to
    my notes we agreed on that.

I remember thinking that this was consistent, but that we had not yet
agreed to this extension.  It is OK with me.  Of course it makes sense
only if :class is specified explicitly, and that would have to be said.
No type inference machinery except for variable-names declared in the
method lambda-list.  

    According to my notes we agreed that defmethod puts in type
    declarations for the specialized parameters.  I don't remember
    agreeing on that, but why not.

I don't know what this means?

    The proliferation of -setf functions (e.g. remove-method-setf)
    is getting disturbing and maybe we need an explicit notion of the
    generic function objects that do setfs.

Should we go back to
  (defmethod (:setf foo) ...)
since qualifiers are not around the name.


DOCUMENTATION
  When are pieces of the Symbolics document appearing on SAIL?  Can
someone summarize for me what agreements on writing and combining were
reached.

-- danny

     ----- End Forwarded Messages -----


-- danny

∨
Received: from SAIL.STANFORD.EDU by AI.AI.MIT.EDU 13 Oct 86 21:27:29 EDT
Date: 13 Oct 86  1823 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Greetings
To:   common-lisp-object-system@SAIL.STANFORD.EDU    


This mailing list is the replacement for

commonloopscore↑.pa@xerox.com

You can mail to it using the address

common-lisp-object-system@sail.stanford.edu

The request address is

common-lisp-object-system-request@sail.stanford.edu

				-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Oct 86 19:29:51 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 10 OCT 86 15:59:10 PDT
Date: Fri, 10 Oct 86 15:58 PDT
From: Gregor.pa@Xerox.COM
Subject: yaccpla (yet another compute class precedence list algorithm)
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <861010155847.2.GREGOR@AVALON.XEROX-PARC>
Line-fold: no


This code implements a compute-class-precedence-list algorithm the many
and varied features of which Danny will describe in a separate message.

Using this changed defclass1 macro you can try it on all the same
examples as the other algorithm.

(DEFMACRO DEFCLASS1 (NAME SUPERCLASSES)
  `(progn (SETF (GET ',NAME 'CLASS-COMPONENTS) ',(REVERSE (CONS NAME SUPERCLASSES)))
	  (setf (get ',name 'supers) ',superclasses)))


(defun compute-class-precedence-list (class)
  (let ((cpl ())
	(must-precede-alist ()))
    ;; We start by computing two values.
    ;;   CPL
    ;;     The depth-first left-to-right up to joins walk of the supers tree.
    ;;   MUST-PRECEDE-ALIST
    ;;     An alist of the must-precede relations. The car of each element of the
    ;;;    must-precede-alist is a class, the cdr is all the classes which must
    ;;     precede that class in the CPL.
    ;;
    ;; Note that the actual walk is breadth-first, right-to-left.
    ;;
    (labels ((walk-supers (class &optional precedence)
	       (format t "}% }S }S" class precedence)
	       (let ((elem (assoc class must-precede-alist)))
		 (if elem
		     (setf (cdr elem) (nunion (cdr elem) precedence))
		     (push (cons class precedence) must-precede-alist)))
	       (let* ((rsupers (reverse (cons class (get class 'supers))))
		      (precedence (cdr rsupers)))
		 (do ((sup rsupers (cdr sup))
		      (pre precedence (cdr pre)))
		     ((null pre))
		   (walk-supers (car sup) pre)))
	       (unless (member class cpl) (push class cpl))))
      (walk-supers class)
      ;; For each class in the cpl, make sure that there are no classes after it which
      ;; should be before it.  We do this by cdring down the list, making sure that for
      ;; each element of the list, none of its must-precedes come after it in the list.
      ;; We use a hand-coded loop so that we can splice things in and out of the CPL as
      ;; we go.
      (let ((tail cpl)
	    (element nil)
	    (move nil)
	    (moves nil))
	(loop (when (null tail) (return))
	      (setq element (car tail)
		    move nil)
	      (dolist (must-precede (cdr (assoc element must-precede-alist)))
		;; This hairy setq does the following:
		;;   The outer OR means if you have already found a MOVE, don't drop it
		;;   unless you find another move.
		;;   The inner OR means once you have found a move, only look for another
		;;   move that comes after it.
		;; The result is that we look for the farthest possible move.
		(setq move (or (member must-precede (or move
							(cdr tail)))
			       move)))
	      (when move
		(when (member element moves)
		  (EXPLAIN-class-ORDERING-ERROR class MUST-PRECEDE-ALIST cpl))
		(push element moves)
		(setf (cdr move) (cons element (cdr move)))
		(setf (car tail) (cadr tail))	;OK to use Interlisp delete trick since it
		(setf (cdr tail) (cddr tail)))	;will never be the last element of the list.
	      (setq tail (cdr tail)))
	(copy-list cpl)))))
-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Oct 86 18:52:44 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 10 OCT 86 15:51:00 PDT
Date: 10 Oct 86 15:51 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Computing the class precedence list
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <861010-155100-1243@Xerox>

Another way of explaining class precedence list.

The class precedence list is a left to right, depth first linearization
of the transitive closure of inheritance from the local super classes of
a class.  It satisfies three constraints:

Constraint-0) A class appears only once in the list
Constraint-1) A class always precedes in the list all its local super
classes
Constraint-2) The order of the local supers is preserved

Stating C1 and C2 slightly differently:

C-1-2) A class must follow any class it is a direct super of,
         or any class it follows in a local-supers list. 

The class precedence can be constructed in three steps.

1) Walk the inheritance tree in left to right depth first order,
recording all super classes in the order visited.

2) Remove duplicates, preserving the last occurrence of any class.
  (This can actually be combined with step 1 without extra consing.).

3) Traverse the resluting list from left to right. If for any class c1,
there is a class to its right that c1 should follow (by C-1-2), move c1
to the right of the rightmost such class.

If any class needs to be moved a second time, it means there is a loops
of constraints that cannot be satisfied.  
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Oct 86 18:52:28 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 10 OCT 86 15:25:59 PDT
Return-Path: <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 10 OCT 86 15:25:27 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 131545; Fri
 10-Oct-86 18:14:24 EDT
Date: Fri, 10 Oct 86 18:13 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Classes document available on SAIL
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <861010181313.1.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No


I transferred the file containing the Classes document over to
"classes.txt" on the CLS,LSP directory at SAIL.    It's in a format that
should be easy for you all to read, although the page breaks are
probably wrong for printers.  

I expect to get to work on Tuesday to start merging my pieces of the
Classes document into the files that Linda set up.    This has been a
busy week for us here, and I haven't had a chance to get started on it
yet.    


∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Oct 86 21:10:31 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 OCT 86 18:09:39 PDT
Return-Path: <@MC.LCS.MIT.EDU:kempf%hplabsc@hplabs.HP.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from MC.LCS.MIT.EDU by Xerox.COM ; 09 OCT 86 18:09:09 PDT
Received: from hplabs.HP.COM by MC.LCS.MIT.EDU  9 Oct 86 21:08:50 EDT
Received: from hplabsc by hplabs.HP.COM ; Thu, 9 Oct 86 15:56:54 pdt
Received: by hplabsc ; Thu, 9 Oct 86 15:55:24 pdt
Date: Thu, 9 Oct 86 15:55:24 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8610092255.AA05179@hplabsc>
To: common-lisp-classes-discussion@mc.lcs.mit.edu,
 commonloopscore↑.pa@Xerox.COM
Subject: "Classes" Document and Agreements Summary
Cc: snyder%hplabsc@hplabs.HP.COM

I read through the "Classes" document in detail, and the executive
summary posted by Danny on Oct. 8. Below is a list of detailed
questions, comments, and corrections which I noticed. There are
several meta-comments, however, which I've summarized at the top
to remove them from the chaff. I plan to get the updated documents
off of Sail and will post any additional comments, as needed.
I hope you'll keep us posted about progress, we've got a lot of
applications people here who are interested in the result. I'll
also post comments on the MetaObject Protocol in the Xerox document
as I get a chance to read through it. I hope these comments can
be of some help. It looks like the standard is starting to shape
up. 
	Jim Kempf		kempf@hplabs

-----------------------------------------------------------------

METACOMMENTS

*"Classes" sounds like an excellent name! 

*With reference to pgs. 9  and 39 in the "Classes" document, 
it would seem that there may be some cases where a user-defined
class might want to inherit from a built-in class. The canonical
example is the class STREAM which one might want to have as the
parent for the class WINDOW in an object-oriented window system.
This would also be a reason to have a class for STREAM, instead
of excluding it, as on pg. 39. Has anyone given thought to how
this would fit in with the proposed CommonWindows standard?

*Does method combination go through the generic function or
through the method itself? If the former, then couldn't method
combination be done using macros? If the latter, then obviously
not. What is the relation between method combination and
DEFGENERIC? Couldn't the :INTERFACE keyword argument to DEFGENERIC
be used to achieve the same effect with somewhat less cognitive 
complexity? In general, I support an effort to make method
combination easier to use and understand. There seems to be
a good deal of power in the idea, but it needs to be better 
integrated with generic functions. See also the comments below
about defining a new class of generic functions.

*The convention for including documentation strings in this
document seems to deviate from the CLtL standard. Is this
a good idea?

*The user-accessable hook to the code walker looks like a
good idea. We'll be interested in seeing the result, though
it might be more appropriate as part of the MetaObject
protocol, since its primary use would seem to be in defining
new metaclasses.

COMMENTS (page numbers reference the "Classes" document)

pg. 5-CLASS-OF/TYPE-OF relationship needs some clarification
for instance objects. What will TYPE-OF return when applied
to an instance object? See comment below on TYPEP

pg. 5-:CLASS option-Is this for class slots? If so, it seems
to be a retraction of some earlier discussion about doing
this in the metaclass. What about inheritance of class
slots? Are seperate copies of class state maintained in
the super and subclass objects or not?

pg. 7-Presumably (TYPE-OF <object>) -> <class-name> for
TYPEP to work correctly?

pg. 7-How is automatic updating of instances done when it is
redefined? Are there any hooks for user defined transformation
of instance state? For class state (re. :CLASS option above)?
Is there some way for a user to override this? Consider the
case of developing extensions to a programming environment
while using the environment. One might not want old instances
of a redefined class to be updated, if the behavior of the
redefined class was not yet solid; otherwise, the environment
might break.

pg. 9-Couldn't :DYNAMIC be done with a subobject. That is, couldn't
one have a slot into which an object with the necessary state was
inserted when required, rather than have the extra slots added
to the object (basically, an Occam's Razor argument)?

pg. 10-The defaults for these options are listed at the end of the
paper. Shouldn't they be here? In particular, for the access 
functions.

pg. 12-MAKE-INSTANCE as a generic function could potentially conflict
with the lambda list congruency test, unless initialization is 
done by a seperate, class specific function (ie. with the class
name as the prefix).

pg. 14-The term "setf-lambda-list" appears to be used differently in
the middle and at the end of the page. In the middle, the term means
a qualified list, at the end, not.

pg. 15-DECLARE should be :DECLARE, and "affect" should be "effect"
(nit-picky English).

pg. 15-For the :ARGUMENT-PRECEDENCE-ORDER, what happens if not
all the parameters are included?

pg. 16-How is :GENERIC-FUNCTION-CLASS different from :INTERFACE?
That is, why would anyone what to define a different generic
function class rather than simply use a different interface definition?
Same comment goes for method combination (as mentioned in the
METACOMMENTS section).

pg. 17-I presume the :CLASS option was included so that lambda
list parameters which were not qualified could be opened up using
the WITH-SLOTS special form. If so, then why allow super class names
as well? Isn't it rather more appropriate to have the name following
:CLASS designate a class or any subclass, as with the class qualifiers
in the lambda list? And what if the parameter isn't of that class
at runtime?

pg. 18-Does CALL-NEXT-METHOD do the same thing as the current
RUN-SUPER in PCL?

pg. 19-Why not have PRINT simply be a generic function? Also, why
not have EQUALP (and perhaps EQUAL, and EQL as well) be generic
functions? This would allow programmers to define their own
notions of equality for two instances, and could come in handy
when objects have circularity.

pg. 21-Need some overview about what method combination is
and some simple examples of when it would come in handy.
Also, a simple glossery of terms, as at the beginning
of the document. Such terms as "primary method" are used
without definition.

pg. 21-What is :PRETTY-NAME used for?

pg. 21-To what extend does the parameter list differ
from DEFMACRO?

pg. 23-24-Some explanation of how these examples work
would be helpful. Also, aren't keywords self evaluating?
If so, then why quote them in the examples?

pg. 24-LOOP is not (yet) standard CL. Should probably
be replaced by something that is.

pg. 26-Must a generic function be defined before 
DEFINE-METHOD-COMBINATION is evaluated? Must all
the mentioned methods? Any of them?

pg. 27-What are the internal arguments mentioned in
the paragraph after the CALL-COMPONENT-METHOD syntax
description?

pg. 32-There is a typo at the top of the page. The
second instance of (PIE CINNAMON APPLE) should be
(PASTRY CINNAMON APPLE).

pg. 37-The default info. here is good, but should
be moved up to where the options are defined.

pg. 39-STREAM might want to have a class associated
with it, for reasons cited in the METACOMMENTS
section.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Oct 86 20:08:33 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 OCT 86 17:04:35 PDT
Date: 9 Oct 86 17:04 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: Summary of Object Standard Discussions 
To: commonloopscore↑.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <861009-170435-1178@Xerox>

(Response to RPG)
    About DEFGENERIC.

    I certainly did not agree that a defgeneric was not required
    before any DEFMETHODs. What I agreed to, and what I carefully
    restated every time someone tried to tranform my statement into an
    agreement statement, was that the first step in convincing me to
    not require a defining statement for a generic function to appear
    before any DEFMETHODs is to rename DEFGENERIC to something else.

We certainly agreed to disagree about the name of this.  How about
the name DESCRIBE-GENERIC.  If all the things said about DEFGENERIC 
in my note had DESCRIBE-GENERIC for DEFGENERIC, then would you agree
DESCRIBE-GENERIC was done implicily by each DEFMETHOD, and the user 
could give a DESCRIBE-GENERIC to obtain a non-default generic function?

(Response to Moon)
    If you make the generic function FOO f-unbound and then do a
    DEFMETHOD or DEFGENERIC for FOO, you get a new generic-function
    object that doesn't know about any of the methods for the old FOO. 
    Those methods are gone (except in the PCL meta-object protocol
    class-direct-methods would still know about those methods, so the
    data structure would be inconsistent).

What data structure is inconsistent.  If one did
(DEFMETHOD FOO ((X c1))...)
(DEFMETHOD FOO ((X c2))...)
(SETQ ZZ (SYMBOL-FUNCTION FOO))
(SETF (SYMBOL-FUNCTION 'FOO) NIL) 
   or (FMAKUNBOUND 'FOO)  ;; I don't understand the difference
Then ZZ is bound to a funcallable object (a generic function) that will
indeed call the first method on an instance of c1. It is also be the
case that a "name" generated for the user for the first method may be
confusing. Doing the two DEFMETHODS again will indeed create a new
generic-function object stored in the symbol function cell of FOO.
The methods will be different, and both stored in the
class-direct-methods of the class c1. This implies perhaps that we need
some protocol for destroying generic-function objects that removes
things from class-direct-methods.

    My notes don't say that.  They say we agreed after discussing
    this and other similar topics that we weren't writing a
    prescriptive style manual for Common Lisp.

My memory was that although we were not writing a prescriptive style
manual we agreed that SETQ was a bad historical holdover, and that by
example we were going to encourage the other style.

     <slot-spec> = <slot-name> | 
                  (<slot-name> <init-value-form>) | (<slot-name>
                  {<slot-option> <option-value>}*)
    with a :default-value <slot-option>.  Any objections?

I don't like those nasty four words (it is an error) about
non-initialized variables.  If we want uninitialized variables, then
this syntax is fine with me.

        :initable <key or nil>  if NIL then not initable

    We did not discuss allowing NIL here.  I don't see any reason
    for it; none of the other slot options allow NIL.  As with the
    accessors the default should be that it's not initable unless you
    say something to make it initable.

How about programs generating structures.  For them, a NIL might be
appropriate. But the initialization protocol should be worked out.  I
prefer slot names to be used as keys rather than keywords in any event
if we have any default.

    I don't like the term "name-qualifier"; the word "name" here is
    just a noise word.  My notes just say "qualifier".  Plain
    "qualifier", with "method qualifier" used when method context is
    not obvious, would be better than "name-qualifier".

"qualifier" is fine -- both are better than "option"

    My notes say we agreed that the funny Common Loops exception to
    the normal argument-precedence-order for methods on individuals
    won't fly.

Agreed.

        If a DEFGENERIC specifies a contract that is not
        congruent with the current contract, it signals an error.  

    We didn't discuss this, if my notes are complete.  I assume you
    mean it only signals an error if there are methods whose parameters
    are not congruent with the new defgeneric's parameters.  That's
    okay; at this point the program development environment comes into
    play, so we shouldn't say any more.
There may be other problems between DESCRIBE-GENERICs.  Should users be
able to change method-combination or generic-function class?  Perhaps.

        WITH-SLOTS
        (with-slots ({var-name}|
                 (var-name (keyword arg)*)) form*)

    Change <var-name> to <instance>, an expression that evaluates
    to an instance.  No reason to limit the possible expressions to
    variables. The expression is evaluated exactly once.  According to
    my notes we agreed on that.

I remember thinking that this was consistent, but that we had not yet
agreed to this extension.  It is OK with me.  Of course it makes sense
only if :class is specified explicitly, and that would have to be said.
No type inference machinery except for variable-names declared in the
method lambda-list.  

    According to my notes we agreed that defmethod puts in type
    declarations for the specialized parameters.  I don't remember
    agreeing on that, but why not.

I don't know what this means?

    The proliferation of -setf functions (e.g. remove-method-setf)
    is getting disturbing and maybe we need an explicit notion of the
    generic function objects that do setfs.

Should we go back to
  (defmethod (:setf foo) ...)
since qualifiers are not around the name.


DOCUMENTATION
  When are pieces of the Symbolics document appearing on SAIL?  Can
someone summarize for me what agreements on writing and combining were
reached.

-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Oct 86 19:10:00 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 OCT 86 16:09:05 PDT
Return-Path: <kempf%hplabsc@hplabs.HP.COM>
Redistributed: commonloopscore↑.pa
Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 09 OCT 86
 16:02:53 PDT
Received: from hplabsc by hplabs.HP.COM ; Thu, 9 Oct 86 15:56:54 pdt
Received: by hplabsc ; Thu, 9 Oct 86 15:55:24 pdt
Date: Thu, 9 Oct 86 15:55:24 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8610092255.AA05179@hplabsc>
To: common-lisp-classes-discussion@mc.lcs.mit.edu,
 commonloopscore↑.pa@Xerox.COM
Subject: "Classes" Document and Agreements Summary
Cc: snyder%hplabsc@hplabs.HP.COM

I read through the "Classes" document in detail, and the executive
summary posted by Danny on Oct. 8. Below is a list of detailed
questions, comments, and corrections which I noticed. There are
several meta-comments, however, which I've summarized at the top
to remove them from the chaff. I plan to get the updated documents
off of Sail and will post any additional comments, as needed.
I hope you'll keep us posted about progress, we've got a lot of
applications people here who are interested in the result. I'll
also post comments on the MetaObject Protocol in the Xerox document
as I get a chance to read through it. I hope these comments can
be of some help. It looks like the standard is starting to shape
up. 
	Jim Kempf		kempf@hplabs

-----------------------------------------------------------------

METACOMMENTS

*"Classes" sounds like an excellent name! 

*With reference to pgs. 9  and 39 in the "Classes" document, 
it would seem that there may be some cases where a user-defined
class might want to inherit from a built-in class. The canonical
example is the class STREAM which one might want to have as the
parent for the class WINDOW in an object-oriented window system.
This would also be a reason to have a class for STREAM, instead
of excluding it, as on pg. 39. Has anyone given thought to how
this would fit in with the proposed CommonWindows standard?

*Does method combination go through the generic function or
through the method itself? If the former, then couldn't method
combination be done using macros? If the latter, then obviously
not. What is the relation between method combination and
DEFGENERIC? Couldn't the :INTERFACE keyword argument to DEFGENERIC
be used to achieve the same effect with somewhat less cognitive 
complexity? In general, I support an effort to make method
combination easier to use and understand. There seems to be
a good deal of power in the idea, but it needs to be better 
integrated with generic functions. See also the comments below
about defining a new class of generic functions.

*The convention for including documentation strings in this
document seems to deviate from the CLtL standard. Is this
a good idea?

*The user-accessable hook to the code walker looks like a
good idea. We'll be interested in seeing the result, though
it might be more appropriate as part of the MetaObject
protocol, since its primary use would seem to be in defining
new metaclasses.

COMMENTS (page numbers reference the "Classes" document)

pg. 5-CLASS-OF/TYPE-OF relationship needs some clarification
for instance objects. What will TYPE-OF return when applied
to an instance object? See comment below on TYPEP

pg. 5-:CLASS option-Is this for class slots? If so, it seems
to be a retraction of some earlier discussion about doing
this in the metaclass. What about inheritance of class
slots? Are seperate copies of class state maintained in
the super and subclass objects or not?

pg. 7-Presumably (TYPE-OF <object>) -> <class-name> for
TYPEP to work correctly?

pg. 7-How is automatic updating of instances done when it is
redefined? Are there any hooks for user defined transformation
of instance state? For class state (re. :CLASS option above)?
Is there some way for a user to override this? Consider the
case of developing extensions to a programming environment
while using the environment. One might not want old instances
of a redefined class to be updated, if the behavior of the
redefined class was not yet solid; otherwise, the environment
might break.

pg. 9-Couldn't :DYNAMIC be done with a subobject. That is, couldn't
one have a slot into which an object with the necessary state was
inserted when required, rather than have the extra slots added
to the object (basically, an Occam's Razor argument)?

pg. 10-The defaults for these options are listed at the end of the
paper. Shouldn't they be here? In particular, for the access 
functions.

pg. 12-MAKE-INSTANCE as a generic function could potentially conflict
with the lambda list congruency test, unless initialization is 
done by a seperate, class specific function (ie. with the class
name as the prefix).

pg. 14-The term "setf-lambda-list" appears to be used differently in
the middle and at the end of the page. In the middle, the term means
a qualified list, at the end, not.

pg. 15-DECLARE should be :DECLARE, and "affect" should be "effect"
(nit-picky English).

pg. 15-For the :ARGUMENT-PRECEDENCE-ORDER, what happens if not
all the parameters are included?

pg. 16-How is :GENERIC-FUNCTION-CLASS different from :INTERFACE?
That is, why would anyone what to define a different generic
function class rather than simply use a different interface definition?
Same comment goes for method combination (as mentioned in the
METACOMMENTS section).

pg. 17-I presume the :CLASS option was included so that lambda
list parameters which were not qualified could be opened up using
the WITH-SLOTS special form. If so, then why allow super class names
as well? Isn't it rather more appropriate to have the name following
:CLASS designate a class or any subclass, as with the class qualifiers
in the lambda list? And what if the parameter isn't of that class
at runtime?

pg. 18-Does CALL-NEXT-METHOD do the same thing as the current
RUN-SUPER in PCL?

pg. 19-Why not have PRINT simply be a generic function? Also, why
not have EQUALP (and perhaps EQUAL, and EQL as well) be generic
functions? This would allow programmers to define their own
notions of equality for two instances, and could come in handy
when objects have circularity.

pg. 21-Need some overview about what method combination is
and some simple examples of when it would come in handy.
Also, a simple glossery of terms, as at the beginning
of the document. Such terms as "primary method" are used
without definition.

pg. 21-What is :PRETTY-NAME used for?

pg. 21-To what extend does the parameter list differ
from DEFMACRO?

pg. 23-24-Some explanation of how these examples work
would be helpful. Also, aren't keywords self evaluating?
If so, then why quote them in the examples?

pg. 24-LOOP is not (yet) standard CL. Should probably
be replaced by something that is.

pg. 26-Must a generic function be defined before 
DEFINE-METHOD-COMBINATION is evaluated? Must all
the mentioned methods? Any of them?

pg. 27-What are the internal arguments mentioned in
the paragraph after the CALL-COMPONENT-METHOD syntax
description?

pg. 32-There is a typo at the top of the page. The
second instance of (PIE CINNAMON APPLE) should be
(PASTRY CINNAMON APPLE).

pg. 37-The default info. here is good, but should
be moved up to where the options are defined.

pg. 39-STREAM might want to have a class associated
with it, for reasons cited in the METACOMMENTS
section.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Oct 86 18:41:55 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 OCT 86 15:41:11 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 09 OCT 86
 15:40:53 PDT
Date: 09 Oct 86 15:40 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Summary of Object Standard Discussions 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <861009-154111-1088@Xerox>


About DEFGENERIC.

I certainly did not agree that a defgeneric was not required before any
DEFMETHODs. What I agreed to, and what I carefully restated every time
someone tried to tranform my statement into an agreement statement, was
that the first step in convincing me to not require a defining statement
for a generic function to appear before any DEFMETHODs is to rename
DEFGENERIC to something else. That is, if we are not going to require such
a defining statement, we should not have an operator with a name that says
``I, sir, am the very defining statement you might think you have to make,
but actually do not.''

Moon said this in his message:

``If you make the generic function FOO f-unbound and then do a DEFMETHOD
  or DEFGENERIC for FOO, you get a new generic-function object that
  doesn't know about any of the methods for the old FOO.  Those methods
  are gone ... so the data structure would be inconsistent....  There
  could be other inconsistencies too.''

If generic functions are first-class, and if we've decided that this
first-class object (which comprises the generic function along with the
methods on it) is stored in the function cell, then FMAKUNBOUNDing them
is what you do when your intention is to `get a new generic-function
object that doesn't know about any of the <old> methods.''

I think this means that Moon did not understand what we agreed to. A
first-class generic function is the thing that you funcall to get the
generic behavior and that has the methods logically inside it. When you
drop the last pointer to the generic function object, the garbage
collector can grab it away. When you do n DEFMETHODs on FOO, the function
cell for FOO is the only thing that logically has a pointer to the generic
function associated with the name FOO. If FMAKUNBOUND does not flush every
old method, and data structures end up inconsistent, then there is a bug
in your implementation.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Oct 86 18:40:13 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 09 OCT 86 14:28:05 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 09 OCT 86 14:27:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 130440; Thu
 9-Oct-86 17:26:13 EDT
Date: Thu, 9 Oct 86 17:25 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Summary of Object Standard Discussions
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <861008-155125-6521@Xerox>
Message-ID: <861009172529.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 8 Oct 86 15:50 PDT
    From: Bobrow.pa@Xerox.COM, Gregor.pa@Xerox.COM

    This is an impression of the basic structure of the agreements we
    reached (and didn't) at the design review meetings in Oregon and Palo
    Alto.  Please provide corrections.

I cross-checked this against my notes.  For brevity, I've deleted portions
of your message where I had nothing to add.

    DEFCLASS SYNTAX

    (defclass <class-name> ({<super-name>}*)
       ({<slot-spec>}*)
       {(<option-name> {<option-argument>}*)}*)

    <slot-spec> = <slot-name> | 
		(<slot-name> <init-value-form> 
		  {<slot-option> <option-value>}*)

We forgot to discuss whether the syntax for <slot-spec>
is that one or the following, which I think is cleaner:
<slot-spec> = <slot-name> | 
              (<slot-name> <init-value-form>) |
              (<slot-name> {<slot-option> <option-value>}*)
with a :default-value <slot-option>.  Any objections?

    SLOT OPTIONS
    ...   
    :initable <key or nil> 
       if NIL then not initable

We did not discuss allowing NIL here.  I don't see any reason
for it; none of the other slot options allow NIL.  As with the
accessors the default should be that it's not initable unless
you say something to make it initable.

       Note that we we didn't resolve instance initialization protocol
       so the real meaning of this option was not determined.

True.

    DEFCLASS OPTIONS
    ....
    (:accessors-with-prefix symbol-or-string)
    (:readers-with-prefix symbol-or-string)

I think you mean :accessor-prefix and :reader-prefix, don't you?
Except for the names this agrees with my notes.

    REJECTED
      :initable-slots, (can be done using :initable slot-option only)

It doesn't say in my notes that this is rejected, only that giving it
with a list of slot names is rejected.  My notes also say that we
rejected the idea that the environment should have an editor command to
automatically put in the :initable slot-options.  So I'm not sure what
we decided about this.  I take it the problem is that you don't want to
build in the convention that keyword symbols (same as Common Lisp
defstruct) rather than slot names (same as Zetalisp defstruct) are used
to initialize the slots?

      :init-keywords (a declaration - not appropriate)

I don't know what you mean by "a declaration", but this will fall
out of resolving instance initialization.

The initialization protocol has to be worked out carefully in the
light of the method argument list congruence rules for &key arguments.
Or vice versa.

    SYNTAX for DEFMETHOD is

    (defmethod <generic-function-name> {name-qualifier}*
       <specialized-lambda-list> <decl-and-or-doc> form*)
    (defmethod-setf <generic-function-name> {name-qualifier}*
       <specialized-lambda-list> <specialized-setf-vars> ...) 

I don't like the term "name-qualifier"; the word "name" here is just a
noise word.  My notes just say "qualifier".  Plain "qualifier", with
"method qualifier" used when method context is not obvious, would be
better than "name-qualifier".

    SPECIALIZED LAMBDA LIST
    A specialized-lambda-list is a Common Lisp lambda-list where any
    REQUIRED argument may be replaced by (arg-name arg-specializer).

We need to be careful to be consistent with CLtL in the use of the
words "argument", "arg", and "parameter".

    INDIVIDUAL METHODS
    The form 'datum means that the argument must be bound to datum
    for the method to be applicable.  (This is the syntax for "individual
    methods") We recommend that the Common Lisp type system to be extended
    to allow 'X to mean the same as (SATISFIES (MEMBER arg '(X)).

I think we have to require that, not recommend it, otherwise parameter
specializers would not be a subset of type specifiers.

(SATISFIES (MEMBER arg '(X)) is not a valid CL type specifier;
you meant to say (MEMBER x).

My notes say we agreed that the funny Common Loops exception to the
normal argument-precedence-order for methods on individuals won't fly.

The method argument list congruence rules have to be stated very
precisely, especially the parts involving &key.  I guess I can
take another try at that later this week if no one else has.

    DEFGENERIC
    To make FOO undefined, one evals
	(SETF (SYMBOL-FUNCTION 'FOO) NIL).
No, you mean (FMAKUNBOUND 'FOO).  I don't think we discussed this enough.

If you make the generic function FOO f-unbound and then do a DEFMETHOD
or DEFGENERIC for FOO, you get a new generic-function object that
doesn't know about any of the methods for the old FOO.  Those methods
are gone (except in the PCL meta-object protocol class-direct-methods
would still know about those methods, so the data structure would be
inconsistent).  There could be other inconsistencies too.  In New
Flavors currently you get the same generic-function object back again,
to avoid inconsistencies similar to these.  Perhaps making f-unbound a
generic function should not be a defined operation in the standard?

    If a DEFGENERIC specifies a contract that is not congruent with the
    current contract, it signals an error.  

We didn't discuss this, if my notes are complete.  I assume you mean it
only signals an error if there are methods whose parameters are not
congruent with the new defgeneric's parameters.  That's okay; at this
point the program development environment comes into play, so we
shouldn't say any more.

My notes say "we need to write up clearly the about four ways thought up
so far to extend this to discriminating on optional/keyword arguments",
but don't say that any particular person took responsibility.

    (:argument-precedence-order <param-name>+)
       This is a permutation of the required args of gf-lambda-list.

RPG said JonL has a proposal for a better way to do this, but I don't
think any of us have seen it yet.  It should be written up and sent to
the mailing list.

    WITH-SLOTS
    (with-slots ({car-name}|(var-name (keyword arg)*)) form*)

Change <var-name> to <instance>, an expression that evaluates to an
instance.  No reason to limit the possible expressions to variables.
The expression is evaluated exactly once.  According to my notes we
agreed on that.

    We agreed to use SETF not SETQ in the specification to promote the style
    of using setf.

My notes don't say that.  They say we agreed after discussing this and
other similar topics that we weren't writing a prescriptive style manual
for Common Lisp.

I actually think it would be better to do the opposite; if SETQ works inside
of WITH-SLOTS it should be used in examples, otherwise people who half-understand
how it is implemented will think that SETQ doesn't work and only SETF can be used
to set the slot pseudovariables that WITH-SLOTS creates.

Other things in my notes:

We agreed that calling CHANGE-CLASS inside of a method or inside of a
WITH-SLOTS can cause semantic problems and also implementation problems.
Semantic problems if the methods or slots you're already working with
are no longer applicable.  Implementation problems if the slots move
around in the memory layout of the instance.  We left it that we need to
work over the mail on the detailed description of when CHANGE-CLASS is
and is not valid.

We will recommend but not require that compiling a file containing
defclass, defgeneric, and defmethod forms does not side-effect the
Lisp world in which the compiler is running.

We agreed that in the default type of method combination, if there
are :before, :after, or :around methods, but no primary method, that
signals an error instead of assuming a primary method that returns NIL.

According to my notes we agreed that defmethod puts in type declarations
for the specialized parameters.  I don't remember agreeing on that,
but why not.

We need better terminology for:
  "argument specifier" -- looks like we settled on "parameter specializer"
  "standard-type-class" or "primitive class" or "builtin class"

The proliferation of -setf functions (e.g. remove-method-setf) is getting
disturbing and maybe we need an explicit notion of the generic function
objects that do setfs.

I'm working on writing up the current state of the define-method-combination
syntax discussion, but I don't know if I'll finish that today.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Oct 86 21:16:24 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 OCT 86 18:15:22 PDT
Return-Path: <LGD@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 08 OCT 86
 18:15:03 PDT
Date: 08 Oct 86 18:14 PDT
From: Linda DeMichiel <LGD@SAIL.STANFORD.EDU>
Subject: new files on CLS,LSP on SAIL 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <861008-181522-6748@Xerox>


I have placed the following files out on CLS,LSP:

concepts.tex, concepts.dvi
functions.tex, functions.dvi
impact.tex, impact.dvi
glossary.tex, glossary.dvi
design.tex, design.dvi
template.tex
macros.tex
various .toc and .tc files

The concepts.* files contain the contents of the first half of
the spec that Danny, Gregor, Dick and I drafted.
The functions.* files contain the second half; they also include some
of the changes we agreed upon last weekend.  Template.tex is
an outline for an individual function page that can be spliced into
functions.tex.

Impact.tex is an empty template for the discussion of how our
specification affects existing Common Lisp functions and how it
may influence modification of Common Lisp.

Glossary.tex is an empty template for our glossary.

Design.tex is an empty template for a discussion of the design
rationale behind the specification.

Macros.tex is the macros file used by TEX.

The concepts, functions, impact, glossary, and design files
are currently set up to generate five chapters of a document
called the "Common Lisp Object System Specification."  As we
discussed, we will probably want to make separate documents
for the presentation of the design rationale and meta-object
protocol.  I have set the files up the current way primarily so
that they can be easy to work with for now and easy to shuffle
into or out of other documents later on.

The .toc and .tc files are used by TEX to generate individual
tables of contents.  If you are concerned about up-to-the-minute
accuracy of the table of contents pages of file foo, then you
should tex foo, copy foo.toc to foo.tc, and tex foo again;
if you don't care, just ignore these files.  The .idx and .fig
files can also be ignored.

Linda

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Oct 86 18:52:13 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 OCT 86 15:51:25 PDT
Date: 8 Oct 86 15:50 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Summary of Object Standard Discussions
In-reply-to: Bobrow.pa's message of 8 Oct 86 13:50 PDT
To: CommonLoopsCore↑.pa@Xerox.COM
From: Bobrow.pa@Xerox.COM, Gregor.pa@Xerox.COM
Message-ID: <861008-155125-6521@Xerox>

This is an impression of the basic structure of the agreements we
reached (and didn't) at the design review meetings in Oregon and Palo
Alto.  Please provide corrections.  The full details should appear in
the documents on Sail of course (and will be hashed out some more).
   

DEFSTRUCT and DEFCLASS

We agreed that DEFSTRUCT in CommonLisp was overloaded. It should be
replaced in Common Lisp by a DEFCLASS and DEFRECORD (name not agreed
on).
DEFCLASS defines classes of objects.  DEFRECORD defines
ways of using named accessors to fetch elements of lists, vectors, and
blocks of memory, and specialized ways of creating such items.

We agreed to recommend that DEFSTRUCT be eliminated from Common
Lisp and replaced with DEFCLASS and DEFRECORD  (most implementations
would continue to provide DEFSTRUCT for backwards compatibility).

---

DEFCLASS SYNTAX

(defclass <class-name> ({<super-name>}*)
   ({<slot-spec>}*)
   {(<option-name> {<option-argument>}*)}*)

<slot-spec> = <slot-name> | 
            (<slot-name> <init-value-form> 
              {<slot-option> <option-value>}*)

 
SLOT OPTIONS

slot-options include
:accessor <generic-fn-name>
:reader   <generic-fn-name>
   any number of readers and/or accessors can be specified
   Readers define no setf - 
  This contrasts with defining an error setf 
  Users can roll their own with defmethod-setf
   
:initable <key or nil> 
   if NIL then not initable
   Note that we we didn't resolve instance initialization protocol
   so the real meaning of this option was not determined.

:allocation  <one of :instance, :class, :dynamic, :none>

NOT AGREED (not discussed) Whether a slot can be specified with options
but no init-value-form

Declared :dynamic slots were discussed.  It was felt this was a
declaration of a time space tradeoff, and hence might not belong.

Undeclared :dynamic slots were discussed, and it was felt that making
the Common Lisp function GET be generic might provide a useful way of
getting and setting undeclared slots.  GET should also find declared
slots if they exist.  No agreement was reached on this.
 

DEFCLASS OPTIONS

(:metaclass class-name)
(:documentation doc-string)

(:accessors-with-prefix symbol-or-string)
(:readers-with-prefix symbol-or-string)

:accessors-with-prefix and :readers-with-prefix are independent of
slot-option specification.  Any number of any of these can be provided
-- a slot can
be given multiple accessors using this option.

Note that accessors are not generated by default.  One of the accessor
generating options (:accessors-with-prefix, :readers-with-prefix,
:accessor, :reader) must be specified for accessors to be generated.

(:constructor ...)
Like the constructor option in defstruct.  Precise behavior still to be
spec'd as part of specing initialization protocol

NOT AGREED
(:default-init-plist {<key> <value>}*)
  This is tied up with the initialization protocol.

REJECTED
  :initable-slots, (can be done using :initable slot-option only)
  :init-keywords (a declaration - not appropriate)

----
MAKE-INSTANCE

(make-instance <class> &rest keys-and-values)
(initialize <instance> &rest)

As mentioned above, we didn't specify the instance intialization
protcol.
A detailed proposal for when the default value forms are run, when the
:initable slots are done and what gets passed to initialize needs to be
sent
out.

---
SLOT-VALUE

We agreed to change the name of get-slot to slot-value.

----
DEFMETHOD

SYNTAX for DEFMETHOD is

(defmethod <generic-function-name> {name-qualifier}*
   <specialized-lambda-list> <decl-and-or-doc> form*)
(defmethod-setf <generic-function-name> {name-qualifier}*
   <specialized-lambda-list> <specialized-setf-vars> ...) 

name-qualifier is a non-null atom (or non-null symbol - NOT AGREED) used
in method-combination.  It is expected that most forms will have 0 or 1
of these name-qualifiers.

CLASSICAL SYNTAX
There will be no "classical method" syntax specified in the standard.

SPECIALIZED LAMBDA LIST
A specialized-lambda-list is a Common Lisp lambda-list where any
REQUIRED argument may be replaced by (arg-name arg-specializer).

An arg-specializer is intended to specify the type of the argument.
The generic function ensures that the method is only called if the
argument is of that type, or some subtype.

An arg-specializer is either a symbol or an expression 'datum.  The
symbol is interpreted as a class name.  We agreed to consider later
the extensions of arg-qualifiers to the entire CL type system (along
lines proposed by Moon in an earlier message).  

INDIVIDUAL METHODS
The form 'datum means that the argument must be bound to datum
for the method to be applicable.  (This is the syntax for "individual
methods") We recommend that the Common Lisp type system to be extended
to allow 'X to mean the same as (SATISFIES (MEMBER arg '(X)).

Individual type specifers are more specific than any other matching
type specifier for a datum.

METHOD ARGUMENT LIST CONGRUENCE
All methods of a generic function must have congruent argument lists.
Congruency is our word to imply that the system can tell whether a call
is syntactically correct.  The rules are:

1) Have the same number of required and optional arguments
2) Allow exactly the same keywords, or use &allow-other-keys
appropriately.
3) All have an &rest or not.


---
GENERIC FUNCTION Objects

There should be one object that is both funcallable and carries the
state that describes the generic function (e.g. the list of all the
method objects for this gf).  This object is side-effected by
generic-functions to add and remove methods, and its data and/or code
will change to reflect any operations.

---
DEFGENERIC

AGREED: 

- DEFGENERIC is NOT required before a method is defined on the
  generic function.

NOT AGREED:
 
- The name DEFGENERIC.


DEFGENERIC is intended to provide information about the contract of the
generic function, and can be evaluated any number of times.  It does not
affect existing methods on the generic function.  To make FOO undefined,
one evals
    (SETF (SYMBOL-FUNCTION 'FOO) NIL).
If a DEFGENERIC specifies a contract that is not congruent with the
current contract, it signals an error.  

A DEFMETHOD will create a generic function if one does not exist,
thus doing a DEFGENERIC with defaults. 

Syntax:
(defgeneric <gen-fn-name> <gen-fn-lambda-list> {<gf-option>}*)

(defgeneric-setf <gen-fn-name> <gen-fn-lambda-list>
   <setf-lambda-list> {<gf-option>}*)

The <gen-fn-lambda-list> is like an ordinary Common Lisp lambda-list
EXCEPT that 
1) optionals may not have default-forms or supplied-p
   and hence the symbol does not mean a default value
   of NIL.  Note that optionals in the methods can have
   default forms and supplied-p's.
2) key-args may not have default-forms or supplied-p
3) No aux variables

Note that the defgeneric passes to the methods exactly the arguments
it receives.  Thus the lambda list in the defgeneric is primarily for
specifying the "shape" of the generic function arguments with which
all the methods must be congruent.

&GENERIC-OPTIONAL

We discussed whether to allow this new keyword in the generic function
argument list.  It must appear before any other &key-words.  Arguemnts
appearing after it are required arguments for the methods.
&GENERIC-OPTIONAL allow specification of default-value forms to be
provided by the generic function before discriminating on the arguments.
No agreement was reached on this issue.  

GF-OPTIONS

(:documentation doc-string>)|string
(:argument-precedence-order <param-name>+)
   This is a permutation of the required args of gf-lambda-list.
(:generic-function-class class-name)
(:method-class class-name)

METHOD COMBINATION SPECIFICATION
We agreed that the method combination would be specified as a specific
option in the defgeneric, but the precise syntax of that option was not
decided.  

We discussed the general issue of the interaction of features specified
by options and the specification of the generic-function-class.  One
possibility is to make :generic-function-class argument be
(:generic-function-class class-name+) and interpret this as mixins with
GENERIC-FUNCTION class.  Specifically, method combination might be
specified as a mixin to the generic function class.


---
DYNAMIC CLASSES

Some support was evinced for a feature that would allow creation of
"dynamic classes", that is classes specified only by their supers.
Using
'(FOO FIE)  instead of a class-name would get or create a class defined
exactly by the mixins FOO and FIE.

No agreement was reached on this.

---
WITH-SLOTS
  We will have only one WITH-SLOTS form.

(with-slots ({car-name}|(var-name (keyword arg)*)) form*)

keywords are
:class class-name
:prefix string-or-symbol
:use-slot-value flag

Is it an error to have conflict of names?
Doing a SETF on var-name is not deemed to effect the meanings of the
slots.

We agreed to use SETF not SETQ in the specification to promote the style
of using setf.

---
INTERNAL MECHANISM OF WITH-SLOTS

We agreed to provide an interface to the code walker used by with-slots
so that people can define their own with-type macros (for encapsulation
or whatever).  A proposal for this needs to be sent out.

---
SETF on qualified variables.

We discussed whether the variables which were the specialized arguments
to the method should be considered as the "same bindings" which caused
the method lookup to call this method or a rebinding.

Less esoterically, the questions are:

Is is legal to setf the specialized arguments to a method.

If so, does this affect call-next-method.

AGREED:
  It is legal to setf the specialized arguments of a method.

  This does not affect call-next-method.


---

DEFINE-METHOD-COMBINATION

We agreed to continue working to simplify and learn how best to explain
declarative method combination.

Moon presented a simplification of define-method-combination which also
allows the implementation of call-next-method.  He will send that to the
entire list.

AGREED: The default type of method combination will allow  primary,
call-next-method and :before and :after methods.

NOT AGREED whether :around methods are in the default, and whether they
are provided for all method-combination types.  


 
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Oct 86 18:13:57 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 OCT 86 14:54:02 PDT
Date: 8 Oct 86 14:53 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: Method Combinations
In-reply-to: DUSSUD%Jenner@ti-csl.CSNET's message of 6 Oct 86 16:24:33
To: DUSSUD%Jenner%ti-csl.CSNet@CSNet-Relay.ARPA
cc: CommonLoopsCore↑.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <861008-145402-6443@Xerox>

    I noticed that the method combination declaration
    (:method-combination) is an option for DEFGENERIC and not for
    DEFCLASS.

    What's the rationale?

method-combination is a property of the generic function.  It must be
uniform for all methods for a particular selector.  It is independent of
the class of any arguments used for method specification.   



-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  7 Oct 86 22:22:01 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 07 OCT 86 18:38:42 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 07 OCT 86 18:37:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 128089; Tue
 7-Oct-86 21:35:55 EDT
Date: Tue, 7 Oct 86 21:35 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Computing the class precedence list
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <861007213525.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

As promised on Friday, this message contains the algorithm used to
compute the precedence list in New Flavors, stripped down to make it
easier to read by removing irrelevant features and arguments, and
adjusted so that it should run in any Common Lisp implementation.  I
tried the one case given at the end, which returns the right answer, but
I haven't exhaustively tested for possible errors in transcription from
the algorithm we actually use.  I seriously doubt that there are any
transcription errors, though.

Summary of the functions contained:

  DEFCLASS1 -- fake version of DEFCLASS for testing purposes
  MAP-COMPONENTS-DEPTH-FIRST -- iteration driving function (also
	used by other parts of our system).  The full reasons for
	having this might not be obvious in the stripped down version.
  MAKE-PRECEDENCE-ALIST -- convert local constraints to the
	partial order, expressed as an alist
  COMPOSE-FLAVOR-COMPONENTS -- convert partial order to total order
  EXPLAIN-COMPONENT-ORDERING-ERROR -- auxiliary function, not included
	here, that contains a lot of hair for explaining precise
	details of conflicting constraints


(DEFMACRO DEFCLASS1 (NAME SUPERCLASSES)
  `(SETF (GET ',NAME 'CLASS-COMPONENTS) ',(REVERSE (CONS NAME SUPERCLASSES))))

;;; Iteration driver
;;; This calls FUNCTION for each component of FLAVOR-NAME at least once.  The arguments
;;; to FUNCTION are the name of the component flavor, the depth of recursion, a list
;;; of the names of all flavors that must locally precede this one (-not- a transitive
;;; closure of the precedence relations!).
;;; If FUNCTION returns NIL, iteration terminates without looking at components to right.
;;; If FUNCTION returns DONT-RECURSE, do younger brothers but not sons.
;;; Undefined components do not cause an error unless FUNCTION does not like them.
;;; The values returned by MAP-COMPONENTS-DEPTH-FIRST are meaningless to the outside caller.
(DEFUN MAP-COMPONENTS-DEPTH-FIRST (FUNCTION FLAVOR-NAME
				   &OPTIONAL (DEPTH 0) (PRECEDENCE NIL) (TRAIL NIL))
  (LET ((CONTINUE (FUNCALL FUNCTION FLAVOR-NAME DEPTH PRECEDENCE))
	(COMPONENTS (GET FLAVOR-NAME 'CLASS-COMPONENTS)))
    (UNLESS (OR (MEMBER CONTINUE '(NIL DONT-RECURSE))
		(MEMBER FLAVOR-NAME TRAIL))	;Break infinite recursion
      (LET ((TRAIL (CONS FLAVOR-NAME TRAIL)))
	;; Use recursion to iterate backwards through list
	(BLOCK RECURSE
	  (LABELS ((ITERATE (COMPONENTS)
		     (WHEN COMPONENTS
		       (LET ((COMPONENT (CAR COMPONENTS)))
			 (UNLESS (EQ COMPONENT FLAVOR-NAME)
			   (ITERATE (CDR COMPONENTS))
			   (UNLESS (MAP-COMPONENTS-DEPTH-FIRST FUNCTION
							       COMPONENT
							       (1+ DEPTH)
							       (CDR COMPONENTS)
							       TRAIL)
			     (RETURN-FROM RECURSE)))))))
	    (ITERATE COMPONENTS)))))
    CONTINUE))

;;; Make alist from component flavor to the components that must be to its left
;;; due to local constraints.  This is -not- the transitive closure of
;;; FLAVOR-LOCAL-COMPONENT-PRECEDENCE, but only the union of it; it's necessary
;;; not to compute the transitive closure here in order for the error reporting
;;; to be able to find cyclic constraints.
(DEFUN MAKE-PRECEDENCE-ALIST (FLAVOR-NAME)
  (LET ((ALIST NIL))
    (MAP-COMPONENTS-DEPTH-FIRST #'(LAMBDA (FLAVOR-NAME DEPTH PRECEDENCE)
				    (DECLARE (IGNORE DEPTH))
				    ;; Construct the union of everything preceding this flavor
				    (LET ((ELEM (ASSOC FLAVOR-NAME ALIST)))
				      (IF ELEM
					  (SETF (CDR ELEM) (UNION (CDR ELEM) PRECEDENCE))
					  (PUSH (CONS FLAVOR-NAME PRECEDENCE) ALIST)))
				    T)
				FLAVOR-NAME)
    (NREVERSE ALIST)))

;;; Compute the FLAVOR-ALL-COMPONENTS list, in the appropriate order.
;;; Check for and explain circular dependencies.
;;; Missing required-flavors and undefined component flavors are detected elsewhere.
(DEFUN COMPOSE-FLAVOR-COMPONENTS (FLAVOR-NAME)
  ;; First combine all the local ordering constraints.
  (LET ((ALIST (MAKE-PRECEDENCE-ALIST FLAVOR-NAME))
	(COMPONENTS NIL) CHANGED SLOW)
    ;; Start with a null components list; the given flavor will always be the first
    ;; component, because it will be the first one encountered by MAP-COMPONENTS-DEPTH-FIRST.
    ;; If there are circular constraints such that the given flavor has to have something
    ;; to its left, this will be detected, because no other flavor is unconstrained.
    ;; Using the local ordering constraints, build an ordered list of components by
    ;; repeated depth-first tree walk until all components have been incorporated that can be.
    ;; The tree walk is done in such an order as to minimize the number of iterations
    ;; through this loop required to come up with the answer.
    ;; SLOW = NIL is an optimization to cut off probably unreachable branches of the tree.
    (LOOP
      (SETQ CHANGED NIL SLOW NIL)
      (MAP-COMPONENTS-DEPTH-FIRST
	#'(LAMBDA (FLAVOR-NAME DEPTH PRECEDENCE)
	    (DECLARE (IGNORE DEPTH PRECEDENCE))
	    (COND ((MEMBER FLAVOR-NAME COMPONENTS) T)	;Already a component, continue
		  ((NOT (ASSOC FLAVOR-NAME ALIST)) 'DONT-RECURSE)  ;Not really a component
		  ((EVERY #'(LAMBDA (PREDECESSOR) (MEMBER PREDECESSOR COMPONENTS))
			  (CDR (ASSOC FLAVOR-NAME ALIST)))
		   ;; This one can go in now, put it in and return T.
		   (PUSH FLAVOR-NAME COMPONENTS)
		   (SETQ CHANGED T))
		  ;; If above LOOP fails, return NIL since everything to right will fail too.
		  ;; But in SLOW mode, disable that optimization.
		  (T SLOW)))
	FLAVOR-NAME)
      (WHEN (NOT CHANGED)
	;; We seem to be done; make sure all components really got incorporated.
	(WHEN (= (LENGTH COMPONENTS) (LENGTH ALIST))
	  (RETURN))
	;; Some components didn't get incorporated.  Either there is an ordering
	;; conflict, or the speedup didn't work.  The speedup fails after recovery
	;; from a conflict, because the constraints are no longer transitive.  It
	;; also fails in the face of partial ordering among the components of a flavor.
	(IF SLOW
	    ;; Already slow: there must be an ordering conflict.
	    ;; Explain it nicely and recover by making an arbitrary choice.
	    (SETQ COMPONENTS (NRECONC (EXPLAIN-COMPONENT-ORDERING-ERROR FLAVOR-NAME ALIST
									COMPONENTS)
				      COMPONENTS))
	    ;; Try again without the speedup.
	    (SETQ SLOW T))))
    ;; Put list of components into normal order
    (NREVERSE COMPONENTS)))


;;;; Example

(DEFCLASS1 C1 ())
(DEFCLASS1 C2 ())
(DEFCLASS1 C3 ())
(DEFCLASS1 C4 (C1 C2))
(DEFCLASS1 C5 (C3 C2))
(DEFCLASS1 C6 (C4 C5))

(COMPOSE-FLAVOR-COMPONENTS 'C6)

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  7 Oct 86 19:27:39 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 07 OCT 86 13:38:37 PDT
Date: 7 Oct 86 13:32 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Anybody know how objects are represented in PCL?
In-reply-to: ingres.Berkeley.EDU!luis%soma.UUCP@rice.edu (Luis Miguel)'s
 message of Tue, 30 Sep 86 16:23:54 PDT
To: ingres.Berkeley.EDU!luis%soma.UUCP@rice.edu
cc: CommonLoops.PA@Xerox.COM
Message-ID: <861007-133837-5205@Xerox>

    Date: Tue, 30 Sep 86 16:23:54 PDT
    From: ingres.Berkeley.EDU!luis%soma.UUCP@rice.edu (Luis Miguel)

    Is there an "object table" of some kind? (like the class
    hash table).

I am not sure what you mean by object table, but if you mean: "is there
a table which has each object which was ever created in it?".  The
answer is no.

    What we want to do is to be able to "swap" objects in and out
    of the system as they are needed (to an object database), and need
to
    know what the appropriate conversions need to be.

I am also not sure what you are asking here.  I get the impression that
you are trying to build some sort of permanent objects system, and that
you need to be able to dump and restore objects.  What I don't know is
why you need to know the internal representation of the instances to do
this.  If you want to look at the internal representation, you can look
in the file called low, but you should keep in mind that this
representation changes from release to release and that it is likely to
change across ports of PCL as well.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  7 Oct 86 05:48:14 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 07 OCT 86 01:37:47 PDT
Return-Path: <sob%soma.UUCP@rice.edu>
Received: from dione.rice.edu ([128.42.1.1]) by Xerox.COM ; 07 OCT 86
 01:36:21 PDT
Received: by dione.rice.edu (AA00973); Tue, 7 Oct 86 03:28:18 CDT
Received: by soma.BCM.TMC.EDU (4.13/sob/Gateway/09-22-86)
 	id AA01558; Tue, 7 Oct 86 03:14:47 CDT
Received: by beno.CSS.GOV (5.54/5.17)
 	id AA00830; Tue, 30 Sep 86 22:11:07 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 30 SEP 86 16:53:49 PDT
Return-Path: <luis@ingres.Berkeley.EDU>
Received: from ingres.Berkeley.EDU ([128.32.156.105]) by Xerox.COM ; 30
  SEP 86 16:48:55 PDT
Received: by ingres.Berkeley.EDU (5.53/1.14)
  	id AA00872; Tue, 30 Sep 86 16:23:54 PDT
Date: Tue, 30 Sep 86 16:23:54 PDT
From: ingres.Berkeley.EDU!luis%soma.UUCP@rice.edu (Luis Miguel)
Message-Id: <8609302323.AA00872@ingres.Berkeley.EDU>
To: CommonLoops.PA@Xerox.COM
Subject: Anybody know how objects are represented in PCL?


	Is there an "object table" of some kind? (like the class
hash table). 
	
	What we want to do is to be able to "swap" objects in and out
of the system as they are needed (to an object database), and need to
know what the appropriate conversions need to be.

	Luis Miguel
	luis@ingres.Berkeley.EDU

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  7 Oct 86 05:48:03 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 07 OCT 86 01:29:52 PDT
Return-Path: <sob%soma.UUCP@rice.edu>
Received: from dione.rice.edu ([128.42.1.1]) by Xerox.COM ; 07 OCT 86
 01:26:10 PDT
Received: by dione.rice.edu (AA00874); Tue, 7 Oct 86 03:23:31 CDT
Received: by soma.BCM.TMC.EDU (4.13/sob/Gateway/09-22-86)
 	id AA01452; Tue, 7 Oct 86 03:13:24 CDT
Received: by seismo.CSS.GOV (5.54/1.14)
 	id AA07283; Fri, 26 Sep 86 19:44:05 EDT
Received: by beno.CSS.GOV (5.54/5.17)
 	id AA17460; Fri, 26 Sep 86 19:16:00 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 26 SEP 86 13:43:17 PDT
Date: Fri, 26 Sep 86 13:36 PDT
From: Xerox.COM!Gregor.pa%soma.UUCP@rice.edu
Subject: missing excl-low file
To: CommonLoops.PA@Xerox.COM
Message-Id: <860926133653.2.GREGOR@AVALON.XEROX-PARC>
Line-Fold: no


For some reason, the file excl-low.l was missing from the /pub/pcl
directory on parcvax.xerox.com.  That file now exists on that directory
so people who want to use PCL in Franz Common Lisp (ExCL) should have no
problems.

Gregor
-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  7 Oct 86 05:47:53 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 07 OCT 86 01:27:56 PDT
Return-Path: <sob%soma.UUCP@rice.edu>
Received: from dione.rice.edu ([128.42.1.1]) by Xerox.COM ; 07 OCT 86
 01:25:47 PDT
Received: by dione.rice.edu (AA00885); Tue, 7 Oct 86 03:23:53 CDT
Received: by soma.BCM.TMC.EDU (4.13/sob/Gateway/09-22-86)
 	id AA01488; Tue, 7 Oct 86 03:13:50 CDT
Received: by seismo.CSS.GOV (5.54/1.14)
 	id AA06834; Mon, 29 Sep 86 16:10:30 EDT
Received: by beno.CSS.GOV (5.54/5.17)
 	id AA10940; Mon, 29 Sep 86 16:10:10 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 29 SEP 86 11:25:38 PDT
Return-Path: <DALY@IBM.COM>
Received: from IBM.COM ([192.5.58.7]) by Xerox.COM ; 29 SEP 86 11:15:57
  PDT
Date: 29 September 1986, 13:08:34 EDT
From: "Timothy P. Daly" <ibm.com!DALY%soma.UUCP@rice.edu>
To: commonloops.pa@Xerox.COM
Message-Id: <092986.130835.daly@ibm.com>
Subject: getting connected

Please add my name to the list of people receiving the common loops
discussions:

DALY@IBM.COM

Thanks.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  7 Oct 86 00:54:31 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 06 OCT 86 21:27:00 PDT
Return-Path:
 <@MC.LCS.MIT.EDU:DUSSUD%Jenner%ti-csl.csnet@CSNET-RELAY.ARPA>
Redistributed: CommonLoopsCore↑.PA
Received: from MC.LCS.MIT.EDU by Xerox.COM ; 06 OCT 86 21:25:38 PDT
Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU  7 Oct 86 00:13:28 EDT
Received: from ti-csl by csnet-relay.csnet id ac01434; 6 Oct 86 18:51
 EDT
Received: from Jenner (jenner.ARPA) by tilde id AA01820; Mon, 6 Oct 86
 16:26:53 cdt
To:
 Common-Lisp-Classes-discussion%mc.lcs.mit.edu%csnet-relay.arpa@RELAY.CS.NET
Cc: 
Subject:        Method Combinations
Date: 6 Oct 86 16:24:33
From: DUSSUD%Jenner%ti-csl.CSNet@CSNet-Relay.ARPA
Message-Id:     <DUSSUD.2738006671@Jenner>

Dave,

I noticed that the method combination declaration (:method-combination)
is an option for DEFGENERIC and not for DEFCLASS.

What's the rationale?

Thanks,
Patrick.


∨
Received: from Xerox.COM by AI.AI.MIT.EDU  6 Oct 86 23:33:51 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 06 OCT 86 18:38:06 PDT
Return-Path: <Swenson.Multics@MIT-MULTICS.ARPA>
Received: from MIT-MULTICS.ARPA by Xerox.COM ; 06 OCT 86 18:32:11 PDT
Acknowledge-To:  "Eric J. Swenson" <Swenson@MIT-MULTICS.ARPA>
Date: Mon, 6 Oct 86 21:27 EDT
From: "Eric J. Swenson" <Swenson@MIT-MULTICS.ARPA>
Subject:  Change of Address
To: CommonLoops.PA@Xerox.COM
Message-ID:  <861007012741.131505@MIT-MULTICS.ARPA>

Would you please change my address from Swenson@multics.mit.edu to
ejs%acorn@live-oak.mit.edu?  Thank you.  (Sorry I sent this to this
address but mail to CommonLoops-Request failed.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  6 Oct 86 20:04:11 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 06 OCT 86 16:54:20 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 06 OCT 86 16:52:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 126666; Mon
 6-Oct-86 19:48:49 EDT
Date: Mon, 6 Oct 86 19:48 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Taking the politics out of Standardization
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <861006-144452-4065@Xerox>
Message-ID: <861006194832.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 6 Oct 86 14:44 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    The document will be stored on SAIL (sail.stanford.edu)
    on the area
       CLS,LST
       password: MIXIN

I think the actual directory is CLS,LSP (not LST).

Symbolics people: SU-AI:name.type[CLS,LSP].  name is six characters,
type is three.  When it asks you to log in type CLS,LSP including
the comma.  We don't parse SU-AI pathnames, so you need to type
the .type every time you type a pathname or it will disappear.  The
directory disappears, too, but that's okay because you are logged in
to it.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  6 Oct 86 18:27:05 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 06 OCT 86 14:44:52 PDT
Date: 6 Oct 86 14:44 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Taking the politics out of Standardization
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <861006-144452-4065@Xerox>

As we agreed on Friday, we will create a single document:

"       DRAFT

   A Proposed Specification
of a Common Lisp Object Standard"

   by (in alphabetical order)

D. Bobrow, L. DeMichiel, D. Gabriel, K. Kahn, S. Keene, G. Kiczales, L.
Masinter, D. Moon, D. Weinreb 

from (perhaps with footnote connections)
Lucid, Symbolics, Xerox

The document will be stored on SAIL (sail.stanford.edu)
on the area
   CLS,LST
   password: MIXIN
It will consist of merged and rewritten parts of both documents modified
to reflect our most recent technical decisions.    

The specification document will contain no history or explicit statement
of goals, but will provide a detailed technical description of the
current state of our understanding of the specification.  We hope to
have a version of this document available for the next ANSI X3J13
meeting, currently scheduled for December.  This implies having the
document ready for distribution to committee members in mid to late
November.

We would also like to have (at some time) a separate document describing
the rationale(s) for various decisions, and alternatives considered.


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 30 Sep 86 22:20:56 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 30 SEP 86 16:53:49 PDT
Return-Path: <luis@ingres.Berkeley.EDU>
Received: from ingres.Berkeley.EDU ([128.32.156.105]) by Xerox.COM ; 30
 SEP 86 16:48:55 PDT
Received: by ingres.Berkeley.EDU (5.53/1.14)
 	id AA00872; Tue, 30 Sep 86 16:23:54 PDT
Date: Tue, 30 Sep 86 16:23:54 PDT
From: luis@ingres.Berkeley.EDU (Luis Miguel)
Message-Id: <8609302323.AA00872@ingres.Berkeley.EDU>
To: CommonLoops.PA@Xerox.COM
Subject: Anybody know how objects are represented in PCL?


	Is there an "object table" of some kind? (like the class
hash table). 
	
	What we want to do is to be able to "swap" objects in and out
of the system as they are needed (to an object database), and need to
know what the appropriate conversions need to be.

	Luis Miguel
	luis@ingres.Berkeley.EDU

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 29 Sep 86 21:29:57 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 29 SEP 86 18:02:04 PDT
Date: 29 Sep 86 17:58:55 PDT (Monday)
From: Hostrop.PA@Xerox.COM
Subject: {eris}<Lispcore>...
To: Lispcore↑.pa@Xerox.COM, CommonLoopsCore↑.pa@Xerox.COM,
 AISTest↑.x@Xerox.COM
cc: , Hostrop.PA@Xerox.COM
Reply-To: Hostrop.PA@Xerox.COM
Message-ID: <860929-180204-1109@Xerox>


...has but 3664 pgs left - Those of you writing to this directory are
encouraged to pare out obsolete versions wherever it makes sense. Your
cooperation is greatly appreciated by all patrons of {eris}<Lispcore>.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 29 Sep 86 16:26:34 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 29 SEP 86 11:25:38 PDT
Return-Path: <DALY@IBM.COM>
Received: from IBM.COM ([192.5.58.7]) by Xerox.COM ; 29 SEP 86 11:15:57
 PDT
Date: 29 September 1986, 13:08:34 EDT
From: "Timothy P. Daly" <DALY@ibm.com>
To: commonloops.pa@Xerox.COM
Message-Id: <092986.130835.daly@ibm.com>
Subject: getting connected

Please add my name to the list of people receiving the common loops
discussions:

DALY@IBM.COM

Thanks.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Sep 86 19:31:41 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 26 SEP 86 13:43:17 PDT
Date: Fri, 26 Sep 86 13:36 PDT
From: Gregor.pa@Xerox.COM
Subject: missing excl-low file
To: CommonLoops.PA@Xerox.COM
Message-ID: <860926133653.2.GREGOR@AVALON.XEROX-PARC>
Line-fold: no


For some reason, the file excl-low.l was missing from the /pub/pcl
directory on parcvax.xerox.com.  That file now exists on that directory
so people who want to use PCL in Franz Common Lisp (ExCL) should have no
problems.

Gregor
-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Sep 86 16:27:01 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 26 SEP 86 12:39:22 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 26 SEP 86 12:38:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 115970; Fri
 26-Sep-86 15:27:09 EDT
Date: Fri, 26 Sep 86 15:27 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Class Precedence List
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860926-095028-5231@Xerox>
Message-ID: <860926152702.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 26 Sep 86 09:45 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

            The search I would be interested in is not the one
            where there are differences of order only, but ones in which a
            subclass has the classes in a different order than a super. 
            This could lead to strangeness for a user who tests an
            operation on a superclass, and finds then happening differently
            in a subclass.

        That is exactly what the New Flavors ordering rules, as
        compared with either breadth-first or depth-first search, are
        intended to avoid.  It might be that there are cases where they
        don't avoid this problem, but I'd have to see a specific example. 

    What are the class precedence list for the following
    classes (flavors)

    class    Supers     Components
    F1       B C        (F1 B C)
    F2       A C        (F2 A C)
    F3       A B        (F3 A B)
    F4       B A        (F4 B A)
          
    G        F1 F2      (G F1 B F2 A C)
    H        G F3       (H G F1 F2 F3 A B C)
    K        G F4       (K G F1 F2 F4 B A C)

    In particular, what are the lists for G, H and K.

I filled them into your message above, using a program of course.

I see; now I see what you meant by testing an operation on a
superclass and happening differently on a subclass.  G is the
superclass and H is the subclass.

    H and K must have A and B in opposite orders.  Both have G as a super.
    G doesn't care but must have some order.

That's right.  If the relative ordering of A and B matters, it
should have been declared explicitly, possibly using the
:component-order option (remember, that's one of the defflavor
options whose usefulness you couldn't see).  In fact in the very
many real cases where this happens that I enumerated the other
day, the relative ordering of A and B does not matter.  In this
particular specific example, the programmer who wrote F3 and F4
seems to have declared explicitly that the relative ordering of
A and B is immaterial.

The proposed extension from (I think) KMP that I mentioned the
other day is intended to provide automatic detection of whether
or not the relative ordering of A and B matters, instead of
making it the responsibility of the programmer to say whether
it matters.  My comments on that extension from the other day
still stand.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Sep 86 12:54:21 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 26 SEP 86 09:50:47 PDT
Redistributed: CommonLoopsCore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 26 SEP 86 09:50:28 PDT
Date: 26 Sep 86 09:45 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: Class Precedence List
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 25 Sep 86 14:58 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860926-095047-5234@Xerox>

        The search I would be interested in is not the one
        where there are differences of order only, but ones in which a
        subclass has the classes in a different order than a super. 
        This could lead to strangeness for a user who tests an
        operation on a superclass, and finds then happening differently
        in a subclass.

    That is exactly what the New Flavors ordering rules, as
    compared with either breadth-first or depth-first search, are
    intended to avoid.  It might be that there are cases where they
    don't avoid this problem, but I'd have to see a specific example. 

What are the class precedence list for the following
classes (flavors)

class	    Supers
F1       B C          
F2       A C          
F3       A B
F4       B A
          
G        F1 F2             
H        G F3
K        G F4         

In particular, what are the lists for G, H and K.

H and K must have A nd B in opposite orders.  Both have G as a super.
G doesn't care but must have some order.
 


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 25 Sep 86 18:08:24 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 25 SEP 86 12:53:27 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 25 SEP 86 12:52:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 114016; Thu
 25-Sep-86 14:58:46 EDT
Date: Thu, 25 Sep 86 14:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Class Precedence List
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860925-080001-4023@Xerox>
Message-ID: <860925145850.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 25 Sep 86 07:59 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    The search I would be interested in is not the one where there are
    differences of order only, but ones in which a subclass has the classes
    in a different order than a super.  This could lead to strangeness for a
    user who tests an operation on a superclass, and finds then happening
    differently in a subclass.

That is exactly what the New Flavors ordering rules, as compared with either
breadth-first or depth-first search, are intended to avoid.  It might be that
there are cases where they don't avoid this problem, but I'd have to see
a specific example.  The proposed extension, which I kind of like but have
neither implemented nor evaluated its effect on real programs, deals more
stringently with this issue by examining all pairs of component classes whose
order is unconstrained and determining whether exchanging them would alter
any inherited methods; if not, their order doesn't matter, because it doesn't
affect behavior.  If so, signal an error.  This extension would ensure that
no matter which of the possible total orderings consistent with the partial
ordering is chosen, the behavior is the same.

Even though I like this idea (due to KMP originally I believe) I can't
support putting it into a standard, since it hasn't been tried in the
real world.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 25 Sep 86 18:07:43 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 25 SEP 86 12:20:31 PDT
Date: 25 Sep 86 12:12 PDT
From: masinter.pa@Xerox.COM
Subject: Re: initial class lattice
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 23 Sep 86 16:48 EDT
To: commonloopscore↑.PA@Xerox.COM
Message-ID: <860925-122031-4341@Xerox>

Masinter:   The objective is to allow class-of to be fast even in
implementations...

Moon:

It might pay to examine this a little more closely.  To continue with
the example of a compiled-function that is also a vector, the time to do
get-slot of a vector doesn't matter, as long as it doesn't slow down the
time to do get-slot of other types of objects.  After all, vectors don't
have slots.  Are there examples of other operations that are performance
critical for primitive objects and depend on class-of?  I can't imagine
any.  So the question is really whether the implementor is smart enough
to implement class-of in such a way that the exception cases, where a
complicated test is required to determine the class, don't slow down the
normal case.  This seems a low enough level of issue that it shouldn't
be allowed to dictate the semantics of the language.

Masinter:

Your point is well taken. I agree now that the performance issue is not
critical.
However, the issue remains: which types in CLtL are intrinsic and which
are extrinsic? Clearly (satisfies evenp) is an extrinsic type -- it
depends on a view of the data rather than on the data itself. The
current type system is muddy enough that it allows some implementations
to treat compiled-function-p and hash-table-p and read-table-p as if
they were testing extrinsic properties rather than intrinsic ones, and
thus, the types would not correspond directly to classes.

I think this is one of those awful, picky issues that are irrelevant to
the whole proposal but that standards are made of. The tradeoff is
between power (they're classes, which means you can write discriminators
on them) and portability (some implementations might treat
compiled-function as a sublcass of vector, and others not) and the
constraint of not changing drastically the implementation requirements
of the system. Which would you rather give up? 

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 25 Sep 86 15:26:24 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 25 SEP 86 11:29:36 PDT
Date: 25 Sep 86 11:21 PDT
From: masinter.pa@Xerox.COM
Subject: Re: (change-class x y) => (setf (class-of x) y)?
In-reply-to: masinter.PA's message of 24-Sep-86 20:33:16 PDT
To: commonloopscore↑.PA@Xerox.COM
Message-ID: <860925-112936-4275@Xerox>

Let me give a less "off-the-cuff" reply:

For those objects whose class is mutable, the "class-of" the object is
as much of a "generalized variable" as many of the other Common Lisp
constructs which are changed using SETF. The general direction has been
to use SETF whenver possible as the principle way in which objects are
modified; few excepts were made in Common Lisp even where tradition
would have chosen different names. 

The notion that some objects have a mutable class may seem strange, but
it seems no more or less strange if the operation is called
"set-class-of" or "change-class" or "setf (class-of". 

In any case, the name "change-class" is awkward; there is no other
modify-operation in Common Lisp that is called "change", although
"set-class" or "set-class-of" might be reasonable.




∨
Received: from Xerox.COM by AI.AI.MIT.EDU 25 Sep 86 11:08:24 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 25 SEP 86 08:02:33 PDT
Date: 25 Sep 86 08:02 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: [Guy Steele <gls@Think.COM>: Syntax of defstruct  versus
 DEFCLASS]
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860925-080233-4027@Xerox>

I asked Guy his opinion about this issue.

Here is his response.


From: Guy Steele <gls@Think.COM>
Subject: Syntax of defstruct  versus DEFCLASS
To: Bobrow.pa
Cc: gls@AQUINAS.ARPA
In-Reply-To: <860921-160133-1351@Xerox>
Message-Id: <860922161225.1.GLS@DESCARTES.THINK.COM>

Danny,
  I haven't seen all of the discussion that led up to this,
of course.  Moon's technical criticism of DEFSTRUCT syntax
is well taken for the most part.  It has also bothered me
that the option syntax is not like other uses of keywords
in the language (namely keyword-value pairs), and that you
cannot have slot-options without specifying a value.

  If DEFCLASS is to solve some of the modularity problems
such as the distinction between implementation access and
client access, then it is sufficiently different that it is
appropriate to make a clean break and design a good syntax.
If the aim is to be a semantically minimal extension of
DEFSTRUCT, then it should also be a syntactically minimal
extension of DEFSTRUCT.  (How is that for waffling?  I have
no strong absolute feelings about the issue; I can only
express an opinion on how it should be done relative to a
set of goals.)

  As for :conc-name, I think that is really stupid.  Why not
let there simply be a default way of making names, and the
default can be overridden for each slot with a slot-option?

--Guy


 
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 25 Sep 86 11:07:49 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 25 SEP 86 08:00:01 PDT
Date: 25 Sep 86 07:59 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: Class Precedence List
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 22 Sep 86 16:36 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860925-080001-4023@Xerox>


The search I would be interested in is not the one where there are
differences of order only, but ones in which a subclass has the classes
in a different order than a super.  This could lead to strangeness for a
user who tests an operation on a superclass, and finds then happening
differently in a subclass.

However, the partial order is probably the best we can do.  I have not
yet seen your code.  Haven't asked Gregor.
-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 24 Sep 86 23:36:27 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 24 SEP 86 20:33:49 PDT
Redistributed: commonloopscore↑.PA@XEROX.ARPA
Received: from Cabernet.ms by ArpaGateway.ms ; 24 SEP 86 20:33:34 PDT
From: masinter.PA@Xerox.COM
Date: 24 Sep 86 20:33:16 PDT
Subject: Re: (change-class x y) => (setf (class-of x) y)?
In-reply-to: DLW@ALDERAAN.SCRC.Symbolics.COM's message of Wed, 24 Sep 86
 23:14 EDT, <860924231419.9.DLW@CHICOPEE.SCRC.Symbolics.COM>
To: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
cc: Kahn.pa@Xerox.COM, commonloopscore↑.PA@Xerox.COM
Message-ID: <860924-203349-3799@Xerox>

All other things being equal, fewer odd names are better. Are you
claiming you like "(change-class x y)" better than "(setf (class-of x)
y)"? If not, do you have a better proposal?

P.S. Consider that it never makes sense to do (PUSH X (SYMBOL-FUNCTION
Y)) either.

P.P.S. Consider that we do shrink adjustable arrays by DECFing their
FILL-POINTER.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 24 Sep 86 23:19:11 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 24 SEP 86 20:17:09 PDT
Return-Path: <DLW@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.PA@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 24 SEP 86 20:16:44 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 112892; Wed
 24-Sep-86 23:09:39 EDT
Date: Wed, 24 Sep 86 23:14 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: (change-class x y) => (setf (class-of x) y)?
To: Kahn.pa@Xerox.COM
cc: commonloopscore↑.PA@Xerox.COM
In-Reply-To: <860921-171550-1381@Xerox>
Message-ID: <860924231419.9.DLW@CHICOPEE.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 Sep 86 17:15 PDT
    From: Ken Kahn <Kahn.pa@Xerox.COM>

    I like Larry's suggestion for the same reasons that most people like
    SETF -- fewer names to deal with.

Minimizing the number of names does not mean that things are necessarily
clearer, simpler, and/or easier to understand.

SETF is a construct that deals with a concept that we usually call a
"generalized variable".  A generalized variable is, conceptually, a
place to put something.  Evaluating the generalized variable returns the
contents of the place.  Using SETF on the generalized variable stores
something into the place.  That's what SETF is basically about, and
that's how you'd explain SETF in a Lisp course.

Within this conceptual framework, (CLASS-OF ...) does not constitute
a "generalized variable".

In this case, you are attempting to minimize the number of names by
overloading one name with two different functions.  This does not make
things simpler or easier to learn.

P.S. Consider that it would never make sense to do (PUSH X (CLASS-OF Y)).

P.P.S.  Consider that we do not grow a vector by doing (SETF (LENGTH X) 10).

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 23 Sep 86 16:53:58 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 23 SEP 86 13:50:39 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.PA@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 23 SEP 86 13:50:24 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 111046; Tue
 23-Sep-86 16:48:02 EDT
Date: Tue, 23 Sep 86 16:48 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: initial class lattice
To: commonloopscore↑.PA@Xerox.COM
In-Reply-To: <860922-134803-1141@Xerox>
Message-ID: <860923164810.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 22 Sep 86 13:42 PDT
    From: masinter.pa@Xerox.COM

    The objective is to allow class-of to be fast even in implementations
    where some other predicates (e.g., compiled-function-p) are slow.  Any
    meta-operation needs to first get the class so that it can participate
    in discrimination, and meta-operations are performance critical; e.g.,
    there are a number of operations (e.g., get-slot) which are defined in
    terms of the meta-class rather than the class, and which might compile
    inline as a method-invocation on class-of. For that reason, the leaves
    of the initial class hierarchy should be restricted to be those items
    which are known to be immediately computable from the object and from
    its type tags.

It might pay to examine this a little more closely.  To continue with
the example of a compiled-function that is also a vector, the time to do
get-slot of a vector doesn't matter, as long as it doesn't slow down the
time to do get-slot of other types of objects.  After all, vectors don't
have slots.  Are there examples of other operations that are performance
critical for primitive objects and depend on class-of?  I can't imagine
any.  So the question is really whether the implementor is smart enough
to implement class-of in such a way that the exception cases, where a
complicated test is required to determine the class, don't slow down the
normal case.  This seems a low enough level of issue that it shouldn't
be allowed to dictate the semantics of the language.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 23 Sep 86 12:00:55 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 23 SEP 86 08:58:55 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 23 SEP 86 08:58:39 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110635; Tue
 23-Sep-86 11:53:08 EDT
Date: Tue, 23 Sep 86 11:53 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Name of RUN-SUPER
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860923115320.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

[This was sent last Saturday but apparently did not go through.
In resending it I changed the suggestion from NEXT-METHOD to
CALL-NEXT-METHOD.]

There is a problem with the name of RUN-SUPER.  With the introduction
of multimethods, it can no longer be said that RUN-SUPER runs the method
of the superclass.  It might use the next argument to choose a method,
and in fact get that method from a class much more specific than the class
from which the current method came.  Similarly, the introduction of around
methods mean that RUN-SUPER could be running a more specific method, if
the next method is a primary method rather than another around method.
In both cases, RUN-SUPER is running the next method, not necessarily a
method from a superior class.

For these reasons, I feel that a more appropriate name for this
primitive would be CALL-NEXT-METHOD.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 23 Sep 86 11:46:22 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 23 SEP 86 08:45:12 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 23 SEP 86 08:44:46 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110609; Tue
 23-Sep-86 11:41:09 EDT
Date: Tue, 23 Sep 86 11:41 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: class-of compiled objects
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860922-222708-1576@Xerox>
Message-ID: <860923114122.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 22 Sep 86 22:26:48 PDT
    From: MASINTER.pa@Xerox.COM

    In those implementations where compiled-function is a subtype of vector,
    the only alternative would be to allow (class-name (class-of (make-array
    ...))) to return 'compiled-function for some unspecified arguments to
    make-array, even if the results were not intended to be treated as a
    compiled function.

Sure, but why is that a problem?  Surely that object is indistinguishable
from a compiled-function in every other way, unless an intelligent algorithm
checked the machine instructions in it for plausibility as output from the
compiler, so why not make the class structure consistent with the rest of
the implementation in calling it a compiled-function?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 23 Sep 86 01:38:59 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 22:35:07 PDT
From: MASINTER.pa@Xerox.COM
Date: 22 Sep 86 22:34:47 PDT
Subject: generic function objects
To: commonloopscore↑.pa@Xerox.COM
Message-ID: <860922-223507-1578@Xerox>

(For  reference, the question is, is installing a generic function done
with

(setf (symbol-function 'foo) (make-generic-function ...))

or with

(setf (symbol-generic-function 'foo) ...)



I've been meditating on "class-named" and came up with "find-class"
instead, in keeping with "find-package". Another alternative would be
"symbol-class" but that is pretty hopeless, and the class isn't a
property of the symbol, the symbol is just a name for the class.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 23 Sep 86 01:31:38 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 22:27:08 PDT
From: MASINTER.pa@Xerox.COM
Date: 22 Sep 86 22:26:48 PDT
Subject: class-of compiled objects
To: (moon)
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860922-222708-1576@Xerox>

In those implementations where compiled-function is a subtype of vector,
the only alternative would be to allow (class-name (class-of (make-array
...))) to return 'compiled-function for some unspecified arguments to
make-array, even if the results were not intended to be treated as a
compiled function.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 21:17:06 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 18:04:16 PDT
Date: 22 Sep 86 17:58 PDT
From: masinter.pa@Xerox.COM
Subject: Re: default optional arguments to a generic function
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860922-180416-1453@Xerox>

I think the causes of differences here are twofold: first, whether the
default argument behavior of a function is part of its "external"
contract or something internal, and secondarily, whether language
constructs should be added to enforce contracts.

I do not believe that the argument limits (minimum, maximum, optional,
keyword) are part of the "external contract" of a function. That is,
from the point of view of the caller, there is no difference between a
&rest argument that explicitly checks if too many arguments are supplied
and a &optional argument. While there have been a number of proposals to
add such information to Common Lisp, they have foundered partly on the
objections that such information is not part of the external interface.

If argument behavior is not part of the "external" contract, then of
course methods can simply *differ* on the number of arguments supplied.
Of course, if you get to a method with too many or too few arguments,
you will get an error, just like if you call a function with the wrong
number of arguments.

While this might be "bad programming style" in some cases, it is
legitimate in others (Kahn's arguments about local vs global
consistency). 

Environment tools can help detect inconsistent use of arguments in a
method, just as they can help detect a disparity between the number of
arguments supplied and the number expected in static code.


Finally, I object to language constructs in Lisp whose primary function
is to enforce contracts between the caller and callee. While adding the
notion of functional interfaces to Lisp is an interesting research
topic, and matching the interface specification to the various
implementations of that interface a useful construct in modular
programming languages, it does not belong attached to the "object
oriented" part of the language.

Perhaps we want a construct:

(define-function-interface name argument-shape values-shape
documentation) 

which asserts that "name" will take arguments described by
argument-shape (which includes both extentional and intentional type
descriptions) and returns values described by values-shape, and has the
following documentation string, and then build some environment tools
that allow programs to be compiled in such a manner that any
disagreement between the function-interface and a defintion or use is
signalled by the compiler/checker. This would be an interesting
facility. It sort of looks like DEFGENERIC. But it doesn't belong here.

Larry

 


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 21:00:33 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 SEP 86 17:50:04 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 17:45:29 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110252; Mon
 22-Sep-86 20:37:50 EDT
Date: Mon, 22 Sep 86 20:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: default optional arguments to a generic function
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860921-180617-1396@Xerox>
Message-ID: <860922203704.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 Sep 86 18:06 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    The following principles seem to be ones we have agreed to with respect
    to generic functions and methods.

    1) Methods should be able to take any Common Lisp lambda-list.  In
    particular the default defmethod must be able to look like a defun.

    2) defgeneric should be optional, unless special options are used, such
    as :generic-function-class.

    3) The contract of the generic function should be true for all methods,
    and that contract should be computable from a defmethod form.

Agreed.

    This seems to lead to two competing proposals (Gregor says I am
    oversimplifying)

    Proposal a) The generic function specifies the full argument list, and
    all methods must have congruent argument lists.  This leads to the
    problem of defining congruence (Moon proposed some rules, but as
    Masinter pointed out, they had a problem with renaming of variables used
    in default value forms).  It also leads to redundancy in the methods --
    making it difficult to change a default value form in a single place.
    However, Gregor favors this scheme as later extendible by removing
    restrictions.  He would allow methods to take extra keywrod args if
    &allow-other-keys appears in the defgeneric.

    Proposal b) The generic function specifies only the required arguments,
    and methods discriminate only on those arguments.  However, methods can
    have arbitrary argument list beyond the required  arguments.  From any
    method, the generic contract can be computed.  All methods must have the
    same number of min-args.

I'm not sure these are the only possible proposals.  However, proposal
(a) certainly sounds less kludgy as described here.  Note that all of
the nonsense with default-value-form congruence is only necessary if use
of optional and keyword arguments for method selection is permitted.  At
this point it seems clear to me that there is no way our "sound basis"
goal will allow us to standardize on any form of that at this time,
since anything we come up with is going to be new and untried.  I favor
standardizing on a minimal design that does not preclude adding more
features as extensions later, when we understand their implications.
My understanding of the user community's desires is that they would
rather see a smaller standard that is published sooner, rather than a
hairier standard that takes longer to start benefiting them.

    This allows cases 1a) and 1b)

	Case 1a.  "draw-line"

	    draw-line takes an optional, the width of the line in
	    device dependent units.  Because they are device dependent
	    units, each individual method would like to default this
	    argument on its own.

	    (defmethod draw-line ((dev printer) p1 p2
				     &optional (width 7)) ...)

	    (defmethod draw-line ((dev window) p1 p2
				     &optional (width 1)) ...)

	    Case 1b.

	    Within case 1, some methods may want to take an extra
	    argument.  Also see case 3 which is similar.

	    (defmethod draw-line ((d gray-display) p1 p2
				     &optional (width 3) 
								(gray *gray1*))

	  ..)

	Date: Wed, 17 Sep 86 16:15 EDT
	From: David A. Moon 
	The problem here is that the generic function doesn't have a
	consistent contract.  The meaning, or even the existence, of one
	argument depends on the class of another argument.  I don't see how
	a caller of draw-line could operate without knowing the exact
	method that was going to be called. From experience I know it's
	possible to have all sorts of arguments about whether this is good
	or bad programming practice.  In New Flavors, these arguments were
	resolved in favor of consistency of contracts, rather than the
	increased flexibility of different contracts for different methods,
	but not everyone was happy. 

    I think it is possible to know that a method is coming from a particular
    part of the class lattice (without knowing the exact method) and  hence
    know the local contract.  Consistency of generic contract is only in the
    required argument set.

As I said, it's possible to have all kinds of arguments about this, and
everyone has their own idea of what they would like to see.  I don't
even disagree with what you just said.  However, the way we are going
around and around on this doesn't sound to me like something that is
ready for standardization.  We should tread carefully in this area.

    To take care of GFD#2, I propose that we allow the generic to specify
    optionals that it fills in.  The contract between the generic and the
    methods is to always supply these required method arguments.  I claim it
    should not be part of the contract between the generic and the method to
    provide that information.  

I can't figure out what the last two sentences, taken as a whole, are saying.

			       I propose a lambda list keyword option
    &generic-optional in the generic function.  Optional argument
    specifications after this provide only argument names and default value
    forms, but cannot have a supplied-p variable. 

    For example:
    (defgeneric draw (thing &generic-optional (place *draw-window*))
		"Draw thing on place.") 

    (defmethod draw ((thing line) (place raster-display)) ...)
    
    (defmethod draw ((thing line) (place vector-display)) ...)
 
    Methods must have required arguments where generic-optionals are
    provided.  Optionals in methods cannot be discriminated on.

This is fine as a proposal, but I don't think it belongs in a standard.
Next week, or next month, there might be a different idea that seems
better.

    Case 3 "move" is outlawed by this proposal, because the number of
    required arguments differ.

OK.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 19:31:27 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 SEP 86 15:32:37 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 15:31:30 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110144; Mon
 22-Sep-86 18:03:58 EDT
Date: Mon, 22 Sep 86 18:03 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: initial class lattice
To: commonloopscore↑.PA@Xerox.COM
In-Reply-To: <860922-134803-1141@Xerox>
Message-ID: <860922180312.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 22 Sep 86 13:42 PDT
    From: masinter.pa@Xerox.COM

    The objective is to allow class-of to be fast even in implementations
    where some other predicates (e.g., compiled-function-p) are slow....
    For that reason, the leaves
    of the initial class hierarchy should be restricted to be those items
    which are known to be immediately computable from the object and from
    its type tags.
    ....
    Another thing CLASS-OF is good for is a more principled approach to what
    type-of attempts and fails at. TYPE-OF is hopelessly underspecified,
    and, as such, is not useful in portable code.

    CLASS-OF, however, is reasonably well specified (once the bugs in the
    initial class lattice are worked out), and then an implementation 

    (defun type-of (x) (class-name (class-of x)))

    would be a reasonable way of "cleaning up" what is otherwise a mess.

So TYPE-OF a compiled function would be VECTOR.  Sorry, I can't agree
that this constitutes cleaning up the mess!  This is independent of the
other issues in your message and shouldn't be allowed to cast doubt
on them.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 18:00:07 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 14:44:21 PDT
Date: 22 Sep 86 14:30 PDT
From: masinter.pa@Xerox.COM
Subject: Re: Syntax of DEFCLASS
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Sun, 21 Sep 86 18:20 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
line-fold: no
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860922-144421-1211@Xerox>

Many of your arguments are historical ("The real problem with defstruct is that it was designed nine years ago...") I thought I would check the historical record. I've scanned the Common Lisp mail for the last 4 years and found only the following. The lack of any proposals to change defstruct, while there've been proposals galore to do lots of violence, leads me to believe that the syntax, while not the "best", is certainly adequate. And, now that there are thousands of users of Common Lisp and at least 8 textbooks and numerous courses and etc, I think we're best off living with it. I don't think a proposal to change it will fly. 
 
Date: 1 October 1982 04:06-EDT
From: Alan Bawden <ALAN at MIT-MC>
Subject:  DEFSTRUCT options syntax
To: Common-Lisp at SU-AI

From the last meeting:

  17. Can we standardize on keywords always being used as
      name-value pairs?  The worst current deviants are
      WITH-OPEN-FILE and DEFSTRUCT options.  

          Yes.  The Lisp Machine LISP group will make a
          proposal soon for OPEN, WITH-OPEN-FILE, and
          DEFSTRUCT.

While everyone agrees that OPEN and WITH-OPEN-FILE should be fixed (and they already have been fixed on the Lisp Machine), the case for DEFSTRUCT is not as clear.  In my opinion the change is gratuitous since the options list in a defstruct is NOT a function call.  Furthermore it is more than a non-trivial incompatible change since each option has to be re-thought in light of the fact that it can now be given only one argument rather than any number.  (Note that the :CONSTRUCTOR and :INCLUDE options take advantage of this multiple-argument ability.)

I asked Moon and DLW if they agreed with me on this subject.  Moon replied:

    Date: Thursday, 30 September 1982  00:44-EDT
    From: MOON at SCRC-TENEX
    To:   DLW at SCRC-TENEX
    cc:   Alan
    Re:   gratuitous change to defstruct syntax.

    I've changed my mind about this since August, and am now in agreement with
    Alan.  Partly this was caused by thinking about what it would mean to
    change DEFFLAVOR to use alternating keywords and values; it seems very
    clear that it would make it much worse.  Thinking about this more made me
    decide that some special forms have syntax that looks something like a
    function call, but many are totally unrelated to function calls and trying
    to wedge them into the same mold is just confused (and confusing).
    Certainly the way OPEN used to be was wrong, and fixing it was a big win.
    But I think DEFSTRUCT should stay with "option" or "(option args...)"
    syntax, as should DEFFLAVOR, DEFSYSTEM, DEFSITE, and who knows what else.
    It probably is not a coincidence that these are all "defining" forms.

DLW is also in agreement with me on this.  How about it folks, can we keep DEFSTRUCT parsing its options the way it is now?



02-Oct-82  0939	Guy.Steele at CMU-10A 	keyword pairs and DEFSTRUCT
Date:  2 October 1982 1240-EDT (Saturday)
From: Guy.Steele at CMU-10A
To: common-lisp at SU-AI
Subject: keyword pairs and DEFSTRUCT

I am in sympathy with leaving DEFSTRUCT as is.  Indeed, there may be something odd about DEF-forms.  OPEN was the biggest thorn, to my mind.


13-Oct-82  1309	STEELE at CMU-20C 	Ballot results  
Date: 13 Oct 1982 1608-EDT
From: STEELE at CMU-20C
Subject: Ballot results
To: common-lisp at SU-AI


...

27.  Shall DEFMACRO, DEFSTRUCT, and other defining forms also be allowed to take documentation strings as possible and appropriate?
	(y) yes   (n) no

Issue 27: *** Y *** Hedrick: Y	Wholey: Y	Fahlman: Y	Weinreb: Y	Killian: Y Zubkoff: Y	Moon: Y		van Roggen: Y	Masinter: Y	RMS: Y Dyer: Y		Bawden: Y	Feinberg: Y	Ginder: Y	Burke et al.: Y Brooks: Y	Gabriel: Y	DECLISP: Y	Steele: Y	Dill: X Scherlis: Y	Pitman: Y	Anderson: Y

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 17:59:52 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 SEP 86 14:06:06 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 13:56:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110053; Mon
 22-Sep-86 16:53:37 EDT
Date: Mon, 22 Sep 86 16:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Generic Function Objects
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860922-113354-189@Xerox>
Message-ID: <860922165254.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 22 Sep 86 11:27 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    It is my belief (actually, I am pretty sure Danny and Dick agree), that
    this reduces to the problem of fast funcall for compiled, indefinite
    extent lexical closure fast.  We assumed that most Common Lisps had
    tackled that problem, and could re-use the same technology.

Personally I think it's important for the wide acceptance of this standard
for it to avoid features that could cause unnecessary efficiency problems
on some implementations.  No matter how fast funcalling a closure is, it's
going to be a little slower than calling something that isn't a closure.
If every microsecond counts, this could be a problem.

As I said, Symbolics has no problem with this, but I think that before
putting something into the standard that might cause problems for some
implementations we should either get wider input so we can be sure that
it won't cause problems, or we should reexamine the benefits of putting
it into the standard to make sure the benefits outweigh the costs.

No one has ever answered my question of what are the benefits, unless I
missed the answer.  As far as I can tell, the sole benefit is that you
can say #'FOO instead of (GENERIC-FUNCTION-NAMED 'FOO).  Perhaps there
is something else that I am missing.  So far no one has ever answered
this question.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 17:59:41 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 SEP 86 14:02:42 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 13:39:46 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110024; Mon
 22-Sep-86 16:37:51 EDT
Date: Mon, 22 Sep 86 16:36 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Class Precedence List
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860922-101203-1764@Xerox>
Message-ID: <860922163653.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 22 Sep 86 10:11 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>, Ken Kahn
    ....Notice that the order of A and B are in opposite orders in precedence
    lists for G and H.  Is this freedom desirable?  

I don't see why not.  It seems to me that if there is no constraint on
the ordering of those classes, you are not doing the user a favor by
complaining that H is illegal when it doesn't violate any local ordering
constraints.  You're just harrassing the user.

I wrote a little program that searched the world on my machine for pairs
of flavors that don't always appear in the same order.  It found 1830
pairs.  I think this is some sort of evidence that this freedom is, in
fact, desirable.  I looked at a few pairs and they generally seem to be
flavors whose ordering doesn't matter because they have orthogonal
behavior (i.e. no methods in common).

						    If not, then our
    algorithm is good.  If so, then ???

I think this must be an example of the problem I suspected in my
previous message where your algorithm, by using a total ordering as a
standin for a partial ordering, generates spurious ordering constraints
which then get you into trouble.  What are the reasons for not using the
partial ordering instead?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 17:59:28 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 13:48:03 PDT
Date: 22 Sep 86 13:42 PDT
From: masinter.pa@Xerox.COM
Subject: Re: initial class lattice
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 22 Sep 86 12:00 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: commonloopscore↑.PA@Xerox.COM
Message-ID: <860922-134803-1141@Xerox>

The objective is to allow class-of to be fast even in implementations
where some other predicates (e.g., compiled-function-p) are slow.  Any
meta-operation needs to first get the class so that it can participate
in discrimination, and meta-operations are performance critical; e.g.,
there are a number of operations (e.g., get-slot) which are defined in
terms of the meta-class rather than the class, and which might compile
inline as a method-invocation on class-of. For that reason, the leaves
of the initial class hierarchy should be restricted to be those items
which are known to be immediately computable from the object and from
its type tags.

For newly defined classes, we can insure that class-of can be executed
quickly. However, for the built-in classes, we need to integrate over
the range of Lisp implementations so as not to invalidate what would
otherwise be a good implementation technique (read: hack). If
compiled-function is allowed to inherit from vector, then it must be
that for any vector, (class-of ...) needs to ask compiled-function-p,
which could be relatively expensive. It is much preferable to "leave it
out".... certainly it can be added in for those that keep it separate.
There were reasons before to not make requirements on the implementation
of compiled functions, and they remain.

It is unacceptable to define arbitrary subclass relationships, because
the type predicates would disagree with the class predicates. (vectorp
x) but (class-of x) isn't a subclass of vector.

The major problem with "type specifiers" which are not class in
discrimination is avoiding ambiguity and insuring portability. 

- - - - - - -

Another thing CLASS-OF is good for is a more principled approach to what
type-of attempts and fails at. TYPE-OF is hopelessly underspecified,
and, as such, is not useful in portable code.

CLASS-OF, however, is reasonably well specified (once the bugs in the
initial class lattice are worked out), and then an implementation 

(defun type-of (x) (class-name (class-of x)))

would be a reasonable way of "cleaning up" what is otherwise a mess.

CLASS-OF allows meta-class discrimination, e.g., (mapcar #'(lambda
(slot) (get-slot x slot) (class-slots (class-of x)))).

- - - - - - - -
We should be explicit about allowable extensions to the class lattice
(e.g., for all vectors, it is only required that class-of return a
subclass of class vector, and it is possible to add intermediate classes
as well).


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 15:06:18 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 11:33:54 PDT
Date: 22 Sep 86 11:27 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Generic Function Objects
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 22 Sep 86 13:56 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860922-113354-1892@Xerox>

It is my belief (actually, I am pretty sure Danny and Dick agree), that
this reduces to the problem of fast funcall for compiled, indefinite
extent lexical closure fast.  We assumed that most Common Lisps had
tackled that problem, and could re-use the same technology.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 15:06:12 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 11:31:13 PDT
Date: 22 Sep 86 11:19 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Class Precedence List
In-reply-to: Danny Bobrow <Bobrow.pa>, Kahn's message of 21 Sep 86 19:19
 PDT
To: Bobrow.pa@Xerox.COM, Kahn.pa@Xerox.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860922-113113-1887@Xerox>

One problem with this algorithm is that compute-class-precedence-list is
required to be a function of the local-supers tree.  It is specifically
not allowed to just snarf the CPL of a class that it comes across, but
rather must recompute it.  I have not yet figured out what the
implications are, in this particular case, of violating this rule. 

Another problem with this algortihm is that it doesn't, at least from
the explanation you give, seem any easier to explain than Moon's rules.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 14:33:13 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 22 SEP 86 11:00:26 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 10:59:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 109808; Mon
 22-Sep-86 13:58:00 EDT
Date: Mon, 22 Sep 86 13:56 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Generic Function Objects
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860921-153930-1345@Xerox>
Message-ID: <860922135659.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 Sep 86 15:39 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    In the existing CommonLoops papers and code, there is an object called
    the discriminator and piece of code called the discriminating function.
    The discriminating function was stored inside the discriminator, and
    when the discriminator was "named", was also stored in the
    symbol-function cell of the symbol which named the discriminator.  The
    discriminating-function was the thing you funcalled, the discriminator
    was the thing that you passed to add-method.

    A potentially better design combines the discriminator and the
    discriminating function into a single, closure-like, object called the
    generic function.  The generic function is funcallable; funcalling it
    causes method lookup to happen.  Accessors which used to work on the
    discriminator work directly on the generic function.  In particular,
    generic-function-methods returns a list of all the methods defined on a
    generic function. 

    Generic functions are mutable, and are side-effected by add-method and
    remove-method. An alternative proposal makes them immutable, add-method
    and remove-method return new generic-functions, see Masinter's message
    of 21-Sep-86 12:26:49 PDT.

    We spent a fair amount of time discussing the implementation
    implications of this.  We believe that this does not cause serious
    implementation problems.  At least the mutable case can even be
    implemented fairly efficiently in PCL.

    This new scheme has not yet been discussed on this list though.  This
    message is intended to spark that discussion.

Well, Dick brought this up on 29 August, and I discussed it on 3 Sep
(see Message-ID: <860903155437.5.MOON@EUPHRATES.SCRC.Symbolics.COM>),
and Dick replied with some vague answers ("I think we have a cleaner design than
what you suggest."), (see Message-ID: <860903-150632-1329@Xerox>),
but it seems to have been dropped after that.

I still believe what I said back then:
  The primary reason for keeping them separate is to gain the freedom
  to perform implementation-dependent optimizations of the time-critical
  operation of calling a generic function.  In our implementation we could
  rather easily make the function definition of the name of a generic
  function be an acceptable argument to the other operations on generic
  functions, as a synonym for the generic function meta-object itself,
  but I'm not sure if all implementations could do this, since Common Lisp
  defines very little of the characteristics of a compiled-function as an
  object.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 13:18:44 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 10:12:03 PDT
Date: 22 Sep 86 10:11 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: Class Precedence List
In-reply-to: Danny Bobrow <Bobrow.pa>, Kahn's message of 21 Sep 86 19:19
 PDT
To: Bobrow.pa@Xerox.COM, Kahn.pa@Xerox.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860922-101203-1764@Xerox>

    A recursive rule that computes class precedence lists locally.

    1) A class c1 cannot be given any super that has c1 in its
    class-precedence list.

    2) If c1 has one superclass c2, then the class precedence list
    of c1 is (cons c1 (c-p-l c2))

    3) If c1 has two superclasses, c2 and c3, then use (cons c1
      (merge-pls (c-p-l c2) (c-p-l c3))

    where (merge-pls first second) takes the prefix of first until
    it finds an element in common with second. If there is none, then
    use all of first.  Follow by the prefix of second up to the common
    element. If this has any element in common with the rest of first,
    signal an error.  Insert the common element.  Repeat until first is
    empty, then append the rest of second.

    4) If there are more than 2, then merge the pairs in an
    associative manner


    The claim is that this algorithm produces lists that obey all
    of Moon's rules, is local and one pass.


Some more thought has shown that although this is true, it gives an
error in cases where Moon's multipass algorithm is claimed to work.
Consider classes with supers

class	    Supers    Precedence Lists
F1       B C          F1 B C Object
F2       A C          F2 A C Object
F3       A B          F3 A B Object
G        F1 F2        G F1 B F2 A C Object
     (The legal Moon list computed by Moon's algortihm and ours)
H        G F3         Error!!! by our algorithm

But a legal Moon precedence list for H is

H G F1 F2 F3 A B C Object


Notice that the order of A and B are in opposite orders in precedence
lists for G and H.  Is this freedom desirable?  If not, then our
algorithm is good.  If so, then ???


-- danny and ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 13:18:19 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 SEP 86 09:51:36 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 09:40:08 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 109702; Mon
 22-Sep-86 12:38:18 EDT
Date: Mon, 22 Sep 86 12:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Class Precedence List
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860921-191928-1425@Xerox>
Message-ID: <860922123733.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 Sep 86 19:19 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>, Kahn.pa@Xerox.COM

    A recursive rule that computes class precedence lists locally.

    1) A class c1 cannot be given any super that has c1 in its
    class-precedence list.

    2) If c1 has one superclass c2, then the class precedence list of c1 is
    (cons c1 (c-p-l c2))

    3) If c1 has two superclasses, c2 and c3, then use
      (cons c1 (merge-pls (c-p-l c2) (c-p-l c3))

    where (merge-pls first second)
    takes the prefix of first until it finds an element in common with
    second.
    If there is none, then use all of first.  Follow by the prefix of second
    up to the common element. If this has any element in common with the
    rest of first, signal an error.  Insert the common element.  Repeat
    until first is empty, then append the rest of second.

    4) If there are more than 2, then merge the pairs in an associative
    manner

This requires that the class-precedence-list of every class be available
explicitly.  In our implementation we compute and store only the
precedence list of classes that are instantiated, or are going to be
instantiated.  For example, in the world I am running right now there
are 2668 classes, of which 1736 (65%) have class-precedence-lists and
932 (35%) don't.  Only 643 (24%) of the classes have actually been
instantiated, so an implementation that wasn't as concerned about
preparing things in advance of instantiation would have a higher cost
for precomputing the class-precedence-list of every class.  I checked a
world that was booted this morning, rather than a fortnight ago, and
hasn't been used for program development, and the percentages are not
significantly different.

    The claim is that this algorithm produces lists that obey all of Moon's
    rules, is local and one pass.

    "Proof"

    A class with no super obeys Moon's rules

    Proceed by induction.  

    Clearly (1) Each class precedes it own supers

    (2) Local ordering is preserved, since no ordering in the individual
    lists is changed by the merge. And the first element of each sublist
    (the local supers) have their order preserved.

    (3) Duplicate elimination always puts things as early as they can go.


    Several minutes thought has shown no problem with this.???

This algorithm might be okay, but I'm having trouble understanding your
description with enough precision to be sure what it does.  I can't be
sure that using the class-precedence-lists of the superclasses does the
same thing as looking directly at the constraints in each class, since
the class-precedence-list is a total ordering, and therefore contains
spurious orderings that are not implied by the partial ordering that the
programmer specified.

If you translate your algorithm to Lisp code and send it to me, I'll be
happy to check it against my algorithm, by eye and by running a thousand
test cases that I happen to have lying around.  (Unfortunately I don't
have a comprehensive set of test cases that are supposed to signal errors,
but I'll try two or three).

You have the Lisp code for my algorithm, don't you?  I think I sent it
to Gregor a long time ago.  We are making all of the New Flavors source
code publically available, subject only to the requirement that people
who copy it don't remove our copyright, so if you don't have the code
let me know and I'll send it to you.  I can send you just the class
precedence functions through the mail, or with more delay I could send
everything on some medium (maybe I have to have a signed agreement not
to yank off the copyright before I can send everything).

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 12:16:26 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 SEP 86 09:08:43 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 09:04:06 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 109670; Mon
 22-Sep-86 12:01:47 EDT
Date: Mon, 22 Sep 86 12:00 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: initial class lattice
To: commonloopscore↑.PA@Xerox.COM
In-Reply-To: <860921-222430-1479@Xerox>
Message-ID: <860922120053.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 Sep 86 22:24:10 PDT
    From: MASINTER.PA@Xerox.COM

    I had some questions about the initial class lattice for Common Lisp
    types.

I've been thinking about this also, but wasn't quite ready to mail out
my complete list yet.  I'll give some comments now, though.  In most
cases I agree with you.

    First, since Common Lisp doesn't require "compiled-function" or
    "function" to be first-class, they can't be classes in the initial
    hierarchy. (Recall that a compiled function is allowed to be a vector,
    for example.)

COMPILED-FUNCTION is allowed to inherit from VECTOR [does it say this in
CLtL someplace?], but it's still meaningful to ask "is this object a
compiled-function", so it should be meaningful to define a method that
applies if one of its arguments is a compiled-function.  On the other
hand, the definition of the FUNCTION type (CLtL p.32) is so vague that
even though there is a FUNCTIONP function, I hesitate to say that it
should be meaningful to define a method that applies if one of its
arguments is a function.  So I agree with you about FUNCTION, but
disagree on COMPILED-FUNCTION.

It is an interesting point that, although we can identify some classes
for the built-in Common Lisp types, we can't identify all the subclass
relationships among these classes, which in fact are implementation-dependent.
One could say that there are standardized subclass relationships, which
are different from the implementation-dependent subtype relationships,
but I think that approach would be confusing and cause problems.  I think
it's better for the subclass relationships to reflect reality, even when
that makes them implementation-dependent.  My intuition is that this will
not introduce any new portability problems that were not already present.

Alternatively, these built-in types could be allowed as specifiers in
methods, but not be considered classes.  After all, they already do not
participate in the full class protocol.  Built-in types are not acceptable
to MAKE-INSTANCE and are not acceptable as superclasses in DEFCLASS.
That way, there wouldn't be any issue of possible inconsistency between
SUBTYPEP and sub-class relationships.  On the other hand, this could just
be ducking the issue, since one still must ask what methods are inherited
by a given object.

Perhaps what it comes down to is: what is the CLASS-OF function good for?

Any thoughts on this?

    Second, while "standard-char" is well defined, I don't think it should
    be a class; I imagine it would otherwise be difficult to make (class-of
    #\a) return something other than (class-of #\page). 

I agree with you that STANDARD-CHAR shouldn't be a class, i.e. shouldn't
be something that can have methods defined.  My reason would be that it
is too specific, that is, it doesn't seem useful to have a different
method for STANDARD-CHAR than for CHARACTER for any generic function I
can think of.  Thus I wouldn't allow STANDARD-CHAR until I was allowing
all of the other Common Lisp type-specifiers that are really
predications rather than classes.  On the other hand, it would only take
one example of a generic function that had different methods for
STANDARD-CHAR and CHARACTER to change my mind on this one.

I don't see why there would be any special implementation problems in
CLASS-OF, though.

    Third, I don't think that bit, fixnum and bignum should be defined to be
    part of the required class lattice, because they correspond conceptually
    to "range" types.

I agree with you here.  BIT is in the same category as STANDARD-CHAR.
KEYWORD and STRING-CHAR are also in this category.

FIXNUM and BIGNUM are implementation characteristics of integers; they
don't change the behavior (given a definition of behavior abstract enough
to rule out performance differences).  Thus I don't think it makes sense
for methods to make a distinction between FIXNUM and BIGNUM.  This is
different from my reason for excluding BIT.

    Finally, for those items that have multiple superclasses, we need to
    either define an order or else remove one of the superclasses.

I agree.

    I like having "list" as a class, but the precidence for NIL needs to be
    defined. I'd say that NIL was a symbol first and a list second, on the
    basis that "list" is an abstraction but "symbol" is quite concrete, and,
    at least when I write 'em, I tend to put the concrete classes before the
    abstract ones.

That was my reasoning also.  Converting a partial ordering to a total
ordering for the sake of brevity, I would rank classes in order from
most specific to most general:
  RATIONAL FLOAT NUMBER SYMBOL LIST VECTOR ARRAY SEQUENCE
These are all the built-in classes that definitely have subclasses.

    As for simple-vector, simple-bit-vector, simple-string, my inclination
    is that "simple" isn't a particularly interesting dimension to
    discriminate on; removing "simple-array" would do most of the cleanup,
    and saying that a "vector" is first an array and secondly a sequence
    would finish it off. 

I think this is similar to the fixnum/bignum situation.  Simpleness of an
array is an implementation characteristic, not a behavior characteristic.
I agree with both of your points here (don't have classes for simple-xxx;
array is more specific than sequence).

    On further examination, there are no requirements that stream,
    hash-table, readtable, package, pathname or random-state be distinct
    from other types (p 33), and my belief is that these cannot then be
    required to be "first class" classes, in that (class-of (make-hash-table
    ...)) might return the same as (class-of (make-array ...)) for suitable
    arguments.

    Perhaps this can be stated in the subjunctive, e.g. "if these are
    distinct types in your Common Lisp implementation, they'll probably be
    distinct classes in any implementation of this spec".

The language in CLtL pp.33-5 wasn't written with the concept of
inheritance in mind, it seems.  However, there are predicates defined to
test for all of these types, and they are required to be distinct from
each other (third bullet on p.35), so I don't think an implementation
could have them totally indistinguishable from other types.  I.e.
(class-of (make-hash-table ...))  might return the same as (class-of
(make-array ...)) for suitable arguments, but not for -all- arguments.
Given this, it just means that (SUBTYPEP 'HASH-TABLE 'ARRAY) is
implementation-dependent, which doesn't seem fatal to the idea of
HASH-TABLE being a class.  My thinking was to allow methods to
discriminate on all of the types you mentioned, except STREAM.  I
exclude STREAM for the same reason as FUNCTION; its definition is too
vague (but see below).

My reasons for excluding other built-in types listed in CLtL Table 4-1:
    ATOM		this is (NOT CONS), and we're not doing NOT yet
			[see McAllester and Zabih Boolean Classes paper
			at OOPSLA for some thoughts on why NOT is hard].
    COMMON		specification is too vague
    NIL			no object can be an instance of this type

Another way of looking at these choices is that if there is a MAKE-xxx
function, or something equivalent, I have included the type, but if there
isn't, I have excluded it.  Since there aren't separate functions for
making BITs, FIXNUMs, and BIGNUMs, they're excluded.  FUNCTION is excluded
because there is no function to make functions, but COMPILED-FUNCTION
is included because COMPILE exists.  STREAM is excluded because there
isn't one function to make streams, and in fact many different types
of objects can be streams.  This line of reasoning isn't watertight,
but it's a pretty good heuristic.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 11:32:22 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 SEP 86 08:19:44 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 22 SEP 86 08:19:13 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 109619; Mon
 22-Sep-86 11:17:24 EDT
Date: Mon, 22 Sep 86 11:16 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: another name for "run-super"
To: MASINTER.PA@Xerox.COM
cc: commonloopscore↑.PA@Xerox.COM
In-Reply-To: <860922-012236-1523@Xerox>
Message-ID: <860922111626.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 22 Sep 86 1:22:20 PDT
    From: MASINTER.PA@Xerox.COM

    call-next-method. (Or, if you want, apply-next-method). 

Call-next-method is a better suggestion than mine: next-method.
If we were to add an extension to allow different arguments to be
substituted when calling the next method, both call-next-method
and apply-next-method would be necessary (one is like funcall,
the other is like apply), so I think these are good names.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 04:26:18 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 SEP 86 01:22:36 PDT
From: MASINTER.PA@Xerox.COM
Date: 22 Sep 86 1:22:20 PDT
Subject: another name for "run-super"
To: commonloopscore↑.PA@Xerox.COM
Message-ID: <860922-012236-1523@Xerox>

names matter, I guess.

There's no "run" in Common Lisp, and no "super" in CommonLoops. How about

call-next-method. (Or, if you want, apply-next-method). 


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 22 Sep 86 01:37:06 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 22:24:30 PDT
From: MASINTER.PA@Xerox.COM
Date: 21 Sep 86 22:24:10 PDT
Subject: initial class lattice
To: commonloopscore↑.PA@Xerox.COM
Message-ID: <860921-222430-1479@Xerox>

I had some questions about the initial class lattice for Common Lisp
types.

First, since Common Lisp doesn't require "compiled-function" or
"function" to be first-class, they can't be classes in the initial
hierarchy. (Recall that a compiled function is allowed to be a vector,
for example.)

Second, while "standard-char" is well defined, I don't think it should
be a class; I imagine it would otherwise be difficult to make (class-of
#\a) return something other than (class-of #\page). 

Third, I don't think that bit, fixnum and bignum should be defined to be
part of the required class lattice, because they correspond conceptually
to "range" types.

Finally, for those items that have multiple superclasses, we need to
either defince an order or else remove one of the superclasses.

I like having "list" as a class, but the precidence for NIL needs to be
defined. I'd say that NIL was a symbol first and a list second, on the
basis that "list" is an abstraction but "symbol" is quite concrete, and,
at least when I write 'em, I tend to put the concrete classes before the
abstract ones.

As for simple-vector, simple-bit-vector, simple-string, my inclination
is that "simple" isn't a particularly interesting dimension to
discriminate on; removing "simple-array" would do most of the cleanup,
and saying that a "vector" is first an array and secondly a sequence
would finish it off. 

(I'm typing this at a stupid dial-in mailer which doesn't allow me to
edit, so I'll add as an afterthought):

On further examination, there are no requirements that stream,
hash-table, readtable, package, pathname or random-state be distinct
from other types (p 33), and my belief is that these cannot then be
required to be "first class" classes, in that (class-of (make-hash-table
...)) might return the same as (class-of (make-array ...)) for suitable
arguments.

Perhaps this can be stated in the subjunctive, e.g. "if these are
distinct types in your Common Lisp implementation, they'll probably be
distinct classes in any implementation of this spec".

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 22:28:44 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 19:19:28 PDT
Date: 21 Sep 86 19:19 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Class Precedence List
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>, Kahn.pa@Xerox.COM
Message-ID: <860921-191928-1425@Xerox>

A recursive rule that computes class precedence lists locally.

1) A class c1 cannot be given any super that has c1 in its
class-precedence list.

2) If c1 has one superclass c2, then the class precedence list of c1 is
(cons c1 (c-p-l c2))

3) If c1 has two superclasses, c2 and c3, then use
  (cons c1 (merge-pls (c-p-l c2) (c-p-l c3))

where (merge-pls first second)
takes the prefix of first until it finds an element in common with
second.
If there is none, then use all of first.  Follow by the prefix of second
up to the common element. If this has any element in common with the
rest of first, signal an error.  Insert the common element.  Repeat
until first is empty, then append the rest of second.

4) If there are more than 2, then merge the pairs in an associative
manner




The claim is that this algorithm produces lists that obey all of Moon's
rules, is local and one pass.

"Proof"

A class with no super obeys Moon's rules

Proceed by induction.  

Clearly (1) Each class precedes it own supers

(2) Local ordering is preserved, since no ordering in the individual
lists is changed by the merge. And the first element of each sublist
(the local supers) have their order preserved.

(3) Duplicate elimination always puts things as early as they can go.


Several minutes thought has shown no problem with this.???

danny and ken   


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 21:15:45 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 18:06:17 PDT
Date: 21 Sep 86 18:06 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: default optional arguments to a generic function
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860921-180617-1396@Xerox>

The following principles seem to be ones we have agreed to with respect
to generic functions and methods.

1) Methods should be able to take any Common Lisp lambda-list.  In
particular the default defmethod must be able to look like a defun.

2) defgeneric should be optional, unless special options are used, such
as :generic-function-class.

3) The contract of the generic function should be true for all methods,
and that contract should be computable from a defmethod form.

This seems to lead to two competing proposals (Gregor says I am
oversimplifying)

Proposal a) The generic function specifies the full argument list, and
all methods must have congruent argument lists.  This leads to the
problem of defining congruence (Moon proposed some rules, but as
Masinter pointed out, they had a problem with renaming of variables used
in default value forms).  It also leads to redundancy in the methods --
making it difficult to change a default value form in a single place.
However, Gregor favors this scheme as later extendible by removing
restrictions.  He would allow methods to take extra keywrod args if
&allow-other-keys appears in the defgeneric.

Proposal b) The generic function specifies only the required arguments,
and methods discriminate only on those arguments.  However, methods can
have arbitrary argument list beyond the required  arguments.  From any
method, the generic contract can be computed.  All methods must have the
same number of min-args.

This allows cases 1a) and 1b)

    Case 1a.  "draw-line"

        draw-line takes an optional, the width of the line in
        device dependent units.  Because they are device dependent
        units, each individual method would like to default this
        argument on its own.

        (defmethod draw-line ((dev printer) p1 p2
                                 &optional (width 7)) ...)

        (defmethod draw-line ((dev window) p1 p2
                                 &optional (width 1)) ...)

        Case 1b.

        Within case 1, some methods may want to take an extra
        argument.  Also see case 3 which is similar.

        (defmethod draw-line ((d gray-display) p1 p2
                                 &optional (width 3) 
  						            (gray *gray1*))

      ..)

    Date: Wed, 17 Sep 86 16:15 EDT
    From: David A. Moon 
    The problem here is that the generic function doesn't have a
    consistent contract.  The meaning, or even the existence, of one
    argument depends on the class of another argument.  I don't see how
    a caller of draw-line could operate without knowing the exact
    method that was going to be called. From experience I know it's
    possible to have all sorts of arguments about whether this is good
    or bad programming practice.  In New Flavors, these arguments were
    resolved in favor of consistency of contracts, rather than the
    increased flexibility of different contracts for different methods,
    but not everyone was happy. 


I think it is possible to know that a method is coming from a particular
part of the class lattice (without knowing the exact method) and  hence
know the local contract.  Consistency of generic contract is only in the
required argument set.

To take care of GFD#2, I propose that we allow the generic to specify
optionals that it fills in.  The contract between the generic and the
methods is to always supply these required method arguments.  I claim it
should not be part of the contract between the generic and the method to
provide that information.  I propose a lambda list keyword option
&generic-optional in the generic function.  Optional argument
specifications after this provide only argument names and default value
forms, but cannot have a supplied-p variable. 

For example:
(defgeneric draw (thing &generic-optional (place *draw-window*))
            "Draw thing on place.") 

(defmethod draw ((thing line) (place raster-display)) ...)
    
(defmethod draw ((thing line) (place vector-display)) ...)
 
Methods must have required arguments where generic-optionals are
provided.  Optionals in methods cannot be discriminated on.

Case 3 "move" is outlawed by this proposal, because the number of
required arguments differ.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 20:28:19 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 17:23:57 PDT
Date: 21 Sep 86 17:23 PDT
Sender: Kahn.pa@Xerox.COM
Subject: Re: default optional arguments to a generic function
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 17 Sep 86 16:15 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860921-172357-1384@Xerox>


    (defun draw (thing &optional (place *draw-window*
    place-supplied-p))
      "Draw thing on place."
      (draw-internal thing place place-supplied-p))
        
    (defmethod draw-internal ((thing line) (place raster-display)
    place-supplied-p) ...)
        
    (defmethod draw-internal ((thing line) (place vector-display)
    place-supplied-p) ...)
    
    Flavors provides the feature that you don't have to make
    up the auxiliary name draw-internal, which is confusing because
    the externally visible interface is named draw but you put methods
    on draw-internal.  You do this by (translating out of the present
    Flavors syntax, which is too biased against multimethods):
    
    (defgeneric draw (thing &optional (place *draw-window*
    place-supplied-p))
      "Draw thing on place."
      (:method-arguments thing place place-supplied-p)
      (:function
        (funcall (generic draw) thing place place-supplied-p)))
        
    (defmethod draw ((thing line) (place raster-display)
    place-supplied-p) ...)
        
    (defmethod draw ((thing line) (place vector-display)
    place-supplied-p) ...)

I liked your proposal until I started to imagine myself writing DRAW
methods and having to keep in my head that someone can call DRAW with 1
or 2 arguments but my methods have 3 required arguments.  I find this
less confusing than the alternative of using DRAW-INTERNAL where "the
externally visible interface is named draw but you put methods on
draw-internal".



----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 20:20:16 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 17:15:50 PDT
Date: 21 Sep 86 17:15 PDT
Sender: Kahn.pa@Xerox.COM
Subject: Re: (change-class x y) => (setf (class-of x) y)?
In-reply-to: Danny Bobrow <Bobrow.pa>'s message of 21 Sep 86 16:03 PDT
To: Bobrow.pa@Xerox.COM
cc: MASINTER.PA@Xerox.COM, commonloopscore↑.PA@Xerox.COM,
 nuyens.PA@Xerox.COM, sybalsky.PA@Xerox.COM, pavel.PA@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860921-171550-1381@Xerox>

I like Larry's suggestion for the same reasons that most people like
SETF -- fewer names to deal with.

    change-class is a sufficiently serious operation that having a
    separate name is important.  It does significantly more than simply
    set a field, so (setf (class-of x) y) would be misleading to a
    user.

Its true that the implementation would do "significantly more than
simply set a field" but I fail to see why that misleads the user.
Consider in Common Lisp (SETF (MACRO-FUNCTION ...) ...) which in some
implementations causes a macro expansion cache to become invalidated
causing some hash tables to be cleared.  How is the user "mislead" here?
Do you mean that in the two cases the user is likely to have a mistaken
performance model by using SETF?   But (SETF (GET-SLOT ...) ..)
may cause arbitrary computation too.

----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 19:42:08 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 16:34:16 PDT
Date: 21 Sep 86 16:34 PDT
Sender: Kahn.pa@Xerox.COM
Subject: Re: Short Names   
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 20 Sep 86
 10:36 PDT
To: RPG@SAIL.STANFORD.EDU
cc: commonloopscore↑.pa@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860921-163416-1364@Xerox>

    In Common Lisp we decided to not use up many of the `good' names
    or characters so that users could have them. Exceptions are
    time-honored Lisp names, such as LET and CONS.


Skimming the index of the Silver book reveals the following short names
which to my knowledge were not "time-honored Lisp names":

bit, block, byte, close, character, complex, count, describe, elt,
every, export, find, import, keyword, loop, merge, ...

----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 19:11:37 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 16:05:03 PDT
Date: 21 Sep 86 16:03 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: (change-class x y) => (setf (class-of x) y)?
In-reply-to: MASINTER.PA's message of 21-Sep-86 15:34:29 PDT
To: MASINTER.PA@Xerox.COM
cc: commonloopscore↑.PA@Xerox.COM, nuyens.PA@Xerox.COM,
 sybalsky.PA@Xerox.COM, pavel.PA@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860921-160503-1357@Xerox>

    (change-class x y) => (setf (class-of x) y)?
    There doesn't seem to be any apparent reason to make
    change-class a separate "thing", rather than a notation that
    class-of is setf-able for some kinds of objects.


change-class is a sufficiently serious operation that having a separate
name is important.  It does significantly more than simply set a field,
so (setf (class-of x) y) would be misleading to a user.


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 18:56:30 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 15:51:01 PDT
From: MASINTER.PA@Xerox.COM
Date: 21 Sep 86 15:50:46 PDT
Subject: make vs make-instance
To: commonLoopsCore↑.PA@Xerox.COM
Message-ID: <860921-155101-1347@Xerox>

The CommonLoops paper used only two short names, viz "make" and "with". 

"make" was chosen, not so much because it is frequently typed and thus
needs to be short, but rather in conformance with the Common Lisp style
in defstruct, namely that

(make-ship :a 3 :b 17)

seemed like a simple step away from

(make 'ship :a 3 :b 17)

and is further away from

(make-instance 'ship :a 3 :b 17).

If it is any help, make-instance is also incompatible with having a
structure named "instance", which seems as likely to me at the moment as
the user having a function or macro named "make".

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 18:43:13 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 15:39:30 PDT
Date: 21 Sep 86 15:39 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Generic Function Objects
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Message-ID: <860921-153930-1345@Xerox>


In the existing CommonLoops papers and code, there is an object called
the discriminator and piece of code called the discriminating function.
The discriminating function was stored inside the discriminator, and
when the discriminator was "named", was also stored in the
symbol-function cell of the symbol which named the discriminator.  The
discriminating-function was the thing you funcalled, the discriminator
was the thing that you passed to add-method.

A potentially better design combines the discriminator and the
discriminating function into a single, closure-like, object called the
generic function.  The generic function is funcallable; funcalling it
causes method lookup to happen.  Accessors which used to work on the
discriminator work directly on the generic function.  In particular,
generic-function-methods returns a list of all the methods defined on a
generic function. 

Generic functions are mutable, and are side-effected by add-method and
remove-method. An alternative proposal makes them immutable, add-method
and remove-method return new generic-functions, see Masinter's message
of 21-Sep-86 12:26:49 PDT.

We spent a fair amount of time discussing the implementation
implications of this.  We believe that this does not cause serious
implementation problems.  At least the mutable case can even be
implemented fairly efficiently in PCL.

This new scheme has not yet been discussed on this list though.  This
message is intended to spark that discussion.


-- danny, Gregor
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 18:40:43 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 15:35:27 PDT
From: MASINTER.PA@Xerox.COM
Date: 21 Sep 86 15:34:29 PDT
Subject: (change-class x y) => (setf (class-of x) y)?
To: commonloopscore↑.PA@Xerox.COM
cc: nuyens.PA@Xerox.COM, sybalsky.PA@Xerox.COM, pavel.PA@Xerox.COM
Message-ID: <860921-153527-1339@Xerox>

There doesn't seem to be any apparent reason to make change-class a
separate "thing", rather than a notation that class-of is setf-able for
some kinds of objects.

Opinions?
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 18:32:25 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 21 SEP 86 15:22:58 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 21 SEP 86 15:22:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 109241; Sun
 21-Sep-86 18:21:05 EDT
Date: Sun, 21 Sep 86 18:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Syntax of DEFCLASS
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860921-135148-1298@Xerox>
Message-ID: <860921182022.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 Sep 86 13:51 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    In an internal design review at Xerox of the current state of the
    specification, strong arguments were presented why defclass should have
    a syntax parallel to that of defstruct.  These were:

I thought we had been through this already.  I'll see if I can reconstruct
the arguments that lead to the decision not to use the defstruct syntax.

    1) Learnability -- Currently people know that syntax.  Simple variations
    ae easier to learn than extensive ones.

This is true, but on the other hand the syntax of defstruct is not
consistent with the syntax of anything else.  In any case this is hardly
likely to be the part that newcomers to object-oriented programming find
the most difficult to learn.

    2) Documentation -- Current documentation of defstruct could be used in
    large part to document defclass.  This makes the book stay smaller.  It
    makes all books written about Common Lisp have to say less. 

This is true, but the percentage decrease in the description of
object-oriented programming would be quite small.

    3) Elimination of defstruct from the language -- If the syntax is
    similar, and the transformation from defstruct to defclass forms is
    straightforward, it will be easier to argue for the removal of
    defstruct.  (Creation of structures and use of :type might be replaced
    by use of the :metaclass option.)
  
This is true, but not compelling.  Defstruct could be removed from the
language regardless of whether the syntax is similar, as long as a given
defstruct form can be mechanically translated into an equivalent defclass
form.

    The major problem with using defstruct synatx for defclass seems to be
    figuring out how to avoid having two conflicting sets of options
    depending on the :metaclass.

    In particular, the current :accessors-with-prefix defclass option is
    different than the :conc-name option.  

    Other, less significant options which cause problems are
    :initable-slots, :initialize-only vs. :read-only and :init-keywords.

I don't think these are the main problems at all.  The real problem with
defstruct is that it was designed nine years ago, is not consistent with
current ideas of easy-to-understand syntax for defining forms, and is
a gross kludge.  Rather than perpetuate this wart on the language, we
ought to be replacing it with something better.  Requiring compatibility
with defstruct is requiring compatibility with the mistakes of the past,
and in my opinion would seriously impair the understandability and
usability of the object-oriented programming facility for only small
gains.  All of the arguments above are true, but I think they are much
too weak to outweigh the problems of defstruct.  Here are some specifics:

The original syntax of defstruct didn't allow for options, so they had
to be added by a kludge -- replacing the name with a list of the name
and options.  The original syntax of defstruct didn't allow for
documentation, so it had to be added by another kludge -- using a string
instead of a slot name.  Slot-options had to be added by yet a third
kludge, which requires that an initialization form be specified whether
or not it is desired in order to specify slot-options.  The format of
slot-options is not consistent with the format of regular options
(admittedly the currently proposed DEFCLASS has the same problem, and it
appears to be difficult to fix).  The format of the :INCLUDE option does
not admit straightforward extension to multiple superclasses; one kludge
or another is required to get around this.

Defstruct contains violations of abstraction or modularity; it has no
concept of a separation between the implementation of a structure (or
class) and clients of that structure or class.  For example, all slots
can be initialized to arbitrary values when constructing a structure;
this ought to be under the control of the implementation of the
structure.  Similarly, the ability of the implementation of a structure
to modify a slot is not separated from the ability of the clients to do
so.

The default values for the :CONC-NAME, :CONSTRUCTOR, :COPIER, and
:PREDICATE options are inappropriate.  (Perhaps not everyone agrees that
all of these are inappropriate, but the existence of controversy is
sufficient reason by itself to reconsider these defaults.)  If the
object-oriented facility is an extension of DEFSTRUCT, it would be
forced to make the same inappropriate choices for the sake of
compatibility.

Given all of these problems, a clean break with the past is a better
choice than trying to maintain compatibility with a kludge.  Of course
defstruct cannot be removed immediately, because one does not make
sudden incompatible changes to a language that thousands of people are
using, but the long-term plan should be to phase out defstruct once
a replacement has been accepted as a standard.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 17:36:19 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 21 SEP 86 14:32:30 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 21 SEP 86 14:32:05 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 109234; Sun
 21-Sep-86 17:30:25 EDT
Date: Sun, 21 Sep 86 17:29 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: mutable vs immutable generic functions
To: CommonLoopsCore↑.PA@Xerox.COM
cc: masinter.PA@Xerox.COM, pavel.PA@Xerox.COM, nuyens.PA@Xerox.COM,
 sybalsky.PA@Xerox.COM
In-Reply-To: <860921-122706-1235@Xerox>
Message-ID: <860921172940.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 Sep 86 12:26:49 PDT
    From: masinter.PA@Xerox.COM

    The question is: are Generic Functions mutable or immutable objects? 

    Example:
    (defmethod foo ((a widget)) .1.)
    (setq foofn #'foo)
    (defmethod foo ((a warble)) .2.)
    (funcall foofn (make-warble) ...)

    Mutable:

    defmethod, add-method, remove-method, etc.  destructively modify the
    generic function to include the new method. In the example, the funcall
    will get definition .2..

    Immutable:

    Generic functions are still objects that can be passed around, sent to
    FUNCALL, etc. However, they are immutable. add-method, remove-method
    merely return a {it new} generic function with the specified method
    added or removed. In the example, the funcall will get a generic
    function which does *not* see the defmethod. 

    defmethod merely replaces symbol-function with a new generic function.

    Unspecified:

    The standard doesn't say. Implementations are free to choose. It is an
    error to rely upon what happens.  

    Pro & Cons:

    mutable vs immutable:
    mutable better than immutable:
    Mutable is a powerful feature. It is consistent with the current
    implementation of PCL. (This is what's written in the documentation that
    I have.) Mutable allows more efficient method-definition than immutable.

    Immutable is better than mutable:
    Mutable is too powerful a feature. It allows programs to do things they
    shouldn't be able to do). Mutable is inconsistent with the use of
    functions elsewhere in Common Lisp.  (A program could, when handed a
    function, remove all of its methods and insert a "default
    implementation" of its own choosing).

    Unspecified vs specified:
    spec it: Programs that depend on one behavior vs the other will be
    difficult to port if left unspecified.
    don't spec it: Many programs won't care, and leaving it unspecified will
    allow greater implementation freedom. If we can't agree, we will have to
    leave it unspecified.

Your arguments make sense to me, and I firmly believe that it should be
unspecified.  Here's why:

In New Flavors the interaction between doing #'foo and adding or
removing a method of foo varies depending on factors that the user might
not be able to predict easily.  This is because there are multiple
implementations of what PCL calls discriminating functions, and
depending on which implementation Flavors happens to choose the result
of #'foo might capture some or all of the current set of methods or
might be independent of the current set of methods.  I imagine that on
stock-hardware this implementation freedom would be even more important,
if high performance was a goal.  In your terminology, generic functions
in New Flavors are sometimes mutable, sometimes immutable, and sometimes
partially mutable.

This has not bothered any programmers, as far as I know, in the 9 or 10
months that New Flavors has been in use.  This shouldn't surprise us,
since ordinary functions behave similarly.  Consider these examples:

[1] (defun foo (...)
      ...
      (foo-1...))
    (defun foo-1 (...)
      ...)

[2] (defun foo (...)
      (flet ((foo-1 (...) ...))
	...
	(foo-1...)))

Suppose someone does #'foo and saves it away, and then a second someone
redefines foo-1, an internal function of foo whose existence is not known
to the first someone.  In example 1, the behavior of the saved-away foo
changes, in example 2 it stays the same, yet as far as the contract of
the function foo is concerned these two ways of implementing its
internal function are equivalent.

Depending on one's taste, one could say this shows that Common Lisp does
not have a well-defined semantics, or one could say that this is just an
example of the way that, in Lisp, copying the value of a variable
doesn't copy the object, just the reference to the object.  Either way,
I think it makes sense for generic functions to have the same freedom of
behavior when their internal subroutines are changed that ordinary
functions enjoy.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 16:58:24 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 13:51:48 PDT
Date: 21 Sep 86 13:51 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Syntax of DEFCLASS
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860921-135148-1298@Xerox>

In an internal design review at Xerox of the current state of the
specification, strong arguments were presented why defclass should have
a syntax parallel to that of defstruct.  These were:

1) Learnability -- Currently people know that syntax.  Simple variations
ae easier to learn than extensive ones.

2) Documentation -- Current documentation of defstruct could be used in
large part to document defclass.  This makes the book stay smaller.  It
makes all books written about Common Lisp have to say less. 

3) Elimination of defstruct from the language -- If the syntax is
similar, and the transformation from defstruct to defclass forms is
straightforward, it will be easier to argue for the removal of
defstruct.  (Creation of structures and use of :type might be replaced
by use of the :metaclass option.)
  

The major problem with using defstruct synatx for defclass seems to be
figuring out how to avoid having two conflicting sets of options
depending on the :metaclass.

In particular, the current :accessors-with-prefix defclass option is
different than the :conc-name option.  

Other, less significant options which cause problems are
:initable-slots, :initialize-only vs. :read-only and :init-keywords.


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 21 Sep 86 15:33:16 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 86 12:27:06 PDT
From: masinter.PA@Xerox.COM
Date: 21 Sep 86 12:26:49 PDT
Subject: mutable vs immutable generic functions
To: commonloopscore↑.pa@Xerox.COM, pavel.PA@Xerox.COM,
 nuyens.PA@Xerox.COM, sybalsky.PA@Xerox.COM
Message-ID: <860921-122706-1235@Xerox>

(This note came out of a design review meeting with some of the Common
Lisp implementors here. )


This is very condensed form of the arguments:

The question is: are Generic Functions mutable or immutable objects? 

Example:
(defmethod foo ((a widget)) .1.)
(setq foofn #'foo)
(defmethod foo ((a warble)) .2.)
(funcall foofn (make-warble) ...)

Mutable:

defmethod, add-method, remove-method, etc.  destructively modify the
generic function to include the new method. In the example, the funcall
will get definition .2..

Immutable:

Generic functions are still objects that can be passed around, sent to
FUNCALL, etc. However, they are immutable. add-method, remove-method
merely return a {it new} generic function with the specified method
added or removed. In the example, the funcall will get a generic
function which does *not* see the defmethod. 

defmethod merely replaces symbol-function with a new generic function.

Unspecified:

The standard doesn't say. Implementations are free to choose. It is an
error to rely upon what happens.  

Pro & Cons:

mutable vs immutable:
mutable better than immutable:
Mutable is a powerful feature. It is consistent with the current
implementation of PCL. (This is what's written in the documentation that
I have.) Mutable allows more efficient method-definition than immutable.


Immutable is better than mutable:
Mutable is too powerful a feature. It allows programs to do things they
shouldn't be able to do). Mutable is inconsistent with the use of
functions elsewhere in Common Lisp.  (A program could, when handed a
function, remove all of its methods and insert a "default
implementation" of its own choosing).

Unspecified vs specified:
spec it: Programs that depend on one behavior vs the other will be
difficult to port if left unspecified.
don't spec it: Many programs won't care, and leaving it unspecified will
allow greater implementation freedom. If we can't agree, we will have to
leave it unspecified.


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 20 Sep 86 14:36:24 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 20 SEP 86 10:36:38 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 20 SEP 86
 10:36:27 PDT
Date: 20 Sep 86 10:36 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Short Names   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860920-103638-2050@Xerox>


It is tempting to want to use short names for things that are imagined to
be used frequently. People designing an object-oriented programming
language feel that the primitives they define will be the ones frequently
used. Recall that in the overall age of Lisp, CommonLoops has hardly
any history. Moreover, because the designer of it feels that his primitives
are the right ones, perhaps a second-generation CommonLoops hacker
will feel that some different primitives are right.

In Common Lisp we decided to not use up many of the `good' names
or characters so that users could have them. Exceptions are time-honored
Lisp names, such as LET and CONS. 

If you choose a long name for MAKE-INSTANCE, then the user can
macro-ify it to a short name. If you choose a short, nice name
like MAKE, no one else can use it. That is, the long name is
the safe choice.

Also, do you suppose that your choice of the meaning of an
English word like MAKE for a technical operation is better than
what a real programmer would want to choose as the meaning?

I strongly object to using names that are likely to be of use to
programmers to name operations that are meaningful in his application.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 19 Sep 86 14:34:41 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 SEP 86 10:45:24 PDT
Date: 19 Sep 86 10:37 PDT
Sender: Kahn.pa@Xerox.COM
Subject: Short names like MAKE
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Kahn.pa@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860919-104524-1315@Xerox>

I've hesitated to bring this up since it seems that everyone is happy
with the change from MAKE to MAKE-INSTANCE.  I'm not.

I think short names are appropriate when something is used frequently
enough.  I'm glad LET isn't called LET-VARIABLES, CONS isn't called
MAKE-CONS etc.  My expectation is that all user defined data structures
will be created by MAKE(-INSTANCE) and that programs frequently do
create structures.  To put it more extremely than I really believe --
The only things that programs will make will be made by MAKE or by
existing primitive type creation functions (CONS, MAKE-ARRAY...) 

I feel less strongly about WITH vs WITH-INSTANCE since I don't really
know how often people will be using it explictly.(Btw, I like Moon's
WITH keyword syntax for dealing with prefix, class etc. though I also
share Larry's concern that the cases where they will be used are rare
enough that the added complexity isn't worth it.)


----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 19 Sep 86 14:34:28 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 19 SEP 86 10:42:24 PDT
Return-Path: <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 19 SEP 86 10:42:02 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 108123; Fri
 19-Sep-86 13:40:40 EDT
Date: Fri, 19 Sep 86 13:38 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Summary of features we all agree on
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, bobrow.pa@Xerox.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860910003916.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860919133856.4.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No

    Date: Wed, 10 Sep 86 00:39 EDT
    From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>

      Date: 5 Sep 86 18:49 PDT
      From: Bobrow.pa@Xerox.COM

This is from the section on DEFCLASS slot-options.

	  :allocation 
   
      :allocation can have values
       :instance (allocated in the instance),
       :class (storage allocated in the class and shared by all
	       instances),
       :dynamic (storage allocated in the instance on first use
	  (like Flavors Proplist mixin)
       :none  expect accessor methods for this to be defined for
	 this slot in this class
 
    We need to discuss which of these allocation options belong in
    the standard.  Maybe only a subset of them.

This is the last I've heard (read) of :allocation.  Maybe it's time to
start discussing the :allocation options again.  I've elaborated on
Danny's write-up above with some information from the CommonLoops paper,
and added one thing.    For :dynamic, I assume that if you initialize
the slot with a keyword argument to MAKE-INSTANCE, the slot gets
allocated right then.   True?

Also, would you clarify what you meant by:  

       :none  expect accessor methods for this to be defined for
	 this slot in this class

---------------------------------------------------------------------

	
:allocation keyword    

    Specifies where storage is allocated for this slot.  The keyword can
    be one of these: 

    :instance     Storage is allocated in the instance itself;  each
                  instance has its separate value for this slot.  This
                  is the default.   

    :class        Storage is allocated in the class.   Thus a single
                  value for this slot is shared by all instances. 

    :dynamic      Storage is allocated in the instance at the time of
                  the first use of the slot.  If the slot is initialized
                  with a keyword argument to MAKE-INSTANCE, the slot is
                  allocated then.   If the first access is a read, then
                  storage is allocated and the default value declared
                  in the DEFCLASS, if any, is stored in the slot and
                  returned.  If the first access is a SETF, then storage
                  is allocated and the value is stored in the slot and
                  returned.  This option allows infrequently-used slots
                  to take storage only when necessary. 

    :none         No storage is to be allocated; the slot should not
                  exist in instances of this class.  This is used to
                  override inheritance of slots defined by a
                  super-class.   

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 19 Sep 86 12:48:32 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 SEP 86 09:37:30 PDT
Date: 19 Sep 86 09:37 PDT
Sender: Bobrow.pa@Xerox.COM
Subject: Re: Summary of features we all agree on
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 19 Sep 86 10:55 EDT
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.PA@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Message-ID: <860919-093730-1229@Xerox>

    The important distinction that these names have to imply is
    that one generic function can read and write, while the other can
    only read.

    The name :read-accessor is confusing.  It implies that the
    generic function is capable of both reading and accessing.

    The names :accessor and :read-accessor do not go together well.
     If we are going to use :reader-accessor, the appropriate companion
    option should be named :read-and-write-accessor.    That way the
    user understands that :read-and-write-accessor does more than
    :read-accessor.  

    I prefer the names :accessor and :reader because they really
    describe what the generic function can do.   The one generated by
    :ACCESSOR has the capability of ACCESSING (both reading and being
    used with SETF). The one generated by :READER has the capability of
    READING.


I like this choice of names, :accessor and :reader.


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 19 Sep 86 11:10:27 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 19 SEP 86 08:04:35 PDT
Return-Path: <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 19 SEP 86 08:03:52 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 107881; Fri
 19-Sep-86 10:57:38 EDT
Date: Fri, 19 Sep 86 10:55 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Summary of features we all agree on
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860910003916.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860919105557.2.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No

    Date: Wed, 10 Sep 86 00:39 EDT
    From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>

      Date: 5 Sep 86 18:49 PDT
      From: Bobrow.pa@Xerox.COM

	class-name is a non-null symbol that names the class being
	defined.  If a class is already defined with this name, this
	definition replaces the old definition.  The default
	meta-class ensures that when the definition of a class
	changes, each existing instance of the class is updated to the
	new format the next time it is accessed.
  
	 Each slot-spec is one of:
  
	  slot-name       a non-null symbol.
  
	   (slot-name initial-value-form)
  
  
	  (slot-name slot-option...)
	    Each slot-option is an option name followed by its value.
	    The defined slot-options and their arguments are:
  
	   = initial-value-form
		   This an alternate way for providing a default
		   initial value form.

    By the way I'm not wedded to the name "=".  I couldn't think of
    a clearer name when I tried for a few minutes, but perhaps
    someone else can.

The name "=" seems inappropriate here. 

How about :initial-value?   Other possibilities:  :default-value, 
:default-initial-value, :initial-contents.  

	  :accessor generic-function-name
		Specifies that a function named generic-function-name
		be automatically generated, to read the value of this
		slot.  SETF may be used with generic-function name to
		write the value of the slot.
   
      OK.  If generic-function-name is NIL then this is a NOOP.
      Specified so programs can generate these.
  
	  :reader generic-function-name
		Specifies that a function named generic-function-name
		be automatically generated, to read the value of this
		slot.
  
      We have called this :read-accessor.  

    I think users would find the distinction between :read-accessor
    and :accessor confusing.  Perhaps we need some more opinions
    here, it's a difficult judgement.

The important distinction that these names have to imply is that one
generic function can read and write, while the other can only read.

The name :read-accessor is confusing.  It implies that the generic
function is capable of both reading and accessing.

The names :accessor and :read-accessor do not go together well.  If
we are going to use :reader-accessor, the appropriate companion option
should be named :read-and-write-accessor.    That way the user
understands that :read-and-write-accessor does more than :read-accessor.  

I prefer the names :accessor and :reader because they really describe
what the generic function can do.   The one generated by :ACCESSOR has
the capability of ACCESSING (both reading and being used with SETF).
The one generated by :READER has the capability of READING.

					   We specify that if this is
      given, then SETF may NOT be used with this accessor. If
      generic-function-name is NIL then this is a NOOP.
  
    Agreed.



∨
Received: from Xerox.COM by AI.AI.MIT.EDU 19 Sep 86 03:13:31 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 15:35:09 PDT
Return-Path: <dcmartin@ingres.Berkeley.EDU>
Received: from ingres.Berkeley.EDU ([128.32.156.105]) by Xerox.COM ; 18
 SEP 86 15:32:59 PDT
Received: by ingres.Berkeley.EDU (5.53/1.2)
 	id AA28636; Thu, 18 Sep 86 14:38:01 PDT
Message-Id: <8609182138.AA28636@ingres.Berkeley.EDU>
From: "David C. Martin" <dcmartin@ingres.Berkeley.EDU>
Office: 440 Evans - x2-9585
Home: 2441 Haste St #37, Berkeley, CA 94704 - (415) 843-6470
Fortran: is not backward, NARTROF is backwards.
To: Ted Kowalski <frodo@faraday.ece.cmu.edu>
Cc: CommonLoops.pa@Xerox.COM, Gregor.pa@Xerox.COM
Precedence: priority-mail
In-Reply-To: Your message of Thu, 18 Sep 86 14:24:16 edt
Subject: Re: common loops for franz
Date: 18 Sep 86 14:37:58 PDT (Thu)
Sender: dcmartin@ingres.Berkeley.EDU

Yeah, there should be... I am running it w/ Franz ExCl and I last updated
on 8/28 from parcvax.  If you would like, I can make it publically ftp'able
from my VAX.  We have also added the make-specializable feature to the
Franz implementation.

dcm
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:47:21 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 18 SEP 86 15:00:48 PDT
Date: 18 Sep 86 14:56 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: FTP problems.
In-reply-to: ALarson@HI-MULTICS.ARPA's message of Thu, 18 Sep 86 15:31
 CDT
To: ALarson@HI-MULTICS.ARPA
cc: CommonLoops.pa@Xerox.COM, VaxcSystem↑.pa@Xerox.COM
Message-ID: <860918-150048-9078@Xerox>

parcvax has been having hiccups with a new version of Unix. I'm not sure
they've been resolved yet, will keep you posted. 
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:46:51 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 18 SEP 86 14:11:59 PDT
Date: 18 Sep 86 14:13 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Proposed Goals (Statement for OOPSLA)
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860918-141159-9040@Xerox>

In reading over these messages, I realized that what we were doing was
not describing technical goals and history, but setting up marketing
positions for corporations.  I (and Gregor) are not in any position to
negotiate statements that have that kind of implication, and this
discussion is not appropriate for this list. Instead, let's continue
discussions of the important technical issues we need to resolve.     


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:46:28 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 18 SEP 86 13:48:55 PDT
Date: 18 Sep 86 13:47 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: DEFCLASS should replace DEFSTRUCT 
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 18 Sep 86
 10:16 PDT
To: RPG@SAIL.STANFORD.EDU
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860918-134855-9009@Xerox>

Having missed the early discussions of what ambiguity lies in the
original specification, I am forced to repeat the questions and hope
that you will have the patience to repeat the replies. If it is any
consolation, I think you will have to repeat this with others who might
have liked the spec, and suggest, if you have not done so, save your
replies.

To address your particular concerns:

"In particular, the use of Defmethod as a vague replacement for Defun to
create a cloud of
functions that are invoked variously misses the goal of a clearly
understood construct. What precisely is the contract between this cloud
and the outside world? "

What precisely is the contract between an ordinary function and the
outside world? 

The specification of the behavior of a set of methods is no less defined
than the specification of what functions, macros and special forms do in
Common Lisp.

"How does this cloud relate to Lisp functions?"
It is different from any lisp function.

"If you can FUNCALL this cloud, can you affect it by affecting the thing
that sits in the symbol-function cell of a symbol? "

You cannot FUNCALL a cloud. You can FUNCALL a symbol and a function
object. A set of methods is neither. Perhaps you are asking the more
precise question:

"After (defmethod move ((x point) dx dy) ...), what does
(symbol-function 'move) return?"

I would answer that the answer belongs in the standard as much as the
question

"After (defmacro mood (x dx dy) ...), what does (symbol-function 'mood)
return?"

on which Common Lisp the Language is silent.

I think that your characterization of the early CommonLoops proposal as
"more like a slogan than a well-designed system." is incorrect, and even
more perjorative than the characterization of Common Lisp as "more like
a treaty than a specification."



∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:46:13 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 13:44:38 PDT
Return-Path: <ALarson.SoftTech@HI-MULTICS.ARPA>
Received: from HI-MULTICS.ARPA by Xerox.COM ; 18 SEP 86 13:42:04 PDT
Date: Thu, 18 Sep 86 15:31 CDT
From: ALarson@HI-MULTICS.ARPA
Subject:  FTP problems.
To: CommonLoops.pa@Xerox.COM
Message-ID:  <860918203156.583664@HI-MULTICS.ARPA>

I recently attempted to FTP the PCL software from PARCVAX.xerox.com, and
had much difficulty.  Specifically the last 500-2K bytes of most of the
files were not transferred (at least not received).  The system
administration people at my site (A large Multics) say no one else has
experienced the same trouble and suggested that I find out if anyone
else trying to get the software was having difficulty.  So, did anyone
else have any trouble FTPing the code?

The following is a partial transcript of the FTP session:
The first line below is a DIR, the next two are GETs (of course the first
one worked correctly as predicted by Murphy).

Aaron.
----------------------------------------

user←ftp:   -rw-r--r--  1 270      41          10366 May 30 11:01 defsys.l

user←ftp:  150 Opening data connection for defsys.l (10.1.0.94,62250) (10366 bytes).

226 Transfer complete.

Total elapsed time:  27.6 seconds.
10366 bytes transferred in 24.4 seconds (3343 bits/sec).

user←ftp:  

user←ftp:  150 Opening data connection for defsys.l (10.1.0.94,43178) (10366 bytes).

226 Transfer complete.

Total elapsed time:  30.7 seconds.
10224 bytes transferred in 25.5 seconds (3150 bits/sec).

user←ftp:
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:46:04 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 18 SEP 86 13:25:33 PDT
Date: 18 Sep 86 13:23 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: The name of WITH
In-reply-to: Bobrow.pa's message of 18 Sep 86 08:28 PDT
To: Bobrow.pa@Xerox.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860918-132533-8979@Xerox>

I think that under a with/with-slots/with-instances that programmers
should be encouraged (required?) to use SETF instead of SETQ to modify
slots.

(defmumble move-to ((p point) new-x new-y)
   (with-slots (p)
	(setf x new-x)
	(setf y new-y)))

even though setq will "do".


I think the "prefix" option was added as a "fix" to the possibility of
conflicting slot names, and that the cure is worse than the disease. If
there's conflict, use the accessor functions instead.
  
(defmumble move-to-point ((p point) (p2 point))
    (with-slots (p)
	(setf x (point-x p2))
	(setf y (point-y p2))))



∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:45:56 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 11:41:26 PDT
Return-Path: <frodo@faraday.ECE.CMU.EDU>
Received: from faraday.ECE.CMU.EDU by Xerox.COM ; 18 SEP 86 11:36:26 PDT
Received: by faraday.ECE.CMU.EDU (4.12/4.7)
 	id <AA04222 frodo>; Thu, 18 Sep 86 14:24:16 edt;
Date: Thu, 18 Sep 86 14:24:16 edt
From: Ted Kowalski <frodo@faraday.ECE.CMU.EDU>
Message-Id: <8609181824.AA04222@faraday.ECE.CMU.EDU>
To: CommonLoops.pa@Xerox.COM
Subject: common loops for franz
Cc: Gregor.pa@Xerox.COM

the readme.tx file mentions a excl, but I didn't find one in /pub/pcl
does it exist?
thanks
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:45:46 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 11:02:27 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 18 SEP 86 11:02:01 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 107073; Thu
 18-Sep-86 13:58:43 EDT
Date: Thu, 18 Sep 86 13:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: WITH-SLOTS
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860918-082650-8617@Xerox>
Message-ID: <860918135841.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 18 Sep 86 08:28 PDT
    From: Bobrow.pa@Xerox.COM

    WITH-SLOTS allows you access slots using a variable name.  For example...

    The syntax of with-slots is:

    (with-slots ({var-name|(var-name var-prefix [class-name]}*) . body)

It's nice to see a concrete specification of something.  I have some
syntactic suggestions: I think it would be clearer to use keyword arguments
rather than a mixture of positional arguments and multiple operator names.
I would suggest these three keywords:
  :class class-name -- the class, or a super class, of the instance.
  :prefix string -- prefixed to the slot names (can be a symbol or a string).
  :direct boolean -- t means access slots directly, nil means call the
	accessor functions, which might invoke methods.

Thus the syntax would become

  (with-slots ({var-name|(var-name &key class prefix direct) . body)

and your examples would become

  (defclass point () ((x 0) (y 0)) (:accessors-with-prefix point-))

  (defmethod move ((p point) dx dy)
    (with-slots (p)  ;; p is known to be a point from the method-signature
       (setq x (+ x dx) y (+ y dy))))

  (with-slots ((p :direct t)) (setq x (+ x dx) y (+ y dy)))) 

  (defmethod make-same-height ((p1 point) (p2 point))
  ;;; set the y coord of p1 to the y of p2, its reference.
  ;;; slots of p1 are accessed using the slot names
  ;;; slots of p2 are accessed using ref-<slot-name>
     (with-slots (p1 (p2 :prefix ref-)) (setq y ref-y)))

  (defmethod make-horizontal ((l line))
     (let ((left (left-point l)) (right (right-point l)))
       (with-slots ((left  :class point :prefix left-)
		    (right :class point :prefix right-))
	 (setq left-y right-y))))

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:45:30 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 10:57:33 PDT
Return-Path: <skeene@ALDERAAN.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ALDERAAN.SCRC.Symbolics.COM ([192.10.41.109]) by
 Xerox.COM ; 18 SEP 86 10:57:06 PDT
Received: from JUNCO.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM
 via CHAOS with CHAOS-MAIL id 5379; Thu 18-Sep-86 13:52:29 EDT
Date: Thu, 18 Sep 86 13:51 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: The name of WITH
To: Bobrow.pa@Xerox.COM
cc: skeene@STONY-BROOK.SCRC.Symbolics.COM,
 Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860918-082650-8617@Xerox>
Message-ID: <860918135152.0.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No

    Date: 18 Sep 86 08:28 PDT
    From: Bobrow.pa@Xerox.COM

Thanks for the information on WITH-SLOTS.   I have two questions. 
 
	 Does WITH-SLOTS only give you variables for each slot, or does it
	 also give you a "SELF" variable for the object itself?    If it
    also
	 provides  a variable for the object, maybe WITH-INSTANCE would be a
	 better name. 

    In the standard syntax for methods, there is no special name self.  The
    user chooses the name for an object.  WITH-SLOTS allows you access slots
    using a variable name.  For example,

    (defclass point () ((x 0) (y 0)) (accessors-with-prefix point-))

If the class of point had been defined without specifying the
:accessors-with-prefix option, what happens when you define (or run?)
the method below?

    (defmethod move ((p point) dx dy)
      (with-slots (p)  ;; p is known to be a point from the method-signature
	 (setq x (+ x dx) y (+ y dy))))

    In this example, p could have been used to refer to the point itself.
     (+ x dx) expands to 
     (+ (point-x p) dx) etc.

    Using %with-slots

    (%with-slots (p) (setq x (+ x dx) y (+ y dy)))) 

     (+ x dx) expands to 
     (+ (get-slot p x) dx)

[text deleted here on syntax of WITH-SLOTS]  

    %with-slots is identical to with, except that 
    with-slots expands slot references to access functions and
    %with-slots expands slot references to direct accesses


So, I guess the idea is this:  You would use %WITH-SLOTS if you really
wanted full access to the slots whether or not they were declared to be
accessible in the DEFCLASS.    You would use WITH-SLOTS if you wanted
the system to prevent you from accessing a slot that was not declared
accessible in the DEFCLASS.   Another reason to use WITH-SLOTS is to 
ensure that the accessor generic function is run -- which might include
some :before or :after methods.  



∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:44:53 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 10:02:49 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 18 SEP 86
 10:02:32 PDT
Date: 18 Sep 86 10:01 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Proposed Goals (Statement for OOPSLA)  
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860918-100249-8718@Xerox>


Sonya's improvements are generally good. I changed her original
sentence

``We will produce a portable implementation by evolving Portable
Common Loops...''

because it can parse in a funny way if you use a slightly less primary
definition of `evolve' than `to exhibit or produce through evolution.'
The definition is `to emit' as in `to evolve gases.'  I parsed it as
it would appear in this sentence:

``Danny Bobrow ate a large plate of refried beans last night, went
back to PARC, and accidentally evolved Portable Common Loops.  He
apologized profusely for his bad manners.''

Your rephrasing is better than mine, but it does commit Xerox to doing
the work of updating PCL, which they may elect not to do.

One reason for the phrasing of the pedigree paragraph is to emphasize
that the influence of New Flavors on CommonLoops has been going on for
over a year, and that the proposed standard will be more nearly along
the line of evolution, if you will, of CommonLoops as influenced by
New Flavors than a fresh merging of the two systems off the lines of
either.  That is, the proposed standard will not be especially like
the CommonLoops of a year ago, but it will be very much like the
CommonLoops of today, because a movement towards New Flavors has
already taken place.

The reason for wanting to reason this way is to give the community
some sense of continuity over the past year. People will possibly rest
more comfortably if they believe that the ideas have developed over a
year's time rather than over a month's time.

The proposed standard will be what it will be, and its pedigree will
be of interest only to historians, and those historians will be able
to see the family lines accurately.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 18 Sep 86 22:44:42 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 10:16:46 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 18 SEP 86
 10:16:32 PDT
Date: 18 Sep 86 10:16 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: DEFCLASS should replace DEFSTRUCT 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860918-101646-8740@Xerox>


I bow to those who use mailers that sort mail according to subject:
My message is responsive to the discussion which has gone on under
this subject line, but the contents of my remarks and of the remarks
to which I reply bear no semantic relationship to the subject line.

There indeed was a simplicity in the early CommonLoops proposal, but the
simplicity was the simplicity of a naive proposal. In particular, the
use of Defmethod as a vague replacement for Defun to create a cloud of
functions that are invoked variously misses the goal of a clearly understood
construct. What precisely is the contract between this cloud and the outside
world? How does this cloud relate to Lisp functions? If you can FUNCALL this
cloud, can you affect it by affecting the thing that sits in the symbol-function
cell of a symbol? Simply stated, is the cloud a first-class object, or is it
like the heap?

The `negotiating' group is doing more than negotiating: It is attempting to
bring some design sense into the picture. The early CommonLoops proposal
was more like a slogan than a well-designed system.

			-rpg-

∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 16:09:48 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3349; 18 Sep 86 11:09:28 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 07:43:05 PDT
Return-Path: <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 18 SEP 86 07:42:09 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106864; Thu
 18-Sep-86 10:34:54 EDT
Date: Thu, 18 Sep 86 10:33 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proposed Goals (Statement for OOPSLA)
To: Bobrow.pa@Xerox.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917-113216-7821@Xerox>
Message-ID: <860918103320.8.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No

    Date: 17 Sep 86 11:33 PDT
    From: Bobrow.pa@Xerox.COM

    Dick edited Sonya's version, then Danny and Gregor edited his to produce
    this.

Thanks for your quick response on this.   I've revised the text of this
statement to include your changes (except for one paragraph), and I also
corrected a few typos in your version.   Anything that I changed from 
your version is enclosed in *asterisks* below.    

Moon has sent another version of the paragraph in question for you to
comment on.   It's also included here.  

    HISTORY AND MOTIVATION

    There is currently substantial experience with object-oriented
    programming paradigms within a variety of contexts. The two groups
    *have have* the most experience in this area are Symbolics and Xerox.

Only one "have"

    Flavors, an important object-oriented programming extension to Lisp,
    has been in use for more than 7 years. Over that period many valuable
    lessons
    have been learned about object-oriented programming in Lisp. In 1985,
    Symbolics took these lessons to heart and designed New Flavors, which
    is a compatible extension to Flavors.

    Xerox has had more than 10 years of experience with object-oriented
    programming, both within the Lisp tradition and within the Smalltalk
    tradition.  Over that period many lessons were learned, and in 1985
    Xerox
    began to design a new object-oriented programming extension to Common
    Lisp, called CommonLoops.

    In mid-1985 these two groups became aware of each other.  These 
    two object-oriented extensions to Lisp had important similarities.
    CommonLoops evolved to include some of the ideas in *new Flavors*.

Capitalize "New Flavors". 

    Many people in the Common Lisp community now see a need for defining a
    standard for object-oriented programming that would be part of Common
    Lisp.  The primary benefit of such a standard would be the ability to
    write portable Common Lisp code in an object-oriented style.

    At the Common Lisp committee meeting in Boston in December 1985, many
    vendors of application software made it clear how important such a
    standard is to them.  Again at the ACM Conference on Lisp and Functional
    Programming in Cambridge in August 1986, the same point was made.

    After the ACM Conference there was a meeting of the Common Lisp
    Object-oriented Programming Committee.  A clear consensus was reached
    that
    work should begin immediately to define a standard.  Representatives
    from Xerox, Lucid, Symbolics, LMI, HP, Sun, and the Japanese CommonLisp
    committee supported this consensus.

    A working group composed of representatives from Xerox and Symbolics met
    after the ACM Conference; at the meeting this working group reached
    agreement on several general goals.

    *In brief, the standard will be based on the meta-object framework of
    CommonLoops, which allows experimentation with different philosophies of
    object-oriented programming.  Additional features from new Flavors will
    be added to CommonLoops to flesh out the programmer interface; in
    particular, a declarative method combination facility patterned after
    that in new Flavors has been added to CommonLoops to create an extension
    to Common Lisp that represents the best features of both systems.*

We prefer the paragraph below, because it makes it clear that the new
thing isn't CommonLoops:   

"In brief, the standard will be based on the meta-object framework of
CommonLoops, which allows experimentation with different philosophies of
object-oriented programming.  The programmer interface on top of this
framework will combine the most useful features of CommonLoops and New
Flavors, such as multimethods from CommonLoops and declarative method
combination from Flavors.  The standard will be an extension to Common
Lisp that incorporates the best features of both systems." 

    PROGRESS IN AUGUST AND SEPTEMBER

    During August and September, representatives from Xerox, Symbolics, and
    Lucid began work on a draft specification of the standard.  This working
    group started with the basic programmer interface for defining new
    classes
    and writing methods and generic functions.  *This work is ongoing, but a
    draft of the programmer interface is available - the meta-object
    protocol specification will be available soon.*

Let's make that two complete sentences:   "This work is ongoing, but a
draft of the programmer interface is available.   The meta-object
protocol specification will be available soon."


    GOALS FOR THE STANDARD

    Some high-level goals were stated and agreed-upon:

    Sound basis     The standard will include the aspects of object-oriented
		    programming that are well-understood at this time.  The
		    standard will omit ideas that are still subjects for
		    research.

    Flexibility     The meta-object protocol of the standard will offer a
		    flexible framework for other designers to implement
		    different schemes.  This encourages exploration of
		    different styles of object-oriented programming.

    Power           The standard will offer the basic tools for writing
		    programs in an object-oriented style, and will be
    powerful
		    enough that it meets the needs of most programs.  It
    should
		    not be necessary for programmers to extend the system to
    do
		    straightforward object-oriented programming.

    Simplicity      The standard will specify just the language, not the
		    programming tools and interactive development
    environment.

    Compatibility   It should be a convenient and simple procedure to
    translate
		    programs written in CommonLoops or New Flavors to the
    new
		    standard.  We intend to provide tools that will perform
    the
		    translation automatically.

    Implementation  The standard will allow efficient implementation on
    stock
		    hardware as well as specialized machines.
                                                                        
    FEATURES TO BE INCLUDED IN THE STANDARD

    The following features *wil be* included in the standard..  This is not an

"will be"

    exhaustive list, but is intended to communicate some of the areas of
    agreement that have been reached.

    Generic functions
		    The standard will use the normal Lisp function-calling
		    syntax.

    Class and Type Space Merging
		    Every object in the Lisp system has a class and hence
    can
		    be used to select methods.

    Dispatching     The standard will allow dispatching on the class of one
		    (classical methods) or more (multi-methods) arguments.

    Multiple inheritance
		    Classes can be combined together freely; they
		    need not fit into a rigid hierarchy.

    Meta-objects    The standard defines objects for the major
    implementation
		    entities of the system to allow for extensibility.
		    Classes, methods, and generic functions all have
		    corresponding objects, organized by well-defined,
		    documented protocols.

    Declarative Method Combination
		    Method selection and combination can be controlled
		    declaratively.  Users can define new
		    method combination paradigms.

    FUTURE PLANS

    The working group is developing a draft specification for the
    standard.  The specification process will involve the community in the
    feedback process.

    *Portable Common Loops will evolve to to track the new specification.
    This portable implementation will enable the community to experiment
    with and
    gain a deeper understanding of the ideas than is possible with only a
    specification.*

A. Only one "to". 

B. I prefer my original text "We wil produce a portable implementation
by evolving Portable Common Loops..." instead of your "Portable Common
Loops will evolve..."   PCL isn't going to evolve spontaneously.  
How about saying "Xerox will update Portable Common Loops to track the
new specification?" 

C. Let's recast that last sentence to take the distracting clause out of the
middle. 

That paragraph turns into: 

"Xerox will update Portable Common Loops to track the new specification.
By experimenting with the portable implementation, the community can
gain a deeper understanding of the ideas than would be possible by
reading the specification alone."



  


∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 16:09:46 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3354; 18 Sep 86 11:59:34 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 18 SEP 86 08:36:41 PDT
Date: 18 Sep 86 08:38 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: DEFCLASS should replace DEFSTRUCT
In-reply-to: Masinter.pa's message of 17 Sep 86 19:50 PDT
To: Masinter.pa@Xerox.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860918-083641-8627@Xerox>

     I think that the reason that CommonLoops was originally acceptable
     to a large class of people was that it did not add substantially to
     the complexity of the Language. The acceptability of CommonLoops
     partially on that principle, and any movement away from it
     risks losing it.
I think simplifying Common Lisp is an admirable goal, and when this
standard is agreed on, I think the Common Lips community can take on
itself the task of redefining old features on top of the new.  Not only
do I think that defstruct should go away, but the sequence functions
should be made methods, errors should use objects, the type system
should be described in terms of predications, classes, etc.  This
layering of Common Lisp would make a lot cleaner language.  Let us put
these items on our agenda.

BUT we have not yet got an object standard!!!!  We should keep those
goals in the back of our mind, and try to enable such folding.  The job
in front of us at the moment is to ensure we have a useful object
standard. 


-- danny

∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 16:09:19 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3353; 18 Sep 86 11:59:10 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 18 SEP 86 08:26:50 PDT
Date: 18 Sep 86 08:28 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: The name of WITH
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 18 Sep 86 08:17 EDT
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860918-082650-8617@Xerox>

     Does WITH-SLOTS only give you variables for each slot, or does it
     also give you a "SELF" variable for the object itself?    If it
also
     provides  a variable for the object, maybe WITH-INSTANCE would be a
     better name. 

In the standard syntax for methods, there is no special name self.  The
user chooses the name for an object.  WITH-SLOTS allows you access slots
using a variable name.  For example,

(defclass point () ((x 0) (y 0)) (accessors-with-prefix point-))

(defmethod move ((p point) dx dy)
  (with-slots (p)  ;; p is known to be a point from the method-signature
     (setq x (+ x dx) y (+ y dy))))

In this example, p could have been used to refer to the point itself.
 (+ x dx) expands to 
 (+ (point-x p) dx) etc.

Using %with-slots

(%with-slots (p) (setq x (+ x dx) y (+ y dy)))) 

 (+ x dx) expands to 
 (+ (get-slot p x) dx)


The syntax of with-slots is:

(with-slots ({var-name|(var-name var-prefix [class-name]}*) . body)

In the simple case, where only a var-name is used, it is assumed that
the class of the named variable can be determined from the method
signature.  Slot-names from the class can be used to access slots of the
object bound to var-name.  This is illustrated above.

If two or more var-names are given, then they must have disjoint sets of
names for slots  to avoid ambiguity of reference. (but see var-prefix
below). In such a case an error is signalled.

If var-prefix is provided, then references to any slot <slot1> can be
made using the symbol (concat var-prefix <slot1>).  This allows easy
reference to two objects of the same class.  For example,

(defmethod make-same-height ((p1 point) (p2 point))
;;; set the y coord of p1 to the y of p2, its reference.
;;; slots of p1 are accessed using the slot names
;;; slots of p2 are accessed using ref-<slot-name>
   (with-slots (p1 (p2 ref-)) (setq y ref-y)))

Under some circumstances, the class of an object will not be computable
from the method signature, but can be specified by the user.

For example, 
  (defmethod make-horizontal ((l line))
     (let((left (left-point l)) (right (right-point l)))
       (with-slots ((left left- point)(right right- point))
          (setq left-y right-y))))

These last examples are silly in that one would not go to this trouble
to reference a single variable.  But with-slots is very convenient if
you want to do many references.

The scope of these names is lexical (as is obvious from their
trranslation).

%with-slots is identical to with, except that 
with-slots expands slot references to access functions and
%with-slots expands slot references to direct accesses
  


-- danny

∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 16:08:38 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3335; 18 Sep 86 09:22:16 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 18 SEP 86 05:29:12 PDT
Return-Path: <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 18 SEP 86 05:29:01 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106773; Thu
 18-Sep-86 08:19:01 EDT
Date: Thu, 18 Sep 86 08:17 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: The name of WITH
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917233439.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860918081727.4.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No

    Date: Wed, 17 Sep 86 23:34 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

	Date: 17 Sep 86 13:12 PDT
	From: Gregor Kiczales <Gregor.pa@Xerox.COM>

	If people really think the name WITH is too short, then the name
	WITH-SLOTS seems like the obvious best name to me.

    That sounds good to me too.

Does WITH-SLOTS only give you variables for each slot, or does it also
give you a "SELF" variable for the object itself?    If it also provides 
a variable for the object, maybe WITH-INSTANCE would be a better name. 



∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 16:08:37 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3325; 18 Sep 86 03:40:49 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 20:55:02 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 17 SEP 86 20:54:52 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106667; Wed
 17-Sep-86 23:52:13 EDT
Date: Wed, 17 Sep 86 23:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: required-xxx options to defclass
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917-132658-7944@Xerox>
Message-ID: <860917235226.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 17 Sep 86 13:26 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    These options are just hack implementations of something which
    *protocols* would do right.  Given that we don't have protocols, and we
    don't want to clutter the spec with hacks, we should not include these
    options.  Then, when we do figure out how to do protocols "right", there
    won't be these old, obsolete required-xxx options hanging around.

    How do you feel about not having :required-xxx options in the standard?

I'm not convinced that protocols will eliminate the :required-xxx
options.  However, I agree that the "sound basis" item in our professed
statement of goals requires that things we suspect, after sufficient
discussion, are not well understood should not be included.

The question, then, is whether these are sufficiently indispensable to
users to justify including them anyway (the "power" and "compatibility"
goals).  In this case I think the answer is no.  So let's leave these
out of the standard for now.


∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 00:19:59 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3316; 18 Sep 86 00:15:56 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 20:37:55 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 17 SEP 86 20:37:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106656; Wed
 17-Sep-86 23:34:14 EDT
Date: Wed, 17 Sep 86 23:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: The name of WITH
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917-131252-7924@Xerox>
Message-ID: <860917233439.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 17 Sep 86 13:12 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    If people really think the name WITH is too short, then the name
    WITH-SLOTS seems like the obvious best name to me.

That sounds good to me too.


∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 00:18:59 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3315; 18 Sep 86 00:14:53 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 19:54:42 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 17 SEP 86 19:53:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106633; Wed
 17-Sep-86 22:51:47 EDT
Date: Wed, 17 Sep 86 22:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proposed Goals (Statement for OOPSLA)
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917-113216-7821@Xerox>
Message-ID: <860917225211.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 17 Sep 86 11:33 PDT
    From: Bobrow.pa@Xerox.COM

    Dick edited Sonya's version, then Danny and Gregor edited his to produce
    this.

All of the changes are okay with me, except that I have problems with the
style of this one:

    In brief, the standard will be based on the meta-object framework of
    CommonLoops, which allows experimentation with different philosophies of
    object-oriented programming.  Additional features from new Flavors will
    be added to CommonLoops to flesh out the programmer interface; in
    particular, a declarative method combination facility patterned after
    that in new Flavors has been added to CommonLoops to create an extension
    to Common Lisp that represents the best features of both systems.   

This confuses what has been done to CommonLoops so far, adding some
Flavors ideas, with the definition of the standard.  Those are two
different things.  I think I understand what you're trying to get at
with this improvement of the earlier version of this paragraph, and I'd
like to propose this revision:

In brief, the standard will be based on the meta-object framework of
CommonLoops, which allows experimentation with different philosophies of
object-oriented programming.  The programmer interface on top of this
framework will combine the most useful features of CommonLoops and New
Flavors, such as multimethods from CommonLoops and declarative method
combination from Flavors.  The standard will be an extension to Common
Lisp that incorporates the best features of both systems.


∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 00:18:23 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3314; 18 Sep 86 00:14:26 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 19:52:38 PDT
Date: 17 Sep 86 19:50 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: DEFCLASS should replace DEFSTRUCT
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 17 Sep 86 19:49 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860917-195238-8313@Xerox>

I disagree (rather violently). I think that the reason that CommonLoops
was originally acceptable to a large class of people was that it did not
add substantially to the complexity of the Language. The acceptability
of CommonLoops partially on that principle, and any movement away from
it risks losing it.

It is certainly not a separable consideration. 

Similarly, a syntax where DEFUN was syntactically compatible with
DEFMETHOD (or whatever its method alias is called) is another important
simplification of Common Lisp. Making a large number of alternative
forms, adding DEFGENERIC, and number of the other proposed extentions
which have been added by this negotiating group are a potentially
drastic movement away from the simplicity in the original proposal. 

I had been misled into believing the discussions on CommonLoopsCore↑ was
an attempt to do some minor tuning on the way that metaclasses were set
up and initialization. Into the conversation for a couple of days, I've
found that things have drifted radically away from what we and many
others have agreed to support.







∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 00:18:08 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3312; 18 Sep 86 00:12:47 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 13:18:15 PDT
Return-Path: <Moon@ALDERAAN.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ALDERAAN.SCRC.Symbolics.COM ([192.10.41.109]) by
 Xerox.COM ; 17 SEP 86 13:17:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 5208; Wed
 17-Sep-86 16:14:22 EDT
Date: Wed, 17 Sep 86 16:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: default optional arguments to a generic function
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To:
 <860916-103819-6832@Xerox>,<860916135909.5.GREGOR@AVALON.XEROX-PARC>
Message-ID: <860917161551.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 16 Sep 86 10:37 PDT
    From: Bobrow.pa@Xerox.COM

	GFD #1. the defaults from the defgeneric are used only for method
		lookup. This is the kind I described above.  

	GFD #2. the defaults from the defgeneric are used for method lookup
		and also passed to the method.

    There is a fundamental conceptual difference.  I think the notion of
    supplying defaults is part of the contract between the generic function
    and the world.  

I agree.

		    This is an argument for GFD #1.  We all seem to agree
    that defmethods, if they specify optionals, must agree with the generic
    function.  If the EQUALS rule is used for defaults (I support this),
    then I see no reason for the default forms to be evaluated twice.  

This is an argument for GFD #2, I assume.  In GFD #1 I don't see how to
avoid evaluating the default forms twice.

								       If
    methods can have exactly the same supplied-p args as specified in the
    generic function (no more, no less - just local renaming allowed) then
    there is no penalty for passing supplied-p args to each method as
    "required args".  The calling sequence is uniform.

Supplied-p parameters are -not- part of the contract between the generic
function and the world, so requiring them to be the same in all methods
is a bit strange.  It's possible that this is the price we have to pay
to make everything work, but it's ugly.

    Given:
    (defgeneric foo (x &optional y (z *v1* supplied-z)) ...)
    then the following is legal
    (defmethod foo ((x c1) &optional ((y c2)) (z *v1* my-supplied-z))) ..)
    and the following are illegal
    (defmethod foo ((x c1) &optional (y NIL supplied-y)(z *v1*
    my-supplied-z))) ..)
    (defmethod foo ((x c1) &optional y (z *v1* ))) ..)

    One issue to be addressed is the following.  If we insist on the EQUALS
    rule, then if the default value form changes in the defgeneric, it must
    be changed in all methods.  This redundancy is bad design.  

On the other hand, not having the default value lexically visible in the
method could be argued by some people as bad design.  It's a difficult
situation.

								To allow
    arg-specification and supplied-p specification, I suggest another
    keyword &optional-spec.  Following &optional-spec can be 
     {varName|(varName arg-specifier [supplied-p-var])}*
    where the interpretation is the obvious one, given in my message of last
    week.  The rule of supplied-p correspondence still holds, but no default
    value form need be specified.

I think we need a better name than &optional-spec, but otherwise this
sounds reasonable, assuming that we want a way to do this.  The message
from Gregor below raises questions about whether discriminating on
optional arguments is going to fly at all.

    Date: Tue, 16 Sep 86 13:59 PDT
    From: Gregor.pa@Xerox.COM
    Subject: the kinds of method lookup people claim they want
    
    I spent lunch today listening to people talk about the kinds of method
    lookup which they would like to have CommonLoops support.  I was struck
    by the variety of things which people claimed would be natural or
    convenient or even essential.  By the end of lunch I was very confused
    about what we should do about discriminating on optional arguments.
    
    In the interest of confusing the rest of you, I thought I would collect a
    list of all the cases of method definition people thought they would
    want.  Please add any other examples or potential screw cases.
    
    NOTE:  In each of these examples I have used some syntax and some
    defining forms which I intend only to express the example.  Do not
    regard the syntax I have used as a proposal for how we should do
    anything.
    
    Case 1a.  "draw-line"
    
    draw-line takes an optional, the width of the line in device dependent
    units.  Because they are device dependent units, each individual method
    would like to default this argument on its own.

    (defmethod draw-line ((dev printer) p1 p2 &optional (width 7))
      ...)
    
    (defmethod draw-line ((dev window) p1 p2 &optional (width 1))
      ...)
    
    Case 1b.
    
    Within case 1, some methods may want to take an extra argument.  Also
    see case 3 which is similar.
    
    (defmethod draw-line ((d gray-display) p1 p2
					   &optional (width 3)
						     (gray *gray1*))
      ..)

The problem here is that the generic function doesn't have a consistent
contract.  The meaning, or even the existence, of one argument depends
on the class of another argument.  I don't see how a caller of draw-line
could operate without knowing the exact method that was going to be called.
From experience I know it's possible to have all sorts of arguments about
whether this is good or bad programming practice.  In New Flavors, these
arguments were resolved in favor of consistency of contracts, rather than
the increased flexibility of different contracts for different methods,
but not everyone was happy.

The rules I proposed earlier for consistency of defgeneric and defmethod
lambda-lists, which Danny seems to agree with, would rule out both 1a and
1b.  I don't know what to say about this; it may be impossible to please
all of the people all of the time.

    Case 2.  "draw (GFD#2)"
    
    The generic function takes an optional argument.  For all the methods,
    the optional argument should default to the same value.  In addition,
    method lookup should be based on the value of the optional argument
    (after defaulting) and the defaulted value should be passed in.  This
    corresponds to what I previously called GFD#2.
    
    (defgeneric draw (thing &optional (place *draw-window*))
      "Draw thing on place.")
    
    (defmethod draw ((thing line) (place raster-display)) ...)
    
    (defmethod draw ((thing line) (place vector-display)) ...)
    
    People have also said that within the individual methods they would like
    to have access to the supplied-p information for the optional argument.
    
Current ideas seem to be able to satisfy this one.

    Case 3.  "move"
    
    A generic function (e.g. move) has only classical methods.  Some of the
    methods want to accept more arguments than others.  For example: move
    when then first argument is a block takes a position to move to, but
    move when the first argument is a rabbit takes no extra arguments (the
    rabbit will jump up and down).
    
    (defmethod move ((b block) to-x to-y) ..)
    
    (defmethod move ((r rabbit)) ..)
    
This is another case where the function isn't really generic, because
it can only be meaningfully called by someone who knows exactly which
method is being called.

    Case 4.  "Guy's proposal"
    
    In this porposal, method lookup checks argument specifiers for only the
    supplied arguments.  When there are two arguments supplied, the most
    specific of the two argument methods is called.
    
      (defmethod foo (a b &optional (c x) (d y)) body)
    
      is simply an abbreviation for
    
      (defmethod foo (a b) (let ((c x) (d y)) body))
      (defmethod foo (a b c) (let ((d y)) body))
      (defmethod foo (a b c d) body)
    
    So that:
    
    (defmethod gls ((a boat) &optional ((p plane) *default*)) ..)
    (defmethod gls ((a speed-boat)) ...)
    
    (foo <a speed-boat>)           ;runs method 2
    (foo <a speed-boat> <a plane>) ;runs method 1

I hope this one has already been discredited as so confusing that no
one can cope with it.

-+-+-+-

Seeing all these different, and maybe not even mutually compatible,
things that people would like us to do, it is possible that we are
going to have to take the conservative approach and say that for now
we are only going to support discrimination on required arguments,
because discrimination on optional and keyword arguments is not yet
well-understood and there is not yet a concensus among users on which
to base a standard.  GFD #2 can be achieved within this framework
by the expedient of defining an "interface function" that defaults
the arguments, for instance:

(defun draw (thing &optional (place *draw-window* place-supplied-p))
  "Draw thing on place."
  (draw-internal thing place place-supplied-p))
    
(defmethod draw-internal ((thing line) (place raster-display) place-supplied-p) ...)
    
(defmethod draw-internal ((thing line) (place vector-display) place-supplied-p) ...)

Flavors provides the feature that you don't have to make
up the auxiliary name draw-internal, which is confusing because
the externally visible interface is named draw but you put methods
on draw-internal.  You do this by (translating out of the present
Flavors syntax, which is too biased against multimethods):

(defgeneric draw (thing &optional (place *draw-window* place-supplied-p))
  "Draw thing on place."
  (:method-arguments thing place place-supplied-p)
  (:function
    (funcall (generic draw) thing place place-supplied-p)))
    
(defmethod draw ((thing line) (place raster-display) place-supplied-p) ...)
    
(defmethod draw ((thing line) (place vector-display) place-supplied-p) ...)


∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 00:16:24 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3311; 18 Sep 86 00:12:31 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 17:02:09 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 17 SEP 86 17:01:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106573; Wed
 17-Sep-86 20:00:05 EDT
Date: Wed, 17 Sep 86 20:00 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: run-super
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917-093011-7680@Xerox>
Message-ID: <860917200030.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 17 Sep 86 09:29 PDT
    From: Kahn.pa@Xerox.COM, Bobrow.pa@Xerox.COM

    Regarding your code

    (DEFINE-METHOD-COMBINATION :SUPER-DAEMON ()
	 ...
      ;; Remove from dependencies the primary methods that cannot be reached
    by RUN-SUPER
      (SETQ PRIMARY (LOOP FOR METHOD IN PRIMARY
			  COLLECT METHOD
			  WHILE (METHOD-USES-RUN-SUPER METHOD)))
      ;; Return appropriate method combining form
      ...)

    The last method in the primary list should be the first one that does
    not use run-super.  

That's exactly what that code does.  You may have been misled by thinking
that LOOP executes its clauses out of order, the way Interlisp FOR does.
The above LOOP stops -after- collecting the method for which
METHOD-USES-RUN-SUPER is false.

			Only if all primary methods use run-super,
    #'RUN-SUPER-EXHAUSTED must be inserted at the end of the list.  

That's true, the list could be shortened by one element in the case
where the last element is unreachable.  I'll put a comment in my copy of
that program saying that it should be optimized.  Also, I forgot to
include #'RUN-SUPER-EXHAUSTED at the end of the list in the
around-method case, in the revised version of the code I mailed out
earlier today.

								    It is
    not an error for all primary methods to call run-super since in some
    contexts the last primary method may be in another position in the
    *SUPERCLASS-CONTINUATIONS* list.  

That's a good point.  That sinks my idea of detecting the
RUN-SUPER-EXHAUSTED at compile time instead of at run time; good, I can
stop worrying about that.

				      We might also then define run-super?
    that returns NIL if the next continuation  is #'RUN-SUPER-EXHAUSTED.

Yes, we could do that.  Note that standard Common Lisp functions aren't
allowed to have question marks in their names, but I'm sure we could think
of a better name.


∨
Received: from REAGAN.AI.MIT.EDU by AI.AI.MIT.EDU 18 Sep 86 00:16:09 EDT
Received: from Xerox.COM (XEROX.COM) by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 3310; 18 Sep 86 00:12:20 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 16:51:18 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 17 SEP 86 16:50:58 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106567; Wed
 17-Sep-86 19:49:30 EDT
Date: Wed, 17 Sep 86 19:49 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: DEFCLASS should replace DEFSTRUCT
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917-101441-7733@Xerox>
Message-ID: <860917194955.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 17 Sep 86 10:14 PDT
    From: Ken Kahn <Kahn.pa@Xerox.COM>

    A few months ago we believed that CommonLoops could just extend
    DEFSTRUCT to deal with multiple inheritance and metaclasses.  Then there
    was this idea that DEFSTRUCT did some things poorly and we could do them
    better in DEFCLASS.  I am willing to agree to this if the spec proposes
    that we flush DEFSTRUCT from Common Lisp and provide a DEFSTRUCT macro
    for backwards compatibility that is mostly implemented in CommonLoops.
    Why should anyone use DEFSTRUCT anymore?

I believe this should be proposed as a separate standardization item.
I don't think the object-oriented programming standard should stand or
fall on the basis of irrelevant considerations such as whether someone
out there is particularly attached to DEFSTRUCT.


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 21:10:12 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 14:54:07 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 17 SEP 86 14:53:56 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 106466; Wed
 17-Sep-86 17:41:42 EDT
Date: Wed, 17 Sep 86 17:41 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Getting together to work
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860914-111121-5339@Xerox>
Message-ID: <860917174139.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 14 Sep 86 11:11 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>
    ....

The conclusion, after various discussions, is that Sonya Keene, Dave
Moon, and Dan Weinreb will be in Palo Alto from Thursday October 2
through Sunday October 5.  Exact times to be figured out later, but
basically all of Friday and Saturday will be available, possibly late
Thursday, and probably none of Sunday.  I'll send mail with exact times
when we know the flight times.

This what Gregor proposed originally.  I would have liked to have met
before OOPSLA instead, but it proved to be impossible.  I assume we'll
have intense working sessions on the details of the standard for these
two days, with people from Lucid, Symbolics, and Xerox.  Gregor, you're
going to arrange a meeting room and make sure people show up and stuff
like that, right?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 21:10:02 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 13:26:58 PDT
Date: 17 Sep 86 13:26 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: required-xxx options to defclass
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860917-132658-7944@Xerox>

This seems to be an issue that remains to be worked out about defclass.

Until yesterday, I was the only west coast supporter of the
:required-methods etc. options to defclass.  But I have finally given in
and conceded that maybe these should not be in the standard.

I had been able to convince people that these options were not, in fact,
merely a programming environment feature.  But I finally succumbed to
the argument that:

These options are just hack implementations of something which
*protocols* would do right.  Given that we don't have protocols, and we
don't want to clutter the spec with hacks, we should not include these
options.  Then, when we do figure out how to do protocols "right", there
won't be these old, obsolete required-xxx options hanging around.

How do you feel about not having :required-xxx options in the standard?
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 18:19:42 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 13:18:01 PDT
Return-Path: <Moon@ALDERAAN.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ALDERAAN.SCRC.Symbolics.COM ([192.10.41.109]) by
 Xerox.COM ; 17 SEP 86 13:17:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 5189; Wed
 17-Sep-86 15:42:59 EDT
Date: Wed, 17 Sep 86 15:44 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: run-super, whoppers, wrappers
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860917-082814-7626@Xerox>
Message-ID: <860917154410.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 17 Sep 86 08:29 PDT
    From: Bobrow.pa@Xerox.COM

	 To simplify things, I removed :AROUND methods from this version, but
	 it would only take a few lines of code to put them back in if we wished
	 to do so.

    I would like to see the addition for :around. (What do you think
    changing ":around" to ":full-shadow"?)  

The same as I thought on 11 September
(Message-ID: <860911172500.4.MOON@EUPHRATES.SCRC.Symbolics.COM>):
The name :full-shadow doesn't convey much meaning to my ear.

I'm not at all attached to the name "around".  I was just using it in
the absence of anything better, since it was the name someone else (I
forget who) mentioned.  Actually "around" seems to fit with "before" and
"after" better than "full-shadow".  I'd say that "around" is a somewhat
clearer name than "full-shadow", which is miles better than "whopper".
If we can find a clearer name than any of these, I'm all for it.

I should mention again that these "around" methods are different from
whoppers, in that they are implemented by a particular type of method
combination, rather than being available automatically to all types of
method combination.  If the standard said that all types of method
combination should support "around" methods, then either life would be
more difficult for a user wanting to define his own type of method
combination or we would have to subroutinize things so that it was
trivially easy for that user to include "around" support.  I assume
that subroutinization is possible, but I haven't thought out the details.

I may not have made it clear that I don't care whether whoppers per se
are in the standard as long as there is something with equivalent
functionality in the standard.  "Around" methods would suffice, I think.

Wrappers appear to be more powerful than "around" methods, at least in
terms of efficiency (eliminating function calls), but perhaps that can
be licked with an INLINE proclamation; I ought to think about this more.
For purposes of agreement before OOPSLA you don't need to think about
wrappers at all; I'll bring them up later if I don't convince myself
they aren't needed.

					    The particular feature I am interested
    in is how you express the transformation of a form to a method. 

The same way you always convert a form to a function, with lambda.  The
code is at the end of this message.

								    Is
    this what your were referring to in:
	 ;;;; This scheme uses more machine-dependencies to avoid
	 ;;;; an extra level of lambda in the continuations.

Not exactly.  The two earlier implementations of run-super required an
extra lambda for every method called by run-super, for no good reason.
The body of the lambda was just a call-component-method of the method, I
think.  This version eliminates those and calls the methods directly.
The cost of this efficiency improvement is that the RUN-SUPER macrolet
put into methods by TRANSFORM-SUPER-DAEMON-METHOD has to contain
additional hair to pass the arguments along, instead of just funcalling
the continuation with no arguments, and hence more of the Flavors
implementation is visible instead of abstracted out of sight; more about
this below.

	 The important thing is the semantics of how RUN-SUPER and
	 method-combination fit together, which is:
	   all the :BEFORE methods are executed, most-specific first the
	   most specific primary method is executed, and supplies the value(s)
	     if it uses RUN-SUPER, that calls the next primary method,
	     and so on if RUN-SUPER exhausts the supply of primary methods, it
	     signals an error
	   all the :AFTER methods are executed, least-specific first

	 Shall we make this the default method-combination type, or does
	 anyone object?  (Myself, I object to the name RUN-SUPER, and maybe we
	 can think of a more expressive name.  If not, I can live with that one.)

    I am happy with this as the default. I have no better name than run-super.
    run-continuation is not semantically correct, and super has a history people
    can relate to.  

Agreed.

		    I don't like the name "super-daemon" or even "daemon",
    although history rgues for each of those. How about "simple-nested". or just
    "nested" sincer the primary is nested in befores and afters, and run-super
    does dynamically controlled nesting.

"super-daemon" was just a name I was using in the absence of a suggested
name and wasn't a proposal for the standard.  I needed a name so I could
debug my code without clobbering the existing Flavors code.  In the
standard there would be no need to have two distinct method-combination
types, one that does daemons but not run-super, and another that does
daemons and run-super, so fewer names would be required.  "Nested"
doesn't convey any meaning to my ear.  The way to really wimp out would
be to call this type of method-combination "default", since it will be
the default type.  I'd rather have a more descriptive name, though.  Any
ideas?  My default assumption for right now is that it will be named
"daemon", but I'm not attached to that name.  We don't actually need a
name for this in order to reach agreement on the list of things I
proposed last night as a reasonable agenda for the document to be handed
out at OOPSLA.

    I would want to describe super-daemon in the spec in pieces.
    The first would describe the specifcation of run-super alone as in Loops.  Then
    I would describe standar declarative method combination, and the interaction.
    Finally, I would want to describe the method combination language that allows 
    these to be defined.

This sounds good.  This is an extension of the way we do it now:
First we describe solitary methods so there is no combination issue.
Then we describe having one primary method shadow another.  Here you
add run-super.  Then we describe :before, :after, and now :around methods.
Then we describe other built-in types of method-combination.  Then we
describe how to make your own types of method-combination.

Here is the revised code for the method-combination type.  The only
other change is to make TRANSFORM-SUPER-DAEMON-METHOD treat around
methods the same as primary methods.  Note that if I was going to
install this code I would first want to define some more abstractions,
similar to CALL-COMPONENT-METHOD, to hide the messy and
machine-dependent details of the method calling sequences.  I didn't do
that in this version because I wanted to make it work first and then
think about what the appropriate abstractions would be.  Another thing I
would want to do is to redo the STACK-LET since those lists are actually
constant, changing only when a change to the class structure occurs or a
method is redefined.  For this version I construct the continuation list
every time, and then use STACK-LET instead of LET to eliminate the
consing, but it would be better to construct the list once and arrange
for it to be updated when the class structure changes.  This is the sort
of place where I start wishing for meta-object protocols.  I don't want
to spend time thinking about this until after OOPSLA, but for now I'm
assuming that the Common Lisp Classes version of this
DEFINE-METHOD-COMBINATION would be much less ugly, because it would be
built on top of those abstractions and protocols.

(DEFINE-METHOD-COMBINATION :SUPER-DAEMON ()
     ((AROUND "around" :EVERY :MOST-SPECIFIC-FIRST (:AROUND))
      (BEFORE "before" :EVERY :MOST-SPECIFIC-FIRST (:BEFORE))
      (PRIMARY "primary" :EVERY :MOST-SPECIFIC-FIRST () :DEFAULT)
      (AFTER "after" :EVERY :MOST-SPECIFIC-LAST (:AFTER)))
     (:ARGLIST IGNORE &REST ARGS)
     (:METHOD-TRANSFORMER
       ;; Deal with run-super by transforming the method's arglist and body
       (:METHOD-ARGLIST
	 (MULTIPLE-VALUE-SETQ (METHOD-ARGLIST METHOD-BODY)
	   (TRANSFORM-SUPER-DAEMON-METHOD FUNCTION-SPEC METHOD-ARGLIST METHOD-BODY)))
       (:METHOD-BODY METHOD-BODY))
  ;; If there are no daemons, the code produced can be optimized
  (UNLESS (OR BEFORE AFTER)
    (SETQ PRIMARY (NCONC AROUND PRIMARY)
	  AROUND NIL))
  ;; Remove from dependencies the primary methods that cannot be reached by RUN-SUPER
  (SETQ PRIMARY (LOOP FOR METHOD IN PRIMARY
		      COLLECT METHOD
		      WHILE (METHOD-USES-RUN-SUPER METHOD)))
  ;; Return appropriate method combining form
  (IF (NULL AROUND)
      `(MULTIPLE-VALUE-PROG2
	 ,(CALL-COMPONENT-METHODS BEFORE)
	 ,(COND ((NULL PRIMARY) `NIL)
		((AND (NULL (REST PRIMARY))
		      (NOT (METHOD-USES-RUN-SUPER (FIRST PRIMARY))))
		 (CALL-COMPONENT-METHOD (FIRST PRIMARY)))	;Optimize single-method case
		(T
		 ;; Stash the machine-dependent information needed for run-super,
		 ;; then call the first primary method, which will call the rest of them.
		 `(STACK-LET ((*SUPERCLASS-CONTINUATIONS*
				(LIST ,@(LOOP FOR METHOD IN (REST PRIMARY)
					      COLLECT `(FUNCTION ,METHOD)
					      COLLECT `(GET-FLAVOR-MAPPING-TABLE-FOR-INSTANCE
							 SELF ',(METHOD-FLAVOR METHOD)))
				      #'RUN-SUPER-EXHAUSTED)))
		    ,(CALL-COMPONENT-METHOD (FIRST PRIMARY)))))
	 ,(CALL-COMPONENT-METHODS AFTER))
      ;; With both AROUND methods and daemons, need an internal method to call the daemons
      ;; and *SUPERCLASS-CONTINUATIONS* has to be bound around the whole thing
      `(STACK-LET ((*SUPERCLASS-CONTINUATIONS*
		     (LIST ,@(LOOP FOR METHOD IN (REST AROUND)
				   COLLECT `(FUNCTION ,METHOD)
				   COLLECT `(GET-FLAVOR-MAPPING-TABLE-FOR-INSTANCE
					      SELF ',(METHOD-FLAVOR METHOD)))
			   ;;--- The arglist of this lambda should be hidden by an
			   ;;--- abstraction, which would also allow it to not need
			   ;;--- to use &REST all the time
			   #'(LAMBDA (SELF SELF-MAPPING-TABLE .GENERIC. &REST ,ARGS)
			       (MULTIPLE-VALUE-PROG2
				 ,(CALL-COMPONENT-METHODS BEFORE)
				 ,(CALL-COMPONENT-METHOD (FIRST PRIMARY))
				 ,(CALL-COMPONENT-METHODS AFTER)))
			   SELF-MAPPING-TABLE
			   ,@(LOOP FOR METHOD IN (REST PRIMARY)
				   COLLECT `(FUNCTION ,METHOD)
				   COLLECT `(GET-FLAVOR-MAPPING-TABLE-FOR-INSTANCE
					      SELF ',(METHOD-FLAVOR METHOD))))))
	 ,(CALL-COMPONENT-METHOD (FIRST AROUND)))))

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 18:16:02 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 13:12:52 PDT
Date: 17 Sep 86 13:12 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: The name of WITH
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860917-131252-7924@Xerox>

If people really think the name WITH is too short, then the name
WITH-SLOTS seems like the obvious best name to me.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 15:55:41 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 11:51:57 PDT
Date: 17 Sep 86 11:47 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: What we should agree on before OOPSLA
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 16 Sep 86 20:50 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860917-115157-7842@Xerox>

This list looks pretty good to me.

I believe that Sonya's message is a good start for Part 1.  I know that
we have some small changes we want to make to it.  These will be in a
separate message.

I believe that the spec we are working on will satisfy Part 2, once we
work out the basic language facilities to be covered.  I agree that we
can work out all the basic language details you included at the end of
your message.  In addition, we may be able to come to some agreement on
optional arguments, I am not quite ready to quit on this.  

You may be right that we should not include what we have so far for
meta-object protocols.  You are certainly right that we don't have time
to tighten this up.

As I said yesterday, I hope to FEDx a spec to you by the end of the day
today.

In addition, I will try to send messages giving our current status for:

some defclass options which are unresolved,
with
describe-object
define-method-combination

I think these (except define-method-combination) should be easy to
resolve and can they be put in the spec easily.


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 15:55:20 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 11:32:16 PDT
Date: 17 Sep 86 11:33 PDT
From: Bobrow.pa@Xerox.COM
Subject: Proposed Goals (Statement for OOPSLA)
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM
Message-ID: <860917-113216-7821@Xerox>

Dick edited Sonya's version, then Danny and Gregor edited his to produce
this.


       TOWARD A COMMON LISP STANDARD FOR OBJECT-ORIENTED PROGRAMMING

This brief paper summarizes the work that is now going on toward
defining a
new Common Lisp standard for object-oriented programming.

HISTORY AND MOTIVATION

There is currently substantial experience with object-oriented
programming paradigms within a variety of contexts. The two groups
have have the most experience in this area are Symbolics and Xerox.

Flavors, an important object-oriented programming extension to Lisp,
has been in use for more than 7 years. Over that period many valuable
lessons
have been learned about object-oriented programming in Lisp. In 1985,
Symbolics took these lessons to heart and designed New Flavors, which
is a compatible extension to Flavors.

Xerox has had more than 10 years of experience with object-oriented
programming, both within the Lisp tradition and within the Smalltalk
tradition.  Over that period many lessons were learned, and in 1985
Xerox
began to design a new object-oriented programming extension to Common
Lisp, called CommonLoops.

In mid-1985 these two groups became aware of each other.  These 
two object-oriented extensions to Lisp had important similarities.
CommonLoops evolved to include some of the ideas in new Flavors.

Many people in the Common Lisp community now see a need for defining a
standard for object-oriented programming that would be part of Common
Lisp.  The primary benefit of such a standard would be the ability to
write portable Common Lisp code in an object-oriented style.

At the Common Lisp committee meeting in Boston in December 1985, many
vendors of application software made it clear how important such a
standard is to them.  Again at the ACM Conference on Lisp and Functional
Programming in Cambridge in August 1986, the same point was made.

After the ACM Conference there was a meeting of the Common Lisp
Object-oriented Programming Committee.  A clear consensus was reached
that
work should begin immediately to define a standard.  Representatives
from Xerox, Lucid, Symbolics, LMI, HP, Sun, and the Japanese CommonLisp
committee supported this consensus.

A working group composed of representatives from Xerox and Symbolics met
after the ACM Conference; at the meeting this working group reached
agreement on several general goals.

In brief, the standard will be based on the meta-object framework of
CommonLoops, which allows experimentation with different philosophies of
object-oriented programming.  Additional features from new Flavors will
be added to CommonLoops to flesh out the programmer interface; in
particular, a declarative method combination facility patterned after
that in new Flavors has been added to CommonLoops to create an extension
to Common Lisp that represents the best features of both systems.   

PROGRESS IN AUGUST AND SEPTEMBER

During August and September, representatives from Xerox, Symbolics, and
Lucid began work on a draft specification of the standard.  This working
group started with the basic programmer interface for defining new
classes
and writing methods and generic functions.  This work is ongoing, but a
draft of the programmer interface is available - the meta-object
protocol
specification will be available soon.

GOALS FOR THE STANDARD

Some high-level goals were stated and agreed-upon:

Sound basis     The standard will include the aspects of object-oriented
                programming that are well-understood at this time.  The
                standard will omit ideas that are still subjects for
                research.

Flexibility     The meta-object protocol of the standard will offer a
                flexible framework for other designers to implement
                different schemes.  This encourages exploration of
                different styles of object-oriented programming.

Power           The standard will offer the basic tools for writing
                programs in an object-oriented style, and will be
powerful
                enough that it meets the needs of most programs.  It
should
                not be necessary for programmers to extend the system to
do
                straightforward object-oriented programming.

Simplicity      The standard will specify just the language, not the
                programming tools and interactive development
environment.

Compatibility   It should be a convenient and simple procedure to
translate
                programs written in CommonLoops or New Flavors to the
new
                standard.  We intend to provide tools that will perform
the
                translation automatically.

Implementation  The standard will allow efficient implementation on
stock
                hardware as well as specialized machines.
                                                                        
FEATURES TO BE INCLUDED IN THE STANDARD

The following features wil be included in the standard..  This is not an
exhaustive list, but is intended to communicate some of the areas of
agreement that have been reached.

Generic functions
                The standard will use the normal Lisp function-calling
                syntax.

Class and Type Space Merging
                Every object in the Lisp system has a class and hence
can
                be used to select methods.

Dispatching     The standard will allow dispatching on the class of one
                (classical methods) or more (multi-methods) arguments.

Multiple inheritance
                Classes can be combined together freely; they
                need not fit into a rigid hierarchy.

Meta-objects    The standard defines objects for the major
implementation
                entities of the system to allow for extensibility.
                Classes, methods, and generic functions all have
                corresponding objects, organized by well-defined,
                documented protocols.

Declarative Method Combination
                Method selection and combination can be controlled
                declaratively.  Users can define new
                method combination paradigms.

FUTURE PLANS

The working group is developing a draft specification for the
standard.  The specification process will involve the community in the
feedback process.

Portable Common Loops will evolve to to track the new specification.
This portable implementation will enable the community to experiment
with and
gain a deeper understanding of the ideas than is possible with only a
specification.



  
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 15:54:53 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 09:24:58 PDT
Redistributed: CommonLoopsCore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 09:24:43 PDT
Date: 17 Sep 86 09:21 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: default optional arguments to a generic function
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 15 Sep 86 23:57 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860917-092458-7674@Xerox>

Unfortunately, the most important typo in my GFD#1 and GFD#2 message is
that I said I was leaning towards GFD#1.  In fact, I lean towards #2.

	GFD #1. the defaults from the defgeneric are used only for method
		lookup. This is the kind I described above.  

	GFD #2. the defaults from the defgeneric are used for method lookup
		and also passed to the method.

Doesn't your anecdote, which provides a good example of why two methods
should not be allowed to have different default value forms also support
GFD#2?

     Date: Mon, 15 Sep 86 23:57 EDT
     From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
     
     Because of supplied-p parameters, I have to back off on this.

Supplied-p parameters are what confuse me too.  Let me recap my thinking
on this.

I think of the arguments that the generic function accepts as being part
of its contract with the world.  I think of any argument defaulting done
on those arguments as being part of that same contract (I lean towards
GFD#2).

But supplied-p information doesn't have anything to do with the
generic's contract with the world.  Instead, supplied-p information
seems to me to be part of the generic functions contract with its
methods.

For me, the question about supplied-p arguments comes down to deciding
if these two contracts (generic---world, generic---methods) are the
*same*.  In other words, the lambda list which appears in the defgeneric
clearly specifies the generic-world contract, the question is to what
extent does it also specify the generic-methods contract.

If we make the defgeneric completely specify both contracts, then the
defgeneric must say which arguments the methods can (and must) get
supplied-p information for.

If the defgeneric does not specify which arguments supplied-p
information is available for, but rather methods can ask for this
information on a per-method basis, I get confused.


     To compare two lambda-lists for consistency, use the following
rules:

I want to try to re-write these rules to get rid of this EQUAL rule
about optional argument default value forms.  In order to do that, I am
going to ignore the issue of supplied-p arguments (by not allowing
methods to get their hands on that information), and I am going to
assume that defgenerics are required.  Note that my rules compare
defgeneric lambda lists to defmethod lambda lists.

1. The method must accept as required arguments the sum of the generic's
   required optional and rest arguments.

2. &optional may not appear in a defmethod lambda list (an extension
would
   allow this in the case where the defgeneric lambda list has neither
&key
   nor &rest).

3. The method must accept the same keywords as the generic;
   OR it can accept a subset of the ones in the defgeneric if it has
   &allow-other-keys;
   OR it can accept a superset of the ones in the defgeneric if the
   defgeneric has &allow-other-keys.

4. &aux is not allowed in defgenerics, it is allowed in defmethods with
the
   usual meaning.

Here are some examples:

(defgeneric draw (thing &optional (place *drawing-place*)))

(defmethod draw ((thing box) (place window)) ...)
(defmethod draw ((thing box) (place printer)) ...)


(defgeneric save (file &rest things))

(defmethod save ((file fancy-file) things) ...)


(defgeneric shape (thing &optional &key width height &allow-other-keys))

(defmethod shape ((r rectangle) &key width height) ...)
(defmethod shape ((c circle) &key radius) ...)


I another message, I will send a minimal proposal about defmethod
arguments which I think provides all the functionality we really
understand, and could be extended to any optional argument scheme we
eventually work out.  If, by friday, we have settled on a scheme that
works for optional arguments I suggest we put this minimal proposal in
the spec to take to DC and OOPSLA.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 15:54:23 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 10:14:41 PDT
Date: 17 Sep 86 10:14 PDT
Sender: Kahn.pa@Xerox.COM
Subject: DEFCLASS should replace DEFSTRUCT
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Kahn.pa@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860917-101441-7733@Xerox>

A few months ago we believed that CommonLoops could just extend
DEFSTRUCT to deal with multiple inheritance and metaclasses.  Then there
was this idea that DEFSTRUCT did some things poorly and we could do them
better in DEFCLASS.  I am willing to agree to this if the spec proposes
that we flush DEFSTRUCT from Common Lisp and provide a DEFSTRUCT macro
for backwards compatibility that is mostly implemented in CommonLoops.
Why should anyone use DEFSTRUCT anymore?  CommonLoops can provide a
STRUCTURE-CLASS metaclass that provides the same performance/capability
trade-offs as current DEFSTRUCT.  The :TYPE option is weird but it could
still be supported, so that instances and "structures" built out of
lists and vectors can be made and accessed in a uniform manner
(MAKE-INSTANCE, GET-SLOT...).  CLASS-OF won't work on them so one can't
put methods on them but that's the case in any case.  16 pages of the
Silver Book could go away if DEFSTRUCT is flushed.  It would be a shame
if Common Lisp had to have two ways of defining structured objects, one
of which subsumes the other.

In Sonya's message about goals she states:

    Simplicity      The standard will specify just the language, not the
                    programming tools and interactive development
environment.

I think a more important aspect of Simplicity is that the language
specified not be unduely complex.  Adding DEFCLASS and not removing
DEFSTRUCT clearly does add unneccessary complexity.

----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 15:54:01 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 09:30:11 PDT
Date: 17 Sep 86 09:29 PDT
Sender: Kahn.pa@Xerox.COM
Subject: Re: run-super
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 16 Sep 86 17:10 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
From: Kahn.pa@Xerox.COM, Bobrow.pa@Xerox.COM
Message-ID: <860917-093011-7680@Xerox>

Regarding your code

(DEFINE-METHOD-COMBINATION :SUPER-DAEMON ()
     ...
  ;; Remove from dependencies the primary methods that cannot be reached
by RUN-SUPER
  (SETQ PRIMARY (LOOP FOR METHOD IN PRIMARY
		      COLLECT METHOD
		      WHILE (METHOD-USES-RUN-SUPER METHOD)))
  ;; Return appropriate method combining form
  ...)

The last method in the primary list should be the first one that does
not use run-super.  Only if all primary methods use run-super,
#'RUN-SUPER-EXHAUSTED must be inserted at the end of the list.  It is
not an error for all primary methods to call run-super since in some
contexts the last primary method may be in another position in the
*SUPERCLASS-CONTINUATIONS* list.  We might also then define run-super?
that returns NIL if the next continuation  is #'RUN-SUPER-EXHAUSTED.


----- ken and danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 13:27:55 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 17 SEP 86 09:24:58 PDT
Redistributed: CommonLoopsCore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 09:24:43 PDT
Date: 17 Sep 86 09:21 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: default optional arguments to a generic function
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 15 Sep 86 23:57 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860917-092458-7674@Xerox>

Unfortunately, the most important typo in my GFD#1 and GFD#2 message is
that I said I was leaning towards GFD#1.  In fact, I lean towards #2.

	GFD #1. the defaults from the defgeneric are used only for method
		lookup. This is the kind I described above.  

	GFD #2. the defaults from the defgeneric are used for method lookup
		and also passed to the method.

Doesn't your anecdote, which provides a good example of why two methods
should not be allowed to have different default value forms also support
GFD#2?

     Date: Mon, 15 Sep 86 23:57 EDT
     From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
     
     Because of supplied-p parameters, I have to back off on this.

Supplied-p parameters are what confuse me too.  Let me recap my thinking
on this.

I think of the arguments that the generic function accepts as being part
of its contract with the world.  I think of any argument defaulting done
on those arguments as being part of that same contract (I lean towards
GFD#2).

But supplied-p information doesn't have anything to do with the
generic's contract with the world.  Instead, supplied-p information
seems to me to be part of the generic functions contract with its
methods.

For me, the question about supplied-p arguments comes down to deciding
if these two contracts (generic---world, generic---methods) are the
*same*.  In other words, the lambda list which appears in the defgeneric
clearly specifies the generic-world contract, the question is to what
extent does it also specify the generic-methods contract.

If we make the defgeneric completely specify both contracts, then the
defgeneric must say which arguments the methods can (and must) get
supplied-p information for.

If the defgeneric does not specify which arguments supplied-p
information is available for, but rather methods can ask for this
information on a per-method basis, I get confused.


     To compare two lambda-lists for consistency, use the following
rules:

I want to try to re-write these rules to get rid of this EQUAL rule
about optional argument default value forms.  In order to do that, I am
going to ignore the issue of supplied-p arguments (by not allowing
methods to get their hands on that information), and I am going to
assume that defgenerics are required.  Note that my rules compare
defgeneric lambda lists to defmethod lambda lists.

1. The method must accept as required arguments the sum of the generic's
   required optional and rest arguments.

2. &optional may not appear in a defmethod lambda list (an extension
would
   allow this in the case where the defgeneric lambda list has neither
&key
   nor &rest).

3. The method must accept the same keywords as the generic;
   OR it can accept a subset of the ones in the defgeneric if it has
   &allow-other-keys;
   OR it can accept a superset of the ones in the defgeneric if the
   defgeneric has &allow-other-keys.

4. &aux is not allowed in defgenerics, it is allowed in defmethods with
the
   usual meaning.

Here are some examples:

(defgeneric draw (thing &optional (place *drawing-place*)))

(defmethod draw ((thing box) (place window)) ...)
(defmethod draw ((thing box) (place printer)) ...)


(defgeneric save (file &rest things))

(defmethod save ((file fancy-file) things) ...)


(defgeneric shape (thing &optional &key width height &allow-other-keys))

(defmethod shape ((r rectangle) &key width height) ...)
(defmethod shape ((c circle) &key radius) ...)


I another message, I will send a minimal proposal about defmethod
arguments which I think provides all the functionality we really
understand, and could be extended to any optional argument scheme we
eventually work out.  If, by friday, we have settled on a scheme that
works for optional arguments I suggest we put this minimal proposal in
the spec to take to DC and OOPSLA.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 17 Sep 86 11:59:23 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 17 SEP 86 08:28:14 PDT
Date: 17 Sep 86 08:29 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: run-super
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 16 Sep 86 17:10 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860917-082814-7626@Xerox>

     To simplify things, I removed :AROUND methods from this version, but
     it would only take a few lines of code to put them back in if we wished
     to do so.

I would like to see the addition for :around. (What do you think
changing ":around" to ":full-shadow"?)  The particular feature I am interested
in is how you express the transformation of a form to a method. Is
this what your were referring to in:
     ;;;; This scheme uses more machine-dependencies to avoid
     ;;;; an extra level of lambda in the continuations.
 
That is, would you please fix up the following rough form of
the body of whopper-super-daemon combination. 
What would it look like in Common Lisp?  Thanks.  

(STACK-LET ((*SUPERCLASS-CONTINUATIONS*
			    (LIST ,@(LOOP FOR METHOD IN (REST AROUND)
					  COLLECT `(FUNCTION ,METHOD)
					  COLLECT `(GET-FLAVOR-MAPPING-TABLE-FOR-INSTANCE
						     SELF ',(METHOD-FLAVOR METHOD)))
				  (make-method-from-form `(MULTIPLE-VALUE-PROG2 ...))
;;; the (MULTIPLE-VALUE-PROG2 ...) is the body found in the referenced message.
;;; this last form transforms that expression appropriately 
                     )))
		,(CALL-COMPONENT-METHOD (FIRST AROUND)))))    


---
     The important thing is the semantics of how RUN-SUPER and
     method-combination fit together, which is:
       all the :BEFORE methods are executed, most-specific first the
       most specific primary method is executed, and supplies the value(s)
         if it uses RUN-SUPER, that calls the next primary method,
         and so on if RUN-SUPER exhausts the supply of primary methods, it
         signals an error
       all the :AFTER methods are executed, least-specific first

     Shall we make this the default method-combination type, or does
     anyone object?  (Myself, I object to the name RUN-SUPER, and maybe we
     can think of a more expressive name.  If not, I can live with that one.)

I am happy with this as the default. I have no better name than run-super.
run-continuation is not semantically correct, and super has a history people
can relate to.  I don't like the name "super-daemon" or even "daemon",
although history rgues for each of those. How about "simple-nested". or just
"nested" sincer the primary is nested in befores and afters, and run-super
does dynamically controlled nesting.

I would want to describe super-daemon in the spec in pieces.
The first would describe the specifcation of run-super alone as in Loops.  Then
I would describe standar declarative method combination, and the interaction.
Finally, I would want to describe the method combination language that allows 
these to be defined.



∨
Received: from Xerox.COM by AI.AI.MIT.EDU 16 Sep 86 23:24:08 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 16 SEP 86 16:24:56 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 16 SEP 86 16:23:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 81031;
 Tue 16-Sep-86 17:10:40 EDT
Date: Tue, 16 Sep 86 17:10 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: run-super
To: CommonLoopsCore↑.pa@Xerox.COM
References: <860905004612.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860916171027.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

The referenced message, from 5 September, contains two implementations
of RUN-SUPER in Flavors.  This message contains a third implementation
that eliminates some problems with the other two implementations, which
were discussed in that message.  All three of these implementations have
been tested and work.  To simply things, I removed :AROUND methods from
this version, but it would only take a few lines of code to put them
back in if we wished to do so.

I see no reason why this couldn't be the default method-combination type
in Common Lisp Classes.  Compilation will be a little slower than in
Flavors, but not much slower, and code that doesn't use run-super will
not pay any efficiency cost, while code that does use run-super will be
quite efficient.

Of course this exact implementation could not be used, because it uses
Flavors interfaces in place of meta-object protocols, uses Symbolics'
code-walker rather than one that can be assumed to be present in every
implementation, and contains machine-dependencies, especially connected
with the way method dispatching works in our system.  That's not
important, the important thing is the semantics of how RUN-SUPER and
method-combination fit together, which is:
  all the :BEFORE methods are executed, most-specific first
  the most specific primary method is executed, and supplies the
value(s)
    if it uses RUN-SUPER, that calls the next primary method, and so on
    if RUN-SUPER exhausts the supply of primary methods, it signals an
error
  all the :AFTER methods are executed, least-specific first

Shall we make this the default method-combination type, or does anyone
object?  (Myself, I object to the name RUN-SUPER, and maybe we can think
of a more expressive name.  If not, I can live with that one.)

Most of the hair in this code is connected with optimizations so that if
run-super is not used, the compiled code is exactly the same as in
Flavors
:daemon method-combination (no extra overhead for run-super).

;;;; Dynamically plus lexically scoped version, avoids problems of both
the above.
;;;; This scheme uses more machine-dependencies to avoid an extra level
of
;;;; lambda in the continuations.
;;;; I removed :AROUND methods but they could easily be added back in.

;;; List of alternating methods and self-mapping-tables, used by
RUN-SUPER
(DEFVAR *SUPERCLASS-CONTINUATIONS*)

;;; Shadowed by a MACROLET
(DEFUN RUN-SUPER ()
  (ERROR "RUN-SUPER not called from a proper lexical environment.
RUN-SUPER is only valid in a primary method with :SUPER-DAEMON
method-combination."))

;;; Appears at the tail of *SUPERCLASS-CONTINUATIONS*
;;; Change this to a function that just returns NIL if you prefer that
semantics
(DEFUN RUN-SUPER-EXHAUSTED (&REST IGNORE)
  (ERROR "RUN-SUPER called from the least specific method; no more
methods are available."))

(DEFINE-METHOD-COMBINATION :SUPER-DAEMON ()
     ((BEFORE "before" :EVERY :MOST-SPECIFIC-FIRST (:BEFORE))
      (PRIMARY "primary" :EVERY :MOST-SPECIFIC-FIRST () :DEFAULT)
      (AFTER "after" :EVERY :MOST-SPECIFIC-LAST (:AFTER)))
     (:METHOD-TRANSFORMER
       ;; Deal with run-super by transforming the method's arglist and
body
       (:METHOD-ARGLIST
	 (MULTIPLE-VALUE-SETQ (METHOD-ARGLIST METHOD-BODY)
	   (TRANSFORM-SUPER-DAEMON-METHOD FUNCTION-SPEC METHOD-ARGLIST
METHOD-BODY)))
       (:METHOD-BODY METHOD-BODY))
  ;; Remove from dependencies the primary methods that cannot be reached
by RUN-SUPER
  (SETQ PRIMARY (LOOP FOR METHOD IN PRIMARY
		      COLLECT METHOD
		      WHILE (METHOD-USES-RUN-SUPER METHOD)))
  ;; Return appropriate method combining form
  `(MULTIPLE-VALUE-PROG2
     ,(CALL-COMPONENT-METHODS BEFORE)
     ,(COND ((NULL PRIMARY) `NIL)
	    ((AND (NULL (REST PRIMARY))
		  (NOT (METHOD-USES-RUN-SUPER (FIRST PRIMARY))))
	     (CALL-COMPONENT-METHOD (FIRST PRIMARY)))	;Optimize single-method
case
	    (T
	     ;; Stash the machine-dependent information needed for run-super,
	     ;; then call the first primary method, which will call the rest of
them.
	     `(STACK-LET ((*SUPERCLASS-CONTINUATIONS*
			    (LIST ,@(LOOP FOR METHOD IN (REST PRIMARY)
					  COLLECT `(FUNCTION ,METHOD)
					  COLLECT `(GET-FLAVOR-MAPPING-TABLE-FOR-INSTANCE
						     SELF ',(METHOD-FLAVOR METHOD)))
				  #'RUN-SUPER-EXHAUSTED)))
		,(CALL-COMPONENT-METHOD (FIRST PRIMARY)))))
     ,(CALL-COMPONENT-METHODS AFTER)))

;;; Determine whether this method needs a binding of
*SUPERCLASS-CONTINUATIONS*
;;; This works by calling a machine-dependent facility
(DEFUN METHOD-USES-RUN-SUPER (FUNCTION-SPEC)
  (MULTIPLE-VALUE-BIND (VALUE FOUND)
      (COMPILER:FILE-DECLARATION FUNCTION-SPEC 'USES-RUN-SUPER)
    (IF FOUND VALUE (SI:FUNCTION-SPEC-GET FUNCTION-SPEC
'USES-RUN-SUPER))))

;;; Arrange for NOTE-WHETHER-METHOD-USES-RUN-SUPER to be called when
this method
;;; is defined, via the USES-RUN-SUPER declaration.  It would be better
to do this
;;; with meta-object protocols, when we have them.
(PUSHNEW '(USES-RUN-SUPER ADD-NOTE-WHETHER-METHOD-USES-RUN-SUPER)
	*DEFMETHOD-DECLARATIONS* :TEST #'EQUAL)

(DEFUN ADD-NOTE-WHETHER-METHOD-USES-RUN-SUPER (FUNCTION-SPEC DECLARATION
IGNORE)
  `((NOTE-WHETHER-METHOD-USES-RUN-SUPER ',FUNCTION-SPEC ',(SECOND
DECLARATION))))

;;; Called when a primary method with :SUPER-DAEMON method combination
is defined
(DEFUN NOTE-WHETHER-METHOD-USES-RUN-SUPER (FUNCTION-SPEC USES-RUN-SUPER)
  (LET ((CHANGED (AND (FDEFINEDP FUNCTION-SPEC)
		      (NOT (EQ (SI:FUNCTION-SPEC-GET FUNCTION-SPEC 'USES-RUN-SUPER)
			       USES-RUN-SUPER)))))
    ;; Record the information where METHOD-USES-RUN-SUPER can find it.
    (IF USES-RUN-SUPER
	(SI:FUNCTION-SPEC-PUTPROP FUNCTION-SPEC T 'USES-RUN-SUPER)
	(SI:FUNCTION-SPEC-REMPROP FUNCTION-SPEC 'USES-RUN-SUPER))
    ;; If combined methods have to call a different set of primary
methods now, update them.
    (WHEN CHANGED
      (RECOMPILE-FLAVOR (METHOD-FLAVOR FUNCTION-SPEC)
			:GENERIC (METHOD-GENERIC FUNCTION-SPEC)
			:IGNORE-EXISTING-METHODS T))))

;;; Expand any RUN-SUPER in the body of this method into the appropriate
code
;;; to call the next method on the continuation list and rebind that
list to its tail.
;;; This works by calling some machine-dependent facilities.
(DEFUN TRANSFORM-SUPER-DAEMON-METHOD (FUNCTION-SPEC METHOD-ARGLIST
METHOD-BODY)	 
  (DECLARE (VALUES METHOD-ARGLIST METHOD-BODY))
  ;; This is for primary methods only
  (UNLESS (OR (NULL (METHOD-OPTIONS FUNCTION-SPEC))
	      (EQUAL (METHOD-OPTIONS FUNCTION-SPEC) '(:DEFAULT)))
    (RETURN-FROM TRANSFORM-SUPER-DAEMON-METHOD (VALUES METHOD-ARGLIST
METHOD-BODY)))
  ;; Check whether the method actually uses RUN-SUPER
  (MULTIPLE-VALUE-BIND (DECLARATIONS BODY)
      (SI:FIND-BODY-DECLARATIONS METHOD-BODY NIL)
    (COND ((LT:MAPFORMS (LAMBDA (SUBFORM KIND USAGE RUN-SUPER-USED)
			  (IGNORE USAGE)
			  (COND (RUN-SUPER-USED
				 (VALUES T T))		;No need to look any further
				((AND (LISTP KIND) (EQUAL SUBFORM '(RUN-SUPER)))
				 (VALUES T T))		;RUN-SUPER called as a function
				(T (VALUES NIL NIL))))	;else keep looking
			(CONS 'PROGN BODY))
	   ;; This method contains a call to RUN-SUPER.
	   ;; Record that for the benefit of METHOD-USES-RUN-SUPER.
	   (WHEN COMPILER:UNDO-DECLARATIONS-FLAG
	     (COMPILER:FILE-DECLARE FUNCTION-SPEC 'USES-RUN-SUPER T))
	   ;; Adjust the arglist so we can pass the arguments on to the next
method.
	   (MULTIPLE-VALUE-BIND (ARGUMENTS APPLY NEW-METHOD-ARGLIST)
	       (LT:LAMBDA-LIST-ARGUMENTS METHOD-ARGLIST)
	     (VALUES
	       NEW-METHOD-ARGLIST
	       ;; Make the body copy the continuations from the special
variable
	       ;; into a lexical variable so that it gets scoped properly if
this method
	       ;; contains RUN-SUPER inside a LAMBDA, and so that if RUN-SUPER
is done
	       ;; twice the same method gets called each time, and put a
MACROLET
	       ;; of RUN-SUPER around the body.
	       `(,@DECLARATIONS
		 (DECLARE (USES-RUN-SUPER T))
		 (LET ((.SUPERCLASS-CONTINUATIONS. *SUPERCLASS-CONTINUATIONS*))
		   (MACROLET
		     ((RUN-SUPER ()
			`(LET ((*SUPERCLASS-CONTINUATIONS* .SUPERCLASS-CONTINUATIONS.))
			   ;; Machine-dependent call similar to CALL-COMPONENT-METHOD
			   (,',(IF APPLY 'APPLY 'FUNCALL)
			    (POP *SUPERCLASS-CONTINUATIONS*)	;Method
			    SELF
			    (POP *SUPERCLASS-CONTINUATIONS*)	;Mapping-table
			    .GENERIC.
			    ,',@ARGUMENTS))))
		     ,@BODY))))))
	  (T
	   ;; Ordinary method that doesn't use RUN-SUPER.  Record that fact for
	   ;; the benefit of METHOD-USES-RUN-SUPER, and return original arglist
and body
	   ;; with a declaration added saying it doesn't use run-super.
	   (WHEN COMPILER:UNDO-DECLARATIONS-FLAG
	     (COMPILER:FILE-DECLARE FUNCTION-SPEC 'USES-RUN-SUPER NIL))
	   (VALUES METHOD-ARGLIST
		   `(,@DECLARATIONS
		     (DECLARE (USES-RUN-SUPER NIL))
		     ,@BODY))))))


(DEFGENERIC SDTEST (X Y)
  (:METHOD-COMBINATION :SUPER-DAEMON))

(DEFFLAVOR SDTEST1 () ())
(DEFFLAVOR SDTEST2 () (SDTEST1))
(DEFFLAVOR SDTEST3 () (SDTEST2))

(DEFMETHOD (SDTEST SDTEST1) (X)
  (LIST 1 X))

(DEFMETHOD (SDTEST SDTEST2) (X)
  (CONS 2 (RUN-SUPER)))

(DEFMETHOD (SDTEST SDTEST3) (X)
  (CONS 3 (RUN-SUPER)))

(SDTEST (MAKE-INSTANCE 'SDTEST3) 105)
; => (3 2 1 105)

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 16 Sep 86 23:21:27 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 16 SEP 86 17:51:41 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 16 SEP 86 17:51:14 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 105361; Tue
 16-Sep-86 20:48:21 EDT
Date: Tue, 16 Sep 86 20:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: What we should agree on before OOPSLA
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860916205006.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

Here is what I would like us to try to agree on, in time to write it up
and distribute it to whoever is interested at OOPSLA.  I have pared this
list down to what I think is possible if we focus on this.  I think it's
important to come up with something real, if we take seriously the
promise we made to the community in August.

 - A statement of the goals and general character of this project.  This
   could be based on what SKeene mailed out this morning (Tuesday), with
   modifications resulting from other people's review of it.
   
 - The syntax of the most basic language facilities, with very brief
   discussions of their semantics and a statement that additional
   facilities are still being discussed.  See proposed list below.
   
 - A statement that meta-object protocols will exist and be precisely
   defined, but currently they are not ready to go into the document
   (assuming there isn't enough time left for this).


Basic language facilities that I think we can agree on by the end of
next week:
  DEFCLASS
    overall syntax
    some of the options
    some or all of the slot-options
    class precedence rules
  DEFGENERIC
    overall syntax
    some or all of the options
    setf syntax
  DEFMETHOD
    "general" syntax, with space left for "classical" syntax
    discrimination on required arguments
    discrimination by classes
    setf syntax
  WITH
    the only problem here is the name, which is too short
  MAKE-INSTANCE
    interface seen by the caller
    we may have to defer the protocol for initialization methods
  CLASS-OF
  PRINT-OBJECT
  DESCRIBE-OBJECT (can we name this DESCRIBE?)
  DEFINE-METHOD-COMBINATION
    we may have to postpone the details of this if we
    have trouble agreeing

This leaves out a great deal, but should be enough to give people
a good idea of what is coming.  At this point I think we should
leave out anything that we are having trouble converging on and
deal with it later.  There will be a face to face meeting after
OOPSLA.

I'd like some feedback on this!

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 16 Sep 86 19:01:00 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 16 SEP 86 14:00:48 PDT
Date: Tue, 16 Sep 86 13:59 PDT
From: Gregor.pa@Xerox.COM
Subject: the kinds of method lookup people claim they want
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860916135909.5.GREGOR@AVALON.XEROX-PARC>
Line-fold: no


I spent lunch today listening to people talk about the kinds of method
lookup which they would like to have CommonLoops support.  I was struck
by the variety of things which people claimed would be natural or
convenient or even essential.  By the end of lunch I was very confused
about what we should do about discriminating on optional arguments.

In the interest of confusing the rest of you, I thought I would collect a
list of all the cases of method definition people thought they would
want.  Please add any other examples or potential screw cases.

NOTE:  In each of these examples I have used some syntax and some
defining forms which I intend only to express the example.  Do not
regard the syntax I have used as a proposal for how we should do
anything.

Case 1a.  "draw-line"

draw-line takes an optional, the width of the line in device dependent
units.  Because they are device dependent units, each individual method
would like to default this argument on its own.

(defmethod draw-line ((dev printer) p1 p2 &optional (width 7))
  ...)

(defmethod draw-line ((dev window) p1 p2 &optional (width 1))
  ...)

Case 1b.

Within case 1, some methods may want to take an extra argument.  Also
see case 3 which is similar.

(defmethod draw-line ((d gray-display) p1 p2
		                       &optional (width 3)
						 (gray *gray1*))
  ..)

Case 2.  "draw (GFD#2)"

The generic function takes an optional argument.  For all the methods,
the optional argument should default to the same value.  In addition,
method lookup should be based on the value of the optional argument
(after defaulting) and the defaulted value should be passed in.  This
corresponds to what I previously called GFD#2.

(defgeneric draw (thing &optional (place *draw-window*))
  "Draw thing on place.")

(defmethod draw ((thing line) (place raster-display)) ...)

(defmethod draw ((thing line) (place vector-display)) ...)

People have also said that within the individual methods they would like
to have access to the supplied-p information for the optional argument.

Case 3.  "move"

A generic function (e.g. move) has only classical methods.  Some of the
methods want to accept more arguments than others.  For example: move
when then first argument is a block takes a position to move to, but
move when the first argument is a rabbit takes no extra arguments (the
rabbit will jump up and down).

(defmethod move ((b block) to-x to-y) ..)

(defmethod move ((r rabbit)) ..)

Case 4.  "Guy's proposal"

In this porposal, method lookup checks argument specifiers for only the
supplied arguments.  When there are two arguments supplied, the most
specific of the two argument methods is called.

  (defmethod foo (a b &optional (c x) (d y)) body)

  is simply an abbreviation for

  (defmethod foo (a b) (let ((c x) (d y)) body))
  (defmethod foo (a b c) (let ((d y)) body))
  (defmethod foo (a b c d) body)

So that:

(defmethod gls ((a boat) &optional ((p plane) *default*)) ..)
(defmethod gls ((a speed-boat)) ...)

(foo <a speed-boat>)           ;runs method 2
(foo <a speed-boat> <a plane>) ;runs method 1
-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 16 Sep 86 14:31:10 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 16 SEP 86 10:39:58 PDT
Redistributed: CommonLoopsCore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 16 SEP 86 10:38:19 PDT
Date: 16 Sep 86 10:37 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: default optional arguments to a generic function
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 15 Sep 86 23:57 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860916-103958-6836@Xerox>

    GFD #1. the defaults from the defgeneric are used only for method
	    lookup. This is the kind I described above.  

    GFD #2. the defaults from the defgeneric are used for method lookup
	    and also passed to the method.

There is a fundamental conceptual difference.  I think the notion of
supplying defaults is part of the contract between the generic function
and the world.  This is an argument for GFD #1.  We all seem to agree
that defmethods, if they specify optionals, must agree with the generic
function.  If the EQUALS rule is used for defaults (I support this),
then I see no reason for the default forms to be evaluated twice.  If
methods can have exactly the same supplied-p args as specified in the
generic function (no more, no less - just local renaming allowed) then
there is no penalty for passing supplied-p args to each method as
"required args".  The calling sequence is uniform.

Given:
(defgeneric foo (x &optional y (z *v1* supplied-z)) ...)
then the following is legal
(defmethod foo ((x c1) &optional ((y c2)) (z *v1* my-supplied-z))) ..)
and the following are illegal
(defmethod foo ((x c1) &optional (y NIL supplied-y)(z *v1*
my-supplied-z))) ..)
(defmethod foo ((x c1) &optional y (z *v1* ))) ..)


One issue to be addressed is the following.  If we insist on the EQUALS
rule, then if the default value form changes in the defgeneric, it must
be changed in all methods.  This redundancy is bad design.  To allow
arg-specification and supplied-p specification, I suggest another
keyword &optional-spec.  Following &optional-spec can be 
 {varName|(varName arg-specifier [supplied-p-var])}*
where the interpretation is the obvious one, given in my message of last
week.  The rule of supplied-p correspondence still holds, but no default
value form need be specified.



-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 16 Sep 86 09:34:37 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 16 SEP 86 06:29:26 PDT
Return-Path: <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 16 SEP 86 06:28:46 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 104492; Tue
 16-Sep-86 09:25:51 EDT
Date: Tue, 16 Sep 86 09:25 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Goals of the Specification   
To: Masinter.pa@Xerox.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860915-161758-6228@Xerox>
Message-ID: <860916092549.2.SKEENE@JUNCO.SCRC.Symbolics.COM>

    Date: 15 Sep 86 16:15 PDT
    From: Masinter.pa@Xerox.COM

    The current list contents of commonloopscore↑.pa@xerox.com is:

    Bobrow.pa Common-Lisp-Class-archive@Stony-Brook.SCRC.Symbolics.COM
    COMMON-LISP-OBJECT-SYSTEM@SU-AI.ARPA
    CommonLoops-Spec-Archive@AI.AI.MIT.EDU DLW@QUABBIN.SCRC.Symbolics.COM
    edsel!lgd@navajo.stanford.edu Gregor.pa Kahn.pa Lanning.pa
    LGD@SU-AI.arpa Masinter.pa Moon@STONY-BROOK.SCRC.Symbolics.COM
    SKeene@STONY-BROOK.SCRC.Symbolics.COM

    I assume RPG gets the mail via COMMON-LISP-OBJECT-SYSTEM@SU-AI.ARPA,
    although I don't know who else does. I'm not sure who LDG is (I assume
    someone at Lucid) or SKeene@STONY-BROOK.SCRC.Symbolics.COM.

I'm a writer at Symbolics.  -- Sonya Keene 


    I don't think I object to what I've heard of the goals, I just didn't
    see the list. Avoiding obvious name conflicts with Flavors and allowing
    mechanical translation of Flavors, while a bow to backward
    compatibility, is not an onerous one.


 

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 16 Sep 86 09:30:05 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 16 SEP 86 06:24:50 PDT
Return-Path: <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 16 SEP 86 06:24:34 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 104483; Tue
 16-Sep-86 09:16:58 EDT
Date: Tue, 16 Sep 86 09:16 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Proposed Goals (Statement for OOPSLA)
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860916091654.1.SKEENE@JUNCO.SCRC.Symbolics.COM>




I think it's important for us to start thinking about OOPSLA in regards to
this standardization effort.  It would be best to pass out something
written, because that way we can all agree before-hand on the written
statement, and after the meeting there won't be any confusion about what
was said.

I've put together a draft statement that could either stand alone, or be
the preface to some more specific documentation (if we have that in time).

Please let me know what you think about this Statement, and also your
thoughts on any other documentation that we could prepare (and get
consensus on) in time for the conference.

--------------------------------------------------------------

       TOWARD A COMMON LISP STANDARD FOR OBJECT-ORIENTED PROGRAMMING

This brief paper summarizes the work that is now going on toward defining a
new Common Lisp standard for object-oriented programming.

HISTORY AND MOTIVATION

Many people in the Common Lisp community see a need for defining a standard
for object-oriented programming that would be part of Common Lisp.  The
primary benefit of such a standard would be the ability to write portable
Common Lisp code in an object-oriented style.

At the Common Lisp committee meeting in Boston in December 1985, many
vendors of application software made it clear how important such a standard
is to them.  Again at the ACM Lisp Conference in Cambridge in August 1986,
the same point was made.

After the ACM Lisp Conference, there was a meeting of the Common Lisp
Object-oriented Programming Committee.  A clear consensus was reached that
we should begin work immediately to define a standard.  Representatives
from Xerox, Lucid, Symbolics, LMI, HP, Sun, and the Japanese CommonLisp
committee supported this consensus.

A working group composed of representatives from Xerox and Symbolics met
after the ACM Lisp Conference.  At that meeting we reached agreement on
several general goals.

In brief, the standard will be based on the meta-object framework of
CommonLoops, which allows experimentation with different philosophies of
object-oriented programming.  The standard will also take advantage of the
years of experience of Flavors, and include Flavors features such as
declarative method combination.  The standard will not be CommonLoops, nor
will it be Flavors; however it will incorporate the most useful features
from both.

PROGRESS IN AUGUST AND SEPTEMBER

During August and September, representatives from Xerox, Symbolics, and
Lucid began work on a draft specification of the standard.  We started with
the basic programmer interface for defining new classes and writing methods
and generic functions.  This work is ongoing, but it has not yet reached a
state where documentation is available.  [We hope that this sentence turns
out to be false, but for the moment it is true.]

GOALS FOR THE STANDARD

Some high-level goals were stated and agreed-upon:

Sound basis     The standard will include the aspects of object-oriented
                programming that are well-understood at this time.  The
                standard will omit ideas that are still subjects for
                research.

Flexibility     The meta-object protocol of the standard will offer a
                flexible framework for other designers to implement
                different schemes.  This encourages exploration of
                different styles of object-oriented programming.

Power           The standard will offer the basic tools for writing
                programs in an object-oriented style, and will be powerful
                enough that it meets the needs of most programs.  It should
                not be necessary for programmers to extend the system to do
                straightforward object-oriented programming.

Simplicity      The standard will specify just the language, not the
                programming tools and interactive development environment.

Compatibility   It should be a convenient and simple procedure to translate
                programs written in CommonLoops or Flavors to the new
                standard.  We intend to provide tools that will perform the
                translation automatically.

Implementation  The standard will allow efficient implementation on stock
                hardware as well as specialized machines.
                                                                        
FEATURES TO BE INCLUDED IN THE STANDARD

We are planning on including the following features.  This is not an
exhaustive list, but is intended to communicate some of the areas of
agreement that have been reached.

Generic functions
                The standard will use the normal Lisp function-calling
                syntax.

Class and Type Space Merging
                Every object in the Lisp system has a class and hence can
                be used to select methods.

Dispatching     The standard will allow for several types of dispatching,
                including classical methods (which dispatch on a single
                object) and multi-methods (which dispatch on more than one
                object).

Multiple inheritance
                Modules of behavior can be combined together freely; they
                need not fit into a rigid hierarchy.

Meta-objects    The standard defines objects for the major implementation
                entities of the system to allow for extensibility.
                Classes, methods, and generic functions all have
                corresponding objects, organized by well-defined,
                documented protocols.

Declarative Method Combination
                Method selection and combination are controlled
                declaratively, making it easier to construct programs from
                a collection of modules.  Users can easily define new
                method combination paradigms.

FUTURE PLANS

The working group intends to develop a draft specification for the
standard.  We will continue to involve the community in the feedback
process.

We will produce a portable implementation by evolving Portable Common Loops
to track the new specification.  The portable implementation will enable
the community to experiment with the ideas, gain a deeper understanding of
the ideas than is possible with only a specification, and ensure that the
new object-oriented programming language receives adequate real-life
testing before its adoption as a standard.


∨
Received: from Xerox.COM by AI.AI.MIT.EDU 16 Sep 86 00:05:19 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 20:59:04 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 15 SEP 86 20:58:46 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 80635;
 Mon 15-Sep-86 23:57:49 EDT
Date: Mon, 15 Sep 86 23:57 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: default optional arguments to a generic function
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860915152433.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860915235743.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Mon, 15 Sep 86 15:24 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

I have a bit more to say on this topic.  I'll try to keep it short.

	Date: Sun, 14 Sep 86 18:04 PDT
	From: Gregor.pa@Xerox.COM

	...So, I see two different schemes for generic function defaulting:

	GFD #1. the defaults from the defgeneric are used only for method
		lookup. This is the kind I described above.  

	GFD #2. the defaults from the defgeneric are used for method lookup
		and also passed to the method.

	There is a fundamental conceptual difference here.  I am not sure which
	I prefer, but I am leaning towards number 1.

A good reason to prefer GFD #1 is that it doesn't interfere with
supplied-p parameters in the methods.  This is particularly important
for people who want to program with defmethod instead of defun, and
hence require that defmethod supports all the features of defun.  Ken
Kahn's suggestion of an alternate method-defining macro that does both
the defgeneric and the defmethod could take care of this, but it would
be nice to avoid introducing that extra special form if it isn't really
necessary.

A bad reason to prefer GFD #2 is that it is easier to implement the
discriminating function in straight Common Lisp, because methods are
always called with the same number of arguments.

    If there is no reason to allow programs that can tell the difference
    between GFD #1 and GFD #2, then I think we should forbid them, since
    obviously this leads to confusion.

Because of supplied-p parameters, I have to back off on this.  I think
we should go with GFD #1, same as Gregor leans toward.

    I think we also agree that the arglists of generic functions and methods
    must be consistent....

I have an anecdote that might illuminate the issue of whether two
methods for the same generic function should be allowed to have
different default-value forms for an optional argument, even when the
argument is not used for discrimination.  We have a stream operation
called read-cursorpos.  It takes an optional argument which is the units
in which the position is to be measured (pixels or characters).  The
default value for that argument is supposed to be pixels, but one or two
of the methods defaulted it to characters instead.  This caused bugs,
especially when streams are nested and one stream applies read-cursorpos
to another stream.  Because Flavors only requires that methods have
consistent numbers of arguments, and doesn't check consistency of
default-value forms, these bugs had to be found the hard way.  I tried
to think of an example where the freedom to have different default values
for an optional argument in different methods would be useful, but
could not come up with one.

Here is a proposed precise definition for arglist consistency.  It's a
bit longwinded, but I found that was necessary to make it precise and
cover all the cases.  Comments and amendments are invited.  Terminology
follows CLtL p.60.

The lambda-lists of all methods for a given generic function must be
consistent with each other and with the lambda-list in the defgeneric
[if defgeneric is optional, add "if present"].  Attempting to define a
method with an inconsistent lambda-list signals an error; a program
development environment might offer to modify the conflicting
lambda-lists to make them all consistent.

To compare two lambda-lists for consistency, use the following rules:

(1) The numbers of required parameters must be equal.

(2) The numbers of optional parameters must be equal.  In addition, the
initforms for corresponding optional parameters must be equal (using the
Lisp function EQUAL); an omitted initform is the same as NIL.

(3) If one lambda-list contains &rest or &key, so must the other
lambda-list.  It is valid for one lambda-list to have &rest and the
other to have &key.

(4) If both lambda-lists contain &key, the sets of keywords must be the
same, except that it is valid for a keyword to appear only in one
lambda-list if the other lambda-list contains &allow-other-keys.

(5) Keyword parameters with equal keywords that appear in both
lambda-lists must have equal initforms (using the Lisp function EQUAL);
an omitted initform is the same as NIL.

(6) Keyword parameters of a method, whose keywords are not among the
generic function's keyword parameters' keywords, cannot be type
qualified (i.e. cannot be used for discrimination).

(7) If an initform that appears in both lambda-lists references an
earlier parameter, that parameter must have the same name in both
lambda-lists and in the case of keyword parameters the parameter
specifiers must appear in the same order.  This ensures that variable
names in initforms have the same meaning everywhere the initform
appears.  [If defmethod is allowed inside a non-top-level lexical
context, add appropriate additional language about captured free
variables.]

(8) Ignore &aux and everything after it.

Note that parameter names, type qualifiers, and the names and presence
of supplied-p parameters have no effect on lambda-list consistency.
Lambda-list consistency in more abstract terms is: the minimum number of
arguments must be equal; the maximum number of arguments must be equal;
default values for optional and keyword parameters must be consistent;
the set of keyword parameter keywords must be consistent; the defgeneric
must contain all argument-defaulting information required for
discrimination.

These rules are stricter than necessary in the sense that initforms are
compared with EQUAL, rather than a predicate that determines whether the
result of evaluating them would be EQUAL.  Thus "foo" and (quote "foo")
would not be considered consistent initforms.  Furthermore, if an
initform references a parameter earlier in the lambda-list, the name of
the parameter matters.  I don't think the stricter rules hurt anything,
and they are simpler to explain than the minimal rules would be.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 23:07:54 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 19:22:39 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 15 SEP 86 19:22:24 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 80612;
 Mon 15-Sep-86 22:20:24 EDT
Date: Mon, 15 Sep 86 22:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Defmethod syntax
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860913002227.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860915222018.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

I prefer (1b), with (1a) a close second.  (2) has too many funny
restrictions and (3) has too many special form names.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 20:04:15 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 16:17:58 PDT
Date: 15 Sep 86 16:15 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Goals of the Specification   
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 15 Sep 86 18:44 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860915-161758-6228@Xerox>

The current list contents of commonloopscore↑.pa@xerox.com is:

Bobrow.pa Common-Lisp-Class-archive@Stony-Brook.SCRC.Symbolics.COM
COMMON-LISP-OBJECT-SYSTEM@SU-AI.ARPA
CommonLoops-Spec-Archive@AI.AI.MIT.EDU DLW@QUABBIN.SCRC.Symbolics.COM
edsel!lgd@navajo.stanford.edu Gregor.pa Kahn.pa Lanning.pa
LGD@SU-AI.arpa Masinter.pa Moon@STONY-BROOK.SCRC.Symbolics.COM
SKeene@STONY-BROOK.SCRC.Symbolics.COM

I assume RPG gets the mail via COMMON-LISP-OBJECT-SYSTEM@SU-AI.ARPA,
although I don't know who else does. I'm not sure who LDG is (I assume
someone at Lucid) or SKeene@STONY-BROOK.SCRC.Symbolics.COM.


I don't think I object to what I've heard of the goals, I just didn't
see the list. Avoiding obvious name conflicts with Flavors and allowing
mechanical translation of Flavors, while a bow to backward
compatibility, is not an onerous one.


 
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 20:04:04 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 15:58:51 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 15 SEP 86 15:58:13 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 80550;
 Mon 15-Sep-86 18:44:05 EDT
Date: Mon, 15 Sep 86 18:44 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Goals of the Specification   
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860915-122039-5943@Xerox>
Message-ID: <860915184400.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 15 Sep 86 12:20 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    It is difficult to design for a set of goals set in a meeting
    that hardly anyone attened. Masinter did not attend it; neither
    did I.  You cannot blame us for tryin to use only good design criteria
    rather than these hidden goals.

The goals weren't set in that four-person meeting at MIT on Friday after
the Lisp conference, but in earlier discussion that I thought you were
involved in (but I might be remembering wrong).  There was a policy
statement that we decided we weren't ready to hand out during the Lisp
Conference (or the object-oriented programming committee meeting that
coincided with the Lisp conference) which contained the goals.  I agree
that I erred in assuming that everyone on this mailing list had already
bought into a particular list of goals (in fact I have no idea who is
the complete population of this mailing list).

In any case, if we don't even agree on the goals of this project, we'd
better bring that out into the open and agree on some goals as soon as
possible.  Having heard almost nothing from you, I can only go on what
I have.  We Symbolics people are about to net-mail out a proposed
statement of goals, which can serve as a starting point for discussion.
Maybe that will help.

    I would say that the goals of backwards compatibility are admirable
    as long as they don't imply a poorer design. We will probably have
    to live with the new specification longer than the switchover period.
    One can claim that Common Lisp itself is a poorer language because
    it had to be compatible with MacLisp and like other existing Lisps.

One has.

    I have few problems with requiring additional Common Lispage as part
    of the CommonLos spec.

Again this is a question of goals.  Is it more important to make it easy
for every Common Lisp implementation to implement this spec, or to make
the spec include all the good ideas we might have thought of?  The only
statement of goals for this project I have ever seen speaks of simplicity
and implementability.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 20:03:50 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 14:20:18 PDT
Date: 15 Sep 86 14:22 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Defmethod syntax
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 15 Sep 86 13:37 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860915-142018-6089@Xerox>

sorry... I was off the mailing list for a while, and missed the earlier
discussion.

I'm happy with spelling the new way of defining methods  some other way
than "defmethod". I don't care what the name is exactly, but I'd like it
to be short & simple to remember; I thought define-method was too long.
(I originally long ago proposed spelling it "defun".) 

Here's some more names

defpartial	(defines a partial function)
defmeth	(shorter than define-method, but otherwise an unfortunate
abbrev)
deffunction	(I know this is longer, but it emphasizes the "function"
nature
		of the beast well enough that I include it)
deffn		even shorter than defun, defines "partial functions" (don't
groan)
		I like this one the most. You can make a function into a method
		with a single character delete.




∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 20:03:41 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 12:26:13 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 15 SEP 86 12:25:35 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 80419;
 Mon 15-Sep-86 15:24:38 EDT
Date: Mon, 15 Sep 86 15:24 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: default optional arguments to a generic function
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860914180428.4.GREGOR@AVALON.XEROX-PARC>
Message-ID: <860915152433.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Sun, 14 Sep 86 18:04 PDT
    From: Gregor.pa@Xerox.COM

    For clarity, this message assumes that you have to do a defgeneric
    before a defmethod.  I don't want to make up my mind about having to do
    a defgeneric before a defmethod until I understand this issue of
    defaulting optional arguments.

    I have tried to process all the preceding mail on this subject.  Forgive
    me if I have just re-iterated an existing position.

    As terminology:

      GENERIC FUNCTION DEFAULTING is when the generic function proper
      provides default values for optional arguments to the generic
      function.  In the kind of generic function defaulting I am talking
      about, the defaulted values are used as part of the method lookup
      and passed on to whichever method is invoked.

      METHOD DEFAULTING is when a particular method provides default
      values for some of its arguments.

    In this variant of generic function defaulting, it signals an error to
    attempt to define a method on a generic function which accepts less than
    the number of arguments that the generic function defaulting can
    produce.  Here is an example:

    (defgeneric draw (thing place &optional (clip-mask *clip-mask*)) ..)

    This defmethod is legal:

    (defgeneric draw ((thing block) (place window) clip-mask) ..)

    But this defmethod is not:

    (defgeneric draw ((thing block) (place window)) ..)

    Moon's variant of generic function defaulting, in which the defaulted
    values are dropped on the floor after method lookup does not have this
    problem.  Each method must accept only as many required arguments as the
    generic function proper.

In my proposal of 2 September I had intended to require that each method
must accept the same number of arguments as the generic function.  My
proposal could be read otherwise if you believe that "is an error" means
the programmer can do it anyway, but I hadn't intended to propose that.
I think we all agree that requiring that the minimum number of arguments,
maximum number of arguments, and keyword parameter keywords be consistent
between all methods and the generic function is acceptable, at least I
don't recall anyone arguing against it and several people have proposed it.

    So, I see two different schemes for generic function defaulting:

    GFD #1. the defaults from the defgeneric are used only for method
	    lookup. This is the kind I described above.  

    GFD #2. the defaults from the defgeneric are used for method lookup
	    and also passed to the method.

Actually, the kind you described above seems to me to be GFD #2.
But that's not important, unless it means that I have completely
misunderstood what you're saying.  I think the breakdown into GFD #1
and GFD #2 really clarifies what's going on here.

    There is a fundamental conceptual difference here.  I am not sure which
    I prefer, but I am leaning towards number 1.  Because...

My proposal of 2 September was intended to eliminate the distinction
between these by declaring invalid any program that can tell the difference.
I guess that was not very clear in the proposal.  Does anyone have reasons
why programs that can tell the difference between GFD #1 and GFD #2 should
be allowed?  This would mean that the optional argument would be defaulted
to one value for method selection and then be defaulted to a different value
in the actual method, or else not accepted as an argument at all if we
didn't require the defmethod and defgeneric arguments to be consistent.

If there is no reason to allow programs that can tell the difference between
GFD #1 and GFD #2, then I think we should forbid them, since obviously this
leads to confusion.

	Date: Thu, 4 Sep 86 16:15 EDT
	From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
    
	(make-specializable 'print)

    This is the same as:    

    (defgeneric print (object &optional stream))
    
	(defmethod print (x &optional ((stream gee-whiz-display))) ...)
    
	But (let ((*standard-output* <instance of the gee-whiz-display>))
	      (print <lisp-object>))
	calls the wrong method!  This is what I have been complaining about all
	along.  This is the key issue.

    I agree that this is the key issue.  Using GFD #1, there is no problem.
    You would have to specify a default value for the second argument to the
    PRINT generic function as a whole:

    (defgeneric print (object &optional (stream *standard-output*))

    Then the example:

    (let ((*standard-output* <instance of the gee-whiz-display>))
      (print <lisp-object>))

    would get the right method.
    -------

This example is obscured by the unclarity of the definition of
PRINT in the Common Lisp manual, which makes it unclear exactly where the
substitution of the value of *standard-output* for an unsupplied second
argument happens.  I in fact thought when I sent that message that
(make-specializable 'print) would be the same as (defgeneric print
(object &optional (stream *standard-output*)), but I hadn't read CLtL
carefully enough to realize that PRINT accepts NIL as a stream argument.

Of course we don't really want to specialize PRINT anyway, since it's
the function that outputs a carriage return before the object and a
space after.  What we really want to specialize is the internal
function, not named by CLtL, that is called by all of PRINT, PRIN1,
PRINC, PPRINT, WRITE, FORMAT }S, PRIN1-TO-STRING, etc.  But that ruins
the example, since surely that internal function has the stream as
a required argument, not an optional one.

- - -

I think that we are actually in complete agreement here.  For an optional
argument to be used for discrimination, the defaulting has to be in the
defgeneric.  Now we can decide whether, when you do a defmethod without
first doing a defgeneric, it signals an error or generates an implied
defgeneric according to well-defined rules.

I think we also agree that the arglists of generic functions and methods
must be consistent; we need to define precisely what that means, but
intuitively I think it means that they are equal except for the names of
the arguments and the type qualifications in the methods.  Seeing the
confusion that can arise from subtle inconsistencies, e.g. different
default values for optional arguments, I now favor requiring stronger
consistency than mere agreement of number of arguments.  This needs to
be refined to a more precise specification; if people agree with the
intuitive specification I will volunteer to produce a precise
specification for consideration.

Does anyone disagree that we agree?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 20:03:15 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 12:20:39 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 15 SEP 86
 12:20:21 PDT
Date: 15 Sep 86 12:20 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Goals of the Specification   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860915-122039-5943@Xerox>


It is difficult to design for a set of goals set in a meeting
that hardly anyone attened. Masinter did not attend it; neither
did I.  You cannot blame us for tryin to use only good design criteria
rather than these hidden goals.

I would say that the goals of backwards compatibility are admirable
as long as they don't imply a poorer design. We will probably have
to live with the new specification longer than the switchover period.
One can claim that Common Lisp itself is a poorer language because
it had to be compatible with MacLisp and like other existing Lisps.

I have few problems with requiring additional Common Lispage as part
of the CommonLos spec.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 14:50:00 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 10:48:48 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 15 SEP 86 10:44:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 80362;
 Mon 15-Sep-86 13:43:29 EDT
Date: Mon, 15 Sep 86 13:43 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Naming and Identity Proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860914161007.3.GREGOR@AVALON.XEROX-PARC>
Message-ID: <860915134324.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Sun, 14 Sep 86 16:10 PDT
    From: Gregor.pa@Xerox.COM

    I am not sure what you mean by making the concept of the names and
    identities of methods precise.  Or what it is about the identities of
    methods you want to specify.

To quote from my message of 2 Sep, which your message is a reply to:
"The key property of these names is that when two defmethod forms with the same
name (according to the EQUAL function) are evaluated, the second defmethod
replaces the method defined by the first defmethod, rather than defining a
second method."

    Is this just for portable environment features like TRACE?  

What would be needed for TRACE is a further extension, not merely making the
concept of method identity precise, but also reifying it as a Lisp
object that can be used as the method's name in the arguments to TRACE.
I wasn't proposing that, since it seems to be leaving the area of object
oriented programming and getting into other parts of the Common Lisp
specification.  To quote again from my message:
"In an implementation that has function-specs, these lists can be used as
function-specs to access the method's definition, trace it, and so forth.
In other implementations I guess there is no way to perform those operations."

In other words, I'm not proposing to require every implementation to have
function-specs (I would certainly like to, but not as part of the
object-oriented programming proposal).

I think I should have been clearer about what I meant by an identity and
what I meant by a name.  If the above hasn't clarified it, let me know and
I'll work harder on it.

								If so then I
    agree that we need to specify a way to tell trace to trace a particular
    method, but I don't believe we need to specify the kind of functionality
    that comes to mind when I think of method names.

What functionality is that?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 14:49:50 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 10:42:43 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 15 SEP 86 10:38:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 80355;
 Mon 15-Sep-86 13:37:12 EDT
Date: Mon, 15 Sep 86 13:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860913-105044-4936@Xerox>
Message-ID: <860915133708.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 13 Sep 86 10:51 PDT
    From: Masinter.pa@Xerox.COM

    (4) two other names:

    General syntax:
      (DEFMETHOD {generic-function | (generic-function {option}*)}
		 {lambda-list | qualified-lambda-list}
	{declaration | doc-string}*
	{form}*)


    (This combines the forms of your (2), and is upward compatible with DEFUN) 

    and 

    Classical syntax:
      (DEFINE-CLASSICAL-METHOD (generic-function self-class {option}*)
		 lambda-list
	{declaration | doc-string}*
	{form}*)

This would be fine except that it violates the goal we set for ourselves
last month of providing smooth migration paths for existing users of
Flavors and Portable Common Loops.  Since you can't tell a new-style
DEFMETHOD from a Flavors DEFMETHOD, it would be impossible to provide
incremental mechanical translation.  I don't think we should contemplate
abandoning that goal without a more compelling reason than merely liking
the spelling DEFMETHOD more than any other.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 15 Sep 86 14:49:36 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 86 10:38:36 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 15 SEP 86 10:37:26 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 80351;
 Mon 15-Sep-86 13:34:06 EDT
Date: Mon, 15 Sep 86 13:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Identification   
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860914-183219-5434@Xerox>
Message-ID: <860915133401.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 14 Sep 86 18:31 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Presumably a method is identified by the pair of its generic function
    and its argument signature (the classes of the arguments). Also,
    presumably, the function FIND-METHOD uses this pair.

You forgot some things, such as the method-options.  This was discussed
extensively in my message of 2 Sep 86, message ID
<860902233747.7.MOON@EUPHRATES.SCRC.Symbolics.COM>.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 14 Sep 86 21:41:26 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 14 SEP 86 18:32:19 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 14 SEP 86
 18:32:09 PDT
Date: 14 Sep 86 18:31 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Method Identification   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860914-183219-5434@Xerox>

Presumably a method is identified by the pair of its generic function
and its argument signature (the classes of the arguments). Also,
presumably, the function FIND-METHOD uses this pair.
			-rpg-

------- End undelivered message -------

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 14 Sep 86 21:11:51 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 14 SEP 86 18:06:04 PDT
Date: Sun, 14 Sep 86 18:04 PDT
From: Gregor.pa@Xerox.COM
Subject: default optional arguments to a generic function
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860914180428.4.GREGOR@AVALON.XEROX-PARC>
Line-fold: no


For clarity, this message assumes that you have to do a defgeneric
before a defmethod.  I don't want to make up my mind about having to do
a defgeneric before a defmethod until I understand this issue of
defaulting optional arguments.

I have tried to process all the preceding mail on this subject.  Forgive
me if I have just re-iterated an existing position.

As terminology:

  GENERIC FUNCTION DEFAULTING is when the generic function proper
  provides default values for optional arguments to the generic
  function.  In the kind of generic function defaulting I am talking
  about, the defaulted values are used as part of the method lookup
  and passed on to whichever method is invoked.

  METHOD DEFAULTING is when a particular method provides default
  values for some of its arguments.

In this variant of generic function defaulting, it signals an error to
attempt to define a method on a generic function which accepts less than
the number of arguments that the generic function defaulting can
produce.  Here is an example:

(defgeneric draw (thing place &optional (clip-mask *clip-mask*)) ..)

This defmethod is legal:

(defgeneric draw ((thing block) (place window) clip-mask) ..)

But this defmethod is not:

(defgeneric draw ((thing block) (place window)) ..)

Moon's variant of generic function defaulting, in which the defaulted
values are dropped on the floor after method lookup does not have this
problem.  Each method must accept only as many required arguments as the
generic function proper.


So, I see two different schemes for generic function defaulting:

GFD #1. the defaults from the defgeneric are used only for method
        lookup. This is the kind I described above.  

GFD #2. the defaults from the defgeneric are used for method lookup
        and also passed to the method.

There is a fundamental conceptual difference here.  I am not sure which
I prefer, but I am leaning towards number 1.  Because...

    Date: Thu, 4 Sep 86 16:15 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
    
    (make-specializable 'print)

This is the same as:    

(defgeneric print (object &optional stream))

    
    (defmethod print (x &optional ((stream gee-whiz-display))) ...)
    
    But (let ((*standard-output* <instance of the gee-whiz-display>))
	  (print <lisp-object>))
    calls the wrong method!  This is what I have been complaining about all
    along.  This is the key issue.

I agree that this is the key issue.  Using GFD #1, there is no problem.
You would have to specify a default value for the second argument to the
PRINT generic function as a whole:

(defgeneric print (object &optional (stream *standard-output*))

Then the example:

(let ((*standard-output* <instance of the gee-whiz-display>))
  (print <lisp-object>))

would get the right method.
-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 14 Sep 86 19:17:26 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 14 SEP 86 16:11:31 PDT
Date: Sun, 14 Sep 86 16:10 PDT
From: Gregor.pa@Xerox.COM
Subject: Method Naming and Identity Proposal
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860902233747.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860914161007.3.GREGOR@AVALON.XEROX-PARC>
Line-fold: no

I am not sure what you mean by making the concept of the names and
identities of methods precise.  Or what it is about the identities of
methods you want to specify.

Is this just for portable environment features like TRACE?  If so then I
agree that we need to specify a way to tell trace to trace a particular
method, but I don't believe we need to specify the kind of functionality
that comes to mind when I think of method names.
-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 14 Sep 86 14:22:04 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 14 SEP 86 11:14:41 PDT
Redistributed: CommonLoopsCore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 86 11:14:27 PDT
Date: 14 Sep 86 11:14 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: ordering of defclasses
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 12 Sep 86 17:22 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860914-111441-5341@Xerox>

     Date: Fri, 12 Sep 86 17:22 EDT
     From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
     
     
     Flavors in fact requires that all of the component flavors must be
     defined before you can do a defmethod.  I believe the reason for this
     applies to Common Lisp Classes as well, and would translate into a third
     rule:
     
       All the classes in the included classes tree of a class must be
       defined (known to the compiler) before it is legal to
       evaluate (compile) a WITH.
     
     With this addition, I agree.

Right.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 14 Sep 86 14:15:53 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 86 11:11:21 PDT
Date: 14 Sep 86 11:11 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Getting together to work
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 12 Sep 86 14:34 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860914-111121-5339@Xerox>

Danny can't make it anytime between Washington and Oopsla.

DLW can't make it until the 24th.

During Washington or OOPSLA there isn't enough time (or peace and quiet).

In your message, you say "Sonya can't really spend a whole week away
from the office."  Does this mean that Sonya can't make it after OOPSLA
(because she is going to OOPSLA)?

If in fact Sonya can't make it right after OOPSLA then I don't see any way
that we are going to be able to take advantage of the travel we are going to
be making anyways to get together.  But I do think we should get together
real soon.  Would you all be interested in coming out here the week after
OOPSLA?
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 13 Sep 86 13:55:16 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 SEP 86 10:50:44 PDT
Date: 13 Sep 86 10:51 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Defmethod syntax
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Sat, 13 Sep 86 00:22 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860913-105044-4936@Xerox>

(4) two other names:

General syntax:
  (DEFMETHOD {generic-function | (generic-function {option}*)}
             {lambda-list | qualified-lambda-list}
    {declaration | doc-string}*
    {form}*)


(This combines the forms of your (2), and is upward compatible with DEFUN) 

and 

Classical syntax:
  (DEFINE-CLASSICAL-METHOD (generic-function self-class {option}*)
             lambda-list
    {declaration | doc-string}*
    {form}*)



∨
Received: from Xerox.COM by AI.AI.MIT.EDU 13 Sep 86 00:35:17 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 12 SEP 86 21:30:40 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 12 SEP 86 21:30:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79830;
 Sat 13-Sep-86 00:28:43 EDT
Date: Sat, 13 Sep 86 00:28 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: abbreviated form of WITH
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860913002840.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

Elaborating on something Danny Bobrow mentioned, it would be possible
to extend the syntax of argument qualifications to provide an automatic
WITH.  The optional prefix-name and type-name arguments to WITH should
be optionally specifiable.  This syntax can be used on more than one
argument, but the program is invalid if there are any name conflicts,
just as in LET and just as in WITH with more one name-specification.

This seems like a good idea.  There are several ways it could be done,
let me try and propose some.  The syntax is the syntax for a
discriminating parameter specifier, in the BNF variant explained on page
8 of Common Lisp: the Language, except that lowercase means italics and
uppercase means roman.

(1) (variable class :WITH-VARS [prefix-name [type-name]])

(2) (variable :INSIDE class [prefix-name [type-name]])

(3) (variable class :WITH T [:PREFIX prefix-name] [:CLASS type-name])

(4) (variable :CLASS class :WITH T [:PREFIX prefix-name])

In all of these, the meaning of (variable class) is not changed.

You who are reading this will probably come up with some better ideas.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 13 Sep 86 00:29:19 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 12 SEP 86 21:24:12 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 12 SEP 86 21:23:51 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79829;
 Sat 13-Sep-86 00:22:32 EDT
Date: Sat, 13 Sep 86 00:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Defmethod syntax
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860913002227.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

I've read all the mail on this again and I'd like to try to converge
on something that we can all agree on.  This message is an attempt to
lay out all the issues without including any advocacy.

I think we can decide on the syntax of defmethod independent of issues
of discriminating on optional arguments, whether defgeneric is required
or optional, the abbreviated form of WITH that Danny Bobrow mentioned
(discussed in a separate message), and whether the syntax for classical
methods is a required or optional part of the standard.  (The syntax for
classical methods has to be provided for in some form in order to meet
the goal of migration through mechanical translation that we set for
ourselves last month, as you recall.)

I see three viable proposals.  I will give each proposal in the BNF
variant explained on page 8 of Common Lisp: the Language, except that
lowercase means italics and uppercase means roman, along with six
examples (the first lines of the same six methods for each).  The six
examples are: a multimethod without options; a multimethod with an
option; a default method without options; a default method with an
option; a classical method without options; and a classical method with
an option.

Each proposal actually comes in (a) and (b) forms, depending on what we
do about SETF.  That's discussed after the basic proposals.  Definitions
of nonterminal symbols are at the end of this message, so they don't
get in the way.


THREE VIABLE PROPOSALS:

(1) Unparenthesized Options

General syntax:
  (DEFMETHOD generic-function {option}*
             {lambda-list | qualified-lambda-list}
    {declaration | doc-string}*
    {form}*)

Classical syntax:
  (DEFMETHOD (generic-function self-class {option}*)
             {lambda-list | qualified-lambda-list}
    {declaration | doc-string}*
    {form}*)

(defmethod foo ((a c1) (b c2))
(defmethod foo :before ((a c1) (b c2))
(defmethod foo (a b)
(defmethod foo :before (a b)
(defmethod (foo c1) (b)
(defmethod (foo c1 :before) (b)


(2) Untyped Arglist

General syntax:
  (DEFMETHOD generic-function
             {lambda-list | qualified-lambda-list}
    {declaration | doc-string}*
    {form}*)
and
  (DEFMETHOD (generic-function {option}*)
             qualified-lambda-list
    {declaration | doc-string}*
    {form}*)

Classical syntax:
  (DEFMETHOD (generic-function self-class {option}*)
             lambda-list
    {declaration | doc-string}*
    {form}*)

(defmethod foo ((a c1) (b c2))
(defmethod (foo :before) ((a c1) (b c2))
(defmethod foo (a b)
(defmethod (foo :before) ((a t) b)
(defmethod (foo c1) (b)
(defmethod (foo c1 :before) (b)


(3) Two Names

General syntax:
  (DEFINE-METHOD generic-function
                 {lambda-list | qualified-lambda-list}
    {declaration | doc-string}*
    {form}*)
and
  (DEFINE-METHOD (generic-function {option}*)
                 {lambda-list | qualified-lambda-list}
    {declaration | doc-string}*
    {form}*)

Classical syntax:
  (DEFMETHOD (generic-function self-class {option}*)
             {lambda-list | qualified-lambda-list}
    {declaration | doc-string}*
    {form}*)

(define-method foo ((a c1) (b c2))
(define-method (foo :before) ((a c1) (b c2))
(define-method foo (a b)
(define-method (foo :before) (a b)
(defmethod (foo c1) (b)
(defmethod (foo c1 :before) (b)


SETF VARIANTS:

There are two different ways to add the ability to define methods for
SETF of a generic function to each proposal:

(a) Tack -SETF onto the special form name.

(b) Replace generic-function with (SETF generic-function).

In both variants, a setf-lambda-list is inserted between the regular
lambda-list and the {declaration | doc-string}* that begins the body.


DRAWBACKS OF EACH PROPOSAL:

(1) lambda-list is not always the second subform of DEFMETHOD.

(2) In general syntax, you cannot use options without having a
qualified-lambda-list rather than a plain lambda-list.  In other
words, a default daemon method has to have an extra t in it.
Classical syntax cannot be used to write multi-methods.
Classical syntax is a bit harder to identify at a glance,
although it's not syntactically ambiguous.

(3) Twice as many special forms.

(a) Twice as many special forms.  Need DEFGENERIC-SETF, too.

(b) Funny syntax, SETF in the car of a list means something different
from other symbols in the car of a list, i.e. the cdr of the list is not
{option}*.  Also SETF in the generic function changes the parsing of the
rest of the defmethod.


NONTERMINALS:

  generic-function -- a symbol that names the generic function
                      being specialized.
  self-class -- a symbol that names the class of the first argument.
  option -- a non-nil symbol or a number, used by method
            combination to identify the method.
  lambda-list -- as defined in CLtL p.60.
  qualified-lambda-list -- a lambda-list with at least one
            variable replaced by a type-qualified variable
            so that discrimination occurs on that argument.
  setf-lambda-list -- {lambda-list | qualified-lambda-list}
            except that for now there can be only one parameter.
  declaration, doc-string, form -- as defined in CLtL.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 21:33:44 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 SEP 86 16:35:39 PDT
Date: 12 Sep 86 16:35 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Getting together to work
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 12 Sep 86 14:34 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860912-163539-4576@Xerox>

     From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
     Subject: Getting together to work
     
     I talked about this with Dan and Sonya.  We agree that we need a
face to
     face meeting, but we're not sure about the timing.  We all think it
would
     be better to have the meeting before OOPSLA rather than after, so
that
     at OOPSLA we are all telling the same story to people we talk to.
Also
     we promised at the Lisp conference that we would hand something out
     at OOPSLA showing our progress, and it seems like a good idea to
have
     a face to face meeting to finalize what goes into that document.


Having the face to face meeting before OOPSLA might get us to all be
telling the same story to people we talk to at OOPSLA.   But I don't
think there would be time for it to have any effect on what goes into
the document.  Anything other than real minor changes would take several
days to get into the document.

The reasons I had thought of getting together afterwards were:

 - to be able to incorporate the things that come up talking to other
people at OOSPLA

 - to try not to put too much stuff between now and OOPSLA since I at
least have lot of work to do just getting ready for OOPSLA.

- to put it in an open ended time slot so that if we got on a roll we
could keep on rolling.

For these reasons (particularly the first two) my initial reaction to
getting together before OOPSLA is not enthusiastic.  I will try to get
all of us out here to talk about it sometime soon and see what we all
think though, maybe I am wrong.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 17:47:52 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 12 SEP 86 14:35:40 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 12 SEP 86 14:23:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 102194; Fri
 12-Sep-86 17:22:45 EDT
Date: Fri, 12 Sep 86 17:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: ordering of defclasses
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860912130952.1.GREGOR@AVALON.XEROX-PARC>
Message-ID: <860912172209.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Fri, 12 Sep 86 13:09 PDT
    From: Gregor.pa@Xerox.COM

    Currently the spec makes no statement about when all the included
    classes of a class must be defined:

      1. They must be defined before the defclass is evaluated.  PCL does
    this now.  I don't like this it makes it harder to order loading of
    files for no good reason.

      2. They must be defined before an instance of the class is created.
    This is what flavors does now and is what I think we should do.  It
    takes only a very little bit of implementation overhead and provides the
    user with nice convenience.

    So, these two rules should be added to the spec:

    All the classes in the included classes tree of a class must be defined
    before it is legal to make an instance of the class.

    A class must be defined before it can be mentioned as an argument
    specifier in a defmethod.

Flavors in fact requires that all of the component flavors must be
defined before you can do a defmethod.  I believe the reason for this
applies to Common Lisp Classes as well, and would translate into a third
rule:

  All the classes in the included classes tree of a class must be
  defined (known to the compiler) before it is legal to
  evaluate (compile) a WITH.

With this addition, I agree.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 17:47:37 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 SEP 86 14:23:30 PDT
Date: 12 Sep 86 14:23 PDT
Sender: Lanning.pa@Xerox.COM
Subject: Re: the line munger (nee folder)
In-reply-to: Gregor Kiczales <Gregor.pa>'s message of 12 Sep 86 13:51
 PDT
To: Gregor.pa@Xerox.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
From: Stan Lanning <Lanning.pa@Xerox.COM>
Reply-to: Lanning.pa@Xerox.COM
Message-ID: <860912-142330-4425@Xerox>

    ...just set your fill column to 80...

Try 72, not 80.  Where would we be without Hollerith cards and FORTRAN?

----- smL
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 17:47:26 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 SEP 86 13:51:57 PDT
Date: 12 Sep 86 13:51 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: the line munger (nee folder)
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 12 Sep 86 01:03 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
To: RPG@SU-AI.ARPA
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860912-135157-4391@Xerox>

It hadn't occured to me that there were mailer's that wouldn't let you
put extra stuff in message headers.  I guess you all don't stand a
chance of hiring Shebs.

Unfortunately, there is no way to "fix" this at this end.  This is
considered a feature, so the person who maintains the mailer isn't
interested in fixing it.  The mailer is written in a language I don't
know so I can't even try to fix this myself.

Come to think of it, if you all just set your fill column to 80 you
shouldn't get bit by this.  We just have to be sure to fill our messages
by hand before we send them.  The reason this gets confusing is that
messages are only filled when the leave the internal network here.  When
Danny sends a message, You all get it line-folded, but he and I don't,
so its confusing for us to understand what you all are complaining
about.

Sorry.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 17:47:09 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 12 SEP 86 13:31:52 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 12 SEP 86 13:06:28 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79640;
 Fri 12-Sep-86 14:34:31 EDT
Date: Fri, 12 Sep 86 14:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Getting together to work
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860910-154308-2286@Xerox>
Message-ID: <860912143428.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 10 Sep 86 15:42 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    We had made a plan to get together monday moring at OOPSLA and work on
    the spec.  I believe that we will have more work to do than can be done
    in three hours.

    Instead, I propose that we get together Friday and Saturday after OOPSLA
    in Palo Alto.  This will give us enough time to actually get some work
    done, and takes advantage of existing travel to get a lot of people in
    the same place.

I talked about this with Dan and Sonya.  We agree that we need a face to face
meeting, but we're not sure about the timing.  We all think it would be better
to have the meeting before OOPSLA rather than after, so that at OOPSLA we are
all telling the same story to people we talk to.  Also we promised at the Lisp
conference that we would hand something out at OOPSLA showing our progress,
and it seems like a good idea to have a face to face meeting to finalize what
goes into that document.

If we're going to meet before OOPSLA there are some constraints.  Dan is not
available until the 24th.  Dan and I are not available on the 26th.  Sonya
can't really spend a whole week away from the office.  There seem to be several
possibilities:

Meet on the weekend Sep 27-28, or just Sep 28, either in Palo Alto or in
Portland.  It's probably possible for us to fly out Friday night, but
obviously a one-day meeting would be a little easier logistically than a
two-day meeting.  I don't know if one day is enough.

Meet on Thursday Sep 25 either in Cambridge or in Washington (this is the day
after the X3J13 meeting).

We also need to start talking through the mail about what excatly we're going
to have ready to hand out to the public at OOPSLA.

    I propose that we use the Monday morning at OOPSLA time to have a more
    open meeting with people from LMI and HP.

This sounds good.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 16:33:50 EDT
Received: from Semillon.ms by ArpaGateway.ms ; 12 SEP 86 13:11:48 PDT
Date: Fri, 12 Sep 86 13:09 PDT
From: Gregor.pa@Xerox.COM
Subject: ordering of defclasses
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860912130952.1.GREGOR@AVALON.XEROX-PARC>
Line-fold: no


In seperate messages, I am going to send out some general comments about
the current draft of the West Coast spec.  I am sending these to the
entire list even though I realize that the east coast people haven't
seen this spec, and that they aren't happy about this.

I have been assured that the legal problems with sending the spec to the
east coast have now all been fixed.  They weren't big problems, no-one
questions that the spec should be distributed, its just that someone far
from here had to be reminded why they should sign the release ("in my
left hand you see the release form, in my right hand you see a
Louisville Slugger... pick a hand, any hand").

-- Currently the spec makes no statement about when all the included
classes of a class must be defined:

  1. They must be defined before the defclass is evaluated.  PCL does
this now.  I don't like this it makes it harder to order loading of
files for no good reason.

  2. They must be defined before an instance of the class is created.
This is what flavors does now and is what I think we should do.  It
takes only a very little bit of implementation overhead and provides the
user with nice convenience.

So, these two rules should be added to the spec:

All the classes in the included classes tree of a class must be defined
before it is legal to make an instance of the class.

A class must be defined before it can be mentioned as an argument
specifier in a defmethod.

-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 16:33:41 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 SEP 86 12:50:49 PDT
Date: 12 Sep 86 12:48 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Defmethod syntax proposal
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 12 Sep 86 01:02 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860912-125049-4322@Xerox>

     Date: Fri, 12 Sep 86 01:02 EDT
     From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
     
     Aside from that, I think we are in serious danger of falling into the
     trap of trying to make a standard that contains the latest ideas that we
     just thought of recently, rather than the stodgy old ideas that are
     known to work but aren't any fun any more ...
     ...  Think about the things that everyone hates the most about Common
     Lisp, for instance.

I agree.

     If we really think that only the latest ideas are any good, and
     everything else should be removed from the standard.

We don't.


      I don't think anything based on heuristics is going to be acceptable as
      a standard.

Of course, but I wasn't suggesting it as part of the standard.  Because I believe
that the classical defmethod has no place in the standard, I was only suggesting
that we should craft the standard in such that in your environment, it should be
possible to distinguish a flavors defmethod from a standard one.

     Date: 12 Sep 86 08:29 PDT
     From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
     
     I think we ought to concentrate on finding
     the right abstractions and specifying them

I claim that we have.  One abstraction is defining a method;  that is done with
defmethod.  Another abstraction is defining a lexical context in which the slots
of an object can be accessed as if they were variables; that is done with with.

     Date: Fri, 12 Sep 86 11:59 EDT
     From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>

     Yes.  The idea of New Flavors was to get rid of "message passing" and
     instead go to "generic functions".  We did that, and New Flavors still
     has "self" and "auto-with" even though it has "generic functions"
     instead of "message passing".

Frankly, I claim that is an inelegance in the design of new flavors.

     What makes them go away is not "generic functions",
     but "multimethods".

No, I think that generic functions makes them go away.  What multimethods
do is make it clear that generic functions should make self and auto-with go
away.  Multimethods, being the general case of generic functions make it
clear that it is wrong to think of any single distinguished argument to a
generic function as somehow having a greater status than the others.

     It seems to me that you folks are worried that providing the
     "traditional" syntax will discourage users from taking advantage of the
     greater power provided by the multimethod capability of the new spec.  I
     believe that we can take care of this by the organization and phrasing
     of the documentation of the spec.

I agree that documentation can go a long way towards making it clear that
classical defmethod syntax is an abbreviation for a defmethod and a with.
But I don't think we are worried about what you suggest we are.  I frankly
think that extending the behavior of the standard defmeth so that it does
auto-with is conceptually in-elegant.

But I agree that it provides a convenience that many people have grown
used to.  So, given appropriate documentation, and a design for arguments
to defmethod which is nice, I might be willing to concede on this issue.  But
I suspect that we are going to have to go to having to seperate names for
these things, which is where we were two weeks ago (but they were the
wrong names).
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 12:43:55 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 12 SEP 86 09:39:22 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 12 SEP 86 09:08:47 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79520;
 Fri 12-Sep-86 11:56:53 EDT
Date: Fri, 12 Sep 86 11:59 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <860912010224.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860912115905.1.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: Fri, 12 Sep 86 01:02 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    I don't agree with the idea that self and "auto-with" have something to
    do with message-passing and are therefore obsolete.

Yes.  The idea of New Flavors was to get rid of "message passing" and
instead go to "generic functions".  We did that, and New Flavors still
has "self" and "auto-with" even though it has "generic functions"
instead of "message passing".  Rather, "self" and "auto-with" are
associated with having generic functions with only one argument that's
discriminated on.  What makes them go away is not "generic functions",
but "multimethods".

It seems to me that you folks are worried that providing the
"traditional" syntax will discourage users from taking advantage of the
greater power provided by the multimethod capability of the new spec.  I
believe that we can take care of this by the organization and phrasing
of the documentation of the spec.  We can make it clear that the
"traditional" syntax is stricly weaker than the "modern" syntax, and has
no additional capabilities, and is being provided because the style is
well-known and traditional, rather than because it's considered to be
"better" in any interesting sense.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 11:45:37 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 12 SEP 86 08:40:17 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 12 SEP 86
 08:29:28 PDT
Date: 12 Sep 86 08:29 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Defmethod Syntax   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860912-084017-4039@Xerox>


Moon makes two points. The first is that `self' and `auto-with'
form part of a larger, older tradition of OOP, and we shouldn't
ignore that tradition in order to get the `latest, most final'
ideas in the proposal. He also mentioned that he didn't think
these concepts were inextricably linked to message-passing and are
therefore obsolete.

I believe that these concepts are linked to message-passing, but
not absolutely linked. I think we ought to concentrate on finding
the right abstractions and specifying them; I don't think we should
gratuitously add features that users can implement with our abstractions
simply because `users find them useful.' On the other hand, Moon is
right that it is a mistake to opt for the latest, greatest at the
expense of well-understood concepts. We ought to consider `self'
and `auto-with' more carefully in this light. In other words,
I believe that `self' and `auto-with' are linked to message-passing,
and, even so, they might not be obsolete.

The second point is about distinguishing two forms of defmethod.
I feel it is imperative to find clear rules of distinguishing the
forms rather than invent another defmethod-like form. Only if
the possible syntactic means of distinguishing them are horrendous
should we consider proliferating functions/special forms/macros.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 01:10:15 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 11 SEP 86 22:04:56 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 11 SEP 86 22:04:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79318;
 Fri 12-Sep-86 01:03:40 EDT
Date: Fri, 12 Sep 86 01:03 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: the line munger (nee folder)
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860911-182703-3536@Xerox>
Message-ID: <860912010338.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 11 Sep 86 18:26 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    You can prevent the Xerox mailer from doing you the favor of chopping
    all your lines at 72 characters by putting a "Line-Fold: NO" header in
    your messages.

Sorry, Zmail doesn't let me put in headers that aren't part of the mail
standard.  I'm sure I can figure out how to subvert it, but before I try
let me ask how easy it is to fix it at your end.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 12 Sep 86 01:08:25 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 11 SEP 86 22:03:45 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 11 SEP 86 22:03:31 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79317;
 Fri 12-Sep-86 01:02:26 EDT
Date: Fri, 12 Sep 86 01:02 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860911150805.2.GREGOR@AVALON.XEROX-PARC>
Message-ID: <860912010224.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 11 Sep 86 15:08 PDT
    From: Gregor.pa@Xerox.COM

	Date: Mon, 8 Sep 86 18:41 EDT
	From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
    
	    Date: 8 Sep 86 13:13 PDT
	    From: Bobrow.pa@Xerox.COM
    
	    I meant that I propose that we not describe classical syntax
	    as part of the standard.  It would simply be a backwards
	    compatibility feature for Flavors users.
    
	It's really more than that; it provides conceptual compatibility for
	people who are familiar with most any of the other existing
	object-oriented programming languages, particularly Smalltalk-80.
	It provides the familiar concepts of instance variables and "self".
	Because of the widespread establishment of these concepts, I think
	it's worth putting this into the standard for everyone, despite the
	minor inelegance of having two syntaxes when only one is logically
	necessary.

    Yes, it does provide conceptual compatibility with the other existing
    "object-oriented" programming languages.  But I place that conceptual
    compatibility in the same category as "message passing".  Namely that it
    is not the model we want to be emphasing to users.  This new standard is
    generic functions.  It isn't message passing.  Self and "auto-with" on
    self are "message-passing" concepts not generic function concepts.

    I don't think we want to be providing support in the standard for
    thinking about generic functions as something that they aren't, namely
    flavors/smalltalk style "message passing". 

I don't agree with the idea that self and "auto-with" have something to
do with message-passing and are therefore obsolete.

Aside from that, I think we are in serious danger of falling into the
trap of trying to make a standard that contains the latest ideas that we
just thought of recently, rather than the stodgy old ideas that are
known to work but aren't any fun any more.  Putting in the latest ideas
always sounds good, even to me, but historically it has almost always
resulted in bad standards or standards that aren't widely accepted or
both.  Think about the things that everyone hates the most about Common
Lisp, for instance.  Some of them are due to trying to be compatible
with older languages, but most of them are due to putting in new things
that seemed well thought out at the time, but in fact were not as well
thought out as we thought.  Making a successful standard always includes
making compromises between desire and practice.

If we really think that only the latest ideas are any good, and everything
else should be removed from the standard, then what we are really saying
is that this is the wrong time to make a standard.

    For now, the best I can come up with is to propose that it might be
    enough to come up with heuristics to tell the two kinds of defmeths
    apart instead of just rules.  If the heuristics fail to identify the
    defmeth for sure than an error would be generated or something.

I don't think anything based on heuristics is going to be acceptable as
a standard.  If we have to resort to heuristics then we will be very
much better off using two different names for the two kinds of
method-defining forms.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 21:35:57 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 86 18:27:03 PDT
Date: 11 Sep 86 18:26 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: the line munger (nee folder)
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Message-ID: <860911-182703-3536@Xerox>

You can prevent the Xerox mailer from doing you the favor of chopping
all your lines at 72 characters by putting a "Line-Fold: NO" header in
your messages.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 21:29:13 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 86 18:20:48 PDT
Date: 11 Sep 86 18:20 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: spelling of metaclass etc.
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Line-Fold: NO
Message-ID: <860911-182048-3532@Xerox>

In today's meeting we decided to spell metaclass without a hyphen.
This was in recognition of its having graduated to the status of a real
instead of a (I won't even say it).
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 21:29:07 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 86 18:19:01 PDT
Date: 11 Sep 86 18:18 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: specifying metaclass etc.
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Line-fold: NO
Message-ID: <860911-181901-3531@Xerox>

I was wrong.  It does make sense to be able to specify the class
of a class, the class of a generic-function and the class of methods
on that generic-function.  For reasons which are complicated, doing
this doesn't buy as much power as it does in PCL, but it still buys
enough power to be worth doing.  SO:

add a :class option to defclass
add a :class (or :generic-function-class) option to make-generic and
   defgeneric
add a :method-class option to defgeneric and make-generic
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 18:36:06 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 11 SEP 86 15:10:52 PDT
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from Semillon.ms by ArpaGateway.ms ; 11 SEP 86 15:10:18 PDT
Date: Thu, 11 Sep 86 15:08 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Defmethod syntax proposal
To: DLW@ALDERAAN.SCRC.Symbolics.COM, Bobrow.pa@Xerox.COM,
 Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860908223153.1.DLW@CHICOPEE.SCRC.Symbolics.COM>,
              The message of 8 Sep 86 16:13-PDT from Bobrow.pa,
              <860908184131.4.DLW@CHICOPEE.SCRC.Symbolics.COM>,
              The message of 8 Sep 86 13:13-PDT from Bobrow.pa,
              <860908125848.1.MOON@EUPHRATES.SCRC.Symbolics.COM>,
              The message of 8 Sep 86 09:10-PDT from Bobrow.pa,
              <860905205118.7.MOON@EUPHRATES.SCRC.Symbolics.COM>,
              <860904180145.6.MOON@EUPHRATES.SCRC.Symbolics.COM>,
              The message of 5 Sep 86 10:52-PDT from Bobrow.pa,
              The message of 4 Sep 86 13:38-PDT from Bobrow.pa,
              <860904150145.7.MOON@EUPHRATES.SCRC.Symbolics.COM>,
              The message of 3 Sep 86 18:03-PDT from Bobrow.pa,
              <860902235003.8.MOON@EUPHRATES.SCRC.Symbolics.COM>,
              <860903004049.0.DLW@CHICOPEE.SCRC.Symbolics.COM>,
              <860903004113.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860911150805.2.GREGOR@AVALON.XEROX-PARC>
Line-fold: no


I think I have digested all the mail on this topic.

    Date:  3 Sep 86 18:03 PDT
    From: Bobrow.pa


    3) :discriminator-class (now called :generic-function-class) and
    :method-class are not options of defmethod.  They are (advanced)
    options of defgeneric.

:discriminator-class and :method-class are not features of defgeneric.
For the same reasons that the :class argument to defclass no longer
exists, these no longer exist.

    Date:  8 Sep 86 09:10 PDT
    From: Bobrow.pa

    In "classical" syntax, no argument of lambda-list can be type
    specified.  In general syntax at least one must be specifed if
    you are using method combination options.

    Date: Mon, 8 Sep 86 12:58 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    I don't see why method combination options would be disallowed
    for default methods.  If it doesn't make sense to allow such
    options for default methods, then we can go back to that proposal.

I think it makes perfect sense to have method combination options on
default methods.  A :around default method is the canonical example.


    Date: Mon, 8 Sep 86 18:41 EDT
    From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
    
        Date: 8 Sep 86 13:13 PDT
        From: Bobrow.pa@Xerox.COM
    
        I meant that I propose that we not describe classical syntax
        as part of the standard.  It would simply be a backwards
        compatibility feature for Flavors users.
    
    It's really more than that; it provides conceptual compatibility for
    people who are familiar with most any of the other existing
    object-oriented programming languages, particularly Smalltalk-80.
    It provides the familiar concepts of instance variables and "self".
    Because of the widespread establishment of these concepts, I think
    it's worth putting this into the standard for everyone, despite the
    minor inelegance of having two syntaxes when only one is logically
    necessary.

Yes, it does provide conceptual compatibility with the other existing
"object-oriented" programming languages.  But I place that conceptual
compatibility in the same category as "message passing".  Namely that it
is not the model we want to be emphasing to users.  This new standard is
generic functions.  It isn't message passing.  Self and "auto-with" on
self are "message-passing" concepts not generic function concepts.

I don't think we want to be providing support in the standard for
thinking about generic functions as something that they aren't, namely
flavors/smalltalk style "message passing". 

I do think we should be providing support in the standard so that an
environment which supports flavors as well as the standard can only have
one defmethod symbol and can unamiguosly determine whether or or not the
defmethod is a flavors defmethod or a CLOS defmethod.   I used to think
that was easy until I realized that this also had to work for the kinds
of defmethods that people are going to write using release 7 too.

For now, the best I can come up with is to propose that it might be
enough to come up with heuristics to tell the two kinds of defmeths
apart instead of just rules.  If the heuristics fail to identify the
defmeth for sure than an error would be generated or something.  Because
I can't figure out how often the heuristics I had in mind might fail I
thought I would send them out to get your all's opinion:

use the name-and-options-syntax:

(defmethod name-and-options args . body)

and used the heuristics:

 1. name-and-options is a symbol  --> its CLOS for sure
 2. one or more of the "required" args is a list --> CLOS for sure
 3. cadr of name-and-options is name of a flavor --> probably Flavors

 there might be other good rules too.
-------
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 18:35:18 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 86 14:51:32 PDT
Date: 11 Sep 86 14:52 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Whoppers and Ontology   
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 11 Sep 86
 11:42 PDT
To: RPG@SAIL.STANFORD.EDU
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860911-145132-3298@Xerox>

     If I am right then Danny's comment that whoppers are like Loops
method
     combination and continue-whopper is like run-super is not exactly
     correct, I think. 
I meant, but perhaps I didn't say, that this was with whoppers only.
Thus I am agreeing with you.


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 18:35:10 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 11 SEP 86 14:50:50 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 11 SEP 86 14:50:22 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79135;
 Thu 11-Sep-86 17:25:02 EDT
Date: Thu, 11 Sep 86 17:25 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Things on which we agree
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860911-100325-2906@Xerox>
Message-ID: <860911172500.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

[message reformatted to 70-column width to try to avoid linefolding]

    Date: 11 Sep 86 10:03 PDT
    From: Bobrow.pa@Xerox.COM

	     On this topic:

		  :initialize-only flag
		Do we really need this feature? Why not just leave out
		the :accessor if we don't want people to be able to
		setf the slot? [Moon]
	     Presumably the :accessor option indicates that a setfable
	     accessor is made, while its absence still leaves (setf
	     (get-slot ...)  ...) available? Or is GET-SLOT not
	     `agreed to?' If GET-SLOT exists and leaves the slot
	     setfable, then :initialize-only has a role. [RPG]
	 Hmm, if you really think get-slot should be customizable this
	 way, then yes, there should be a slot-option to customize it.
	 Never in a million years would I have figured out from the
	 name of the slot-option that this is what it controls, so I
	 think a better name should be found.  Except for that, I'm
	 amenable to putting this in if someone thinks it's important.
         [Moon]
    What does ":read-only" mean in Flavors on a slot?  It was my
    understanding that it meant that after initialization, one
    couldn't set an instance variable in a method.  :initialize-only
    was put in as a better name (I thought) for :read-only.  Perhaps
    we should drop it as a mechanism that must be supported by the
    system. [Bobrow]

There is no ":read-only" feature in Flavors.  There is one in
defstruct, but it doesn't tell us much since defstruct is so much
simpler.  Let's drop the whole thing unless someone thinks it's
an inportant feature to have.

	 Whoppers (and wrappers) are different from regular methods
	 because they themselves control the way they get combined,
	 instead of being controlled by a method-combination routine
	 defined with define-method-combination.
    This of course is how we have always done method combination in
    Loops, and it has proven most useful to us.  We never allowed
    super classes to dictate what a subclass would do.  Hence the
    similarity that I saw between run-super and continue-whopper.  

I'm not sure this is accurate, but I don't have anything to add beyond
what was in the other message I sent a few minutes ago.

    If we have run-super in primary methods should we have :around
    methods -- and if so, do you prefer the name :full-shadow for this
    type.  Ontologically this name is much sounder, of course, if you
    like that kind of ontology.

The name :full-shadow doesn't convey much meaning to my ear.
Beyond that, I don't have much to say because I can't figure
out what the specific proposal is.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 18:34:44 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 11 SEP 86 14:40:41 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 11 SEP 86 14:40:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 79120;
 Thu 11-Sep-86 17:14:47 EDT
Date: Thu, 11 Sep 86 17:14 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Whoppers and Phenomenology
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860911-114314-3067@Xerox>
Message-ID: <860911171444.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 11 Sep 86 11:42 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    I have the following understanding of whoppers (what I'm about to
    explain is a sketch rather than a representation of everything I understand
    about them).

    Suppose we have a lattice with F1 as the most general (or most basic)
    flavor and F2 and F3 increasingly specific. In the flavors documentation
    pictorial style, F3 would be at the top of the tree and F1 at the bottom.
    In the CommonLoops pictorial style, F1 is at the bottom and F3 at the
    top. Consider classical methods only, and suppose there is a whopper
    defined on F1 and primary methods on F2 and F3. Suppose that the
    whopper does something inconsequential and then does a continue-whopper.

    Suppose that the generic function in question is applied to an instance of
    F3, then I think the order of execution is the whopper first, then the
    method for F3. Is this right?  

Right.

				   If I am right then Danny's comment that
    whoppers are like Loops method combination and continue-whopper is like
    run-super is not exactly correct, I think. Aren't whoppers and
    continue-whopper like Loops method combination and run-super within the
    whopper domain (if there are whoppers in the lattice, then
    continue-whopper runs them in most-specific-first order), but that in the
    overall order of execution, whoppers get done first then other method
    types?

That's right.  If you use only whoppers then you can use continue-whopper
and get the same control structure as if you had used only Loops methods
and used run-super.

If on the other hand you have both whoppers and ordinary methods (of
whatever type, primary, :before, or whatever), then all the whoppers get
control before any of the ordinary methods.  Another way of saying the
same thing is that in any given whopper all of the ordinary methods,
regardless of how specific the flavor they are attached to, are "inside
of" continue-whopper (along with the whoppers on less specific flavors).

    Moon: Is it possible in New Flavors or desirable in the Object System to
    mess with the order of execution via method combination defintion (in
    Flavors) or changing the disciminating function (in the Object System) so
    that the user can define whopper-whoppers, which execute before whoppers?
    In other words, are whoppers definable in New Flavors with whoppers
    removed? 

I think these are two (no, three, maybe four) different questions.  Let
me try to answer them separately.

I assume that in Common Lisp with objects the discriminator has control
at some level over whoppers and the user could replace or augment them
by redefining a few methods.  I think the discriminator class operates
at a different level of modularity than the method-combination type,
and that it's good for both of these features to exist.

In Flavors, define-method-combination has no control whatsoever over
defwhoppers; they're handled separately.

In Flavors, the user could define a method-combination type that
understood methods with a particular method-option to behave just like
whoppers, or similarly to whoppers but with some modification such as
whopper-whoppers.  These couldn't be defined with the existing
defwhopper macro, since define-method-combination has no control over
those.  To make those neo-whoppers work with every method-combination
would require modifying every define-method-combination to know about
them.  Other than that it's extremely easy.

It's been proposed several times over the years to extend Flavors
whoppers to give the programmer more control over their ordering than
just having the most-specific ones first.  None of the proposals ever
got implemented.

Interfaces exist by which the user of New Flavors could define
whopper-whoppers, which execute before regular whoppers, without having
to replace regular whoppers with neo-whoppers.  The implementation of
whoppers is in fact table-driven or object-oriented or whatever you want
to call it.  However, these interfaces aren't documented and are likely
to change as a result of the project we are currently all engaged in.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 14:50:08 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 11 SEP 86 11:43:14 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 11 SEP 86
 11:42:51 PDT
Date: 11 Sep 86 11:42 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Whoppers and Ontology   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860911-114314-3067@Xerox>


Dictionaries are not usually in the business of explaining
philosophical traditions, so I'm not surprised you didn't
find a meaning you could use for `ontological.'

I have the following understanding of whoppers (what I'm about to
explain is a sketch rather than a representation of everything I understand
about them).

Suppose we have a lattice with F1 as the most general (or most basic)
flavor and F2 and F3 increasingly specific. In the flavors documentation
pictorial style, F3 would be at the top of the tree and F1 at the bottom.
In the CommonLoops pictorial style, F1 is at the bottom and F3 at the
top. Consider classical methods only, and suppose there is a whopper
defined on F1 and primary methods on F2 and F3. Suppose that the
whopper does something inconsequential and then does a continue-whopper.

Suppose that the generic function in question is applied to an instance of
F3, then I think the order of execution is the whopper first, then the
method for F3. Is this right?  If I am right then Danny's comment that
whoppers are like Loops method combination and continue-whopper is like
run-super is not exactly correct, I think. Aren't whoppers and
continue-whopper like Loops method combination and run-super within the
whopper domain (if there are whoppers in the lattice, then
continue-whopper runs them in most-specific-first order), but that in the
overall order of execution, whoppers get done first then other method
types?

Moon: Is it possible in New Flavors or desirable in the Object System to
mess with the order of execution via method combination defintion (in
Flavors) or changing the disciminating function (in the Object System) so
that the user can define whopper-whoppers, which execute before whoppers?
In other words, are whoppers definable in New Flavors with whoppers
removed? 

Gregor: Can you fix the Xerox re-mailer so that lines are not
broken in a funny way? 

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 11 Sep 86 13:21:49 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 11 SEP 86 10:03:25 PDT
Redistributed: commonloopscore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 86 10:03:12 PDT
Date: 11 Sep 86 10:03 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Things on which we agree
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 10 Sep 86 21:59 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860911-100325-2906@Xerox>

         On this topic:

     	      :initialize-only flag
    	    Do we really need this feature?       Why not just leave out
the
 	    :accessor if we don't want people to be able to setf the slot?

         Presumably the :accessor option indicates that a setfable
accessor
         is made, while its absence still leaves (setf (get-slot ...)
         ...) available? Or is GET-SLOT not `agreed to?' If GET-SLOT
         exists and leaves the slot setfable, then :initialize-only has
a
         role. 
     Hmm, if you really think get-slot should be customizable this way,
then
     yes, there should be a slot-option to customize it.  Never in a
million
     years would I have figured out from the name of the slot-option
that
     this is what it controls, so I think a better name should be found.
     Except for that, I'm amenable to putting this in if someone thinks
it's
     important.
What does ":read-only"  mean in Flavors on a slot?  It was my
understanding that it meant that after initialization, one couldn't set
an instance variable in  a method.  :initialize-only was put in as a
better name (I thought) for :read-only.  Perhaps we should drop it as a
mechanism that must be supported by the system.


     Whoppers (and wrappers) are different from regular methods because
they
     themselves control the way they get combined, instead of being
     controlled by a method-combination routine defined with
     define-method-combination.
This of course is how we have always done method combination in Loops,
and it has proven most useful to us.  We never allowed super classes to
dictate what a subclass would do.  Hence the similarity that I saw
between run-super and continue-whopper.  If we have run-super in primary
methods should we have :around methods  -- and if so, do you prefer the
name :full-shadow for this type.  Ontologically this name is much
sounder, of course, if you like that kind of ontology.





-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Sep 86 22:13:10 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 10 SEP 86 19:01:23 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 10 SEP 86 19:01:07 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 78603;
 Wed 10-Sep-86 21:59:43 EDT
Date: Wed, 10 Sep 86 21:59 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Things on which we agree
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860909-232449-1480@Xerox>
Message-ID: <860910215951.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 09 Sep 86 23:24 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Some of the West Coast people prefer MAKE-INSTANCE to MAKE.
    The motivation is to leave good names alone when reasonably
    short, reasonably descriptive names are available.

Either name is fine with me.

    ********************************************************************

    When I read something like:

	  :accessor generic-function-name
		Specifies that a function named generic-function-name
		be automatically generated, to read the value of this
		slot.  SETF may be used with generic-function name to
		write the value of the slot.
  
    Should I take it to mean the same as


	  :accessor generic-function-name
		Specifies that a generic function named generic-function-name
		be automatically generated, to read the value of this
		slot.  SETF may be used with generic-function-name to
		write the value of the slot.

I think so.  The omission of "generic" before "function" in 1 out of 4
places was probably not intended to mean anything.  It should be rephrased
to be consistent.

    ********************************************************************

    On this topic:

	      :initialize-only flag
  
	    Do we really need this feature?  Why not just leave out the
	    :accessor if we don't want people to be able to setf the slot?

    Presumably the :accessor option indicates that a setfable accessor is
    made, while its absence still leaves (setf (get-slot ...) ...) available?
    Or is GET-SLOT not `agreed to?' If GET-SLOT exists and leaves the slot
    setfable, then :initialize-only has a role. 

Hmm, if you really think get-slot should be customizable this way, then
yes, there should be a slot-option to customize it.  Never in a million years
would I have figured out from the name of the slot-option that this is what
it controls, so I think a better name should be found.  Except for that,
I'm amenable to putting this in if someone thinks it's important.

I think of get-slot as a subprimitive for getting around the normal
accessor mechanism, so I don't see any point to the extra complexity of
providing ways to turn off get-slot reading and writing.  I see even less
point when I think about it harder and suspect that then you would need
a %get-slot, which is the same as get-slot except that it can't be turned
off, as part of the semantics of WITH.

Perhaps other people think of get-slot as something the user would use
all the time, if so that's a bit of a surprise to me.  I do think we
agreed that there should be something that does get-slot (called
symbol-value-in-instance in Flavors; I don't much care for either name).

    ********************************************************************

    Danny said: ``There are two different are proposals under discussion.''

    He was misguided in saying this. He meant that the West Coast discussion
    group was discussing this issue and would probably propose an alternative
    that mentions WITH and %WITH (or some such names). We usually discuss
    things like this out here to try to filter out bad ideas from the set of
    ideas we ship to the Hub.

I haven't been to the Hub in weeks.

    ********************************************************************

    Is the name of the type of method combination a symbol for some deep
    reason or just to keep it a simple name as in other named things?

The latter.

    *********************************************************************

    Are whoppers thought of as being in a different ontological category
    from other method combination types? The continue-whopper `feature'
    seems to hint so. 

Whoppers aren't a method-combination type, they are a kind of method.  I
don't know what an ontological category is, but the dictionary
definition of ontological suggests that deleting the word won't change
the meaning of your question.  Whoppers (and wrappers) are different
from regular methods because they themselves control the way they get
combined, instead of being controlled by a method-combination routine
defined with define-method-combination.

I should point out again that I don't like whoppers, but I support them
for the standard because I have to admit that my users have found them
very useful.  I might not always be the best source of information about
why whoppers are the way they are, for this reason.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Sep 86 19:36:28 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 10 SEP 86 15:43:08 PDT
Date: 10 Sep 86 15:42 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Getting together to work
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Message-ID: <860910-154308-2286@Xerox>

My messages for the next little while are likely to be more curt than
usual, I can only type with one hand.

We had made a plan to get together monday moring at OOPSLA and work on
the spec.  I believe that we will have more work to do than can be done
in three hours.

Instead, I propose that we get together Friday and Saturday after OOPSLA
in Palo Alto.  This will give us enough time to actually get some work
done, and takes advantage of existing travel to get a lot of people in
the same place.

I propose that we use the Monday morning at OOPSLA time to have a more
open meeting with people from LMI and HP.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Sep 86 15:23:24 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 10 SEP 86 10:35:55 PDT
Redistributed: CommonLoopsCore↑.PA
Received: from Cabernet.ms by ArpaGateway.ms ; 10 SEP 86 10:35:21 PDT
Date: 10 Sep 86 10:34 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: draft document
In-reply-to: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>'s message of
 Wed, 10 Sep 86 00:33 EDT
To: Moon@SCRC-STONY-BROOK.ARPA
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860910-103555-1928@Xerox>

The document did not come together as expected, hence the much larger
volume of messages last week, and to be continued.  


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Sep 86 02:29:41 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 09 SEP 86 23:24:49 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 09 SEP 86
 23:24:40 PDT
Date: 09 Sep 86 23:24 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Things on which we agree
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860909-232449-1480@Xerox>


Some of the West Coast people prefer MAKE-INSTANCE to MAKE.
The motivation is to leave good names alone when reasonably
short, reasonably descriptive names are available.

********************************************************************

When I read something like:

      :accessor generic-function-name
	    Specifies that a function named generic-function-name
	    be automatically generated, to read the value of this
	    slot.  SETF may be used with generic-function name to
	    write the value of the slot.
  
Should I take it to mean the same as


      :accessor generic-function-name
	    Specifies that a generic function named generic-function-name
	    be automatically generated, to read the value of this
	    slot.  SETF may be used with generic-function-name to
	    write the value of the slot.

********************************************************************

On this topic:

	  :initialize-only flag
  
	Do we really need this feature?  Why not just leave out the
	:accessor if we don't want people to be able to setf the slot?

Presumably the :accessor option indicates that a setfable accessor is
made, while its absence still leaves (setf (get-slot ...) ...) available?
Or is GET-SLOT not `agreed to?' If GET-SLOT exists and leaves the slot
setfable, then :initialize-only has a role. 

********************************************************************

Danny said: ``There are two different are proposals under discussion.''

He was misguided in saying this. He meant that the West Coast discussion
group was discussing this issue and would probably propose an alternative
that mentions WITH and %WITH (or some such names). We usually discuss
things like this out here to try to filter out bad ideas from the set of
ideas we ship to the Hub.

********************************************************************

Is the name of the type of method combination a symbol for some deep
reason or just to keep it a simple name as in other named things?

*********************************************************************

Are whoppers thought of as being in a different ontological category
from other method combination types? The continue-whopper `feature'
seems to hint so. 

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Sep 86 02:00:13 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 09 SEP 86 22:53:12 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 09 SEP 86
 22:53:02 PDT
Date: 09 Sep 86 22:52 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Class-of Versus Type-of 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860909-225312-1464@Xerox>


Danny asked what I meant when I said that class-of might be ill-defined
in some situation. The situation I thought I was discussing was
the one in which the Common Lisp type system is subsumed by the
class system, and class-of is possibly expected to return `the
most specific class' in the presence of type specifiers which correspond
to classes and in the presence of types/classes that do not exist in
every Common Lisp (like simple- objects). Class-of is perfectly
well-defined in the current proposal in which the Common Lisp standard
type specifiers (minus atom and common) have (builtin) classes.
(Danny, I'm referring to the current West Coast proposal).

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Sep 86 01:00:09 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 09 SEP 86 21:41:34 PDT
Return-Path: <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by
 Xerox.COM ; 09 SEP 86 21:40:45 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 99736; Wed
 10-Sep-86 00:39:48 EDT
Date: Wed, 10 Sep 86 00:39 EDT
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: Re: Summary of features we all agree on
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860905-184912-1633@Xerox>
Message-ID: <860910003916.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

  Date: 5 Sep 86 18:49 PDT
  From: Bobrow.pa@Xerox.COM
  
    (DEFCLASS class-name (slot-spec...) (super-class-name...)
       option...)
  
  Not quite.  We have the opposite order for (super-class-name...)
  and (slot-spec...).
  
  (DEFCLASS class-name (super-class-name...) (slot-spec...)
  option...)

We can probably go along with this, but it ought to be
discussed.  What was the motivation for changing the order?

    class-name is a non-null symbol that names the class being
    defined.  If a class is already defined with this name, this
    definition replaces the old definition.  The default
    meta-class ensures that when the definition of a class
    changes, each existing instance of the class is updated to the
    new format the next time it is accessed.
  
     Each slot-spec is one of:
  
      slot-name       a non-null symbol.
  
       (slot-name initial-value-form)
  
  
      (slot-name slot-option...)
	Each slot-option is an option name followed by its value.
	The defined slot-options and their arguments are:
  
       = initial-value-form
	       This an alternate way for providing a default
	       initial value form.
  
  How is this form distinguished from the previous.  By having more than
  two elements???  

Yes.  (slot-name initial-value-form) is a convenient
abbreviation for (slot-name = initial-value-form).

		   How do you not give an init value form. 

The way you omit the initial value form when giving slot-options
is to omit the = slot-option.  I thought this was discussed in
the mail a while back but I could be misremembering.

By the way I'm not wedded to the name "=".  I couldn't think of
a clearer name when I tried for a few minutes, but perhaps
someone else can.

      :accessor generic-function-name
	    Specifies that a function named generic-function-name
	    be automatically generated, to read the value of this
	    slot.  SETF may be used with generic-function name to
	    write the value of the slot.
  
  OK.  If generic-function-name is NIL then this is a NOOP.
  Specified so programs can generate these.
  
      :reader generic-function-name
	    Specifies that a function named generic-function-name
	    be automatically generated, to read the value of this
	    slot.
  
  We have called this :read-accessor.  

I think users would find the distinction between :read-accessor
and :accessor confusing.  Perhaps we need some more opinions
here, it's a difficult judgement.

				       We specify that if this is
  given, then SETF may NOT be used with this accessor. If
  generic-function-name is NIL then this is a NOOP.
  
Agreed.

      :initable keyword
	    Specifies a keyword to be used to specify an
	    initial value of this slot, when a new instance is
	    being made.
  
  I think this is OK.  Should allow value of NIL.  Default is T

I don't think you meant it when you said "default is T", since
the argument is a keyword.  If you meant that unless the
programmer specifies otherwise, all slots can be initialized by
MAKE with keywords chosen by default, I don't think that is good
data abstraction.  I don't think slots should be visible from
outside of the module that owns a class unless the definer of
the class explicitly makes them visible.  We can provide a
defclass option that makes it very easy to make all the slots
initializable, but the default should be that features like this
are turned off until the programmer turns them on.  This is the
same argument as the one that made us all decide that slot
accessors are not created unless the programmer asks for them.

      :allocation
   
  :allocation can have values
   :instance (allocated in the instance),
   :class (storage allocated in the class and shared by all
	   instances),
   :dynamic (storage allocated in the instance on first use
      (like Flavors Proplist mixin)
   :none  expect accessor methods for this to be defined for
     this slot in this class

We need to discuss which of these allocation options belong in
the standard.  Maybe only a subset of them.

  :initialize-only flag
  
  If flag = T, then this slot cannot be changed after
  initialization (a better name for :read-only).  flag=T implies
  no accessors are generated.  default is NIL.
  
Do we really need this feature?  Why not just leave out the
:accessor if we don't want people to be able to setf the slot?

    If no initial value is specified either in the DEFCLASS or the
    MAKE form, the initial value of the slot is undefined and it
    is an error to reference it.  This is the same behavior as a
    DEFVAR with no initial-value-form.
  
  We hate these "it is an error" statements.  We haven't discussed
  this particular issue.

I don't think the object-oriented programming standard should
try to be the error-handling standard, too!  Let's just say that
referencing an uninitialized slot has the same error
characteristics as referencing an uninitialized special
variable, and leave it to the rest of the language to define
just what that is.

    Each super-class-name is a non-null symbol.
    
    Each option is one of:
    
	option-name
	(option-name argument...)
    
    Each option-name is a keyword that names an option; the
    arguments depend on the option.
  
  OK
  
    The set of defined options and their arguments is:
      
     (:accessor-prefix prefix slot-name...)
     (:reader-prefix prefix slot-name...)
     (:default-init-plist keyword-argument...)
     (:initable-slots slot-name...)
     (:init-keywords keyword...)
  
  The only one of these that we have agreed to is:
  
   (:accessors-with-prefix string-or-symbol)
  
  which causes accessors to be generated with the given prefix for
  ALL slots that do not have local specification of any of
  :accessor, :read-accessor, or :initialize-only.  If this form
  does not appear, then no accessors for slots are generated.

  Note they we have made this be a single default that applies
  uniformly.  No specific slots can be mentioned, and this option
  can appear only once.  The arguments for this way of doing
  business are:
  1) Anything not uniform is local to a slot description
  2) There are no redundant, possibly inconsistent,
  declarations

:accessors-with-prefix is certainly nice and simple, but it is
not the same as the last thing that was discussed in the mail.
And the other options were listed because they appeared in
"things we basically agree on" in the minutes of that meeting we
had at MIT, so we need to keep discussing this until we converge.
  
    (:documentation string)
  
  OK   
  
    (:meta-class class-name)
  
  No, we think this should be done using the meta-object protocol,
  since the parsing of the defclass is not under the control of
  the meta-class.  However, I think we could be convinced
  otherwise.

You're the meta-class experts, but I think the idea of this
option was supposed to be to control the class of the class that
gets instantiated, but not to affect anything about the parsing
of the defclass.

    (:required-classes class-name...)
    (:required-init-keywords keyword...)
    (:required-slots slot-name...)
    (:required-methods generic-function-name...)
  
  No.  These seem like environmental features, and should not be
  part of the spec.  

I think you're wrong here, for two reasons.  One is that I don't
agree that these are environmental; I see them as a necessary
part of defining a class and its relationships with other
classes.  We've found these options to be heavily used when
setting up complex families of classes.

The second reason is that these aren't just error-checking.
:required-slots and :required-classes can make additional slot
names available as variables inside a WITH.  This is necessary
to be able to write methods for abstract classes, and especially
for mixins, when part of the inter-component-class interface
takes the form of slots.

If we disagree we need to keep discussing this.

		     We should make some comment about how
  additional options may be supported by the standard class in
  particular implementations, and ones not understood will either
  be ignored, or have warnings issued. 
   
I don't think having defclass options quietly ignored in some
implementations is going to enhance portability.

    (:constructor function-name lambda-list)
  
  We have allowed the full generality of the defstruct syntax for
  this one.  Do you think it should be restricted to this
  boa-constructor

No, I agree.  Specifically, the lambda-list should be optional,
and default to (&key ...) where the ... is filled in according
to the :initable and :initable-slots (or whatever those options
end up being called) in the obvious way.

    For the :ACCESSOR-PREFIX, :READER-PREFIX, and :INITABLE-SLOTS
    options, you can omit slot-names to indicate that the option
    applies for all slots of this class.
  
  See above
  
    It is legal to specify more than one accessor and reader for a
    single slot.
  
  We argued about this, and decided we didn't like it.  Why is it good?

I think I pointed out in an earlier piece of mail that you might
want to have both an accessor and a reader, where the accessor
is used inside of a module while the reader is a public
interface.  The idea is that you can't change the contents of
the slot using the public interface.  I don't know of
applications for two accessors or two readers, but I don't see
any advantage to adding a special error-check to disallow that.
Why is it bad?

    DEFINING METHODS AND SETF METHODS
    
    The general syntax for defining a method is:
    
    (DEFMETHOD generic-function-name method-option...
      method-lambda-list
       body...)
  
  No.  See my earlier message. 
  
At the time Sonya and I put together this list of things that
we thought had been agreed upon, we didn't know that there was
still disagreement on the syntax of defmethod, since we had not
heard from you.  As it turns out defmethod isn't ready to be
included yet.  We need to keep working on it until we converge.

  ...But we agree that DEFMETHOD-SETF
  is a better name....  Are we not allowing multiple values to be
  stored?  In the silver book it talks about extensions to the
  corresponding list of store variables.  I have no problem with
  the restriction.
  
The extension mentioned on CLtL p.103 hasn't been incorporated
into Common Lisp yet, so I don't think it should be allowed to
sneak in through the object-oriented programming extension.
We should leave syntactic space for it, though, so having the
store-variable in a separate lambda-list is good.

    DEFINING GENERIC FUNCTIONS
    
    (DEFGENERIC generic-function-name lambda-list option...)
    
    (DEFGENERIC-SETF generic-function-name lambda-list
    setf-lambda-list option.
    
    generic-function-name is a non-null symbol.
    
    lambda-list is an ordinary lambda-list except no &aux
    variables are allowed.
  
    setf-lambda-list is (variable-name).
  
  Yes, except that we allow a documentation string before the
  options.  What do you think???

Flavors allows a "naked" documentation string also, but I'm not
sure that ought to be in the standard.  It's a matter of whether
you think it's more important to have the options in a uniform
format or to have defgeneric syntax be more analogous to defun
syntax.

    Each option is one of:
  
	option-name
	(option-name argument...)
  
    Each option-name is a keyword that names an option; the
    arguments depend on the option.
  
  OK
  
    The set of defined options and their arguments is:
    
    [--Should declarations and doc strings be allowed?--]
    
	     (:documentation string)
  
  See above.
  
	     (:optimize spec...)
  
  Is this for all methods, or just the discriminating function.
  This seems weird to me

The question seems weird to me.  I guess the problem is caused
by us including only the syntax and not the semantics so as to
get something out quickly for discussion, which meant that we
completely failed to communicate what this was all about.

The idea of the :optimize option to defgeneric in Flavors is
that there are a variety of possible ways of doing
discrimination, and in order for the system to choose among them
intelligently the user should be able to express his needs.  In
the Common Lisp objected-oriented programming facility I presume
it would be a method of the discriminator, rather than
"the system", that is guided by this option, but otherwise the
concept of the :optimize option seems to carry over directly and
does not seem to be at all specific to Flavors.  I believe it's
more portable for the user's needs to be expressed in terms of
which quality (speed or space) is more important, rather than
directly specifying the exact technique to be used.

	     (:method-combination name argument...)
  
  What is the argument in this form?
  
Optional arguments received by parameters in the
define-method-combination.  See the Flavors documentation.

	     (:generic-function-class class-name)
	     (:method-class class-name)
	     (:order parameter-name...)
  
  We have been using :dispatch-order for the keyword :order.  It
  should really be :argument-precedence-order.

:argument-precedence-order is the best name I've heard for this
yet.

		 [more?]
  
  Additional options should be allowed, as in defclass.

	      WITH
    
    We have agreed that WITH should exist, but we haven't decided
    anything more specific about it yet.
  
  Right; we haven't decided anything yet.  There are two different
  proposals under discussion.  One turns names in calls on the
  accessors (we call that one WITH).  The other turns them into
  primitive slot accesses (we call that one %WITH).
  
No proposal is "under discussion" if the people on the east coast
haven't seen it.  Send them along and we'll be happy to discuss
them.
  
    DEFINING NEW TYPES OF METHOD COMBINATION
    
    (DEFINE-SIMPLE-METHOD-COMBINATION name operator-name
				      [single-arg-is-value]
				      [pretty-name])
    
    This function defines a new type of method combination in
    which all the methods are called and their values are passed
    to the operator specified by operator-name.
    
    name is a non-null symbol, often a keyword, that is the name
    of the type of method combination being defined.
  
    operator-name can be a symbol or a lambda-expression, the name
    of a function, a macro, or a special form.
  
    single-arg-is-value is t or nil; by default it is nil.
    
    pretty-name is a string.  It defaults to the lower case
    version of the supplied name.
  
  We haven't agreed to this at all yet.  super-daemon method
  combination we believe in. But this simple case seems strange to
  me, and if it can be defined with the stronger
  DEFINE-METHOD-COMBINATION, then let's not put it in the spec.

It's a convenient abbreviation for people who don't want to have
to understand the full define-method-combination to do something
simple.  What are you going to tell the user whose program is
non-portable because you decided to leave this out?

  I didn't see whoppers described in daemon combination section of
  the Flavors manual -- at least not in the early section.  Does
  this mean that it is not a feature of daemon combination?

Whoppers are described in their own section.  They are not a
feature of daemon combination or any other particular type of
combination.

  We believe that at least on the west coast, run-super will be
  used much more than daemon combination.  Hence my attempt to
  unify them.  An answer to Moons answer next week.
  
    (DEFINE-METHOD-COMBINATION method-combination-type-name
			       lambda-list
			       (method-pattern...) 
			       option...
       body...)
    
    This function behaves the same way as in Flavors.  See the
    Flavors documentation for details.
  
  We believe that a simple version of this should be in the spec.
  I don't know yet what simple means.  At least powerful enough to
  define the extended features, but not including the full library
  of standardly available combinations types.
  
    Making a New Instance
    
    (MAKE class-name keyword-argument...)
    
    MAKE is the function that makes and initializes an instance of
    a class.  The allowed keyword-arguments depend on the DEFCLASS
    form.  Any keyword specified with the :INITABLE,
    :INITABLE-SLOTS, or :INIT-KEYWORDS option is allowed.
  
    If a keyword-argument is given to MAKE, it overrides any
    default that is given in the DEFCLASS form, such as the
    :DEFAULT-INIT-PLIST option, or the initial-value-form syntax.
  
  Modulo isssues on keywords and specification of initable, this
  is basically correct.
  
  
    OTHER FUNCTIONS
    
    Other functions of interest to the general programmer
    [---tbd---].
    
    This list came from the 8 August meeting; it can serve as a
    starting agenda for this section:
    
	find-flavor / class-named
  
  Yes class-named
  
	typep
  
  classp is the right name

The name TYPEP is already specified by Common Lisp, we can't
change it to something else.  The issue here is what is to be
changed in the documentation of typep when the object-oriented
programming extension is added to the Common Lisp specification.

	type-of
	class-of
  
  Yes on class-of
  
	operation-handled-p ??
  
  Something like this is needed
  
	remove-class
	   remove-method
	   change-class
  
  Yes


If we can discuss and reach agreement upon the few points of
disagreement above, we should be able to send out a revised
version of "Summary of features we all agree on" in a couple
of days and then move on to deeper issues.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 10 Sep 86 00:59:19 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 09 SEP 86 21:35:06 PDT
Return-Path: <Moon@ALDERAAN.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ALDERAAN.SCRC.Symbolics.COM ([192.10.41.109]) by
 Xerox.COM ; 09 SEP 86 21:34:51 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 3422; Wed
 10-Sep-86 00:33:50 EDT
Date: Wed, 10 Sep 86 00:33 EDT
From: David A. Moon <Moon@SCRC-STONY-BROOK.ARPA>
Subject: lack of word from the west coast
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860910003335.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

The draft document outlining what has been learned so far
in the Xerox/Lucid meetings, which you said you would send
by the end of last week, has not yet arrived.  I think you
had better send it again.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Sep 86 22:46:47 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 SEP 86 18:34:49 PDT
Date: 9 Sep 86 18:34 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: [Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>:
 Summary of features we all agree on ]
In-reply-to: Kahn.pa's message of 8 Sep 86 14:07 PDT
To: Kahn.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM, CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860909-183449-1216@Xerox>

          :initialize-only flag
     
     
     We need to be clear what "after initialization" means.  Can one
send an
     "initialize-with-plist" message to an "already initialized"
instance?  

I think so (How can we stop it?)  But that is different than using a
SETF to change the value.  Users can almost always get around read-only
declarations not protected by hardware.  I prefer the name
:initialize-only to :read-only despite history. 

        (:meta-class class-name)
     There are different uses of meta-classes.  There are those that
just
     make performance trade-offs and need not be concerned with "the
parsing
     of the defclass".  It would be reasonable to be able to use the
     :meta-class at least in such cases. 
I agree.

          (MAKE class-name keyword-argument...)

     I would prefer that the first argument to MAKE is either a
class-name or
     a class.

I agree.


-- danny
     
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Sep 86 22:46:37 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 SEP 86 17:52:00 PDT
Date: 9 Sep 86 17:46 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Subtypep 
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 08 Sep 86
 17:35 PDT
To: RPG@SAIL.STANFORD.EDU
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860909-175200-1153@Xerox>

     CLASS-OF will be as poorly defined as the current TYPE-OF.

Why is this ill-defined?  It is not TYPE-OF.  It returns the most
specific class for the instance.


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  9 Sep 86 22:46:30 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 SEP 86 17:20:21 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 09 SEP 86 17:19:37 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 77621;
 Tue 9-Sep-86 19:41:24 EDT
Date: Tue, 9 Sep 86 19:41 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: [Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>:
          Summary of features we all agree on ]
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860909194125.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

Here is a copy of Danny's long message from Friday, reformatted
to try to keep the Xerox mail redistribution program from
garbling it by wrapping long lines without regard for
indentation.

Date: 5 Sep 86 18:49 PDT
From: Bobrow.pa@Xerox.COM
Subject: [Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>:
 Summary of features we all agree on ]
To: CommonLoopsCore↑.PA@Xerox.COM
cc: Bobrow.pa@Xerox.COM
Message-ID: <860905-184912-1633@Xerox>


  Part I describes the basic tools for defining classes,
  methods, generic functions, and method combination types, and
  for making instances of classes.

  DEFINING CLASSES
  
  (DEFCLASS class-name (slot-spec...) (super-class-name...)
     option...)

Not quite.  We have the opposite order for (super-class-name...)
and (slot-spec...).

(DEFCLASS class-name (super-class-name...) (slot-spec...)
option...)

  class-name is a non-null symbol that names the class being
  defined.  If a class is already defined with this name, this
  definition replaces the old definition.  The default
  meta-class ensures that when the definition of a class
  changes, each existing instance of the class is updated to the
  new format the next time it is accessed.

   Each slot-spec is one of:

    slot-name       a non-null symbol.

     (slot-name initial-value-form)


    (slot-name slot-option...)
      Each slot-option is an option name followed by its value.
      The defined slot-options and their arguments are:

     = initial-value-form
	     This an alternate way for providing a default
             initial value form.

How is this form distinguished from the previous.  By having more than
two elements???  How do you not give an init value form. 

    :accessor generic-function-name
	  Specifies that a function named generic-function-name
	  be automatically generated, to read the value of this
	  slot.  SETF may be used with generic-function name to
	  write the value of the slot.

OK.  If generic-function-name is NIL then this is a NOOP.
Specified so programs can generate these.

    :reader generic-function-name
	  Specifies that a function named generic-function-name
	  be automatically generated, to read the value of this
	  slot.

We have called this :read-accessor.  We specify that if this is
given, then SETF may NOT be used with this accessor. If
generic-function-name is NIL then this is a NOOP.

    :initable keyword
          Specifies a keyword to be used to specify an
	  initial value of this slot, when a new instance is
	  being made.

I think this is OK.  Should allow value of NIL.  Default is T

    :allocation
 
:allocation can have values
 :instance (allocated in the instance),
 :class (storage allocated in the class and shared by all
         instances),
 :dynamic (storage allocated in the instance on first use
    (like Flavors Proplist mixin)
 :none  expect accessor methods for this to be defined for
   this slot in this class
                
:initialize-only flag

If flag = T, then this slot cannot be changed after
initialization (a better name for :read-only).  flag=T implies
no accessors are generated.  default is NIL.

  If no initial value is specified either in the DEFCLASS or the
  MAKE form, the initial value of the slot is undefined and it
  is an error to reference it.  This is the same behavior as a
  DEFVAR with no initial-value-form.

We hate these "it is an error" statements.  We haven't discussed
this particular issue.

  Each super-class-name is a non-null symbol.
  
  Each option is one of:
  
      option-name
      (option-name argument...)
  
  Each option-name is a keyword that names an option; the
  arguments depend on the option.

OK

  The set of defined options and their arguments is:
    
   (:accessor-prefix prefix slot-name...)
   (:reader-prefix prefix slot-name...)
   (:default-init-plist keyword-argument...)
   (:initable-slots slot-name...)
   (:init-keywords keyword...)

The only one of these that we have agreed to is:

 (:accessors-with-prefix string-or-symbol)

which causes accessors to be generated with the given prefix for
ALL slots that do not have local specification of any of
:accessor, :read-accessor, or :initialize-only.  If this form
does not appear, then no accessors for slots are generated.

Note they we have made this be a single default that applies
uniformly.  No specific slots can be mentioned, and this option
can appear only once.  The arguments for this way of doing
business are:
1) Anything not uniform is local to a slot description
2) There are no redundant, possibly inconsistent,
declarations

  (:documentation string)

OK   

  (:meta-class class-name)

No, we think this should be done using the meta-object protocol,
since the parsing of the defclass is not under the control of
the meta-class.  However, I think we could be convinced
otherwise.

  (:required-classes class-name...)
  (:required-init-keywords keyword...)
  (:required-slots slot-name...)
  (:required-methods generic-function-name...)

No.  These seem like environmental features, and should not be
part of the spec.  We should make some comment about how
additional options may be supported by the standard class in
particular implementations, and ones not understood will either
be ignored, or have warnings issued. 
 
  (:constructor function-name lambda-list)

We have allowed the full generality of the defstruct syntax for
this one.  Do you think it should be restricted to this
boa-constructor

  For the :ACCESSOR-PREFIX, :READER-PREFIX, and :INITABLE-SLOTS
  options, you can omit slot-names to indicate that the option
  applies for all slots of this class.

See above

  It is legal to specify more than one accessor and reader for a
  single slot.

We argued about this, and decided we didn't like it.  Why is it good?

  DEFINING METHODS AND SETF METHODS
  
  The general syntax for defining a method is:
  
  (DEFMETHOD generic-function-name method-option...
    method-lambda-list
     body...)

No.  See my earlier message. 

   (DEFMETHOD name-and-options
    method-lambda-list
     body...)

   generic-function-name is a non-null symbol.

name-and-options is a non-null symbol or (name . method-options)

See my earlier message.

  Each method-option is a non-null atom that describes the type
  of this method.  Some examples of method-options are:
    :BEFORE and :AFTER.

  method-lambda-list is a lambda-list with one difference.
  Where a lambda-list allows only a variable and not a list, a
  type-qualified-variable may be used.  However,
  type-qualified-variables cannot be used for &aux variables,
  supplied-p parameters, or &rest parameters.  A
  type-qualified-variable is a list such as:
    (variable-name type-specifier).
  Note that the use of &optional is still under discussion.

  type-specifier ---tbd---

type-specifer and its uses should be replaced by
argument-specifier.  This will include class-names
(class-specifiers) and individuals.  The meaning of
argument-specifier may be extended by users who build their own
discriminators.

  For convenience in defining a classical method, the following
  syntax is provided:
  
  (DEFMETHOD (generic-function-name first-arg-type method-option...)
    method-lambda-list
    body...)
  
  The classical syntax is equivalent to the following expression
  in the general syntax:
  
  (DEFMETHOD generic-function-name method-option...
    ((self first-type-arg) method-lambda-list...)
    (with (self)
      body...))

See other message

  The general syntax for defining a SETF method is:
  
  (DEFMETHOD-SETF generic-function-name method-option...
    method-lambda-list setf-lambda-list
    body...)
  
  The classical syntax for defining a SETF method is:
  
  (DEFMETHOD-SETF (generic-function-name first-arg-type
		   method-option...)
    method-lambda-list setf-lambda-list
    body...)
  
  generic-function-name and method-option are the same as for
  DEFMETHOD.
  
  setf-lambda-list is a lambda-list containing exactly one
  required parameter, which may be type-qualified.  In other
  words, setf-lambda-list is one of:

   (variable-name)
   ((variable-name type-specifier))

Same problem with this syntax.  But we agree that DEFMETHOD-SETF
is a better name.  If you liked my other syntax suggestions,
then this one follows.  Again type-specifier ->
argument-specifier.  Are we not allowing multiple values to be
stored.  In the silver book it talks about extensions to the
corresponding list of store variables.  I have no problem with
the restriction.

  DEFINING GENERIC FUNCTIONS
  
  (DEFGENERIC generic-function-name lambda-list option...)
  
  (DEFGENERIC-SETF generic-function-name lambda-list
  setf-lambda-list option.
  
  generic-function-name is a non-null symbol.
  
  lambda-list is an ordinary lambda-list except no &aux
  variables are allowed.

  setf-lambda-list is (variable-name).

Yes, except that we allow a documentation string before the
options.  What do you think???

  Each option is one of:

      option-name
      (option-name argument...)

  Each option-name is a keyword that names an option; the
  arguments depend on the option.

OK

  The set of defined options and their arguments is:
  
  [--Should declarations and doc strings be allowed?--]
  
	   (:documentation string)

See above.

	   (:optimize spec...)

Is this for all methods, or just the discriminating function.
This seems weird to me

	   (:method-combination name argument...)

What is the argument in this form?

	   (:generic-function-class class-name)
	   (:method-class class-name)
	   (:order parameter-name...)

We have been using :dispatch-order for the keyword :order.  It
should really be :argument-precedence-order.

	       [more?]

Additional options should be allowed, as in defclass.

            WITH
  
  We have agreed that WITH should exist, but we haven't decided
  anything more specific about it yet.

Right; we haven't decided anything yet.  There are two different
proposals under discussion.  One turns names in calls on the
accessors (we call that one WITH).  The other turns them into
primitive slot accesses (we call that one %WITH).


  DEFINING NEW TYPES OF METHOD COMBINATION
  
  (DEFINE-SIMPLE-METHOD-COMBINATION name operator-name
				    [single-arg-is-value]
				    [pretty-name])
  
  This function defines a new type of method combination in
  which all the methods are called and their values are passed
  to the operator specified by operator-name.
  
  name is a non-null symbol, often a keyword, that is the name
  of the type of method combination being defined.

  operator-name can be a symbol or a lambda-expression, the name
  of a function, a macro, or a special form.

  single-arg-is-value is t or nil; by default it is nil.
  
  pretty-name is a string.  It defaults to the lower case
  version of the supplied name.

We haven't agreed to this at all yet.  super-daemon method
combination we believe in. But this simple case seems strange to
me, and if it can be defined with the stronger
DEFINE-METHOD-COMBINATION, then let's not put it in the spec.

I didn't see whoppers described in daemon combination section of
the Flavors manual -- at least not in the early section.  Does
this mean that it is not a feature of daemon combination?

We believe that at least on the west coast, run-super will be
used much more than daemon combination.  Hence my attempt to
unify them.  An answer to Moons answer next week.

  (DEFINE-METHOD-COMBINATION method-combination-type-name
			     lambda-list
			     (method-pattern...) 
			     option...
     body...)
  
  This function behaves the same way as in Flavors.  See the
  Flavors documentation for details.

We believe that a simple version of this should be in the spec.
I don't know yet what simple means.  At least powerful enough to
define the extended features, but not including the full library
of standardly available combinations types.

  Making a New Instance
  
  (MAKE class-name keyword-argument...)
  
  MAKE is the function that makes and initializes an instance of
  a class.  The allowed keyword-arguments depend on the DEFCLASS
  form.  Any keyword specified with the :INITABLE,
  :INITABLE-SLOTS, or :INIT-KEYWORDS option is allowed.

  If a keyword-argument is given to MAKE, it overrides any
  default that is given in the DEFCLASS form, such as the
  :DEFAULT-INIT-PLIST option, or the initial-value-form syntax.

Modulo isssues on keywords and specification of initable, this
is basically correct.


  OTHER FUNCTIONS
  
  Other functions of interest to the general programmer
  [---tbd---].
  
  This list came from the 8 August meeting; it can serve as a
  starting agenda for this section:
  
      find-flavor / class-named

Yes class-named

      typep

classp is the right name

      type-of
      class-of

Yes on class-of

      operation-handled-p ??

Something like this is needed

      remove-class
	 remove-method
	 change-class

Yes


-- danny

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 22:50:35 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 19:31:19 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 08 SEP 86 19:31:08 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 76895;
 Mon 8-Sep-86 22:30:03 EDT
Date: Mon, 8 Sep 86 22:31 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: Bobrow.pa@Xerox.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860908-161339-3280@Xerox>
Message-ID: <860908223153.1.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: 8 Sep 86 16:13 PDT
    From: Bobrow.pa@Xerox.COM

    (defmethod foo ((self class-name) ...) provides self as a cliche, and
    allows those users the optioning of providing a more mnemonic name for
    self.  Instance variables (or slots as we are calling them) are
    available in either case.  

No, they aren't.  You have to put in a WITH yourself.  Otherwise there
are slots but there aren't instance variables, that is, variables of
which there is one per instance, which behave like variables.

			       Using the general syntax also encourages
    users to remmber that this is a generic function and others may define
    extensions (new defmethods) that specialize more than one argument.  I
    think that separate syntax will cause mind bugs of the sort -- 'well I
    did a "classical" defmethod so now I can't specialize other args.'

The intention of the "classical" syntax, as I see it, is to provide
something that looks and acts familiar to someone who's used another
system.  As such, naturally it doesn't especially encourage people to
specialize more than one argument.  If you wanted to encourage that, or
if they wanted to do that, they would not use the "classical" syntax in
the first place; they'd use the "modern" syntax.  There's no way both
sets of goals can be accomplished simultaneously, which is the
motivation for having two syntaxes.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 21:01:50 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 17:36:14 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 08 SEP 86
 17:36:05 PDT
Date: 08 Sep 86 17:35 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Subtypep 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860908-173614-3369@Xerox>


Making the class system a proper superset of the current
Common Lisp type system certainly implies an analog (at least)
of SUBTYPEP, which is inconsistent over all Common Lisp
implementations. I mistakenly thought that it was possible
for a stupid implementor to implement TYPEP in terms of SUBTYPEP,
but now I think it's actually impossible. 

Another consideration when thinking about whether to make the class system
a superset of the Common Lisp type system is the lack of specificity as to
what CLASS-OF returns.  CLASS-OF will be as poorly defined as the current
TYPE-OF.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 20:07:03 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 16:21:02 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 08 SEP 86 16:20:48 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 76812;
 Mon 8-Sep-86 19:19:38 EDT
Date: Mon, 8 Sep 86 19:21 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Class versus Type System
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860908141318.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860908192128.5.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: Mon, 8 Sep 86 14:13 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    Surely it will be a disaster if the specification of this standard is so poor
    that users can't figure out what it specifies, except by experimenting with
    a particular implementation that is said to implement the standard.  I hope I
    misunderstood you.

Well, I think RPG is probably right about SUBTYPEP being inconsistent
from one implementation to the next.  As I see it, SUBTYPEP is answering
the following question: "Is it the case that for all objects X, such
that X is of type T1, it is necessarily true that X is of type T2"?  The
problem is that there are two interpretations of this question.  One
interpretation asks "... for all objects X where X is any object that
can exist in this particular superset of Common Lisp ...", and the other
interpretation asks "... for all objects X where X is any object that
can exist in every Lisp that is a subset of Common Lisp ...".  If two
implementations both use the first interpretation, it's easy to see how
they might be inconsistent.

I think that specific cases of this problem have been discussed on
Common-Lisp, but I don't remember the details.  I could be wrong about
this.  They have to do with areas in which the implementor is given
latitude, such as the decision of how to implement instances of
defstructs and things like that.  An easy example might be
  (subtypep 'single-float 'short-float)
in an implementation in which they are the same thing.  This
form returns T T in our implementation.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 20:06:05 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 16:13:56 PDT
Redistributed: CommonLoopsCore↑.PA
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 16:13:39 PDT
Date: 8 Sep 86 16:13 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Defmethod syntax proposal
In-reply-to: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>'s
 message of Mon, 8 Sep 86 18:41 EDT
To: DLW@ALDERAAN.SCRC.Symbolics.COM
cc: Bobrow.pa@Xerox.COM, CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860908-161356-3282@Xerox>

       Date: 8 Sep 86 13:13 PDT
         From: Bobrow.pa@Xerox.COM
     
         I meant that I propose that we not describe classical syntax as
part
         of the standard.  It would simply be a backwards compatibility
feature  
         for Flavors users.  
     
     It's really more than that; it provides conceptual compatibility
for
     people who are familiar with most any of the other existing
     object-oriented programming languages, particularly Smalltalk-80.
     It provides the familiar concepts of instance variables and "self".
     Because of the widespread establishment of these concepts, I think
     it's worth putting this into the standard for everyone, despite the
     minor inelegance of having two syntaxes when only one is logically
     necessary.

(defmethod foo ((self class-name) ...) provides self as a cliche, and
allows those users the optioning of providing a more mnemonic name for
self.  Instance variables (or slots as we are calling them) are
available in either case.  Using the general syntax also encourages
users to remmber that this is a generic function and others may define
extensions (new defmethods) that specialize more than one argument.  I
think that separate syntax will cause mind bugs of the sort -- 'well I
did a "classical" defmethod so now I can't specialize other args.'



-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 19:11:18 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 15:50:27 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 08 SEP 86 15:50:12 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 76801;
 Mon 8-Sep-86 18:39:41 EDT
Date: Mon, 8 Sep 86 18:41 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: Bobrow.pa@Xerox.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860908-131317-2999@Xerox>
Message-ID: <860908184131.4.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: 8 Sep 86 13:13 PDT
    From: Bobrow.pa@Xerox.COM

    I meant that I propose that we not describe classical syntax as part of
    the standard.  It would simply be a backwards compatibility feature for
    Flavors users.  

It's really more than that; it provides conceptual compatibility for
people who are familiar with most any of the other existing
object-oriented programming languages, particularly Smalltalk-80.
It provides the familiar concepts of instance variables and "self".
Because of the widespread establishment of these concepts, I think
it's worth putting this into the standard for everyone, despite the
minor inelegance of having two syntaxes when only one is logically
necessary.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 19:11:07 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 15:29:40 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 08 SEP 86 15:29:22 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 76792;
 Mon 8-Sep-86 18:28:03 EDT
Date: Mon, 8 Sep 86 18:29 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Generic Functions Defined by Defmethod 
To: RPG@SAIL.STANFORD.EDU, commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860908-115423-2902@Xerox>
Message-ID: <860908182948.3.DLW@CHICOPEE.SCRC.Symbolics.COM>

I understand the point you're making.  As I've said, I'm undecided on
this issue personally, but since I believe I understand the other side
of the argument, I'll speak for it.  I think the answer to your point is
as follows:

The analogy you presented with cons cells, is, as you said, extreme.
The opposite extreme analogy might be to insist that, in Lisp, one
explicitly create each symbol before using it, by calling intern on a
string, or something.  After all, the appearance of a symbol means that
it should be looked up in a table; isn't it confusing that sometimes it
should create a symbol rather than looking one up?

Or, to abandon extreme analogies and speak more plainly, the proposed
conceptual model for why defmethod should create a generic function is
that "it's like intern"; the first mention causes an automatic creation,
to save you the trouble of doing one manually.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 17:13:40 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 14:07:37 PDT
Date: 8 Sep 86 14:07 PDT
From: Kahn.pa@Xerox.COM
Subject: Re: [Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>:
 Summary of features we all agree on ]
In-reply-to: Bobrow.pa's message of 5 Sep 86 18:49 PDT
To: Bobrow.pa@Xerox.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860908-140737-3076@Xerox>

     :initialize-only flag
     
     If flag = T, then this slot cannot be changed after initialization
(a
     better name for :read-only).  flag=T implies no accessors are
generated.
     default is NIL.  
     
We need to be clear what "after initialization" means.  Can one send an
"initialize-with-plist" message to an "already initialized" instance?
Also :read-only has the advantage of being the name that defstruct uses.

        (:meta-class class-name)
     No, we think this should be done using the meta-object protocol,
since
     the parsing of the defclass is not under the control of the
meta-class. 
     However, I think we could be convinced otherwise.
     
There are different uses of meta-classes.  There are those that just
make performance trade-offs and need not be concerned with "the parsing
of the defclass".  It would be reasonable to be able to use the
:meta-class at least in such cases.  When the meta-class changes some
functionality, then one may choose to use a different macro than
defclass.

     Making a New Instance
     
     (MAKE class-name keyword-argument...)
     
     MAKE is the function that makes and initializes an instance of a
class.
     The allowed keyword-arguments depend on the DEFCLASS form.  Any
keyword
     specified with the :INITABLE, :INITABLE-SLOTS, or :INIT-KEYWORDS
option
     is allowed.

I would prefer that the first argument to MAKE is either a class-name or
a class.

Regarding the discussion of an implicit defgeneric generated by the
first defmethod I think there is a style that needs to be supported.
The style is to rarely use DEFUN anymore and instead use DEFMETHOD with
only T type specifiers.  (By the way, I don't think there should be any
difference between (foo t) and foo as there is in Danny's recent
message.)  It would be annoying if everytime I wanted to define a
function that I think someone someday might want to specialize that I
need to enter both a defgeneric and a defmethod.  A solution to this
needn't require that defmethod generate a defgeneric if there is none
but might instead rely upon a new macro DEFDEFAULT or some such which
expands to the equivalent of both a defgeneric and a default defmethod.

----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 17:13:26 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 13:13:17 PDT
Redistributed: CommonLoopsCore↑.PA
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 13:13:06 PDT
Date: 8 Sep 86 13:13 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Defmethod syntax proposal
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 8 Sep 86 12:58 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860908-131317-2999@Xerox>


     I don't see why method combination options would be disallowed for
     default methods.  If it doesn't make sense to allow such options
     for default methods, then we can go back to that proposal. 

I think of defmeth with no argument specification as basically a defun
followed by a make-specializable.  If one wants to provide combination
for all methods, than a class specifier of T would allow use of method
combination with full scope. 

     No, the important difference is that in the classical syntax you
don't
     have to say "with" explicitly.

I think it might be a good idea to provide a simple syntax for WITH in
the type specification; for example, ((X class-foo :with-vars)  in the
arglist.

	    With compatibility assured, certain implementations
         could support the "classical" syntax as a convenience
         or a backwards compatibility feature.
     
         In this case I guess I take a minimimalist position.  
     
    I wasn't able to figure out what this means.

I meant that I propose that we not describe classical syntax as part of
the standard.  It would simply be a backwards compatibility feature for
Flavors users.  


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 15:46:11 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 08 SEP 86 11:54:23 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 08 SEP 86
 11:53:50 PDT
Date: 08 Sep 86 10:53 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Generic Functions Defined by Defmethod 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860908-115423-2902@Xerox>


My comments regarding the situation in which DEFMETHOD creates
a generic function in case there is not already one is based on
my belief of the model that users will develop for generic functions
rather than on implementation considerations, which considerations Moon
believes that I have in mind when I make such remarks.

Let me be more precise. Consider the combination

	(defmethod gf ...)

and let us suppose that there is no generic function already
associated with the name, `gf.' Should the defmethod expression
above create a generic function and associate it with the name,
`gf'? My belief of the model that most users of the Common Lisp
Object System will develop is that of a generic function being an
object, some of whose parts comprise the methods defined or specified
by the various defmethod forms which are evaluated and which 
specify the same name with which the generic function in question
is associated. Given the belief that generic functions are primary,
will users be confused by the fact that defmethod, a special form
or macro that is used to define a subpart of an object, creates the
object of which it is a subpart if the object does not already exist?
I believe that they will be confused.

There are two techniques we can use to define defmethod in such a
way that defmethod will create the generic function in case it does
not already exist:

	(1). we can define a generic function as an abstract data type
	     whose signature (the operations that can be used on instances
	     of the abstract data type) includes defmethod along with the
	     functionality of creating generic functions.

	     One possible concern with this approach is that the signature
	     requires possibly confusing-to-the-user behavior from such
	     functions as SYMBOL-FUNCTION. I have not explored this behavior
	     in detail.

	(2). we can state that when the Common Lisp Object System is loaded,
	     every symbol has (or can be considered to have) a generic function
	     associated with it such that this default generic function has no
	     methods associated with it and such that the other properties of
	     the generic function have such default values as we may define.

	     In this way, DEFMETHOD can be crisply defined to operate on
	     the subparts of a generic function while still retaining
	     the functionality Bobrow desires.

I apologize to Moon for the fact that my explanation of my belief of the
model that users will develop for generic functions included an analogy
which was presented using a piece of code, which presentation in terms of
code apparently caused him to believe that my concern was for the
implementation details of generic functions rather than for the user model
of the situation.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 14:48:58 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 11:39:07 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 08 SEP 86 11:38:43 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 76448;
 Mon 8-Sep-86 14:13:18 EDT
Date: Mon, 8 Sep 86 14:13 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Class versus Type System
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860908-102633-2759@Xerox>
Message-ID: <860908141318.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 08 Sep 86 10:25 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
    ....The implication of this observation is that generic
    function invocation is likely to be an expensive operation if SUBTYPEP is
    used as part of the basic method selection implementation.

Since method selection operates (conceptually; I'm not talking about
implementations, which no doubt will all use techniques that are more
optimal than this, but provide the same semantics) by doing a series
of TYPEP tests where the first argument is an argument to the generic
function and the second argument is a type specifier from the lambda list
of a method, I fail to see how the expense of SUBTYPEP could affect the
expense of generic function invocation, since even conceptually SUBTYPEP
is not called during generic function invocation.

The thing SUBTYPEP is useful for is deciding in what order to do those
TYPEP tests.  This happens when constructing the discriminator, not
every time a generic function is invoked.

It's all the same to me if we decide that for practical or other reasons
we don't want to generalize to allow arbitrary Common Lisp type
specifiers to qualify method arguments, but instead decide to limit
these to some subset, even as small a subset as just class names.  Even
though I think it's quite clear how to do the full generalization, I am
always opposed to premature standardization on ideas that have not been
tested in the field.  As I've said before, the one thing we must not do
is to develop yet another type system that is not just a subset of the
regular type system.

    ....The
    implication of the first observation is that it is likely that it will be
    required of the implementors of the basic method selection functions to
    use a common implementation (at some level of abstraction), or else the
    behavior of the basic method selection functions will need to be specified
    in great detail.

Surely it will be a disaster if the specification of this standard is so poor
that users can't figure out what it specifies, except by experimenting with
a particular implementation that is said to implement the standard.  I hope I
misunderstood you.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 14:48:40 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 10:51:10 PDT
Redistributed: CommonLoopsCore↑.PA
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 10:50:46 PDT
Date: 8 Sep 86 10:50 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Methods Selected by Predications More General Than Classes
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 5 Sep 86 22:52 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860908-105110-2796@Xerox>

     The following message (about arg specification) appears to have
been lost in the network...  
I had not seen it.

     I strongly believe that it would be a mistake for the type
specifiers
     in methods to be a whole different type system from the regular
Common
     Lisp type system.  Methods should either allow their arguments to
be
     qualified with any Common Lisp type specifier, or should restrict
the
     allowable type specifiers to a certain subset, but there absolutely
     should not be extensions to the Common Lisp type system that only
work
     in method argument lists.  That would be too confusing.

I disagree.  I think the set of specifiers for methods need not overlap
the Common Lisp type system. Therefore I do not feel at all
uncomfortable with having a different set of specifications based on
classes and individuals.   

HOWEVER, after rereading Moon's message, I felt that he has proposed a
reasonable extension to the current specification mechanism.  Subtypep
must be extended to include

(subtypep class-name1 class-name2) 
  if (subclassp (class-named class-name1) (class-named  class-name2))

I would want to extend the type system to deal with
  (QUOTE inst) as a short hand for
  (SATISFIES (MEMBER '(inst))
since individuals are so useful in type specification.

This imlies the following which is peculiar but OK.
(typep x ''inst) = (eql x 'inst) 


We can think of methods for a generic function as specifying a (nested)
set of guarded clauses. The nesting is determined by subtypep
relationships.  


I think we must trust every implementations subtypep, despite Moon's
worry.  Having two different but similar features in the language is
exactly what we are trying to avoid extending the argument specification
to the full type system.

Since the implementation for classes and individuals as specifiers will
clearly be both the most efficient, and most useful, we might postpone
the description of this to the advanced chapter.

Moon's OR hack should be in implementation notes.


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 13:45:06 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 10:26:33 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 08 SEP 86
 10:26:19 PDT
Date: 08 Sep 86 10:25 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Class versus Type System
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860908-102633-2759@Xerox>


For those who have problems with English, I'll rephrase my remark
and add a few more.

Rephrased remark:

We, the people who are designing the new specification of the Common Lisp
Object System, must take into consideration the fact that, as it currently
stands, there is a distinction between the Common Lisp type system and the
proposed Common Lisp Object System class system.  In order for us to keep
our own terminology straight, I have proposed the term `argument
specifier,' which, loosely speaking, is equivalent to the term `type
specifier' that Moon uses.

Further remarks:

(1) I believe that the Common Lisp type, COMMON, is well-defined. However,
it is possible that people do not have a good model of what it comprises;
also it is possible that COMMON would not be a particularly useful class
within the context of the Common Lisp Object System class system.

(2) Extending the Common Lisp Object System class system to include the
sorts of type predications that the Common Lisp type system admits strikes
me as misguided. First, considering implemenations, SUBTYPEP does not, I
believe, behave uniformly over all Common Lisp implementations; that is, I
believe, although I have no examples at hand, that are two Common Lisp
implementations and two type specifiers, S1 and S2, such that one
implementation returns the values NIL NIL when it evaluates the expression
(subtypep s1 s2) whereas the second implementation returns NIL T when it
evaluates the same expression: it is possible that worse discrepancies
exist. Second, considering implementation technology, the Common Lisp
implementations that supply a SUBTYPEP that behaves in such a way that
most observers would conclude that those Common Lisp systems supply a
SUBTYPEP that produces the most consistently accurate results over a set
of test cases for SUBTYPEP, where the observers are considering most of
the available Common Lisp systems, are Common Lisp systems in which the
implementation of SUBTYPEP is more inefficient than those that are judged
to be less accurate.  The implication of this observation is that generic
function invocation is likely to be an expensive operation if SUBTYPEP is
used as part of the basic method selection implementation.  The
implication of the first observation is that it is likely that it will be
required of the implementors of the basic method selection functions to
use a common implementation (at some level of abstraction), or else the
behavior of the basic method selection functions will need to be specified
in great detail. My third remark is based on hearsay: I know three
mathematicians who regard the Common Lisp type system and SUBTYPEP
in particular with extreme disdain. If any reader of this wishes, I will
interview these individuals to learn their reasons for disdain and 
report those reasons.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 13:44:41 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 10:02:36 PDT
Return-Path: <Moon@YUKON.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by Xerox.COM ;
 08 SEP 86 10:00:04 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM
 via CHAOS with CHAOS-MAIL id 81811; Mon 8-Sep-86 12:57:58 EDT
Date: Mon, 8 Sep 86 12:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860908-091245-2678@Xerox>
Message-ID: <860908125848.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 8 Sep 86 09:10 PDT
    From: Bobrow.pa@Xerox.COM

    In thinking about it over the weekend, I realized that the syntax we proposed

    (defmethod name-or-name-and-options lambda-list ...)

    where  name-or-name-and-options = name|
	   (name {combine-options}*)|
	   (name  class-name {combine-options}*)

    is completely unambiguous whether one is using "classical" syntax and general syntax.
    In "classical" syntax, no argument of lambda-list can be type specified.
    In general syntax at least one must be specifed if you are using
    method combination options.

    <classical-method-def>:=(demethod (generic-name type .{combine-options}*)
       unqualified-lambda-list body)
    <general-method-def>:=(defmethod name qual-or-unqualified-lambda-list body)|
	(defmethod (name . {combine-options}*) qualified-lambda-list body)

That was my original proposal, which foundered on the CommonLoops "default method"
feature, which allows defining a "general" method with no type specifiers.  I don't
see why method combination options would be disallowed for default methods.  If it
doesn't make sense to allow such options for default methods, then we can go back
to that proposal.  I'd be willing to give up the feature of type qualifying additional
arguments while still using classical syntax, for the sake of agreement.

    I do not like having two syntax's as part of the standard.  The difference
    in typing is only four characters (self) and the general syntax makes it clear what
    variable is being used.  

No, the important difference is that in the classical syntax you don't have to
say "with" explicitly.

			     With compatibility assured, certain implementations
    could support the "classical" syntax as a convenience
    or a backwards compatibility feature.

    In this case I guess I take a minimimalist position.  

I wasn't able to figure out what this means.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 12:46:59 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 09:12:45 PDT
Redistributed: CommonLoopsCore↑.PA
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 09:11:09 PDT
Date: 8 Sep 86 09:10 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Defmethod syntax proposal
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 5 Sep 86 20:51 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860908-091245-2678@Xerox>

In thinking about it over the weekend, I realized that the syntax we proposed

(defmethod name-or-name-and-options lambda-list ...)

where  name-or-name-and-options = name|
       (name {combine-options}*)|
       (name  class-name {combine-options}*)

is completely unambiguous whether one is using "classical" syntax and general syntax.
In "classical" syntax, no argument of lambda-list can be type specified.
In general syntax at least one must be specifed if you are using
method combination options.

<classical-method-def>:=(demethod (generic-name type .{combine-options}*)
   unqualified-lambda-list body)
<general-method-def>:=(defmethod name qual-or-unqualified-lambda-list body)|
    (defmethod (name . {combine-options}*) qualified-lambda-list body)


I do not like having two syntax's as part of the standard.  The difference
in typing is only four characters (self) and the general syntax makes it clear what
variable is being used.  With compatibility assured, certain implementations
could support the "classical" syntax as a convenience
or a backwards compatibility feature.

In this case I guess I take a minimimalist position.  


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  8 Sep 86 12:01:59 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 08:49:11 PDT
Redistributed: commonloopscore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 08 SEP 86 08:48:02 PDT
Date: 8 Sep 86 08:46 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Terminology: instances
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 5 Sep 86 20:56 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860908-084911-2654@Xerox>

I would say that all Lisp Objects are instances of some class.  For
example, realnumbers, cons cells, arrays, and structures all are
instances of classes.  Some instances have named substructure which we
call slots.  Slots contain values ... Users can describe how the
structure ofinstances with slots using defclass.



-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 22:58:01 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 19:53:35 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 05 SEP 86 19:53:11 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 75331;
 Fri 5-Sep-86 22:52:05 EDT
Date: Fri, 5 Sep 86 22:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Methods Selected by Predications More General Than Classes
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860905225205.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

The following message appears to have been lost in the network.
At least, it's not in the archive, and Danny's messages indicate
that he obviously hasn't read it.  Maybe what really happened is
that I forgot to send it, but just edited it into my own file.
In any case, here it is.


CommonLoops allows method selection by classes and by one kind of
predication, equality to a constant (EQL, I presume).  If we're going to
go more general than classes, we should allow the full generality of
Common Lisp types, i.e. arbitrary predications.  The problem with that
is that there can be predications that have objects in common, but do
not have a subtype/supertype relationship.  Thus if methods are defined
for both predications, it is not clear which method has precedence.

I think the answer is that actually encountering such a method ambiguity
signals an error, but that should not stop you from defining a method on
one predication, only from defining methods on two overlapping
predications.  Note that by shadowing the ambiguous method pair with a
method on a more specific class you can prevent the error from being
signalled (I say a more specific class rather than a more specific
predication because the specificness of course has to be computable--see
below).

I strongly believe that it would be a mistake for the type specifiers
in methods to be a whole different type system from the regular Common
Lisp type system.  Methods should either allow their arguments to be
qualified with any Common Lisp type specifier, or should restrict the
allowable type specifiers to a certain subset, but there absolutely
should not be extensions to the Common Lisp type system that only work
in method argument lists.  That would be too confusing.  This means that
the way CommonLoops does methods on individuals now is out.  If we're
going to include methods on individuals in the standard, they have to
be done with MEMBER, not with QUOTE.  I believe that in fact methods
on arbitrary predications can be implemented, allowing the whole Common
Lisp type system to be supported, and the remainder of this message
is a sketch of one way to implement that.


Any predication can be converted to the canonical form

  (OR (AND class1 test1)
      (AND class2 test2)...)

where each test is any Common Lisp type expression, and the classes are
all distinct.  Any Common Lisp type expression specifies a set of
objects that all belong to some class, even if it's T, along with a
restriction to a subset of the total membership of that class.  OR is
introduced essentially as a performance optimization for method
dispatching, to cut down the frequency of resorting to T as the class
for Common Lisp's OR type specifiers.  Some kind of rule is required to
decide between minimizing the number of terms in the OR and using the
least general classes.  It would also be convenient, but not essential,
to have rules for canonical ordering of the OR terms and canonical
formation of the test type expressions.  Some examples:

  class-name = (OR (AND class-name T))

  (UNSIGNED-BYTE 8) = (OR (AND FIXNUM (INTEGER 0 255)))
    ;assuming FIXNUM is a class on its own, rather than just having INTEGER

  (NOT FLOAT) = (OR (AND T (NOT FLOAT)))

Any two predications can be compared.  In fact SUBTYPEP could be used,
but it's easier to think about in terms of the canonical form.  I could
write down the rules for how to compare canonical forms in terms of
class precedence and SUBTYPEP on the tests.  The result can be a
definite ordering of the predications <, =, >, or disjoint; the latter
means that it is definitely known that no object can satisfy both
predications.  The result can also be that the ordering is uncomputable;
this happens when the same class has two different tests and the
ordering of the tests is uncomputable, e.g. SATISFIES of two different
functions.  When the ordering is uncomputable, all this means is that
less optimization of the discriminating function is possible; at run time
both predications must be evaluated, and if both are true an error must
be signalled.  The discriminating function would exploit the class portion
of the canonical form to avoid evaluating predications when it can prove
from the class that they must be false.

Aside: I don't know whether it's in general safe to trust every
implementation's SUBTYPEP function to work.  It would be a pity if the
portable OOP system had to duplicate that functionality.

Aside: I believe the type COMMON is a predication, not a class.
I think so not only because it's so ill-defined, but also because
I can see how you might conceivably define methods on COMMON but
I don't see the point to having a class inherit from COMMON.

As for NULL and VECTOR, we get to decide whether these types are classes
or predications.  I think it's clear that VECTOR should be a class,
and we just have to choose some precedence order of ARRAY and SEQUENCE.
The advantage of making NULL a predication rather than a class is that
method clashes between the SYMBOL and LIST classes are guaranteed to
signal an error, instead of using whichever non-obvious precedence order
we happened to choose.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 22:03:18 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 18:49:12 PDT
Date: 5 Sep 86 18:49 PDT
From: Bobrow.pa@Xerox.COM
Subject: [Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>:
 Summary of features we all agree on ]
To: CommonLoopsCore↑.PA@Xerox.COM
cc: Bobrow.pa@Xerox.COM
Message-ID: <860905-184912-1633@Xerox>


     Part I describes the basic tools for defining classes, methods,
generic
     functions, and method combination types, and for making instances
of
     classes.

     DEFINING CLASSES
     
     (DEFCLASS class-name (slot-spec...) (super-class-name...)
option...)

Not quite.  We have the opposite order for (super-class-name...) and
(slot-spec...).

(DEFCLASS class-name (super-class-name...) (slot-spec...) option...)


     class-name is a non-null symbol that names the class being defined.
If a
     class is already defined with this name, this definition replaces
the
     old  definition.  The default meta-class ensures that when the
definition of
     aclass changes, each existing instance of the class is updated to
the new
     format the next time it is accessed.


      Each slot-spec is one of:

       slot-name       a non-null symbol.

        (slot-name initial-value-form)


       (slot-name slot-option...)
         Each slot-option is an option name followed by its value.
         The defined slot-options and their arguments are:

        = initial-value-form
                This an alternate way for providing a default initial
value form.
How is this form distinguished from the previous.  By having more than
two elements???  How do you not give an init value form. 
       :accessor generic-function-name
                     Specifies that a function named
generic-function-name
                     be automatically generated, to read the value of
this
                     slot.  SETF may be used with generic-function name
to
                     write the value of the slot.
OK.  If generic-function-name is NIL then this is a NOOP.  Specified so
programs can generate these.
                :reader generic-function-name
                     Specifies that a function named
generic-function-name
                     be automatically generated, to read the value of
this
                     slot.
We have called this :read-accessor.  We specify that if this is given,
then SETF may NOT be used with this accessor. If generic-function-name
is NIL then this is a NOOP. 
                :initable keyword
                     Specifies a keyword to be used to specify an
initial
                     value of this slot, when a new instance is being
made.
I think this is OK.  Should allow value of NIL.  Default is T
                :allocation
 
:allocation can have values
 :instance (allocated in the instance),
 :class (storage allocated in the class and shared by all instances),
 :dynamic (storage allocated in the instance on first use
    (like Flavors Proplist mixin)
 :none  expect accessor methods for this to be defined for this slot
   in this class
                
:initialize-only flag

If flag = T, then this slot cannot be changed after initialization (a
better name for :read-only).  flag=T implies no accessors are generated.
default is NIL.  

     If no initial value is specified either in the DEFCLASS or the MAKE
form,
     the initial value of the slot is undefined and it is an error to
     reference
     it.  This is the same behavior as a DEFVAR with no
initial-value-form.
We hate these "it is an error" statements.  We haven't discussed this
particular issue.

     Each super-class-name is a non-null symbol.
     
     Each option is one of:
     
         option-name
         (option-name argument...)
     
     Each option-name is a keyword that names an option; the arguments
depend
     on
     the option.

OK
   The set of defined options and their arguments is:
     
    (:accessor-prefix prefix slot-name...)
    (:reader-prefix prefix slot-name...)
    (:default-init-plist keyword-argument...)
    (:initable-slots slot-name...)
    (:init-keywords keyword...)
The only one of these that we have agreed to is:

 (:accessors-with-prefix string-or-symbol)

which causes accessors to be generated with the given prefix for ALL
slots that do not have local specification of any of :accessor,
:read-accessor, or :initialize-only.  If this form does not appear, then
no accessors for slots are generated.

Note they we have made this be a single default that applies uniformly.
No specific slots can be mentioned, and this option can appear only
once.  The arguments for this way of doing business are:
1) Anything not uniform is local to a slot description
2) There are no redundant, possibly inconsistent, declarations

    (:documentation string)

OK   

    (:meta-class class-name)
No, we think this should be done using the meta-object protocol, since
the parsing of the defclass is not under the control of the meta-class.
However, I think we could be convinced otherwise.

    (:required-classes class-name...)
    (:required-init-keywords keyword...)
    (:required-slots slot-name...)
    (:required-methods generic-function-name...)

No.  These seem like environmental features, and should not be part of
the spec.  We should make some comment about how additional options may
be supported by the standard class in particular implementations, and
ones not understood will either be ignored, or have warnings issued.
 
    (:constructor function-name lambda-list)
We have allowed the full generality of the defstruct syntax for this
one.  Do you think it should be restricted to this boa-constructor

     For the :ACCESSOR-PREFIX, :READER-PREFIX, and :INITABLE-SLOTS
options,
     you can omit slot-names to indicate that the option applies for all
slots of
     this class.
See above

     It is legal to specify more than one accessor and reader for a
single
     slot.
We argued about this, and decided we didn't like it.  Why is it good?


     DEFINING METHODS AND SETF METHODS
     
     The general syntax for defining a method is:
     
     (DEFMETHOD generic-function-name method-option...
       method-lambda-list
        body...)

No.  See my earlier message. 
      (DEFMETHOD name-and-options
       method-lambda-list
        body...)


   generic-function-name is a non-null symbol.

name-and-options is a non-null symbol or (name . method-options)

See my earlier message.

     Each method-option is a non-null atom that describes the type of
this
     method.  Some examples of method-options are:  :BEFORE and :AFTER.

     method-lambda-list is a lambda-list with one difference.  Where a
     lambda-list allows only a variable and not a list, a
type-qualified-
     variable may be used.  However, type-qualified-variables cannot be
used
     for
     &aux variables, supplied-p parameters, or &rest parameters.  A
     type-qualified-variable is a list such as:  (variable-name
     type-specifier).
     Note that the use of &optional is still under discussion.

     type-specifier ---tbd---


type-specifer and its uses should be replaced by argument-specifier.
This will include class-names (class-specifiers) and individuals.  The
meaning of argument-specifier may be extended by users who build their
own discriminators.

     For convenience in defining a classical method, the following
syntax is
     provided:
     
     (DEFMETHOD (generic-function-name first-arg-type method-option...)
       method-lambda-list
       body...)
     
     The classical syntax is equivalent to the following expression in
the
     general syntax:
     
     (DEFMETHOD generic-function-name method-option...
       ((self first-type-arg) method-lambda-list...)
       (with (self)
    body...))

See other message

     The general syntax for defining a SETF method is:
     
     (DEFMETHOD-SETF generic-function-name method-option...
       method-lambda-list setf-lambda-list
       body...)
     
     The classical syntax for defining a SETF method is:
     
     (DEFMETHOD-SETF (generic-function-name first-arg-type
method-option...)
       method-lambda-list setf-lambda-list
       body...)
     
     generic-function-name and method-option are the same as for
DEFMETHOD.
     
     setf-lambda-list is a lambda-list containing exactly one required
     parameter, which may be type-qualified.  In other words,
     setf-lambda-list
     is one of:

    (variable-name)
    ((variable-name type-specifier))

Same problem with this syntax.  But we agree that DEFMETHOD-SETF is a
better name.  If you liked my other syntax suggestions, then this one
follows.  Again type-specifier -> argument-specifier.  Are we not
allowing multiple values to be stored.  In the silver book it talks
about extensions to the corresponding list of store variables.  I have
no problem with the restriction.  

     DEFINING GENERIC FUNCTIONS
     
     (DEFGENERIC generic-function-name lambda-list option...)
     
     (DEFGENERIC-SETF generic-function-name lambda-list setf-lambda-list
     option.
     
     generic-function-name is a non-null symbol.
     
     lambda-list is an ordinary lambda-list except no &aux variables are
     allowed.

     setf-lambda-list is (variable-name).

Yes, except that we allow a documentation string before the options.
What do you think???

     Each option is one of:

         option-name
         (option-name argument...)

     Each option-name is a keyword that names an option; the arguments
depend
     on the option.
OK

     The set of defined options and their arguments is:
     
     [--Should declarations and doc strings be allowed?--]
     
              (:documentation string)
See above.
              (:optimize spec...)
Is this for all methods, or just the discriminating function. This seems
weird to me 
              (:method-combination name argument...)
What is the argument in this form?
              (:generic-function-class class-name)
              (:method-class class-name)
              (:order parameter-name...)
We have been using :dispatch-order for the keyword :order.  It should
really be 
:argument-precedence-order.  
                  [more?]

Additional options should be allowed, as in defclass.

            WITH
     
         We have agreed that WITH should exist, but we haven't decided
anything
         more specific about it yet.
Right; we haven't decided anything yet.  There are two different
proposals under discussion.  One turns names in calls on the accessors
(we call that one WITH).  The other turns them into primitive slot
accesses (we call that one %WITH).


     DEFINING NEW TYPES OF METHOD COMBINATION
     
     (DEFINE-SIMPLE-METHOD-COMBINATION name operator-name
                                       [single-arg-is-value]
                                       [pretty-name])
     
     This function defines a new type of method combination in which all
the
     methods are called and their values are passed to the operator
specified
     by
     operator-name.
     
     name is a non-null symbol, often a keyword, that is the name of the
type
     of method combination being defined.

     operator-name can be a symbol or a lambda-expression,
     the name of a function, a macro, or a special form.

     single-arg-is-value is t or nil; by default it is nil.
     
     pretty-name is a string.  It defaults to the lower case version of
the
     supplied name.

We haven't agreed to this at all yet.  super-daemon method combination
we believe in. But this simple case seems strange to me, and if it can
be defined with the stronger DEFINE-METHOD-COMBINATION, then let's not
put it in the spec.  

I didn't see whoppers described in daemon combination section of the
Flavors manual -- at least not in the early section.  Does this mean
that it is not a feature of daemon combination?

We believe that at least on the west coast, run-super will be used much
more than daemon combination.  Hence my attempt to unify them.  An
answer to Moons answer next week.  

     (DEFINE-METHOD-COMBINATION method-combination-type-name
                                lambda-list
                                (method-pattern...) option... body...)
     
     This function behaves the same way as in Flavors.  See the Flavors
     documentation for details.

We believe that a simple version of this should be in the spec.  I don't
know yet what simple means.  At least powerful enough to define the
extended features, but not including the full library of standardly
available combinations types.

     Making a New Instance
     
     (MAKE class-name keyword-argument...)
     
     MAKE is the function that makes and initializes an instance of a
class.
     The allowed keyword-arguments depend on the DEFCLASS form.  Any
keyword
     specified with the :INITABLE, :INITABLE-SLOTS, or :INIT-KEYWORDS
option
     is allowed.

     If a keyword-argument is given to MAKE, it overrides any default
that is
     given in the DEFCLASS form, such as the :DEFAULT-INIT-PLIST option,
or
     the initial-value-form syntax.

Modulo isssues on keywords and specification of initable, this is
basically correct.


     OTHER FUNCTIONS
     
     Other functions of interest to the general programmer [---tbd---].
     
     This list came from the 8 August meeting; it can serve as a
starting
     agenda
     for this section:
     
         find-flavor / class-named
Yes class-named
         typep
classp is the right name
         type-of
         class-of
Yes on class-of
         operation-handled-p ??
Something like this is needed
         remove-class
	    remove-method
	    change-class
Yes


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 21:38:18 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 17:58:00 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 05 SEP 86 17:57:20 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 75307;
 Fri 5-Sep-86 20:56:10 EDT
Date: Fri, 5 Sep 86 20:56 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Terminology: instances
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860905-161438-1438@Xerox>
Message-ID: <860905205611.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 5 Sep 86 16:12 PDT
    From: Bobrow.pa@Xerox.COM

    Why do you want to distinguish "primitive" instances from non-primitive
    ones.  I thought of the ugly term "non-slotted instances".  Numbers have
    no slots.  But one can create objects with no slots using defclass.  One
    can also think of CONS cells as having two slots with accessors car and
    cdr.  Is there any thing we need to say about these items aside from
    their history as Common Lisp types?   

See the discussion on 2-3 September about the awkwardness in Sonya's glossary
that resulted from trying to avoid making this distinction.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 21:37:57 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 17:57:09 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 05 SEP 86 17:52:25 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 75306;
 Fri 5-Sep-86 20:51:17 EDT
Date: Fri, 5 Sep 86 20:51 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860905-144956-1108@Xerox>
Message-ID: <860905205118.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 5 Sep 86 10:52 PDT
    From: Bobrow.pa@Xerox.COM
 
      Will (defmethod generic option... lambda-list body...) be okay with you,
      or do we need to keep searching for a suitable syntax?

    I don't like having to put an additional item between the generic name
    and the lambda-list, especially since I expect most methods to not have
    any options declaration.

I think my syntax description was not clear enough.  I am not proposing
that there be anything between the generic name and the lambda-list when
no options are specified.  Let me give some more examples (just the
first line of each):

(defmethod turn-off-valve ((v valve))

(defmethod turn-off-valve :before ((v master-valve))

(defmethod great-scott piece environmental-impact ((x foo) (y bar))

(defmethod (turn-off-valve valve) ()

(defmethod (turn-off-valve master-valve :before) ()

(defmethod (great-scott foo piece environmental-impact) ((y bar))

    An alternative syntaxsuggestion:
 
    (defmethod name-or-name-and-options lambda-list ...)

    where
     name-or-name-and-options = name|
       (name :combination {combine-options}*)|
       (name class-name {combine-options}*)

    or

     name-or-name-and-options = name|
       (name {combine-options}*)|
       (name (:class class-name) {combine-options}*)
 
    I prefer the latter.  
    
Neither of these turns me on.  I think whichever one involves the
"extra" word (:combination or :class) is going to discourage users
from using that style.  I would rather either use the syntax
exemplified above or use different macros for defining classical
methods and general methods.

    An argument for the former is to preserve old Flavors code.

Yes, one criterion I would like to preserve is that a mechanical
translation program can look at a piece of source text and reliably
classify it into CommonLoops, Flavors, or the new Common Lisp standard.
Mechanical translation tools work more smoothly for users if they
operate correctly on their own output; this makes incremental conversion
of programs a lot easier.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 19:43:29 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 16:14:38 PDT
Redistributed: commonloopscore↑.pa
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 16:13:56 PDT
Date: 5 Sep 86 16:12 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Varia    [what a useless subject!]
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 5 Sep 86 16:24 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860905-161438-1438@Xerox>

   We want to distinguish the type hierarchy from the class lattice.

 I thought one of the big points of this whole affair was to do just
 the opposite, i.e. to unify the type lattice and the class lattice.

Right.  RPG was just misguided.  The Common Lisp type lattice is mapped
into the class lattice.  Missing from the class lattice are uses of the
type system that are really predications.  In this category we put the
type atom = (SATISFIES (NOT (CONSP X))
and common (a non-inherited feature) = (SATISFIES (MEMQ X '(CONS ...))

Why do you want to distinguish "primitive" instances from non-primitive
ones.  I thought of the ugly term "non-slotted instances".  Numbers have
no slots.  But one can create objects with no slots using defclass.  One
can also think of CONS cells as having two slots with accessors car and
cdr.  Is there any thing we need to say about these items aside from
their history as Common Lisp types?   


-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 19:43:13 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 15:56:41 PDT
Date: 5 Sep 86 15:56 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Message selection, continued 
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 4 Sep 86 16:15 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860905-155641-1385@Xerox>

  May I assume that everywhere you say "argument specifier" this is a
typo
  for "type specifier"?  Or are you really introducing a new term here?

Yes "argument specifier" is more general term than type specifier or
class specifier.  It can specify, for example, that the argument must
match a particular individual.  Any extensions people want to make about
specification of arguments would go here.  


In yesterday's round with Gabriel and Co. we came up with the following
proposed new set of rules for message selection. 

1)  All uses of defmethod must be preceded by a defgeneric (but see
discussion *1 below), and the defgeneric and the defmethods must all
have congruent lambda-lists.  defmethods can provide argument-specifiers
on optional arguments (but see 6 below).

2) Defgeneric can have an arbitrary lambda-list. 

3) All default values for optional arguments are provided computed from
forms in the defgeneric.

4) When a generic function is called, it computes and fills in values
for any unsupplied arguments.

5) Discrimination is done on the basis of all provided and filled
values. All methods of the generic function that match are considered.
The most specific method is chosen (rules not given here).  
All provided and filled in values are passed to the method.

6)  Since defmethod argument list cannot have default value forms for
optionals, we make the syntax for defmethod lambda-list be: 

defmethod-lambda-list:= ({required-arg}* [&optional {optional-arg}*])

optional-arg:=
	var-name|
	(var-name arg-specifier)
	(var-name arg-specifier supplied-p-name)

The third form is provided to allow a user to supply a local name for
the supplied-p. This supplied-p is computed by the generic function, and
passed in to the method.  It can then be used locally to allow the
program to override the default value provided from defgeneric.  If only
a supplied-p-name is wanted, he arg-specifier T can be used to match any
argument.

*1) RPG and DLW (I believe) support the minimalist position of insisting
that the user always write the defgeneric themselves, and have it
evaluated before the defmethod.  There are several increasingly
DWIM-like positions that back away from this stricture by allowing
defmethod to call defgeneric if no generic function exists. 

a)  If the defmethod specifies no optional arguments, then a defgenric
form is invoked with the stripped lambda list. 

b) Allow the defmethod to specify optional arguments as above, and
create a stripped lambda list for the constructed defgeneric that has
only var-names for the optional arguments; that is, NIL will be provided
for the values of the optional arguments.  The supplied-p portion of the
optional-arg apecification allows internal resetting of the value of the
arg if desired.  If default values other than NIL are wanted, a
defgeneric form must be used.

c) Return to our previous syntax of defmethod, with 
optional-arg:=
	var-name|
	(var-name [default-value-form [supplied-p-name]])
	((var-name arg-specifier) [default-value-form [supplied-p-name]])
Construct a defgeneric from the defmethod simply stripping out the
arg-specifiers.  An error is signalled if any defmethod has a
default-value-form not equal to the one found in the defgeneric. This
provides a syntactic rather than a semantic check on identity of default
values, as proposed by Moon.  Again, as opposed to Moon's suggestion,
the default-values are all computed in the discriminating function, and
passed to the methods.  supplied-p parameters can also be passed to the
methods from the generic function.

Proposal c also implies that every method must contain the same default
value forms, which violates some modularity.  A possible fix for this is
reinterpret the naked var-name to mean unspecified default-value, or to
specify a funny value :no-default-form that can be used in that place
for optionals.

I like either (b) or (c).  An argument for (c) given to me by Ken Kahn
is that users should move from defun to defmethod as a standard way to
program, even when not providing any argument specifiers.  This means
that all their functions are specializable.  This implies allowing a
defmethod syntax that is identical to defun, with no preceding
declaration.  
	

-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 19:42:49 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 14:53:05 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 05 SEP 86 14:46:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 75195;
 Fri 5-Sep-86 16:24:21 EDT
Date: Fri, 5 Sep 86 16:24 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Varia    [what a useless subject!]
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860904-222531-1191@Xerox>
Message-ID: <860905162420.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 04 Sep 86 22:25 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    We want to distinguish the type hierarchy from the class lattice.

I thought one of the big points of this whole affair was to do just
the opposite, i.e. to unify the type lattice and the class lattice.

    Therefore, in messages where I say `argument specifier,' I am
    not, as Moon suggests, making a typo for `type specifier.'

    `Instance of a class' is different from `instance of a flavor' or
    `instance of a defstruct.' We've made a parallel class lattice
    corresponding to the type hierarchy in CLtL. We decided (today) to flush
    ATOM and COMMON from that lattice (vector is an atom). Therefore, a cons
    cell is an instance of the CONS class. Because the metaclass of a CONS
    cell is not the class CLASS (but is BUILT-IN-CLASS or some such) its
    interpretation as an instance is different from that of an instance
    meta-class is CLASS. Everything in Common Lisp is an instance of some
    class.

Fine, but this doesn't seem to address the terminological dilemma I was
asking about.  What do we call the objects that aren't primitive, when we
need to distinguish them from the object that are primitive?

    Danny and I go around daily on the disposition of method selection.

I've noticed.

    We now have yet another proposal for it. In this one this example
    does what DLW expects:

	    (let ((*standard-output* <instance of hairy-display-hardware>))
		 (print foo))

    Because the generic function PRINT has as function parameters:

	    (object &optional (stream *standard-output*))

    Defmethods cannot default unsupplied arguments. Danny's message will
    present this new version. (I'm too burned to do it.)

I look forward to seeing it.

    I'm fresh enough, though, to present why I don't like defmethods
    creating generic functions. In my view, a generic function is 
    something that responds T to (typep <gf> 'function). It has other
    information within itself. It has no name but can be associated with
    a name, just as in

	    (defun foo (x) ...)

    the thing in the symbol-function cell has no name but is associated with
    the name `FOO.' The parts of the generic function are the discriminating
    function, the methods, the function parameters, various class pointers,
    and etc. Usually the methods are stored as part of the method object.

    Defmethod adds another method to a generic function. That is, it adds a
    new subpart to an existing thing. It seems odd to me that adding a new
    subpart should create the thing of which it is to become a part. There is
    a dimension whose extremity is absolute insanity, and the current proposal
    to allow defmethod to create the superpart has a non-zero component of that
    dimension. An example of the insanity at the extreme in this dimension is
    a possible proposal that

	    (setf (car x) 7)

    does this

	    (progn
	     (unless (and (boundp 'x) (typep x 'cons)) (setq x (cons () ())))
	     (setf (car x) 7))

    (Note that Lisp/VM does the equivalent of this

	    (setf (symbol-value <symbol>) <symbol>)

    when the symbol <symbol> is interned.)

    I grant we are not very far down this dimension, but why head that way?

I understand everything you said above, but none of this talk about
implementation addresses my point, which was concerned with the concepts
that the user thinks about.  Thinking about the implementation first is
not a good way to design something that is easy to use and to
understand, in my opinion.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 19:42:08 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 SEP 86 14:49:56 PDT
Date: 5 Sep 86 10:52 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Defmethod syntax proposal
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 4 Sep 86 18:01 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860905-144956-1108@Xerox>

 Will (defmethod generic option... lambda-list body...) be okay with
you,
  or do we need to keep searching for a suitable syntax?  A more real
  example of the syntax would be
    (defmethod turn-off-valve :before ((v master-valve))
      (unless (check-with-safety-engineer v 'off)
        (unsafe-operator-action "Don't do that!  It will explode")))


    Since all the options for method combination are either keywords or
    numbers and type is not, one can distinguish the cases. 
    If this is not the case, 
    we could insist that there always be such a keyword to start.

  They aren't keywords.  You got fooled by looking at existing examples
where
  by coincidence they were always keywords, but in general it's not
going to
  work to restrict the options attached to a method to be always
keywords.
  There are applications where these are names of things and the names
can
  be any symbol (I think we can safely exclude nil, I hope I'm not
wrong).
 
  Will (defmethod generic option... lambda-list body...) be okay with
you,
  or do we need to keep searching for a suitable syntax?


I don't like having to put an additional item between the generic name
and the lambda-list, especially since I expect most methods to not have
any options declaration.

An alternative syntaxsuggestion:
 
(defmethod name-or-name-and-options lambda-list ...)

where
 name-or-name-and-options = name|
   (name :combination {combine-options}*)|
   (name class-name {combine-options}*)

This makes it somewhat more difficult for CommonLoops type users to use
method combination.  Alternatively, Flavors type use could be made
slightly more difficult by using

 name-or-name-and-options = name|
   (name {combine-options}*)|
   (name (:class class-name) {combine-options}*)
 
I prefer the latter.  Method combination code could process the
 (:class class-name) option and change the method definition as
specified by you.

An arguments for the former is to preserve old Flavors code.
-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 01:28:59 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 86 22:25:31 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 04 SEP 86
 22:25:18 PDT
Date: 04 Sep 86 22:25 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Varia    
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860904-222531-1191@Xerox>


We want to distinguish the type hierarchy from the class lattice.
Therefore, in messages where I say `argument specifier,' I am
not, as Moon suggests, making a typo for `type specifier.'

`Instance of a class' is different from `instance of a flavor' or
`instance of a defstruct.' We've made a parallel class lattice
corresponding to the type hierarchy in CLtL. We decided (today) to flush
ATOM and COMMON from that lattice (vector is an atom). Therefore, a cons
cell is an instance of the CONS class. Because the metaclass of a CONS
cell is not the class CLASS (but is BUILT-IN-CLASS or some such) its
interpretation as an instance is different from that of an instance
meta-class is CLASS. Everything in Common Lisp is an instance of some
class.

Danny and I go around daily on the disposition of method selection.
We now have yet another proposal for it. In this one this example
does what DLW expects:

	(let ((*standard-output* <instance of hairy-display-hardware>))
	     (print foo))

Because the generic function PRINT has as function parameters:

	(object &optional (stream *standard-output*))

Defmethods cannot default unsupplied arguments. Danny's message will
present this new version. (I'm too burned to do it.)

I'm fresh enough, though, to present why I don't like defmethods
creating generic functions. In my view, a generic function is 
something that responds T to (typep <gf> 'function). It has other
information within itself. It has no name but can be associated with
a name, just as in

	(defun foo (x) ...)

the thing in the symbol-function cell has no name but is associated with
the name `FOO.' The parts of the generic function are the discriminating
function, the methods, the function parameters, various class pointers,
and etc. Usually the methods are stored as part of the method object.

Defmethod adds another method to a generic function. That is, it adds a
new subpart to an existing thing. It seems odd to me that adding a new
subpart should create the thing of which it is to become a part. There is
a dimension whose extremity is absolute insanity, and the current proposal
to allow defmethod to create the superpart has a non-zero component of that
dimension. An example of the insanity at the extreme in this dimension is
a possible proposal that

	(setf (car x) 7)

does this

	(progn
	 (unless (and (boundp 'x) (typep x 'cons)) (setq x (cons () ())))
	 (setf (car x) 7))

(Note that Lisp/VM does the equivalent of this

	(setf (symbol-value <symbol>) <symbol>)

when the symbol <symbol> is interned.)

I grant we are not very far down this dimension, but why head that way?

I will be away until monday, so enjoy.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  5 Sep 86 00:52:19 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 86 21:48:11 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 04 SEP 86 21:47:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74741;
 Fri 5-Sep-86 00:46:12 EDT
Date: Fri, 5 Sep 86 00:46 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Whoppers and run-super
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860902-183338-1341@Xerox>
Message-ID: <860905004612.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 2 Sep 86 18:33 PDT
    From: Bobrow.pa@Xerox.COM

Sorry about the slow response; I spent a lot of time thinking about this
instead of sending some sort of knee-jerk instant response.

    There seems to be a lot in common between whoppers and the Loops use of
    run-super. I have been trying to work out the appropriate relation
    between run-super and daemon method combination with whoppers.
    Whoppers are not expressible in the method combination language.

This is not completely true.  They could easily be done in the method
combination language.  We chose to do them instead as a separate layer
for the following reasons:

(1) We wanted the behavior of whoppers and wrappers to be constant,
independent of the method-combination type.

(2) We found that in old flavors having to worry about whoppers and
wrappers greatly complicated the definition of each method-combination
type.  It seemed better to do it in a central place and get it out
of the way of the user who wants to define his own method combination.

(3) Whoppers and wrappers seem to us to be fundamentally different
from ordinary methods; in particular, they receive different arguments.
Wrappers, being macros, receive forms as arguments rather than receiving
the arguments of a generic function call.  Less obviously, whoppers
receive different arguments; the continuation used by CONTINUE-WHOPPER
is passed to the whopper as two additional arguments that are added to
the lambda-list by defwhopper (never mind why it's two arguments instead
of one, that's a minor implementation detail.)  There are efficiency
issues, discussed much later in this message, that make us wish to keep
whoppers separate from ordinary methods so as not to slow down ordinary
methods.

(4) I don't like :around methods for the irrelevant reason that Stallman's
flavor system has them and he misimplemented them in a way that appears
especially ugly to the user.  Too much of the implementation mechanism
shows through.

None of these reasons is ineluctably compelling, and we could instead
have chosen to make DEFINE-METHOD-COMBINATION insert into the body a call
to a function to take care of the wrappers and whoppers, and then have
provided an option to turn this off and let the method-combination type
take direct control.  I don't see a lot of benefit from this; what would
be accomplished by taking direct control other than surprising the user
by making wrappers and whoppers behave in an unexpected way?  Maybe there
is something that I am not seeing.

    Neither is run-super.  I believe both could be fixed by adding a new
    standard form corresponding to call-component-methods.

    call-first-with-continuations <list-of-methods>

    calls the first on the list, and makes available the list for the called
    method.  If run-super is invoked in the method, it does:

    (call-first-with-continuations (cdr list-of-methods))


    If continue-whopper we spell "run-super", and whopper as ":around", then
    super-daemon method combination (allowing run-super in primary methods)
    is  defined by something like

    (define-method-combination :super-daemon
      ((around "around" :every :base-flavor-last (:around))
       (before "before" :every :base-flavor-last (:before))
       (primary "primary" :every :base-flavor-last (:primary))
       (after "after" :every :base-flavor-first (:after)))
    (call-first-with-continuations 
       '(,. around
	  (multiple-value-prog2 
	     (call-component-methods , before)
	     (call-first-with-continuations ',primary)
	     (call-component-methods ,after)))

    This makes run-super be a feature of method-combination with
    call-first-with-continuations only.  It has the same model as it has in
    Loops and Smalltalk, and computable at method-definition time.

Don't forget that continue-whopper allows changing the arguments that
are passed on to the continuation, whereas run-super does not.  This can
be important sometimes.  I think that's orthogonal to the rest of the
discussion, however.

    I have not thought through a best implementation.  An obvious one is to
    bind the continuation list of functions in a special variable.

    Does this make sense?  It seems to provide a single coherent story. 

There is no question that something along these lines, with the typos
and bugs taken out, could work.  For example, the following code works
in New Flavors (more comments follow the code):


(DEFVAR *SUPERCLASS-CONTINUATIONS*)

(DEFUN RUN-SUPER ()
  (FUNCALL (POP *SUPERCLASS-CONTINUATIONS*)))

(DEFUN CALL-FIRST-WITH-CONTINUATIONS (FORMS)
  (IF (REST FORMS)
      `(STACK-LET ((*SUPERCLASS-CONTINUATIONS*
		     (LIST ,@(MAPCAR (LAMBDA (FORM)
				       `(LAMBDA ()
					  (DECLARE (SYS:DOWNWARD-FUNCTION))
					  ,FORM))
				     (REST FORMS)))))
	 ,(FIRST FORMS))
      (FIRST FORMS)))

(DEFINE-METHOD-COMBINATION :SUPER-DAEMON ()
     ((AROUND "around" :EVERY :MOST-SPECIFIC-FIRST (:AROUND))
      (BEFORE "before" :EVERY :MOST-SPECIFIC-FIRST (:BEFORE))
      (PRIMARY "primary" :EVERY :MOST-SPECIFIC-FIRST () :DEFAULT)
      (AFTER "after" :EVERY :MOST-SPECIFIC-LAST (:AFTER)))
  (CALL-FIRST-WITH-CONTINUATIONS
    (NCONC (MAPCAR #'CALL-COMPONENT-METHOD AROUND)
	   `((MULTIPLE-VALUE-PROG2
	       ,(CALL-COMPONENT-METHODS BEFORE)
	       ,(CALL-FIRST-WITH-CONTINUATIONS
		  (MAPCAR #'CALL-COMPONENT-METHOD PRIMARY))
	       ,(CALL-COMPONENT-METHODS AFTER))))))

(DEFGENERIC SDTEST (X Y)
  (:METHOD-COMBINATION :SUPER-DAEMON))

(DEFFLAVOR SDTEST1 () ())
(DEFFLAVOR SDTEST2 () (SDTEST1))
(DEFFLAVOR SDTEST3 () (SDTEST2))

(DEFMETHOD (SDTEST SDTEST1) (X)
  (LIST 1 X))

(DEFMETHOD (SDTEST SDTEST2) (X)
  (DECLARE (IGNORE X))
  (CONS 2 (RUN-SUPER)))

(DEFMETHOD (SDTEST SDTEST3) (X)
  (DECLARE (IGNORE X))
  (CONS 3 (RUN-SUPER)))

(DEFMETHOD (SDTEST SDTEST2 :AROUND) (X)
  (LIST "[" (RUN-SUPER) "|" X "]"))

(SDTEST (MAKE-INSTANCE 'SDTEST3) 105)
; => ("[" (3 2 1 105) "|" 105 "]")


This implementation could use some additional error checking.  More importantly,
it contains a serious bug.  The dynamic scoping of *SUPERCLASS-CONTINUATIONS*
means that incorrect results can occur when closures from two different generic
function invocations are calling each other.  To get correct operation, the
continuation must be lexically scoped.  If this sounds esoteric, consider the
following example, which has been taken from a real-life program:

(defmethod print-object :around ((object italicized-object) stream)
  (with-character-face (:italic stream)
    (run-super))

which makes any object of class italicized-object print itself in italics.
With-character-face is just a macro that makes output to the given stream
appear in the given face while executing its body.

This looks fine until you expand the with-character-face macro, which
expands into [the following is simplified from what it actually expands
into in Genera]
  (with-style-internal stream ':italic
		       (lambda (stream) (run-super)))
where with-style-internal is a generic function handled by
a stream method that sets up for italic characters and calls
back into the lambda.  If the handling of with-style-internal
also involves :around methods, *SUPERCLASS-CONTINUATIONS* will
be bound and the run-super inside the lambda will call a
with-style-internal method instead of a print-object method.
No good.

Lexically scoping the continuation is possible in New Flavors also.
An extra argument has to be inserted into the arglist of any method
that uses run-super, to receive the continuation, since it can no
longer be passed behind the lambda-list's back in a special variable,
and this code transformation makes everything a little more complicated.
Here is the working, tested code (more comments after the code):


(DEFUN RUN-SUPER ()
  (ERROR "RUN-SUPER not called from a proper lexical environment."))

;;; Call a method, passing the continuation before the regular arguments
(DEFUN CALL-COMPONENT-METHOD-WITH-CONTINUATION (METHOD CONTINUATION-FORM ARGS)
  (CALL-COMPONENT-METHOD METHOD
			 :ARGLIST (LIST `(LAMBDA ()
					   (DECLARE (SYS:DOWNWARD-FUNCTION))
					   ,CONTINUATION-FORM)
					ARGS)
			 :APPLY T))

;;; Call a sequence of methods, each with a continuation that calls the next
;;; method.  The continuation of the last method is the second argument.
(DEFUN CALL-COMPONENT-METHODS-WITH-CONTINUATION (METHODS CONTINUATION-FORM ARGS)
  (IF METHODS
      (CALL-COMPONENT-METHOD-WITH-CONTINUATION
	(FIRST METHODS)
	(CALL-COMPONENT-METHODS-WITH-CONTINUATION
	  (REST METHODS) CONTINUATION-FORM ARGS)
	ARGS)
      CONTINUATION-FORM))

(DEFINE-METHOD-COMBINATION :SUPER-DAEMON-2 ()
     ((AROUND "around" :EVERY :MOST-SPECIFIC-FIRST (:AROUND))
      (BEFORE "before" :EVERY :MOST-SPECIFIC-FIRST (:BEFORE))
      (PRIMARY "primary" :EVERY :MOST-SPECIFIC-FIRST () :DEFAULT)
      (AFTER "after" :EVERY :MOST-SPECIFIC-LAST (:AFTER)))
     (:METHOD-TRANSFORMER
       ;; Insert continuation argument into methods that can call RUN-SUPER
       (:METHOD-ARGLIST
	 (IF (MEMBER (METHOD-OPTIONS FUNCTION-SPEC)
		     '((:AROUND) () (:DEFAULT))
		     :TEST #'EQUAL)
	     (CONS 'RUN-SUPER-CONTINUATION METHOD-ARGLIST)
	     METHOD-ARGLIST))
       ;; Change arglist used for error-checking correspondingly
       (:GENERIC-METHOD-ARGLIST
	 (IF (MEMBER (METHOD-OPTIONS FUNCTION-SPEC)
		     '((:AROUND) () (:DEFAULT))
		     :TEST #'EQUAL)
	     (LIST* (FIRST GENERIC-METHOD-ARGLIST)
		    'RUN-SUPER-CONTINUATION
		    (REST GENERIC-METHOD-ARGLIST))
	     GENERIC-METHOD-ARGLIST))
       ;; Define RUN-SUPER macro locally in the body of such methods
       (:METHOD-BODY
	 (IF (MEMBER (METHOD-OPTIONS FUNCTION-SPEC)
		     '((:AROUND) () (:DEFAULT))
		     :TEST #'EQUAL)
	     (MULTIPLE-VALUE-BIND (DECLARATIONS BODY)
		 (SI:FIND-BODY-DECLARATIONS METHOD-BODY NIL)
	       `(,@DECLARATIONS
		 (IGNORE RUN-SUPER-CONTINUATION)
		 (MACROLET ((RUN-SUPER ()
			      `(FUNCALL RUN-SUPER-CONTINUATION)))
		   ,@BODY)))
	     METHOD-BODY)))
     (:ARGLIST IGNORE &REST ARGS)
  (CALL-COMPONENT-METHODS-WITH-CONTINUATION
    AROUND
    `(MULTIPLE-VALUE-PROG2
       ,(CALL-COMPONENT-METHODS BEFORE)
       ,(CALL-COMPONENT-METHODS-WITH-CONTINUATION
	  PRIMARY
	  `(ERROR "RUN-SUPER past the least-specific method")
	  ARGS)
       ,(CALL-COMPONENT-METHODS AFTER))
    ARGS))

(DEFGENERIC SDTEST-2 (X Y)
  (:METHOD-COMBINATION :SUPER-DAEMON-2))

(DEFFLAVOR SDTEST1 () ())
(DEFFLAVOR SDTEST2 () (SDTEST1))
(DEFFLAVOR SDTEST3 () (SDTEST2))

(DEFMETHOD (SDTEST-2 SDTEST1) (X)
  (LIST 1 X))

(DEFMETHOD (SDTEST-2 SDTEST2) (X)
  (DECLARE (IGNORE X))
  (CONS 2 (RUN-SUPER)))

(DEFMETHOD (SDTEST-2 SDTEST3) (X)
  (DECLARE (IGNORE X))
  (CONS 3.0 (RUN-SUPER)))

(DEFMETHOD (SDTEST-2 SDTEST2 :AROUND) (X)
  (LIST "[" (RUN-SUPER) "|" X "]"))

(SDTEST-2 (MAKE-INSTANCE 'SDTEST3) 105)
; => ("[" (3.0 2 1 105) "|" 105 "]")



I wouldn't want to make either of these the default, because of the
efficiency cost of all this extra mechanism.  This is based on my
prejudice that "normal" programs won't use run-super and shouldn't have
to pay the cost of keeping around the information needed for run-super
to work.  With modest amounts of additional hair in the
:method-transformer, it should be possible to scan the body of the
method for calls to run-super, and generate different code if it is not
present.  It's midnight, though, so I'm going to stop here.

In conclusion: yes, it's possible to do run-super this way, and
presumably it works about as well as any other way of doing run-super.
Yes, it's possible to do whoppers this way, and they work about as well
as any other way of doing whoppers.  You can't do wrappers exactly this
way, since they are macros rather than functions, but there is certainly
no inherent reason that code for wrappers couldn't be written into a
define-method-combination, too.  The big difference between doing these
things this way and doing them the way New Flavors does it now is
primarily that the expensive continuation-passing mechanisms needed to
make whoppers/run-super work are invoked explicitly by using a different
special form to define a whopper than to define a method, instead of
implicitly by calling run-super somewhere in the body of the method, and
secondarily that the hair for wrappers and whoppers is kept hidden from
the user who just wants to define a new type of method-combination
without having to worry about anything complicated.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 22:45:49 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 86 19:42:00 PDT
Return-Path: <DLW@YUKON.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by Xerox.COM ;
 04 SEP 86 19:41:43 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM
 via CHAOS with CHAOS-MAIL id 80988; Thu 4-Sep-86 22:40:07 EDT
Date: Thu, 4 Sep 86 22:41 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: Let's define our terminology
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860903164956.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860904224151.9.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: Wed, 3 Sep 86 16:49 EDT
    From: Moon@STONY-BROOK.SCRC.Symbolics.COM

			   This suggests that Objects isn't a good name because
    Common Lisp already has objects.

Unfortunately, the rest of the world seems to have decided to use the
phrase "object-oriented programming" to mean the kind of paradigm that
we are providing.  Therefore, it makes some sense to try to include
"object-oriented programming" in the name.  However, "Common Lisp
Object-Oriented Programming System" is kind of long.  (And I am really
very sick and tired of acronyms, and also don't really like the "loops"
since it sound like it has to do with iteration.)

When Danny and Howie Shrobe and I spoke about this at the AAAI, Danny
suggested that the best thing would be to try not to stress an explicit
name for this thing, but rather just let it be part of Common Lisp as
much as possible.  I think I agree with this.  We can't literally say
that it's "part of Common Lisp", since it's really an extension rather
than part of the core language (until further notice) (as far as I
know).  I'd suggest we take the following approach.

For occasions where we can't avoid using a name, use either "Common Lisp
Class System" or "Common Lisp Object System" (pick just one of these and
stick with it; each has pros and cons, as discussed previously).

Entitle the proposal "An Object-Oriented Programming System [or
Standard] for Common Lisp", rather than putting in a brief name.

When comparing our system with others, say things like "... In
Smalltalk-80, you can only inherit from one class, but in Common Lisp,
you can inherit from many classes...", leaving implicit the phrase
"assuming that your Common Lisp is equipped with the object-oriented
programming extension".  Given this, I don't think there will be too
many occasions in which you'd need to write the "name" of the system.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 22:36:54 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 86 19:31:02 PDT
Return-Path: <DLW@YUKON.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by Xerox.COM ;
 04 SEP 86 19:29:24 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM
 via CHAOS with CHAOS-MAIL id 80985; Thu 4-Sep-86 22:18:42 EDT
Date: Thu, 4 Sep 86 22:20 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Message selection, continued 
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860904161513.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860904222009.5.DLW@CHICOPEE.SCRC.Symbolics.COM>

It looks like we're getting close to agreement now.  As far as I can
tell, the following issues are still left standing.

Issue 1:  RPG proposes that (x &optional y) in a defgeneric is not
synonymous with (x &optional (y nil)).  Instead, "If a method has a
argument specifier for some particular argument, and that argument is
not supplied by either the invoking combination or the generic function
defaulting mechanism, that method is not considered in method
selection."  Moon feels that this is a special case exception, and it
would be simpler and better to eliminate it.  DLW agrees with Moon.

Issue 2: RPG proposes that default forms for function parameters that
have type specifiers must be provided in an explicit defgeneric form,
not in any of the defmethod forms.  Moon proposes that if there is no
explicit defgenric form provided, an implicit one is recognized, with
its argument list taken from a defmethod.  (It would be bad for it to
depend on which defmethod, so "it is an error" for it to make any
difference which defmethod is used; they must all be the same, as far
as constructing the implicit defgeneric goes.)

RPG says: "Allowing this situation would require us to frequently say,
as the New Flavors documentation frequently says, "contrary to what you
might believe based on the name `defgeneric,' you don't have to say
defgeneric first."

Moon says: I don't think users are likely to be very happy if they have
to say defgeneric every time they say defmethod, especially if the
defgeneric just repeats the same information that they already specified
in the defmethod.  It just makes the system seem stupid and bureaucratic
to them.

DLW has never completely made up his mind on this issue.  Personally, I
like defgeneric, because I like to have a specific place to define my
protocol that is separate from any of the implementations of the
protocol.  But I am not sure that I'd want to push this requirement onto
everybody.  We don't have enough experience with New Flavors to know
whether other people end up feeling as I do or not.  However, I should
point out that there is no defgeneric in Smalltalk-80, even as an
option, let alone a requirement.  This seems to lend support to Moon's
point.  On the other hand, based on the preceeding mail, it seems to me
that it is much more conceptually obvious for default forms to be in a
defgeneric form, and the idea of having them in a defmethod form can
appear counterintuitive, even though it makes sense under the rule that
such forms are merely promoted into the implied defgeneric form.  Having
a default form in a method gives the impression that the form is evaluated
after the method is invoked (since that's how functions work), but it's
clearly not true since the method isn't even selected until after the
default form is evaluated.  I do think that it appears confusing, even
though the rules, if read and understood completely, are consistent.

Issue 3: However, RPG appears to modify his rule of Issue 2 in his
"print" example, in which he does indeed have a function with an
optional argument, which is disciminated on, and which has a default
value, even though there is no explicit degeneric form.

Moon says:
But (let ((*standard-output* <instance of the gee-whiz-display-hardware>))
      (print <lisp-object>))
calls the wrong method!  This is what I have been complaining about all along.
This is the key issue.

DLW says:
Yes, it's quite unclear why print behaves the way that you say it does.
Why does that second argument default, if there's no defgeneric?  The
best interpretation I can come up with is that make-specializable includes
a special thing that creates some kind of implied defgeneric, copying the
defaulting-forms that the functions argments used to use into this
implied defgeneric.  That would explain the behavior that you describe.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 18:39:42 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 04 SEP 86 15:07:33 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 04 SEP 86 15:07:19 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74496;
 Thu 4-Sep-86 18:02:04 EDT
Date: Thu, 4 Sep 86 18:01 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860904-134037-1557@Xerox>
Message-ID: <860904180145.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 4 Sep 86 13:38 PDT
    From: Bobrow.pa@Xerox.COM

	Because the options are now all those for method-combination, the
	classical flavors syntax can be distinguished from this new Common Lisp
	Object syntax.  

      I don't follow this.  Could you expand on it, with examples?  If the
      syntax is (defmethod (generic option...) lambda-list body...) I don't
      see how this is syntactically distinguished from
      (defmethod (generic type-specifier option...) lambda-list body...).
      That's why I suggested (defmethod generic option... lambda-list body...)
      instead.

    Since all the options for method combination are either keywords or numbers
    and type is not, one can distinguish the cases.  If this is not the case, 
    we could insist that there always be such a keyword to start.

They aren't keywords.  You got fooled by looking at existing examples where
by coincidence they were always keywords, but in general it's not going to
work to restrict the options attached to a method to be always keywords.
There are applications where these are names of things and the names can
be any symbol (I think we can safely exclude nil, I hope I'm not wrong).

Also I don't think there is anything in Common Lisp that says the name of
a type can't be a keyword.  By convention none of the built-in types are
named by keywords, but users might for some reason use keywords as type
names, so I don't think we can safely rely on it.

Will (defmethod generic option... lambda-list body...) be okay with you,
or do we need to keep searching for a suitable syntax?  A more real
example of the syntax would be
  (defmethod turn-off-valve :before ((v master-valve))
    (unless (check-with-safety-engineer v 'off)
      (unsafe-operator-action "Don't do that!  It will explode")))

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 18:39:27 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 04 SEP 86 14:56:02 PDT
Return-Path: <skeene@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 04 SEP 86 14:55:36 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74484;
 Thu 4-Sep-86 17:54:28 EDT
Date: Thu, 4 Sep 86 17:54 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Summary of features we all agree on 
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860904175404.1.SKEENE@JUNCO.SCRC.Symbolics.COM>


This message is an outline of things that we believe the group has agreed
upon so far.  Some sections are fleshed out, but others are just headings
that need to be filled in.  If you disagree with any of the points below,
let us know.

                       PART I:  PROGRAMMER INTERFACE

Part I describes the basic tools for defining classes, methods, generic
functions, and method combination types, and for making instances of
classes.

DEFINING CLASSES

(DEFCLASS class-name (slot-spec...) (super-class-name...) option...)

class-name is a non-null symbol that names the class being defined.  If a
class is already defined with this name, this definition replaces the old
definition.  The default meta-class ensures that when the definition of a
class changes, each existing instance of the class is updated to the new
format the next time it is accessed.

Each slot-spec is one of:

slot-name       a non-null symbol.

(slot-name initial-value-form)
                initial-value-form is any form.  When an instance is made
                and no initial value for this slot is provided, the slot is
                initialized to the value of this form.

(slot-name slot-option...)
                Each slot-option is an option name followed by its value.
                The defined slot-options and their arguments are:

                = initial-value-form
                     This an alternate way for providing a default initial
                     value form.
                :accessor generic-function-name
                     Specifies that a function named generic-function-name
                     be automatically generated, to read the value of this
                     slot.  SETF may be used with generic-function name to
                     write the value of the slot.
                :reader generic-function-name
                     Specifies that a function named generic-function-name
                     be automatically generated, to read the value of this
                     slot.
                :initable keyword
                     Specifies a keyword to be used to specify an initial
                     value of this slot, when a new instance is being made.
                :allocation
                     [tbd]
                [more?]

If no initial value is specified either in the DEFCLASS or the MAKE form,
the initial value of the slot is undefined and it is an error to reference
it.  This is the same behavior as a DEFVAR with no initial-value-form.

Each super-class-name is a non-null symbol.

Each option is one of:

    option-name
    (option-name argument...)

Each option-name is a keyword that names an option; the arguments depend on
the option.  The set of defined options and their arguments is:

    (:accessor-prefix prefix slot-name...)
    (:reader-prefix prefix slot-name...)
    (:default-init-plist keyword-argument...)
    (:initable-slots slot-name...)
    (:init-keywords keyword...)
    (:documentation string)
    (:meta-class class-name)
    (:required-classes class-name...)
    (:required-init-keywords keyword...)
    (:required-slots slot-name...)
    (:required-methods generic-function-name...)
    (:constructor function-name lambda-list)


For the :ACCESSOR-PREFIX, :READER-PREFIX, and :INITABLE-SLOTS options, you
can omit slot-names to indicate that the option applies for all slots of
this class.

It is legal to specify more than one accessor and reader for a single slot.


DEFINING METHODS AND SETF METHODS

The general syntax for defining a method is:

(DEFMETHOD generic-function-name method-option...
  method-lambda-list
  body...)

generic-function-name is a non-null symbol.

Each method-option is a non-null atom that describes the type of this
method.  Some examples of method-options are:  :BEFORE and :AFTER.

method-lambda-list is a lambda-list with one difference.  Where a
lambda-list allows only a variable and not a list, a type-qualified-
variable may be used.  However, type-qualified-variables cannot be used for
&aux variables, supplied-p parameters, or &rest parameters.  A
type-qualified-variable is a list such as:  (variable-name type-specifier).
Note that the use of &optional is still under discussion.

type-specifier ---tbd---

For convenience in defining a classical method, the following syntax is
provided:

(DEFMETHOD (generic-function-name first-arg-type method-option...)
  method-lambda-list
  body...)

The classical syntax is equivalent to the following expression in the
general syntax:

(DEFMETHOD generic-function-name method-option...
  ((self first-type-arg) method-lambda-list...)
  (with (self)
    body...))

The general syntax for defining a SETF method is:

(DEFMETHOD-SETF generic-function-name method-option...
  method-lambda-list setf-lambda-list
  body...)

The classical syntax for defining a SETF method is:

(DEFMETHOD-SETF (generic-function-name first-arg-type method-option...)
  method-lambda-list setf-lambda-list
  body...)

generic-function-name and method-option are the same as for DEFMETHOD.

setf-lambda-list is a lambda-list containing exactly one required
parameter, which may be type-qualified.  In other words, setf-lambda-list
is one of:

    (variable-name)
    ((variable-name type-specifier))

DEFINING GENERIC FUNCTIONS

(DEFGENERIC generic-function-name lambda-list option...)

(DEFGENERIC-SETF generic-function-name lambda-list setf-lambda-list option.

generic-function-name is a non-null symbol.

lambda-list is an ordinary lambda-list except no &aux variables are
allowed.

setf-lambda-list is (variable-name).

Each option is one of:

    option-name
    (option-name argument...)

Each option-name is a keyword that names an option; the arguments depend on
the option.  The set of defined options and their arguments is:

[--Should declarations and doc strings be allowed?--]

    (:documentation string)
    (:optimize spec...)
    (:method-combination name argument...)
    (:generic-function-class class-name)
    (:method-class class-name)
    (:order parameter-name...)
    [more?]

WITH

We have agreed that WITH should exist, but we haven't decided anything more
specific about it yet.

DEFINING NEW TYPES OF METHOD COMBINATION

(DEFINE-SIMPLE-METHOD-COMBINATION name operator-name
                                  [single-arg-is-value]
                                  [pretty-name])

This function defines a new type of method combination in which all the
methods are called and their values are passed to the operator specified by
operator-name.

name is a non-null symbol, often a keyword, that is the name of the type of
method combination being defined.

operator-name can be a symbol or a lambda-expression, the name of a
function, a macro, or a special form.

single-arg-is-value is t or nil; by default it is nil.

pretty-name is a string.  It defaults to the lower case version of the
supplied name.

(DEFINE-METHOD-COMBINATION method-combination-type-name
                           lambda-list
                           (method-pattern...) option... body...)

This function behaves the same way as in Flavors.  See the Flavors
documentation for details.

Making a New Instance

(MAKE class-name keyword-argument...)

MAKE is the function that makes and initializes an instance of a class.
The allowed keyword-arguments depend on the DEFCLASS form.  Any keyword
specified with the :INITABLE, :INITABLE-SLOTS, or :INIT-KEYWORDS option is
allowed.

If a keyword-argument is given to MAKE, it overrides any default that is
given in the DEFCLASS form, such as the :DEFAULT-INIT-PLIST option, or the
initial-value-form syntax.

OTHER FUNCTIONS

Other functions of interest to the general programmer [---tbd---].

This list came from the 8 August meeting; it can serve as a starting agenda
for this section:

    find-flavor / class-named
    typep
    type-of
    class-of
    operation-handled-p ??
    remove-class
    remove-method
    change-class

         PART II:  DEFINED CLASSES, METHOD COMBINATION TYPES, AND
                             GENERIC FUNCTIONS

Part II describes the predefined classes, method combination types, and
generic functions that are available to the programmer.

Predefined generic functions fall into two categories:  those which you can
simply call, and those for which you can write methods.

PREDEFINED CLASSES

[---tbd---]

PREDEFINED METHOD-COMBINATION-TYPES

[---tbd---]

PREDEFINED GENERIC FUNCTIONS YOU CAN CALL

[---tbd---]

PREDEFINED GENERIC FUNCTIONS FOR WHICH YOU CAN DEFINE METHODS

[---tbd---]


              PART III:  PRIMITIVES AND META-OBJECT PROTOCOL

[nothing yet]


∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 17:20:34 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 86 13:40:37 PDT
Date: 4 Sep 86 13:38 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Defmethod syntax proposal
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 4 Sep 86 15:01 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860904-134037-1557@Xerox>

    Because the options are now all those for method-combination, the
    classical flavors syntax can be distinguished from this new Common Lisp
    Object syntax.  

  I don't follow this.  Could you expand on it, with examples?  If the
  syntax is (defmethod (generic option...) lambda-list body...) I don't
  see how this is syntactically distinguished from
  (defmethod (generic type-specifier option...) lambda-list body...).
  That's why I suggested (defmethod generic option... lambda-list body...)
  instead.

Since all the options for method combination are either keywords or numbers
and type is not, one can distinguish the cases.  If this is not the case, 
we could insist that there always be such a keyword to start.



-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 17:20:10 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 04 SEP 86 13:27:25 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 04 SEP 86 13:26:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74342;
 Thu 4-Sep-86 16:15:38 EDT
Date: Thu, 4 Sep 86 16:15 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Message selection, continued 
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860903-230400-1277@Xerox>
Message-ID: <860904161513.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 03 Sep 86 23:02 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Moon asked to hear some more about method selection. In this message
    I will partly be giving you my opinion. Some of this is the same as what
    Danny, Gregor, and I will be sending along in the draft. I will put
    things that are my opinion only [inside square brackets].

    Recall that Danny has emphasized several times that all methods
    must have the same shape, which means that the number of required
    arguments is the same for all and that the number of optionals is the
    same for all.

I think we all agree on that.

    A generic function has associated with it an arglist, which I believe we
    are calling the function parameters, and which is a lambda-list.  It is
    the same shape as each of the methods [or it is NIL.  No methods can be
    added to a generic function unless it already exists using defgeneric or
    make-generic].  I will endeavor to explain the general case, using a new
    wrinkle that Danny proposed to me today.  This new wrinkle is an attempt
    to get some of Moon's defaulting stuff into the final specification.
    Let's assume that there is a function parameters list for the generic
    function, GF, that looks like this,

	    (x &optional (y <instance of class-2>))

    Suppose that two defmethod's on GF had been done which look like this:

    (1)	(defmethod GF ((x <class-1> &optional (y <default-1))...)
    (2)	(defmethod GF ((x <class-1>) &optional ((y <class-2>))) ...)

    Suppose that the combination appears,

	    (GF <instance of class-1>)

    According to Danny's proposal, the function parameters for GF defaults y
    to <instance of class-2>. The two methods are considered, and (2) is
    selected over (1) because it is more specific. An optional in a defmethod
    without a argument specifier attached is treated as if it had the most
    general argument specifier attached to it.

May I assume that everywhere you say "argument specifier" this is a typo
for "type specifier"?  Or are you really introducing a new term here?

    Suppose that the combination is,

	    (GF <instance of class-1> <non-instance of class-2>)

    where <non-instance of class-n> means that this is not an instance of class-n.
    Then the function parameters of the generic function do not figure into
    defaulting. (2) does not match, and (1) is selected.

All okay so far.

    Suppose that the function parameters are,

	    (x &optional y)

    If the combination is,

	    (GF <instance of class-1>)

    then the function parameters entry for GF does not help.
    (2) is not considered, because it discriminates on the second argument.
    (1) is selected and invoked with y defaulted to <default-1>.

Are you saying that (x &optional y) in a defgeneric is not synonymous
with (x &optional (y nil))?  Any Common Lisp programmer is going to be
surprised by that.  What is the motivation for this exception?

    If the combination is,

	    (GF <instance of class-1> <non-instance of class-2>)

    Both (1) and (2) are considered. (2) does not match, and (1) is
    selected, but not defaulted. 

Fine.

    A result of this is that methods with argument specifiers on the optionals
    can only be run when either the optional is supplied by the invoking form
    or by the generic function parameters. To say this again, if a method is
    invoked, then every argument that had a argument specifier attached to it
    had an argument supplied, either by the invoking code or by the function
    parameters, and every such argument was an instance of the class specified
    by the appropriate argument specifier. 

This seems completely sensible.

					   If a method has a argument specifier
    for some particular argument, and that argument is not supplied by either
    the invoking combination or the generic function defaulting mechanism, that
    method is not considered in method selection.

I have not yet seen your motivation for including this exception.  I'd
really like to see it.  To me it seems simpler and better to eliminate this
special case.

    Arguments in the methods with no argument specifier attached are taken to
    have the most general argument specifier attached, but not for purposes of
    deciding whether to consider a method.

    [If no defgeneric is done or if the function parameters are not
    specified with defgeneric, the function parameters are taken to
    be nil, which is interpreted to mean no defaulting takes place. If we
    require a defgeneric before any defmethods, this funny interpretation of
    nil is unnecessary, nor is it necessary to wonder what happens to
    the function parameters every a defmethod is performed. One might think
    it makes sense for defmethod to create a generic function is there isn't one
    and to supply the function parameters also. Allowing this situation
    requires us to frequently say, as the NewFlavors documentation frequently
    says, ``contrary to what you might believe based on the name `defgeneric,'
    you don't have to say defgeneric first.'']

I don't think users are likely to be very happy if they have to say
defgeneric every time they say defmethod, especially if the defgeneric
just repeats the same information that they already specified in the
defmethod.  It just makes the system seem stupid and bureaucratic to
them.

What's wrong with the simple rule that evaluating
  (defmethod generic type-qualified-arglist ...)
when the generic has not been previously defined does
  (defgeneric generic arglist),
where arglist is type-qualified-arglist with the type
specifiers removed?

    Here is the interesting example. The generic function has
    the function parameters,

	    (x &optional (y <non-instance of class-2>))

    Again suppose that two defmethod's on GF had been done which look like this:

    (3)	(defmethod GF ((x <class-1> &optional (y <default-1))...)
    (4)	(defmethod GF ((x <class-1>) &optional ((y <class-2>))) ...)

    The combination is,

	    (GF <instance of class-1>)

    (3) and (4) are both considered. (4) does not match, (3) matches and
    is selected, and y is defaulted to the value <non-instance of class-2>.

I agree completely.

    Here is Weinreb's example,

    (defmethod paint (clr &optional ((bldg office-building) *default-bldg*)) ...)
    (defmethod paint (clr &optional ((bldg residential-building) *default-bldg*)) ...)

    [Actually evaluating these combinations should result in an error
    being signalled, because you cannot default optionals that have argument
    specifiers in a defmethod. Alternatively, they will be ignored.]

    The combination is,

	    (paint 'red)

    Under Danny's proposal, this would signal a method-not-found error.

I don't see how any user not intimately familiar with what is going on
inside could ever respond to this with anything but surprise.  "The
method is right there, why isn't it being called?"

    Suppose that defgeneric is used to place function parameters,

	    (x &optional (bldg *default-bldg*))

    Then the combination,

	    (paint 'red)

    would default the second argument to <instance of office-building>, according
    to Weinreb's scenario. This would invoke the first of the two methods.

Fine.  With the simple rule about defgeneric I proposed above, both of your
scenarios behave this way, and the first scenario doesn't surprise the user.

    [The provisions which are new are that the generic function can default
    unsupplied optionals, but methods cannot. Not supplying the function
    parameters with defgeneric (or one of the other specific means of doing
    so) results in no defaulting ever happening, except when optional
    arguments have no argument specifier attached. This last case happens
    when, for example, you have a method defined like this,

	    (defmethod print (object &optional (stream *standard-io*)) ...)

    Furthermore, no defmethod modifies the function parameters of the generic
    function.]

    The print case is a good example. Suppose we have print defined as usual.
    We now make it a generic function, like this,

	    (make-specializable 'print)

    where make-specializable is defined as (according to Danny),

	    ;;;; This function is spread out for commenting
	    (defun make-specializable (symbol)
	     (let ((gf (make-generic)))	 ;make a generic function
		  (add-method gf () #'print) ;add to the generic function, gf,
					     ;the default method function, which
					     ;has () as the argument specifier,
					     ;where () specially signifies
					     ;the default method function,
					     ;and #'print is the method function.
		  (setf (symbol-function 'print) gf))) ;install it

    [or it is defined as (according to me),

	    (defun make-specializable (symbol)
	     (setf (symbol-function symbol)
		   (make-generic 
		    :default-method-function 
		    (default-method-function
		     (symbol-function symbol)))))

    The default-method-function call is so that make-specializable can
    be called twice. Note that there is no reason why a generic function
    cannot be a default method function.]

    Now we want to specialize print,

	    (defmethod print (x &optional ((stream gee-whiz-display-hardware))) ...)

    Now,
	    (print <lisp-object>) 

    calls the usual print function, with the stream defaulted to the usual
    thing.

	    (print <lisp-object> <instance of the gee-whiz-display-hardware>)

    invokes the new method. Print is the generic example for defaulting
    optionals.

But (let ((*standard-output* <instance of the gee-whiz-display-hardware>))
      (print <lisp-object>))
calls the wrong method!  This is what I have been complaining about all along.
This is the key issue.

    [This discussion presumes that the goal of the default behavior of CLOS is
    to select a single method for each generic function invocation.  If we
    take the term `method combination' to refer to specifying how to handle
    all methods that might apply in a single generic function invocation, then
    we'll need to think some more. I await Moon's explanation of his theory of
    method combination.] 

I think that's independent of the issue in this discussion, and you'll
understand why when you understand method combination.  Dick, I just realized
that we only sent Flavors documentation to Bobrow, and maybe the problem
is that you never saw that documentation.  This was roughly a hundred pages
taken from our manual, which I mailed around the end of July.  If you need
a copy of this I'll send one right away.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 15:58:56 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 04 SEP 86 12:44:18 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 04 SEP 86 12:43:58 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74267;
 Thu 4-Sep-86 15:38:24 EDT
Redistributed-date: Thu, 4 Sep 86 15:38 EDT
Redistributed-to: CommonLoopsCore↑.PA@XEROX.COM
Resent-Comments: Message retransmitted because it failed to go through
 the first time.
Date: Thu, 4 Sep 86 15:01 EDT
From: Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860903-180415-1109@Xerox>
Message-ID: <860904150145.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 3 Sep 86 18:03 PDT
    From: Bobrow.pa@Xerox.COM

    We agree with the problems you describe with the defmethod syntax
    described in the paper.  The options are overloaded.  As you say:

      "options are used for three different things in PCL:
      1) Options like :before and :after that are part of the name of the
       method.
      2) (:setf variable) which specifies that this is a setf-method
       and also specifies the name of the variable that gets bound
       to the new value to be stored (the value of the second subform of
      setf).
      (3) The meta-options (:discriminator-class class-name) and
      (:method-class class-name) that control the classes of
      related meta-objects."

    We propose to solve these problems in a different way.

    1) We will keep only those options that are to be used for method
    combination, and these will all be passed on to the method combination
    code

    2) for setf we propose a top level form

    (defsetfmethod name-and-options
      accessor-argument-specifier-list store-variables-specifier-list
     {declaration | documentation}* {form}*)

    This takes the :setf option out of the options list, shows the update
    variables in the order of evaluation, and keeps the same meaning for the
    options.  Note that store-variables can have argument specifiers.

    3) :discriminator-class (now called :generic-function-class) and
    :method-class are not options of defmethod.  They are (advanced) options
    of defgeneric.  Fancy uses of these options can be done by using the
    programmatic interface (i.e. creating the objects and calling the right
    generic-functions to compose things). 

This looks good to me; let's go with it.

There is a problem with (2); the name defsetfmethod might be too easily
confused with define-setf-method, a Common Lisp operator that already exists.
I would suggest defmethod-setf instead.

I actually prefer modifying the syntax of an existing special form rather
than adding a new special form, thus using (defmethod setf generic ...) or
(defmethod (setf generic) ...) in place of (defmethod-setf generic ...),
but this is a matter of taste and I don't really care which way we go on
it.

    Because the options are now all those for method-combination, the
    classical flavors syntax can be distinguished from this new Common Lisp
    Object syntax.  

I don't follow this.  Could you expand on it, with examples?  If the
syntax is (defmethod (generic option...) lambda-list body...) I don't
see how this is syntactically distinguished from
(defmethod (generic type-specifier option...) lambda-list body...).
That's why I suggested (defmethod generic option... lambda-list body...)
instead.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 15:58:19 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 04 SEP 86 12:29:11 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 04 SEP 86 12:21:56 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 74218;
 Thu 4-Sep-86 15:01:59 EDT
Date: Thu, 4 Sep 86 15:01 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860903-180415-1109@Xerox>
Message-ID: <860904150145.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 3 Sep 86 18:03 PDT
    From: Bobrow.pa@Xerox.COM

    We agree with the problems you describe with the defmethod syntax
    described in the paper.  The options are overloaded.  As you say:

      "options are used for three different things in PCL:
      1) Options like :before and :after that are part of the name of the
       method.
      2) (:setf variable) which specifies that this is a setf-method
       and also specifies the name of the variable that gets bound
       to the new value to be stored (the value of the second subform of
      setf).
      (3) The meta-options (:discriminator-class class-name) and
      (:method-class class-name) that control the classes of
      related meta-objects."

    We propose to solve these problems in a different way.

    1) We will keep only those options that are to be used for method
    combination, and these will all be passed on to the method combination
    code

    2) for setf we propose a top level form

    (defsetfmethod name-and-options
      accessor-argument-specifier-list store-variables-specifier-list
     {declaration | documentation}* {form}*)

    This takes the :setf option out of the options list, shows the update
    variables in the order of evaluation, and keeps the same meaning for the
    options.  Note that store-variables can have argument specifiers.

    3) :discriminator-class (now called :generic-function-class) and
    :method-class are not options of defmethod.  They are (advanced) options
    of defgeneric.  Fancy uses of these options can be done by using the
    programmatic interface (i.e. creating the objects and calling the right
    generic-functions to compose things). 

This looks good to me; let's go with it.

There is a problem with (2); the name defsetfmethod might be too easily
confused with define-setf-method, a Common Lisp operator that already exists.
I would suggest defmethod-setf instead.

I actually prefer modifying the syntax of an existing special form rather
than adding a new special form, thus using (defmethod setf generic ...) or
(defmethod (setf generic) ...) in place of (defmethod-setf generic ...),
but this is a matter of taste and I don't really care which way we go on
it.

    Because the options are now all those for method-combination, the
    classical flavors syntax can be distinguished from this new Common Lisp
    Object syntax.  

I don't follow this.  Could you expand on it, with examples?  If the
syntax is (defmethod (generic option...) lambda-list body...) I don't
see how this is syntactically distinguished from
(defmethod (generic type-specifier option...) lambda-list body...).
That's why I suggested (defmethod generic option... lambda-list body...)
instead.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 02:46:23 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 23:11:44 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 03 SEP 86
 23:11:35 PDT
Date: 03 Sep 86 23:11 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Instant Instance Terminology 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860903-231144-1282@Xerox>


I lost the message to which this is a reply. I believe I am
answering this question: What classes are Common Lisp objects
instances of? For each Standard Type Specifier Symbol (on page
43 of CLtL) there is a builtin class defined, and CLASS-OF a
Common Lisp object returns the most specific of those. 

I don't think slots qua slots or array elements qua array elements are
defined to respond to CLASS-OF.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 02:46:14 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 23:04:00 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 03 SEP 86
 23:03:37 PDT
Date: 03 Sep 86 23:02 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Message selection, continued 
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860903-230400-1277@Xerox>


Moon asked to hear some more about method selection. In this message
I will partly be giving you my opinion. Some of this is the same as what
Danny, Gregor, and I will be sending along in the draft. I will put
things that are my opinion only [inside square brackets].

Recall that Danny has emphasized several times that all methods
must have the same shape, which means that the number of required
arguments is the same for all and that the number of optionals is the
same for all.

A generic function has associated with it an arglist, which I believe we
are calling the function parameters, and which is a lambda-list.  It is
the same shape as each of the methods [or it is NIL.  No methods can be
added to a generic function unless it already exists using defgeneric or
make-generic].  I will endeavor to explain the general case, using a new
wrinkle that Danny proposed to me today.  This new wrinkle is an attempt
to get some of Moon's defaulting stuff into the final specification.
Let's assume that there is a function parameters list for the generic
function, GF, that looks like this,

	(x &optional (y <instance of class-2>))

Suppose that two defmethod's on GF had been done which look like this:

(1)	(defmethod GF ((x <class-1> &optional (y <default-1))...)
(2)	(defmethod GF ((x <class-1>) &optional ((y <class-2>))) ...)

Suppose that the combination appears,

	(GF <instance of class-1>)

According to Danny's proposal, the function parameters for GF defaults y
to <instance of class-2>. The two methods are considered, and (2) is
selected over (1) because it is more specific. An optional in a defmethod
without a argument specifier attached is treated as if it had the most
general argument specifier attached to it.

Suppose that the combination is,

	(GF <instance of class-1> <non-instance of class-2>)

where <non-instance of class-n> means that this is not an instance of class-n.
Then the function parameters of the generic function do not figure into
defaulting. (2) does not match, and (1) is selected.

Suppose that the function parameters are,

	(x &optional y)

If the combination is,

	(GF <instance of class-1>)

then the function parameters entry for GF does not help.
(2) is not considered, because it discriminates on the second argument.
(1) is selected and invoked with y defaulted to <default-1>.

If the combination is,

	(GF <instance of class-1> <non-instance of class-2>)

Both (1) and (2) are considered. (2) does not match, and (1) is
selected, but not defaulted. 

A result of this is that methods with argument specifiers on the optionals
can only be run when either the optional is supplied by the invoking form
or by the generic function parameters. To say this again, if a method is
invoked, then every argument that had a argument specifier attached to it
had an argument supplied, either by the invoking code or by the function
parameters, and every such argument was an instance of the class specified
by the appropriate argument specifier. If a method has a argument specifier
for some particular argument, and that argument is not supplied by either
the invoking combination or the generic function defaulting mechanism, that
method is not considered in method selection.

Arguments in the methods with no argument specifier attached are taken to
have the most general argument specifier attached, but not for purposes of
deciding whether to consider a method.

[If no defgeneric is done or if the function parameters are not
specified with defgeneric, the function parameters are taken to
be nil, which is interpreted to mean no defaulting takes place. If we
require a defgeneric before any defmethods, this funny interpretation of
nil is unnecessary, nor is it necessary to wonder what happens to
the function parameters every a defmethod is performed. One might think
it makes sense for defmethod to create a generic function is there isn't one
and to supply the function parameters also. Allowing this situation
requires us to frequently say, as the NewFlavors documentation frequently
says, ``contrary to what you might believe based on the name `defgeneric,'
you don't have to say defgeneric first.'']

Here is the interesting example. The generic function has
the function parameters,

	(x &optional (y <non-instance of class-2>))

Again suppose that two defmethod's on GF had been done which look like this:

(3)	(defmethod GF ((x <class-1> &optional (y <default-1))...)
(4)	(defmethod GF ((x <class-1>) &optional ((y <class-2>))) ...)

The combination is,

	(GF <instance of class-1>)

(3) and (4) are both considered. (4) does not match, (3) matches and
is selected, and y is defaulted to the value <non-instance of class-2>.

Here is Weinreb's example,

(defmethod paint (clr &optional ((bldg office-building) *default-bldg*)) ...)
(defmethod paint (clr &optional ((bldg residential-building) *default-bldg*)) ...)

[Actually evaluating these combinations should result in an error
being signalled, because you cannot default optionals that have argument
specifiers in a defmethod. Alternatively, they will be ignored.]

The combination is,

	(paint 'red)

Under Danny's proposal, this would signal a method-not-found error.

Suppose that defgeneric is used to place function parameters,

	(x &optional (bldg *default-bldg*))

Then the combination,

	(paint 'red)

would default the second argument to <instance of office-building>, according
to Weinreb's scenario. This would invoke the first of the two methods.

[The provisions which are new are that the generic function can default
unsupplied optionals, but methods cannot. Not supplying the function
parameters with defgeneric (or one of the other specific means of doing
so) results in no defaulting ever happening, except when optional
arguments have no argument specifier attached. This last case happens
when, for example, you have a method defined like this,

	(defmethod print (object &optional (stream *standard-io*)) ...)

Furthermore, no defmethod modifies the function parameters of the generic
function.]

The print case is a good example. Suppose we have print defined as usual.
We now make it a generic function, like this,

	(make-specializable 'print)

where make-specializable is defined as (according to Danny),

	;;;; This function is spread out for commenting
	(defun make-specializable (symbol)
	 (let ((gf (make-generic)))	 ;make a generic function
	      (add-method gf () #'print) ;add to the generic function, gf,
					 ;the default method function, which
			 		 ;has () as the argument specifier,
					 ;where () specially signifies
					 ;the default method function,
					 ;and #'print is the method function.
	      (setf (symbol-function 'print) gf))) ;install it

[or it is defined as (according to me),

	(defun make-specializable (symbol)
	 (setf (symbol-function symbol)
	       (make-generic 
		:default-method-function 
		(default-method-function
		 (symbol-function symbol)))))

The default-method-function call is so that make-specializable can
be called twice. Note that there is no reason why a generic function
cannot be a default method function.]

Now we want to specialize print,

	(defmethod print (x &optional ((stream gee-whiz-display-hardware))) ...)

Now,
	(print <lisp-object>) 

calls the usual print function, with the stream defaulted to the usual
thing.

	(print <lisp-object> <instance of the gee-whiz-display-hardware>)

invokes the new method. Print is the generic example for defaulting
optionals.

[This discussion presumes that the goal of the default behavior of CLOS is
to select a single method for each generic function invocation.  If we
take the term `method combination' to refer to specifying how to handle
all methods that might apply in a single generic function invocation, then
we'll need to think some more. I await Moon's explanation of his theory of
method combination.] 

				 -rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  4 Sep 86 00:27:21 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 21:23:22 PDT
Return-Path:
 <@SAIL.STANFORD.EDU,@WAIKATO.S4CC.SYMBOLICS.COM:KMP@STONY-BROOK.SCRC.Symbolics.COM>
Redistributed: CommonLoopsInternal↑.x
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 03 SEP 86
 21:20:13 PDT
Received: from [128.81.51.90] by SAIL.STANFORD.EDU with TCP; 3 Sep 86
 19:28:44 PDT
Received: from EMU.SCRC.Symbolics.COM by WAIKATO.S4CC.SYMBOLICS.COM via
 CHAOS with CHAOS-MAIL id 54894; Wed 3-Sep-86 19:38:43 EDT
Date: Wed, 3 Sep 86 19:01 EDT
From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
Subject: Re: nested class definitions
To: Masinter.pa@Xerox.COM, Kahn.pa@Xerox.COM
cc: snyder%hplsny@hplabs.HP.COM,
 cl-object-oriented-programming@SU-AI.ARPA
In-Reply-To: <860903-140440-1246@Xerox>
Message-ID: <860903190156.1.KMP@EMU.SCRC.Symbolics.COM>

    Date: 3 Sep 86 14:03 PDT
    From: Masinter.pa@Xerox.COM

    Common Lisp has taken the view that while there are local functions with
    FLET/LABELS and local macros with MACROLET, there aren't any local
    structures. Lets suppose we had something like structure-let ...
    This certainly makes sense for (:type list) because it doesn't entail
    any global data-type-space manipulation, but makes less sense for
    structures & classes? In a recursive call, are the types the same
    because they share names? Or different? ...
    you clearly have a dynamic scope the class and its methods. However,
    most languages that have "local types" use a lexical scope instead. How
    can we get lexically scoped classes?

Part of the issue is that you need to clearly define whether the data
which is locally typed wants to be first-class. That is, does it have
indefinite extent?  If so, then what does it mean for its type to have
been local? Does it mean that there are now no valid operations upon it,
or just that there is some kind of state which various objects might
still be carrying around which allows them to speak to the object even
though no one else can. That is, is its type marker invalidated upon
exit from the valid contour/context, or is the accessibility of the type
in the type lookup table just drastically reduced by exit from the
contour/context in question?

I should note for the record that this issue seems to me to be just like
the question people keep asking about why we have local 
(DECLARE (SPECIAL ...)) and don't insist that things be proclaimed
SPECIAL for all time? I'm not sure I have a good answer to that question
either -- seems me to be mostly a convenience issue.

The impact these convenience things (FLET, LABELS, local SPECIAL
declarations, and now local types) on debugging are potentially severe
and I think they need to be studied carefully so I recommend we go
slowly.  For example, if you declare local types to be invalidated upon
return, you're surely going to accidentally return locally-typed objects
during debugging and they'd have to be pretty well-behaved if you were
going to have a debuggable system. PRINT/READ invertibility is obviously
blown away by such a thing. Also, if the language were defined such that
the compiler were allowed to treat certain types totally lexically, then
you'd potentially get something which had its type compiled away --
which has some potential good effects (speed and space efficiency being
key among them) but you'd risk duplicating the Fortran debuggability
problem where you could lose track of the type of an object or where you
could end up cheating on accesses to typed objects in ways that you
really didn't mean to -- or worse, in ways that you did mean to...

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 21:28:04 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 SEP 86 18:04:15 PDT
Date: 3 Sep 86 18:03 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Defmethod syntax proposal
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 2 Sep 86 23:50 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860903-180415-1109@Xerox>

We agree with the problems you describe with the defmethod syntax
described in the paper.  The options are overloaded.  As you say:

  "options are used for three different things in PCL:
  1) Options like :before and :after that are part of the name of the
   method.
  2) (:setf variable) which specifies that this is a setf-method
   and also specifies the name of the variable that gets bound
   to the new value to be stored (the value of the second subform of
  setf).
  (3) The meta-options (:discriminator-class class-name) and
  (:method-class class-name) that control the classes of
  related meta-objects."

We propose to solve these problems in a different way.

1) We will keep only those options that are to be used for method
combination, and these will all be passed on to the method combination
code

2) for setf we propose a top level form

(defsetfmethod name-and-options
  accessor-argument-specifier-list store-variables-specifier-list
 {declaration | documentation}* {form}*)

This takes the :setf option out of the options list, shows the update
variables in the order of evaluation, and keeps the same meaning for the
options.  Note that store-variables can have argument specifiers.

3) :discriminator-class (now called :generic-function-class) and
:method-class are not options of defmethod.  They are (advanced) options
of defgeneric.  Fancy uses of these options can be done by using the
programmatic interface (i.e. creating the objects and calling the right
generic-functions to compose things). 

Because the options are now all those for method-combination, the
classical flavors syntax can be distinguished from this new Common Lisp
Object syntax.  



-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 21:27:53 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 17:08:43 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 03 SEP 86 16:47:11 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73701;
 Wed 3-Sep-86 19:36:53 EDT
Redistributed-date: Wed, 3 Sep 86 19:36 EDT
Redistributed-to: CommonLoopsCore↑.pa@XEROX.COM
Resent-Comments: Message retransmitted because it failed to go through
 the first time.
Redistributed-date: Wed, 3 Sep 86 17:31 EDT
Redistributed-to: CommonLoopsCore↑.pa@XEROX.COM
Resent-Comments: Message retransmitted because it failed to go through
 the first time.
Date: Wed, 3 Sep 86 16:49 EDT
From: Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: Let's define our terminology
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860902-154511-1144@Xerox>
Message-ID: <860903164956.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 2 Sep 86 15:36 PDT
    From: Bobrow.pa@Xerox.COM

    I don't like the name Classes because it stresses only one aspect of the
    system.  An alternative when we change the name would be "Common Lisp
    Object System" which could be acronymed to CLOS or Close if we add
    environment stuff. 

The name "Common Objects" is already being used by HP.  Is that relevant?

I agree that Classes only stresses one aspect of the system.  One way to
choose a name might be to concentrate on what it adds to Common Lisp that
wasn't already there.  This suggests that Objects isn't a good name because
Common Lisp already has objects.  At the moment I don't have any alternative
suggestion to offer, but I hope it's valuable to offer a principle for 
evaluating suggestions.

    One could even talk about the emporers new CLOS.

Ick!  We should try to avoid a cute name that we will be sick of by the
tenth time we hear it, because we'll be hearing it a lot.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 21:27:39 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 17:08:40 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 03 SEP 86 16:43:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73703;
 Wed 3-Sep-86 19:37:20 EDT
Redistributed-date: Wed, 3 Sep 86 19:37 EDT
Redistributed-to: commonloopscore↑.pa@XEROX.COM
Resent-Comments: Message retransmitted because it failed to go through
 the first time.
Date: Wed, 3 Sep 86 17:22 EDT
From: Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Terminology Explained etc.   
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860903-131607-1169@Xerox>
Message-ID: <860903172207.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 03 Sep 86 12:15 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    ....What I meant by the prose on defaulting is this: Suppose one wrote
    
	    ...&optional ((x <class>) <default>)... (3)
    
    as a defmethod that partially defined a particular generic function, G.
    And suppose that an invocation of G did not supply a value for x. That
    value would be supplied by the default <default>. However, if a value for
    x were supplied, then if method (3) were selected and invoked, we would
    know that x was an instance of the class <class>. Therefore the programmer
    might be justified in writing the body of the method assuming that x was
    indeed an instance of the class <class>.  

Absolutely.

					      If a value for x is not
    supplied, the value is taken from <default>, and so the question arises
    whether <default> is indeed an instance of the class <class>. Further, we
    might wonder whether there ought to be an implicit check made that
    <default> is an instance of the class <class> in cases when <default> is
    used.

In my proposal, no special issue arises.  In the body of the method, x
is an instance of <class> regardless of whether it was supplied or defaulted.
No special implicit checks have to be postulated; the same mechanism ensures
this type constraint on x regardless of whether it was supplied or defaulted.

    Moon writes:

	    (3) The appropriate method or methods are selected based on the
		argument values determined in step 2.

	    (4) Each method is called with the original arguments of the generic
		function.  It is an error for the number of arguments or the 
		keyword names....

    I think this means that a generic function invocation can cause more than
    one method to be invoked.

Yes, because of method combination, not because of anything to do with unsupplied
arguments.  I am not proposing that anything in step 3 be any different, when there
are discriminations on optional arguments, from the way step 3 works when there are
discriminations on required arguments.  I apologize for not writing clearly enough.

    My proposal would signal an error if a unique method were not determined by the
    specified arguments. 

What about method combination?  What about run-super?

Perhaps you could expand on this sentence in a way that addresses DLW's
office/residential-building example; I think that would result in our
understanding each other.

			 One design principle we've been trying to use is that
    the specification should not use the phrase ``is an error'' if it can be
    avoided.

I used the phrase "is an error" in my proposal to avoid getting into any issues
of condition systems, extra constraints on the implementation, etc.  I think
we are trying to define the semantics of valid programs, not the exact nature
of the undefined behavior of invalid programs, so changing "is an error" to
"signals an error" everywhere in my proposal should not affect the meaning of
the proposal.  Personally I feel that the choice of whether an error is required
to be detected by every implementation or not should be independent of the
semantics of the language, and should be chosen based on its own criteria and
tradeoffs, but if you feel that it's an essential principle that all errors
should be signalled I am happy to go along with that.

    Another example shows some of the weirdness involved in Moon's rule:

    Let the generic function RING be specified by the methods:

    (1) (defmethod ring (&optional ((x <class-1>) <instance of class-2>))...)
    (2) (defmethod ring (&optional ((x <class-2>) <instance of class-3>))...)
				    .
				    .
				    .
    (n) (defmethod ring (&optional ((x <class-n>) <instance of class-1>))...)

    We refer to these as ring(1), ring(2),...,ring(n).

    Suppose we write

		    (ring)

    This, I think, causes all of the methods to run, but the fun part is that
    the definition of ring(1) causes ring(2) to be invoked, the definition of
    ring(2) causes ring(3) to be invoked, and etc. If we further decided to
    invent a means to specify the order in which these methods are invoked, we could
    embed a program counter into the optional argument defaulting mechanism.
    You could write any program you wanted simply by invoking one generic function.

This is not at all what I intended in my proposal.  I apologize for not
writing clearly enough.  If I may quote myself, "the value of the
argument is determined by evaluating a default value form taken from a
defmethod or defgeneric.  It is an error for the result to depend on
which defmethod or defgeneric supplies the default value form that is
evaluated."  Thus your ring example is in error according to my proposal.
In a programming environment that followed my suggestion for early warning
of errors, you would get a warning as soon as you defined the second method
for ring, because the default value forms were not equal.  In a programming
environment that was careful to signal these errors (and we could change
"is an error" to "signals an error" if we wished to ensure that all valid
implementations of the standard must be careful in that way), you would not
be able to execute the example without signalling errors.

By the way, what would happen if the same forms were executed in your
proposal?  Now change the defmethods so the type qualifications are still
for <class-1> through <class-n>, but the default value forms are all the
same, and what happens in your proposal?

    If we allowed side effects in the default for optionals, we could probably
    write a constraint relaxation system that would run at each generic function
    invocation.

    Well, you get the idea that I believe Moon's rule is a little too much to
    accept for what should be a simple and easily understandable mechanism. And
    to coin a phrase which I hope will be used as often and with as much gusto
    as ``a sufficiently hairy compiler could...,'' a sufficiently hairy programmer
    could use the meta-object protocol to invent discriminators that do `the right
    thing'.

I apologize for misleading you about the contents of my proposal by side-tracking
you with the phrase "is an error".

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 21:27:08 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 16:47:09 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 03 SEP 86 16:43:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73703;
 Wed 3-Sep-86 19:37:20 EDT
Redistributed-date: Wed, 3 Sep 86 19:37 EDT
Redistributed-to: commonloopscore↑.pa@XEROX.COM
Resent-Comments: Message retransmitted because it failed to go through
 the first time.
Date: Wed, 3 Sep 86 17:22 EDT
From: Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Terminology Explained etc.   
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860903-131607-1169@Xerox>
Message-ID: <860903172207.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 03 Sep 86 12:15 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    ....What I meant by the prose on defaulting is this: Suppose one wrote
    
	    ...&optional ((x <class>) <default>)... (3)
    
    as a defmethod that partially defined a particular generic function, G.
    And suppose that an invocation of G did not supply a value for x. That
    value would be supplied by the default <default>. However, if a value for
    x were supplied, then if method (3) were selected and invoked, we would
    know that x was an instance of the class <class>. Therefore the programmer
    might be justified in writing the body of the method assuming that x was
    indeed an instance of the class <class>.  

Absolutely.

					      If a value for x is not
    supplied, the value is taken from <default>, and so the question arises
    whether <default> is indeed an instance of the class <class>. Further, we
    might wonder whether there ought to be an implicit check made that
    <default> is an instance of the class <class> in cases when <default> is
    used.

In my proposal, no special issue arises.  In the body of the method, x
is an instance of <class> regardless of whether it was supplied or defaulted.
No special implicit checks have to be postulated; the same mechanism ensures
this type constraint on x regardless of whether it was supplied or defaulted.

    Moon writes:

	    (3) The appropriate method or methods are selected based on the
		argument values determined in step 2.

	    (4) Each method is called with the original arguments of the generic
		function.  It is an error for the number of arguments or the 
		keyword names....

    I think this means that a generic function invocation can cause more than
    one method to be invoked.

Yes, because of method combination, not because of anything to do with unsupplied
arguments.  I am not proposing that anything in step 3 be any different, when there
are discriminations on optional arguments, from the way step 3 works when there are
discriminations on required arguments.  I apologize for not writing clearly enough.

    My proposal would signal an error if a unique method were not determined by the
    specified arguments. 

What about method combination?  What about run-super?

Perhaps you could expand on this sentence in a way that addresses DLW's
office/residential-building example; I think that would result in our
understanding each other.

			 One design principle we've been trying to use is that
    the specification should not use the phrase ``is an error'' if it can be
    avoided.

I used the phrase "is an error" in my proposal to avoid getting into any issues
of condition systems, extra constraints on the implementation, etc.  I think
we are trying to define the semantics of valid programs, not the exact nature
of the undefined behavior of invalid programs, so changing "is an error" to
"signals an error" everywhere in my proposal should not affect the meaning of
the proposal.  Personally I feel that the choice of whether an error is required
to be detected by every implementation or not should be independent of the
semantics of the language, and should be chosen based on its own criteria and
tradeoffs, but if you feel that it's an essential principle that all errors
should be signalled I am happy to go along with that.

    Another example shows some of the weirdness involved in Moon's rule:

    Let the generic function RING be specified by the methods:

    (1) (defmethod ring (&optional ((x <class-1>) <instance of class-2>))...)
    (2) (defmethod ring (&optional ((x <class-2>) <instance of class-3>))...)
				    .
				    .
				    .
    (n) (defmethod ring (&optional ((x <class-n>) <instance of class-1>))...)

    We refer to these as ring(1), ring(2),...,ring(n).

    Suppose we write

		    (ring)

    This, I think, causes all of the methods to run, but the fun part is that
    the definition of ring(1) causes ring(2) to be invoked, the definition of
    ring(2) causes ring(3) to be invoked, and etc. If we further decided to
    invent a means to specify the order in which these methods are invoked, we could
    embed a program counter into the optional argument defaulting mechanism.
    You could write any program you wanted simply by invoking one generic function.

This is not at all what I intended in my proposal.  I apologize for not
writing clearly enough.  If I may quote myself, "the value of the
argument is determined by evaluating a default value form taken from a
defmethod or defgeneric.  It is an error for the result to depend on
which defmethod or defgeneric supplies the default value form that is
evaluated."  Thus your ring example is in error according to my proposal.
In a programming environment that followed my suggestion for early warning
of errors, you would get a warning as soon as you defined the second method
for ring, because the default value forms were not equal.  In a programming
environment that was careful to signal these errors (and we could change
"is an error" to "signals an error" if we wished to ensure that all valid
implementations of the standard must be careful in that way), you would not
be able to execute the example without signalling errors.

By the way, what would happen if the same forms were executed in your
proposal?  Now change the defmethods so the type qualifications are still
for <class-1> through <class-n>, but the default value forms are all the
same, and what happens in your proposal?

    If we allowed side effects in the default for optionals, we could probably
    write a constraint relaxation system that would run at each generic function
    invocation.

    Well, you get the idea that I believe Moon's rule is a little too much to
    accept for what should be a simple and easily understandable mechanism. And
    to coin a phrase which I hope will be used as often and with as much gusto
    as ``a sufficiently hairy compiler could...,'' a sufficiently hairy programmer
    could use the meta-object protocol to invent discriminators that do `the right
    thing'.

I apologize for misleading you about the contents of my proposal by side-tracking
you with the phrase "is an error".

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 21:26:21 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 16:44:28 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 03 SEP 86 16:43:39 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73702;
 Wed 3-Sep-86 19:37:05 EDT
Redistributed-date: Wed, 3 Sep 86 19:36 EDT
Redistributed-to: CommonLoopsCore↑.pa@XEROX.COM
Resent-Comments: Message retransmitted because it failed to go through
 the first time.
Redistributed-date: Wed, 3 Sep 86 17:29 EDT
Redistributed-to: CommonLoopsCore↑.pa@XEROX.COM
Resent-Comments: Message retransmitted because it failed to go through
 the first time.
Date: Wed, 3 Sep 86 16:44 EDT
From: Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Terminology: Instances
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860902200841.7.DLW@CHICOPEE.SCRC.Symbolics.COM>
Message-ID: <860903164442.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

The problem discussed below is, I think, the main problem with Sonya's
glossary.  I don't find any solution to this in the CommonLoops documentation
that I have seen, which is extremely fuzzy in this area, so I'm looking
for new ideas.  This message is my best attempt at laying out a clear
explanation of the issues and the possibilities.

The way I see it, objects in Common Lisp + Classes fall into three broad
categories, which we used to call "primitive types", "structures", and
"instances".  Structures and instances are both record types ("record"
in the sense of Pascal rather than the sense of IMS, Columbia, or
Guiness).  The set of primitive types is fixed and only extensible by a
high-powered implementor.  The set of structure and instance types is
user-extensible, but these types don't all belong to users because some
of the built-in types are structures or instances rather than
primitives.  Thus "primitive" and "built-in" are not synonymous; we
have to be careful to avoid sloppy language here.

The difference between a structure and an instance is historical and in
what follows I will ignore the existence of structures.

The problem comes when we make every object have a class.  Now every
object is an instance of a class, but we still need a name for those
objects that aren't primitive and have slots.  I see four possible
solutions:

(1) Try to avoid having a name for non-primitive objects.  This
is the approach Sonya took.

(2) Use the word "instance" to mean non-primitive object and
simultaneously let the phrase "instance of" apply to all objects.
It's hard to be sure, but I think this is the approach the existing
CommonLoops documentation takes.

(3) Use a different word to mean non-primitive object.  Any suggestions?
NIL called them "extends".

(4) Use the phrase "non-primitive object" to mean non-primitive object
and don't try to find a shorter word for it.

    Date: Tue, 2 Sep 86 20:08 EDT
    From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>

	Date: Tue, 2 Sep 86 17:40 EDT
	From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>

	Instance  Every object is an instance of some class.  The term instance is
		  used to describe the instance/class relationship of the object to
		  its class.

    I'm still a bit uncomfortable about this broad definition of the term
    "instance", since it means that any Lisp object is an instance.  Observe
    how this works in your next definition:

	Slots     Slots define the structure of instances of the class, as do
		  DEFSTRUCT slots.  When defining a new class, you specify the
		  slots of the class.  A slot is a place where you can store data
		  inside an instance of a class.

    The phrase "an instance of a class" has been defined to mean "a Lisp
    object".  So in order for this to be fully consistent with the
    definition of "instance", we must say that the term "slot" includes
    elements of arrays, since arrays are instances, etc.  We must also say
    that conses have two "slots" each.  Do we really want our terminology to
    say these things?  Every time you write something about slots, you'll have
    to be careful to make sure it's true of the cdrs of conses.

I'm quite unsure whether we want to regard array elements, list elements, and
the two fields of a cons as slots or as something different from slots.  In
the case of sequence elements, they are a little different from slots because
there is an indefinite number of them and they are numbered rather than named.
Also arrays have other attributes that might be considered to be slots, such
as their length, their rank, their displacement, and their adjustability.

I think the issue of whether or not primitive objects have slots is fairly
independent of the issue of what word(s) we use to refer to non-primitive objects.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 21:25:53 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 15:06:32 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 03 SEP 86
 15:06:11 PDT
Date: 03 Sep 86 15:06 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Varia    
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860903-150632-132@Xerox>


Here are quick answers to your questions:

(1) Our view of generic function is very different from yours.
At the outset I proposed 2 routes: associating generic functions
with names (or symbols) or making generic functions true functions.
Danny and Gregor opted for the latter.

A generic function responds T to (typep <generic function> 'function).
You can (setf (symbol-function <symbol>) <generic function>).

(2) We have worked out just about all the protocol for dealing with
generic functions. Defgeneric syntax is a subset of the NewFlavors syntax.

(3) Making a generic function a function reduces cognitive overload.
The concepts are similar enough that an effort should be make to
collapse rather than expand. I think we have a cleaner design than
what you suggest.

(4) This scheme can easily be implemented with closures and a (possibly
hash) table lookup when you modify the arglist, dispatch order, or such
things.  Various implementations will opt to implement them as a new
low-level data type.  Both paths have been worked out to some extent.

(5) I think we have figured out what issues are raised and have
answered them. For cleanliness, I am about to propose to Danny and
Gregor that a defgeneric (or make-generic) must be done before any defmethods
or add-methods can be performed on the generic function.

Finally, this statement,

    this admits closures being made specializable

means that

(progn
 (flet ((foo (x y) (operate-on x y)))
  (setf (symbol-function 'baz) (make-generic :default-method-function #'foo)))
 (defmethod foo ((x symbolics-hacker) (y lucid-hacker)) (assert `(hates ,y ,x)))
 (foo 'moon 'gabriel))

makes a generic function whose default method function is that defined by
the FLET and which has another method added to it. Of course, the example
represents a false situation. <smiley face>

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 21:25:34 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 15:02:31 PDT
Return-Path: <@SAIL.STANFORD.EDU:Masinter.pa@Xerox.COM>
Redistributed: CommonLoopsInternal↑.x
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 03 SEP 86
 15:00:24 PDT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Sep 86
 14:26:37 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 SEP 86 14:04:40 PDT
Date: 3 Sep 86 14:03 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: nested class definitions
In-reply-to: Kahn.pa's message of 3 Sep 86 10:37 PDT
To: Kahn.pa@Xerox.COM
cc: snyder%hplsny@hplabs.HP.COM,
 cl-object-oriented-programming@su-ai.ARPA
Message-ID: <860903-140440-1246@Xerox>

Common Lisp has taken the view that while there are local functions with
FLET /LABELS and local macros with MACROLET, there aren't any local
structures.    Lets suppose we had something like structure-let:

(structure-let (((foo (:type list)) a b c)
		  (baz x y z))
     (setq kk (make-baz ...))
     (baz-x kk)

    ...)

This certainly makes sense for (:type list) because it doesn't entail
any global data-type-space manipulation, but makes less sense for
structures & classes? In a recursive call, are the types the same
because they share names? Or different? 

In

(let ((c (make 'class ...)))
	(add-method ....)

	...)

you clearly have a dynamic scope the class and its methods. However,
most languages that have "local types" use a lexical scope instead. How
can we get lexically scoped classes?


∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 17:28:53 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 SEP 86 14:07:50 PDT
Date: 3 Sep 86 14:07 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Method Selection   
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 02 Sep 86
 23:15 PDT
To: RPG@SAIL.STANFORD.EDU
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860903-140750-1250@Xerox>

I found Dick's rules summarizing our current understanding not clear, so
I'll try again.

1) All methods must have the same shape argument list.  This can be
specified in the defgeneric form.  This includes any &rest and &key
arguments. (** A relaxation this rule would allow any number of
additonal optional arguments past the ones specified in defgeneric, but
none of these can have arg-specifiers in any method.**)

2) The only arguments that can have argument specifiers are required
arguments and optional arguments.
   a) the syntax for required arguments is 
      (var-name arg-specifier) 
   or var-name    ; this is equivalent to (var-name T)
   b) the syntax for optionals is
	  (var-name default-value supplied-p) ; the usual
    or (var-name = arg-specifier) 
		; I argue later why defaults are not useful here
		; alternatively we could use
		  ((var-name arg-specifier) dummy-default dummy-s-p) 

3) The method defined by
meth1: (defmeth foo ((x c1) &optional (y = c2))
		foo-c1-c2-body)
will only be called if both x and y are supplied and match their
argument specifiers, c1 and c2.

The rule is:

When a generic function is called, unsupplied optionals do not match any
specification for optionals.

Since this is the case, methods with type specifiers in an optional will
never be called unless the optional is supplied.  Hence, a default value
would never be used, and supplied-p would always be T in the body.

This rule resolves the ambiguity in who is called for
     (foo instance-of-c1)
when we have meth2 
meth2: (defmeth foo ((x c1) &optional (y 17 supplied-y-p)
            ...)
as well as meth1.  meth2 is called

This rule also allows the body of foo-c1-c2 to be compiled knowing that
y is an instance of c2.

It also means that
meth3:  (defmeth foo ((x c1) &optional (y = c3))
		foo-c1-c3-body)
does not conflict with meth1, nor would it if there were extra optionals
with default values defined differently. 

Defaults can only be provided in cases where the other arguments
determine the method chosen, and hence two conflicting methods cannot
exist.

Note that this is where this rule differs from Steele's suggestion; it
makes those two conflict.

4) We could add to defgeneric the possibility of specifying
default-values to be used before discrimination.  In this case, the
method invoked would be supplied the default value, without indication
that the value was not provided in the call.  For example, consider:

(defgeneric print (object &optional (stream default-stream)) ...)

There is again no conflict about default values, and the rule is simple.
Generic function defaults are supplied to methods, and discrimination
uses the value of this generically suplied argument.  
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 17:28:30 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 13:16:07 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 03 SEP 86
 13:15:42 PDT
Date: 03 Sep 86 12:15 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Terminology Explained etc.   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860903-131607-1169@Xerox>


Dan Weinreb wondered about some comments I made, and it sounded as if
he didn't understand my bracketing of terms. Without getting into
Husserl let me explain the terminology and then get on to his points.

Following tradition, by `<class>' I mean some unspecified but named class.
This is generally how people write schema without having to invent
a specific instance. It is like saying

	...&optional ((x office-building) *default-building*)...  (1)

except that I don't choose to dream up a class name. One could write

	...&optional ((x <class1>) <instance of class1>)...   (2)

where (2) is a scheme which includes (1) as an example.

What I meant by the prose on defaulting is this: Suppose one wrote

	...&optional ((x <class>) <default>)... (3)

as a defmethod that partially defined a particular generic function, G.
And suppose that an invocation of G did not supply a value for x. That
value would be supplied by the default <default>. However, if a value for
x were supplied, then if method (3) were selected and invoked, we would
know that x was an instance of the class <class>. Therefore the programmer
might be justified in writing the body of the method assuming that x was
indeed an instance of the class <class>.  If a value for x is not
supplied, the value is taken from <default>, and so the question arises
whether <default> is indeed an instance of the class <class>. Further, we
might wonder whether there ought to be an implicit check made that
<default> is an instance of the class <class> in cases when <default> is
used.

Moon writes:

	(3) The appropriate method or methods are selected based on the
	    argument values determined in step 2.

	(4) Each method is called with the original arguments of the generic
	    function.  It is an error for the number of arguments or the 
	    keyword names....

I think this means that a generic function invocation can cause more than
one method to be invoked.

My proposal would signal an error if a unique method were not determined by the
specified arguments. One design principle we've been trying to use is that
the specification should not use the phrase ``is an error'' if it can be
avoided.

Another example shows some of the weirdness involved in Moon's rule:

Let the generic function RING be specified by the methods:

(1) (defmethod ring (&optional ((x <class-1>) <instance of class-2>))...)
(2) (defmethod ring (&optional ((x <class-2>) <instance of class-3>))...)
				.
				.
				.
(n) (defmethod ring (&optional ((x <class-n>) <instance of class-1>))...)

We refer to these as ring(1), ring(2),...,ring(n).

Suppose we write

		(ring)

This, I think, causes all of the methods to run, but the fun part is that
the definition of ring(1) causes ring(2) to be invoked, the definition of
ring(2) causes ring(3) to be invoked, and etc. If we further decided to
invent a means to specify the order in which these methods are invoked, we could
embed a program counter into the optional argument defaulting mechanism.
You could write any program you wanted simply by invoking one generic function.

If we allowed side effects in the default for optionals, we could probably
write a constraint relaxation system that would run at each generic function
invocation.

Well, you get the idea that I believe Moon's rule is a little too much to
accept for what should be a simple and easily understandable mechanism. And
to coin a phrase which I hope will be used as often and with as much gusto
as ``a sufficiently hairy compiler could...,'' a sufficiently hairy programmer
could use the meta-object protocol to invent discriminators that do `the right
thing'.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 17:28:05 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 13:11:33 PDT
Return-Path: <@SAIL.STANFORD.EDU:Kahn.pa@Xerox.COM>
Redistributed: CommonLoopsInternal↑.x
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 03 SEP 86
 13:09:03 PDT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Sep 86
 12:31:09 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 SEP 86 11:13:41 PDT
Date: 3 Sep 86 10:37 PDT
From: Kahn.pa@Xerox.COM
Subject: Re: nested class definitions
In-reply-to: Alan Snyder <snyder%hplsny@hplabs.HP.COM>'s message of Tue,
  2 Sep 86 09:47:07 PDT
To: snyder%hplsny@hplabs.HP.COM
cc: cl-object-oriented-programming@su-ai.ARPA
Message-ID: <860903-111341-1026@Xerox>

There is a sense in which CommonLoops already addresses the problem of
nested class definitions.  CommonLoops is often presented in terms of
DEFMETH and DEFCLASS (or NDEFSTRUCT) but these are user convenient forms
of primitives which do not require classes and generic functions to have
names.  For example, one can write something like

(let ((c (make 'class ...)))
   (add-method some-discriminator (list c ...) ...)
   <body>)

where in the scope of <body> c is a local class.  Instances of it may be
returned and discrimination upon them works fine.   One issue here is
that an ideal implementation of CommonLoops should garbage collect a
class if the only references to them are from discriminators and super
classes.  The garbage collector should also remove the methods involved.

If this turns out to be a useful style one could package up the above in
some friendly macros.

----- ken

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 17:27:37 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 12:56:39 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 03 SEP 86 12:56:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73001;
 Wed 3-Sep-86 15:54:50 EDT
Date: Wed, 3 Sep 86 15:54 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Progress So Far    
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860829-192053-115@Xerox>
Message-ID: <860903155437.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 29 Aug 86 18:20 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    ...we have worried a little about the ontology of generic functions.
    The current implementation of PCL admits the term `generic function' only
    in the sense that various aspects of the code and data structures taken
    together form a set of things that could be called a `generic function.'

    We have tentatively decided that generic functions are objects
    which are first-class objects and which are FUNCALLable. 

Surely no one could argue against this.  The next level of detail is
where issues might start to arise.

To give us some specifics to start from, here is how it works right
now in New Flavors.  I'm not advocating that the standard should work
exactly this way, but it's certainly a starting point for discussion.

A generic function is an object on which certain operations are
possible, such as getting the argument list, finding all the methods
that handle it, etc.  The complete list would be very long and I
don't see any point in trying to list it here.  A generic function is
also a conceptual entity, and this object can be said to be the
representative within the Lisp world of that concept.

Every generic function has a name.  The mapping from names to generic
functions in the run-time environment is immutable; no matter how you
change the attributes of a generic function it continues to be the same
(EQ) object.  There are also "hypothetical" mappings from names to
generic function objects; one such mapping is established each time you
do a compilation, for the compile-time environment, and additional ones
are set up by programmers' tools that deal with "hypothetical worlds."
There could perhaps be anonymous generic functions, but we have seen
that as a can of worms that would introduce many problems with little
visible benefit, so we haven't pursued it.

The function definition of the name of a generic function is -not-
necessarily the generic function object.  In general it is a piece of
code generated for discrimination.  As an optimization, in the simple
classical case the generic function object is used directly as the
function definition and is recognized by the implementation of function
calling, but this is only an optimization.

In CommonLoops terms, the generic function object is a meta-object
and is not necessarily funcallable.  The function definition of the
name of a generic function is something that is funcallable, but is not
the argument for the various operations on a generic function.  I'm not
sure what the advantages of combining these two objects into one would
be; the primary reason for keeping them separate is to gain the freedom
to perform implementation-dependent optimizations of the time-critical
operation of calling a generic function.  In our implementation we could
rather easily make the function definition of the name of a generic
function be an acceptable argument to the other operations on generic
functions, as a synonym for the generic function meta-object itself,
but I'm not sure if all implementations could do this, since Common Lisp
defines very little of the characteristics of a compiled-function as an
object.

So let me ask some specific questions.
(1) How does the model you have in mind differ from the above?
(2) How much of the protocol for generic functions (the possible
operations on these objects) have you figured out?
Assuming you propose that the meta-object that represents a generic
function be the same as the object that you funcall:
(3) What are the advantages of combining these two objects into one?
(4) What does it take to implement this in typical Common Lisps?
If you're proposing the extension to anonymous generic functions:
(5) Have you figured out what issues are raised and what the answers are?

    This admits closures being made specializable. 

In two days I haven't been able to figure out what you meant by the last
sentence.  Could you clarify that, please?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 15:33:32 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 12:02:46 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 03 SEP 86 12:00:10 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72942;
 Wed 3-Sep-86 14:59:11 EDT
Date: Wed, 3 Sep 86 14:59 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Selection   
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860902-231609-1502@Xerox>
Message-ID: <860903145906.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 02 Sep 86 23:15 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Danny and Gregor (and I) finally concluded that it would be better
    to adopt the following rule:

	    Discrimination is based only on supplied arguments.

    Following this rule, default values never figure into discrimination.
    When the fragment

	    ...&optional ((x <class>) <default>)...

    occurs, it means that if X is supplied, it is discriminated on by the class
    <class>, and if it isn't supplied, it is defaulted to <default>, which
    may or may not be of class <class>.

If X is not supplied, is this method invoked or isn't it?  If the answer is
constant, then I don't see how you can say that you are doing meaningful
discrimination on optional arguments.  With your proposed rule, to get the
discrimination you have to supply the argument.  I'd like to see some
examples showing how this proposed rule would be useful.  I already
supplied one example in an earlier message (last week) showing how
discriminating on unsupplied optional arguments can be useful.

    There is further motivation for this; one could have said:

    (defmethod baz ((x plane) &optional ((y boat) <a plane>)) ...)

    where PLANE is not a subclass (transitive) of BOAT.

    Would this signal an error if BAZ were invoked on exactly 1 argument?  The
    default value (<a plane>) is not a subclass of BOAT, so it would be
    reasonable to believe that such an error would be signalled.

Is it unreasonable to believe that the error would be "no applicable method"
(assuming there aren't other methods for baz you haven't shown)?  I suspect
you're thinking that the error is "method inconsistent with itself" rather
than "no applicable method", but you didn't say what error you expected
would be signalled.

    With this rule one need not include language such as ``it is an error
    for default-forms ... to have side effects.'' Default forms can have
    side effects, which do not figure into the selection of a method.

    With this rule, some implementations could be more efficient (?).

If you think these are fatal problems then I think you are arguing for
completely eliminating discrimination on optional arguments, not just for
the rule you outlined above.  I can live with that; there's no point to
putting in extra features that we are not sure are correct.  Also,
discriminating on optional arguments can be done the other way, using the
:function and :method-arglist options to defgeneric, so that the argument
defaulting happens at the front of the discriminating function rather than
in the methods.

    With the Moonrule, generic function invocation can invoke a number
    of methods. This possibly leads to a less clear model of the process
    with little improvement of the functionality. In fact, the muddying
    is well worth avoiding.

Could you rephrase this, please?  I can't figure out what you think is
unusual or unclear about generic function invocation being able to invoke
a number of methods.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 15:33:07 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 03 SEP 86 11:28:13 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 03 SEP 86 11:23:37 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72903;
 Wed 3-Sep-86 14:17:10 EDT
Date: Wed, 3 Sep 86 14:23 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Method Selection   
To: RPG@SAIL.STANFORD.EDU, commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860902-231609-1502@Xerox>
Message-ID: <860903142319.7.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: 02 Sep 86 23:15 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Danny and Gregor (and I) finally concluded that it would be better
    to adopt the following rule:

	    Discrimination is based only on supplied arguments.

    Following this rule, default values never figure into
discrimination.
    When the fragment

	    ...&optional ((x <class>) <default>)...

    occurs, it means that if X is supplied, it is discriminated on by
the class
    <class>, and if it isn't supplied, it is defaulted to <default>,
which
    may or may not be of class <class>.

I don't understand what you're proposing.  Suppose the following two
methods exist:

(defmethod paint (color &optional ((building office-building)
*default-building*)) ...)
(defmethod paint (color &optional ((building residential-building)
*default-building*)) ...)

Now I do (paint 'red), where the value of *default-building* is an
instance of the class office-building.  It seems clear to me that the
first method ought to be invoked.

I can't understand what you're saying it should do.  Yes, it is
defaulted to <default>, which may or may not be of class <class>,
whatever you mean by <class> (there could be more than one <class> if
there are several methods), but what happens under your rule, in this
example?  Does it invoke one method or the other, or both, or do
nothing, or signal an error, or what?

    With the Moonrule, generic function invocation can invoke a number
    of methods. This possibly leads to a less clear model of the process
    with little improvement of the functionality. In fact, the muddying
    is well worth avoiding.

I don't understand what you mean by "a number of methods".  Only one
method is invoked.  The idea is that you first determine the values of
the not-supplied optional arguments, and then you behave exactly as if
all of the optional arguments had been supplied, and pick the
appropriate method according to the usual rules.  Instead of
"Discrimination is based only on supplied arguments", I'd say "First
supply all of the arguments, and then discriminate as if all arguments
were supplied".  That's how I think it ought to work and how I think
Moon's rule works.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 02:48:45 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 02 SEP 86 23:45:19 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 02 SEP 86
 23:45:07 PDT
Date: 02 Sep 86 23:45 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Method Naming and etc   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860902-234519-1508@Xerox>


The method naming scheme needs to be thought through some more with the
further consideration that generic functions need not be named. That is,
there can be anonymous generic functions. With the simple rule proposed in
my message regarding method selection, there is only 1 method invoked when
a generic function is invoked (unless run-super or its ilk is invoked), so
naming/identifying them depends exactly on the argument specifiers.

Placing the method type, Whopper, someplace different from where the
option, :BEFORE, would go hints at some essential difference between the
sort of things that Whoppers and other method combinations are. 
I've not delved into the method combination stuff as deeply as I have
into other areas, so perhaps Moon could start off the background
discussion that will need to go into the spec on this topic?

Clearly the etymology of `method combination' hints that when more than
one method could be applicable (in the possible absence of more specific
methods) that some combining function must be supplied for them. The
`standard' CommonLoops generic function invocation selects the most
specific method.  This is under the control of the meta-class
for the discriminator function.  Another scenario might be that generic
function invocation passes all selectable methods to a combining function,
whose default is to select the most specific (of a certain type of
method).

It would seem that under this theory, :BEFORE, :AFTER, and Whopper are
similar things.

I think the best service to all is to provide the most precise and
crisp semantics we can, and method combination is currently a muddy area.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 02:20:13 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 23:16:09 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 02 SEP 86
 23:15:51 PDT
Date: 02 Sep 86 23:15 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Method Selection   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860902-231609-1502@Xerox>


Danny and Gregor (and I) finally concluded that it would be better
to adopt the following rule:

	Discrimination is based only on supplied arguments.

Following this rule, default values never figure into discrimination.
When the fragment

	...&optional ((x <class>) <default>)...

occurs, it means that if X is supplied, it is discriminated on by the class
<class>, and if it isn't supplied, it is defaulted to <default>, which
may or may not be of class <class>.

There is further motivation for this; one could have said:

(defmethod baz ((x plane) &optional ((y boat) <a plane>)) ...)

where PLANE is not a subclass (transitive) of BOAT.

Would this signal an error if BAZ were invoked on exactly 1 argument?  The
default value (<a plane>) is not a subclass of BOAT, so it would be
reasonable to believe that such an error would be signalled.

With this rule one need not include language such as ``it is an error
for default-forms ... to have side effects.'' Default forms can have
side effects, which do not figure into the selection of a method.

With this rule, some implementations could be more efficient (?).

With the Moonrule, generic function invocation can invoke a number
of methods. This possibly leads to a less clear model of the process
with little improvement of the functionality. In fact, the muddying
is well worth avoiding.

			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 01:21:20 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 22:17:36 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 22:17:18 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72563;
 Wed 3-Sep-86 01:16:19 EDT
Date: Wed, 3 Sep 86 01:16 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: declaring the name of slot accessors
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860828-113956-2368@Xerox>,
              <860902105746.2.DLW@CHICOPEE.SCRC.Symbolics.COM>
Message-ID: <860903011607.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

I haven't completely figured out what I think about this, but I
think it is probably valuable to send you some feedback with what
I think so far, even if it might turn out to be incomplete, since
I've been thinking about this off and on for several days and
haven't come to totally solid conclusions.

    Date: 28 Aug 86 11:39 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    Here is another try at the right mix between convenience and
    cleanliness in automatically generated accessors in defclass.

    Example 1:  Define setf'able accessors for all the slots using the
    "conc-name" "FOO-".

    (defclass foo ()
      ((a 1)
       (b 2))
      (:accessor-prefix foo-))

I'm still not happy with the word "accessor", because it is so vague.
I'll admit I'm not utterly unhappy with it either.  Old Flavors used
the word :accessor-prefix and we got rid of it for what we felt were
good reasons.

By the way, the syntax of all of these examples is messed up, unless
you really decided that the superclass list should precede the slot
list.

    Example 2:  Define setfable accessors for all the slots, the conc-name
    for the slot a is FOO- for b it is BAR-

    (defclass foo ()
      ((a 1)
       (b 2))
      (:accessor-prefix foo- a)
      (:accessor-prefix bar- b))

This extension of the previous example doesn't bother me.

    Example 3: Define setfable accessors for all the slots.  The conc-name
    for a is FOO-.  For all the others it is BAR-.

    (defclass foo ()
      ((a 1)
       (b 2)
       (c 3))
      (:accessor-prefix foo- a)
      (:accessor-prefix bar-))

This is rather odd, because the interpretation of :accessor-prefix with one
subform depends on context, namely what appears in other :accessor-prefix
clauses.  Worse, I don't know whether or not you intend that writing
the two :accessor-prefix clauses in the reverse order would have the same
effect.  Is this really necessary?

    The :non-setfable-accessor-prefix option works the same way, but
    defines non-setfable accessors.

What a terrible name!  How about :reader-prefix?

    The :read-only option would still exist, but it affects the low-level
    slot access code.  Not the generation of methods.

Agreed.

I assume that this example from your message of 13 August is still
operative:

(defclass foo
    ((a 1 :accessor foo-a)
     (b 2 :accessor ship-b))
    ())

An important design principle that applies here is that whenever a
defxxx macro makes up a symbol according to some rule, in this case by
concatenating two strings, it should be possible for the user to specify
explicitly the symbol to be used.  We find that the built-in naming
convention is used almost all the time, but that the need to specify a
different symbol does arise every so often.  It's also conceptually
cleaner to have a way to specify explicitly the same symbol that the
rule would produce; it makes the operation of the macro easier to
explain.

This also applies to keywords for initializing slots, by the way.

Similar to :reader-prefix as a defclass option, :reader would be
permitted as a slot option, which means that the following symbol
is a function that reads this slot but can't be setf'ed.  It is
of course permissible to use both :accessor and :reader in the
same slot, and to use either of them multiple times.  For example,
the :reader might be exported from a package, while the :accessor
might be for internal use only.

Are we going to keep the defstruct bug that you can't specify slot
options without giving an initial value?  There are implementations out
there that distinguish an uninitialized variable from a variable whose
value is NIL.  It's easy to fix the bug, just say that the initial value
is specified with the slot option =, and add an abbreviated syntax so
that (a 1) is an abbreviation for (a = 1).  If you don't like =
substitute your favorite word.  I think this was proposed for CL
defstruct, but I don't remember why it was shot down.

    Date: Tue, 2 Sep 86 10:57 EDT
    From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>

    I think I see what you're trying to do here.  The advantage of this
    syntax is that you only need one option, namely :accessor-prefix, rather
    than having two options, one used for putting a uniform prefix onto all
    the accessor names and another used for assigning specific names to
    specific accessors.  Have I correctly induced the motivation?

    Note that you have to make a rule saying that any number of options of
    the form
      (:accessor-prefix xxx yyy)
    are allowed, but only one option of the form
      (:accessor-prefix xxx)
    is allowed.  This is a reflection of the fact that the two options that
    I referred to above are not syntactically completely symmetrical.

I see no reason to impose a restriction that the user is only allowed to
define one accessor function for a given slot.  See also my comments
under example 3 above about unnecessary context-dependence.

    Another attribute of this proposal is that a specific name for an
    accessor must have the name of the slot as its suffix: there's no way to
    have a slot named x and an accessor for it named foo-y, unless you code
    up the accessor yourself.  I'm not sure whether I think this is a
    problem or not.

I think it's a problem.  See my "design principle" comment above.

    I would tend to prefer having two separate options, but I don't think I
    can offer any very strong argument.  I tend to prefer keeping separate
    things separate, instead of "overloading" things, and this proposal just
    slightly edges into the realm of "overloading".  I admit that this is
    mainly a matter of taste and I don't have any kind of strong argument.

I haven't figured out what I think about this yet.

    I also still tend to favor names such as "readable" and "writable"
    rather than "accessible" or "accessor", because it's not clear from the
    word "access" whether "access" means just reading, or both reading and
    writing.  I don't care precisely what words are used as long as the
    words themselves specify clearly whether we're talking about reading or
    writing.

I haven't figured out what I think about this yet.

    By the way, do we really want to introduce a new feature for :read-only
    slots?  Presumably this means that (setf (get-value 'r-o-slot) x) is
    defined to signal an error, or something like that?  (This isn't on the
    topic of declaring the name of slot accessors.)  It sounds like a
    reasonable idea, but let's not slip it in without considering it
    explicitly.  

I agree.  I thought it was already in, but I might be wrong.  I certainly
am no advocate of it; basically, I think it's a useless idea.

		 From an implementation point of view, it seems that the
    error could be detected at compile time for almost all cases (except for
    debugging tools and things like that, in which high speed doesn't
    matter).  (I'm not an implementation-meister so I'm not confident that
    I'm right about this.)

I don't think you're right, because the exact class of a value is never
known at compile time (all we sometimes know is a superclass), and slot
options can be added to an inherited slot.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 00:46:33 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 21:43:18 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 21:43:06 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72555;
 Wed 3-Sep-86 00:42:07 EDT
Date: Wed, 3 Sep 86 00:41 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860903004049.0.DLW@CHICOPEE.SCRC.Symbolics.COM>
Message-ID: <860903004113.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 3 Sep 86 00:40 EDT
    From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>

    Your proposal seems to be referring to :discriminator-class and
    :method-class as "declarations".  However, it is a general Common Lisp
    rule that declarations, other than good old "special", are semantically
    invisible.  Perhaps these things need to go up in the "options", except
    that they are not atomic so something would have to change (perhaps the
    fact that they start with keywords would disambiguate things enough?).

Since as you say there is already one exception to that rule, it seemed better
to add some more than to mix together radically different kinds of options
in the same list.  More detailed arguments were in my proposal, at the end.
I don't think the atomicness matters; that could easily be handled.

At one point I had considered keeping these things separate from the
regular DECLAREs, thus effectively having three places in a DEFMETHOD
where the user could insert options, but that seemed unnecessarily complex
and confusing, especially when you consider that most users won't need to
think about these things.

I should have included more motivation and rationale in the proposal.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  3 Sep 86 00:39:09 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 21:35:58 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 21:35:47 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72553;
 Wed 3-Sep-86 00:34:43 EDT
Date: Wed, 3 Sep 86 00:40 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Defmethod syntax proposal
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860902235003.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860903004049.0.DLW@CHICOPEE.SCRC.Symbolics.COM>

Your proposal seems to be referring to :discriminator-class and
:method-class as "declarations".  However, it is a general Common Lisp
rule that declarations, other than good old "special", are semantically
invisible.  Perhaps these things need to go up in the "options", except
that they are not atomic so something would have to change (perhaps the
fact that they start with keywords would disambiguate things enough?).

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 23:54:51 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 20:51:24 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 20:51:05 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72534;
 Tue 2-Sep-86 23:50:08 EDT
Date: Tue, 2 Sep 86 23:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Defmethod syntax proposal
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860902235003.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

The following is our feeling about the syntax of defmethod in the Common
Lisp standard.  This proposal is related to the method naming and
identity proposal I am also mailing out, but I think the discussion of
the two proposals will be independent enough that it is better to
consider them separately.

I've taken the fonts off of the following for the benefit of readers
on ascii terminals.  A copy of this with fonts is available on request.


Defmethod should support two syntaxes:

General syntax:    (defmethod generic options... (lambda-list...)
		     declarations...
		     body...)

Classical syntax:  (defmethod (generic type options...) (lambda-list...)
		     declarations...
		     body...)

The classical syntax is exactly equivalent to the following expression
in the general syntax:
	 (defmethod generic options... ((self type) lambda-list...)
	   declarations...
	   (with (self)
	     body...))
The classical syntax is included for conceptual compatibility with the
classical methods of Smalltalk and Flavors and to increase the conciseness
of programs that use this common style.  We think the support of classical
syntax will make the language simpler and more natural for new users.
Classical syntax is recognized when the first subform of defmethod is a
list whose car is not SETF.

generic is the name of a generic function; either a symbol or a list
of two elements, the symbol SETF and a symbol that names another generic
function.  (In Symbolics' implementation, a list of LOCF and the name
of another generic function will also be allowed.)

options... are zero or more non-nil atoms that specify the particular kind
of method being defined, e.g. :before and :after for daemon methods.  These
are part of the name of the method (see discussion below).  Typically the
options are symbols, but applications exist that require numbers as
options.  I don't see any harm in allowing arbitrary atoms as options.  The
semantics of the options depends on the method-combination type.  These
options are not the same as the options in CommonLoops defmeth; see
discussion below.  I'm open to suggestions for a better word than "option"
as the name of this, but haven't come up with anything yet.

lambda-list... is a defun-style lambda list, possibly with type qualifications.
A type qualification is a list (variable type) where a variable name would
be expected.  As in defmacro (CLtL p.146) a type qualification may only be
used where ordinary lambda-list syntax does not allow a list; thus extra
levels of parentheses must be used when type-qualifying &optional and &key
parameters.

declarations... are zero or more DECLARE forms and/or documentation strings.
Certain declarations have specific meaning to defmethod and can be used
here even though they cannot be used in the body of a defun.  (See list below.)

body... is a sequence of zero or more forms as usual.  The body forms are
enclosed in an implicit block whose name is generic, or (second generic) if
generic is a list.

The current list of declarations that have special meaning to defmethod is
as follows.  [We need to decide if these are really in the given packages.]
None of these declarations would be common in code written by the average
user, but they are provided for the sake of extensibility.
 - (:discriminator-class class-name)
   specifies the class of the discriminator meta-object for the generic
   function.  It is an error for a defgeneric and a defmethod, or two
   defmethods, for the same generic function to specify different
   discriminator-classes.
 - (:method-class class-name)
   specifies the class of the method meta-object.
 - (flavor:inhibit-arglist-checking)
   prevents warning that the method's lambda-list is not consistent with
   the generic function's lambda-list.  [I need to check why New Flavors
   has this and whether this should be in the standard.]
 - (flavor:solitary-method)
   the discriminator function should optimize space rather than time when
   this method is the only method for its generic function.
   [Perhaps this should be a defgeneric option instead.]


What I don't like about PCL's present DEFMETH syntax

PCL presently allows two syntaxes for defmeth:
(defmeth generic (lambda-list...) body...)
(defmeth (generic options...) (lambda-list...) body...)

options are used for three different things in PCL:
(1) Options like :before and :after that are part of the name of the method.
(2) (:setf variable) which specifies that this is a setf-method and also
specifies the name of the variable that gets bound to the new value to be
stored (the value of the second subform of setf).
(3) The meta-options (:discriminator-class class-name) and
(:method-class class-name) that control the classes of related meta-objects.

The problems with this are:
 - Options that don't affect the identity of methods (3) are mixed in
   among options that do affect the identity of methods (1,2).  The
   variable name in the :setf option does not affect the identity of
   the method, but the presence of the :setf option does.  (See the
   discussion of method naming and identity mailed separately.)
 - The name of one parameter is outside the lambda-list (2).
 - The generic function name at the front of the defmeth form for a setf
   method (2) is not the actual generic function that is implemented
   by this method.

The advantage of doing setf methods this way is that it is less awkward
when there is an &rest argument, but we think that case is rare and this
advantage is less important than the problems listed above.  Thus we propose
separating the options from the declarations; putting the setf parameter
name together with the rest of the parameters; and using a different
generic function name for setf methods.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 23:42:30 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 20:39:10 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 20:38:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72530;
 Tue 2-Sep-86 23:37:52 EDT
Date: Tue, 2 Sep 86 23:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Naming and Identity Proposal
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860902233747.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

The following is how I think the concept of the names and identities
of methods should be made precise.  It has not been completely converted
from a description of how New Flavors works to a description of
what I think the Common Lisp standard should say, but I think it is
useful to mail it out in its present form for comments.  This proposal
is related to the defmethod syntax proposal I am also mailing out, but
I think the discussion of the two proposals will be independent enough
that it is better to consider them separately.

I've taken the fonts off of the following for the benefit of readers
on ascii terminals.  A copy of this with fonts is available on request.


Each method has a name, which distinguishes it from all other methods.  The
key property of these names is that when two defmethod forms with the same
name (according to the EQUAL function) are evaluated, the second defmethod
replaces the method defined by the first defmethod, rather than defining a
second method.  Thus the identity of a method is its name.

A method name contains the following information.  Changing any one of
these items changes the identity of the method, and nothing else affects
the identity of the method.
  - type of method
  - generic function name
  - type specifiers and positions for discriminating arguments
  - method options, e.g. :before

A method name is a list (method-type generic arg-types . options).  In an
implementation that has function-specs, these lists can be used as
function-specs to access the method's definition, trace it, and so forth.
In other implementations I guess there is no way to perform those operations.

The set of possible method-types should be extensible.  In Flavors, a
method-type is one of the following symbols (all in the flavor: package):
  - method -- all methods defined with defmethod.
  - whopper -- methods defined with defwhopper.  Whoppers use a different
    method type from ordinary methods, rather than using a keyword in the
    options, in order to leave the defmethod options completely under
    the control of the method-combination type and avoid reserved words.
  - wrapper -- methods defined with defwrapper or defwhopper-subst.
  - combined -- internally generated combined methods.
  - read/write/locate-instance-variable -- instance-variable accessors.
    Accessors are different from ordinary methods because they are defined
    differently and implemented in a special efficient way.  There is one
    method-option, the name of the instance-variable.
  - special-instance-variables -- internal special-variable binding wrapper.
  - defun-in-flavor -- not a method, but some routines in Flavors are generic
    enough that they work for both methods and in-flavor functions.
The set of possible method-types in the standard will be smaller, but
extensible.  I think this method-type is independent of the class of the
method object, because changing that class should not change the method's
identity.

The type specifiers and positions for discriminating arguments can be
encoded as a list, one for each argument, with T placeholders for
non-discriminating arguments.  To save space trailing T's can be omitted
and if the list contains one element, a symbol, the symbol can stand alone.

That does not permit discriminating on keyword arguments.  A more general
encoding that could be used is a list of argument descriptors.  Each
argument descriptor is a list of two elements: an argument position and a
type specifier.  An argument position is either an integer for a positional
argument (0 means the first argument) or the keyword of a keyword argument.
To reduce this encoding to canonical form, so encodings can be compared
with EQUAL, remove argument descriptors whose type specifier is T and sort
the remaining descriptors so that all positional arguments precede all
keyword arguments, positional arguments are sorted in increasing numerical
order, and keyword arguments are sorted in increasing alphabetical order.
If the result is ((0 type)) and type is a symbol, use type alone as the
encoding (just to save space in this common case).

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 23:29:27 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 20:26:05 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 20:25:52 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72527;
 Tue 2-Sep-86 23:24:51 EDT
Date: Tue, 2 Sep 86 23:24 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Method Selection proposal
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860902232427.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

Here are the rules that explain what happens when there are methods that
discriminate on optional or keyword arguments.  In this case method
selection can depend on arguments that are defaulted, rather than supplied
explicitly to the generic function.

(1) The generic function is called with some arguments.

(2) The value of each argument used for discrimination is determined.  If
there are unsupplied optional or keyword arguments that are type-qualified
with a type other than T in the lambda-list of any method for this generic
function, the value of the argument is determined by evaluating a default
value form taken from a defmethod or defgeneric.  It is an error for the
result to depend on which defmethod or defgeneric supplies the default
value form that is evaluated.  Programming environments are encouraged to
warn at compile and/or load time when default value forms are not equal.

(3) The appropriate method or methods are selected based on the argument
values determined in step 2.

(4) Each method is called with the original arguments of the generic
function.  It is an error for the number of arguments or the keyword names
not to match, just as with any function call.  Programming environments are
encouraged to warn at compile and/or load time if the methods for a given
generic function, and the defgeneric if present, are not all consistent in
the arguments that they accept.  The minimum number of arguments, maximum
number of arguments (which can be infinite), and keyword names (when &key
is specified and &allow-other-keys is not) must be equal.

It is an error for default value forms for type-qualified arguments to have
side-effects.  These forms can be executed multiple times (once in step 2
and as many times in step 4 as there are methods that get invoked).  These
forms can be executed fewer times at the discretion of the implementation.
For example, if the value of the argument is not actually needed for
discrimination in step 2, because of the specificity of an earlier
argument, or if re-defaulting in step 4 is not actually required because
there is no supplied-p parameter, it is permissible to optimize out the
evaluation of the default value form.  When there are multiple unsupplied
arguments used for discrimination, the order of evaluation of the default
value forms is undefined.  Programming environments are encouraged to warn
at compile time if a default value form in a defmethod or defgeneric can be
proven to have side-effects.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 23:03:16 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 19:40:50 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 19:40:31 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72515;
 Tue 2-Sep-86 22:39:28 EDT
Date: Tue, 2 Sep 86 22:39 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Progress So Far    
To: commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860829-192053-115@Xerox>
Message-ID: <860902223920.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 29 Aug 86 18:20 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    We plan to have the pre-draft of part 1 ready by the end of next week,
    and we will be sending that out. The idea is to have the whole of the
    part written so that a critique a something intended to be self-consistent
    can be made.

On the 26th Gregor said that we would be seeing daily drafts of this.  I'm not
very happy about "daily" turning into "the end of next week".  It's difficult
to cooperate with someone who won't talk.  Perhaps the extra consistency of
the draft will be worth the wait, but on the other hand perhaps the lack of
midcourse correction will cause you to waste a lot of time.

We'll be sending you bits and pieces of what we have as soon as we have it.
We'll try to keep separate issues in separate messages so that the mail is
easier to sort out.  The first batch will be mailed out tonight.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 21:55:01 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 18:33:38 PDT
Date: 2 Sep 86 18:33 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Minutes of our 8 Aug 86 meeting
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 8 Aug 86 23:31 EDT
To: CommonLoopsCore↑.pa@Xerox.COM 
Message-ID: <860902-183338-1341@Xerox>

There seems to be a lot in common between whoppers and the Loops use of
run-super. I have been trying to work out the appropriate relation
between run-super and daemon method combination with whoppers.
Whoppers are not expressible in the method combination language.
Neither is run-super.  I believe both could be fixed by adding a new
standard form corresponding to call-component-methods.

call-first-with-continuations <list-of-methods>

calls the first on the list, and makes available the list for the called
method.  If run-super is invoked in the method, it does:

(call-first-with-continuations (cdr list-of-methods))


If continue-whopper we spell "run-super", and whopper as ":around", then
super-daemon method combination (allowing run-super in primary methods)
is  defined by something like

(define-method-combination :super-daemon
  ((around "around" :every :base-flavor-last (:around))
   (before "before" :every :base-flavor-last (:before))
   (primary "primary" :every :base-flavor-last (:primary))
   (after "after" :every :base-flavor-first (:after)))
(call-first-with-continuations 
   '(,. around
      (multiple-value-prog2 
         (call-component-methods , before)
         (call-first-with-continuations ',primary)
         (call-component-methods ,after)))

This makes run-super be a feature of method-combination with
call-first-with-continuations only.  It has the same model as it has in
Loops and Smalltalk, and computable at method-definition time.

I have not thought through a best implementation.  An obvious one is to
bind the continuation list of functions in a special variable.

Does this make sense?  It seems to provide a single coherent story. 



-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 21:54:47 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 18:21:44 PDT
Return-Path: <Moon@ALDERAAN.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ALDERAAN.SCRC.Symbolics.COM ([192.10.41.109]) by
 Xerox.COM ; 02 SEP 86 18:21:28 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 1780; Tue
 2-Sep-86 20:50:10 EDT
Date: Tue, 2 Sep 86 20:49 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: [Guy Steele <gls@THINK-AQUINAS.ARPA>: Common LOOPS]
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860829162702.3.DLW@CHICOPEE.SCRC.Symbolics.COM>
Message-ID: <860902204953.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Fri, 29 Aug 86 16:27 EDT
    From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>

    I agree with your analysis and this general approach, if we're going to
    allow discimination on optional arguments.  I like that there is a clear
    two-step process, in which first the values of the unsupplied arguments
    are determined, and then the normal discrimination algorithm is applied.
    This is important, because normal discimination is hairy enough as it
    is, and most important because it's something that can be extended and
    altered, and it must be kept clear how a customized discimination
    function acts in the presence of optional arguments.  (Not to mention
    keyword arguments.)

Unfortunately, as far as I can tell from the sketchy documentation Gregor
sent us on 29 July, when you make a customized discrimination function it
completely replaces the normal discrimination function, and thus it could
do something completely different in the face of optional arguments.  I can't
be sure either that I have interpreted the sketchy CommonLoops documentation
correctly or that we want the new Common Lisp standard to use exactly the
same meta-object protocol as Common Loops in this respect.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 21:14:09 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 17:07:02 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: commonloopscore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 17:06:19 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72457;
 Tue 2-Sep-86 20:05:22 EDT
Date: Tue, 2 Sep 86 20:11 EDT
From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>
Subject: Progress So Far    
To: RPG@SAIL.STANFORD.EDU, commonloopscore↑.pa@Xerox.COM
In-Reply-To: <860829-192053-115@Xerox>
Message-ID: <860902201126.8.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: 29 Aug 86 18:20 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    We have tentatively decided that generic functions are objects
    which are first-class objects and which are FUNCALLable. This admits
    closures being made specializable. 

Presumably, then, typically a generic function would be the definition
of the symbol that you use in defgeneric and defmethod.  This sounds
right to me, and I believe it's consistent with what we've been using.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 21:14:00 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 17:06:56 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 17:03:40 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72456;
 Tue 2-Sep-86 20:02:35 EDT
Date: Tue, 2 Sep 86 20:08 EDT
From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>
Subject: Let's define our terminology
To: skeene@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860902174023.6.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <860902200841.7.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: Tue, 2 Sep 86 17:40 EDT
    From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>

    Instance  Every object is an instance of some class.  The term instance is
	      used to describe the instance/class relationship of the object to
	      its class.

I'm still a bit uncomfortable about this broad definition of the term
"instance", since it means that any Lisp object is an instance.  Observe
how this works in your next definition:

    Slots     Slots define the structure of instances of the class, as do
	      DEFSTRUCT slots.  When defining a new class, you specify the
	      slots of the class.  A slot is a place where you can store data
	      inside an instance of a class.

The phrase "an instance of a class" has been defined to mean "a Lisp
object".  So in order for this to be fully consistent with the
definition of "instance", we must say that the term "slot" includes
elements of arrays, since arrays are instances, etc.  We must also say
that conses have two "slots" each.  Do we really want our terminology to
say these things?  Every time you write something about slots, you'll have
to be careful to make sure it's true of the cdrs of conses.

    Super-class
	      Each class can include other classes in its definition; the newly
	      defined class inherits structure (slots) and behavior (methods)
	      from its super-classes.  This is the primary mechanism for
	      program modularity.  A typical mode of use is to define several
	      basic classes and combine them to achieve specialized behavior.

It should be explicit whether this term is transitive or not: does it
include only immediate parents, or all ancestors?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 19:16:54 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 15:45:11 PDT
Date: 2 Sep 86 15:36 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Let's define our terminology
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 2 Sep 86 17:40 EDT
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860902-154511-1144@Xerox>

I don't like the name Classes because it stresses only one aspect of the
system.  An alternative when we change the name would be "Common Lisp
Object System" which could be acronymed to CLOS or Close if we add
environment stuff. 

One could even talk about the emporers new CLOS.

Thank you for the work on the glossary.  We have been working on one as
well.  We will try to fold in your ideas and text.  A pre-draft of
chapter one is coming soon, as RPG mentioned
 
-- danny
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 19:16:19 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 15:19:27 PDT
Return-Path: <dmaclaug@j.bbn.com>
Received: from J.BBN.COM ([8.0.0.14]) by Xerox.COM ; 02 SEP 86 15:08:27
 PDT
Date: Tue, 2 Sep 86 16:53:44 EDT
From: Dawn Clarke MacLaughlin <dmaclaug@j.bbn.com>
To: commonloops.pa@Xerox.COM
Subject:  Add to mailing list
Message-ID: <860902-151927-1110@Xerox>

Please add KAnderson@BBN to this mailing list.  Sorry for
sending this message to everybody but I don't know the right place
for sending requests (I tried commonloops-request.pa but it failed).
Thanks.

Dawn MacLaughlin
∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 18:24:05 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 86 14:44:57 PDT
Return-Path: <skeene@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 14:44:30 PDT
Received: from JUNCO.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72379;
 Tue 2-Sep-86 17:40:40 EDT
Date: Tue, 2 Sep 86 17:40 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Let's define our terminology
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860902174023.6.SKEENE@JUNCO.SCRC.Symbolics.COM>


I think it would be useful to define the terminology we are using for
"the Common Lisp object-oriented programming standard".   This will make
it easier for us to communicate with each other long-distance because we
can say exactly what we mean; it will also make it easier to choose
function and option names consistently, and to write the eventual
specification.

The most important term to define is the name of the standard we are
working on.   Until we name the standard, it's pretty difficult to
compare existing systems such as CommonLoops and Flavors with the
standard.  I agree with Dave's earlier message that we can't name the
new thing either CommonLoops or Flavors, because it isn't either of
them.   I like the name "Classes".   We haven't heard what you people
think of this idea, so I'm going to use Classes as the name of the
standard thing for now.

This Glossary is a first attempt at pinning down the terminology.   I
can update it with comments from you, and add new terms to it as we go
along.    Notice the last part of it is "Terms We Suggest Not Using".  



                                 GLOSSARY

This section defines the terminology used in Classes.  Classes is the
interim name for the proposed Common Lisp standard object-oriented
programming system.

Object    Any Lisp datum, such as a number, a character, or an instance.

Class     An object that describes the structure and behavior of a set of
          objects.  All Lisp objects have a class, and can be queried for
          the class by using the CLASS-OF function.

Instance  Every object is an instance of some class.  The term instance is
          used to describe the instance/class relationship of the object to
          its class.

Slots     Slots define the structure of instances of the class, as do
          DEFSTRUCT slots.  When defining a new class, you specify the
          slots of the class.  A slot is a place where you can store data
          inside an instance of a class.

Slot accessor
          A generic function that accesses the value of a slot.  When
          defining a class, you can specify that a slot should be
          accessible for reading and/or writing.

Meta-class
          Each object has a class.  A class itself is an object which has a
          class.  The meta-class of an object is the class of the class of
          the object.

          A meta-class itself is an object, which has a class.  The term
          meta-class is used to refer to a class that is suitable for being
          the class of a class.  An instance of a meta-class is a class.

Generic Function
          A function that has methods defined for it.

Method    An object that describes how to perform a generic function for a
          given set of arguments.  One or more methods are chosen according
          to the classes of the arguments to the generic function; the
          choosing of the method or methods is called dispatching.

Discriminator
          An object that holds all the methods defined for a generic
          function.  The discriminator contains the code that performs the
          dispatching, which is based on the arguments given to the 
          generic function. 	

          Classical method
                 The dispatching is based on the class of the first
                 argument to the generic function (that is, on the class of
                 a single object).

          Multi-method
                 The dispatching is based on two or more arguments to the
                 generic function (that is, on the class of several
                 objects).

          Individual method
                 The dispatching is done based on the identity of the
                 argument itself.  This allows you to write a method for a
                 particular Lisp object.

          SETF method
                 A method for a SETF generic function.  A SETF generic
                 function is the function that is called when you evaluate
                 an expression such as:  (SETF (G ...) VALUE), where G is
                 any generic function.  One example of G is a slot
                 accessor.

Super-class
          Each class can include other classes in its definition; the newly
          defined class inherits structure (slots) and behavior (methods)
          from its super-classes.  This is the primary mechanism for
          program modularity.  A typical mode of use is to define several
          basic classes and combine them to achieve specialized behavior.






                        TERMS WE SUGGEST NOT USING

Selector  Is this term really necessary?  Isn't the term "generic function"
          the same thing?  We noticed that Gregor's spec uses this term
          three times, and it looks like "generic function" would be just
          as clear in those cases.


∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 16:33:25 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 02 SEP 86 12:35:55 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 11:05:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72118;
 Tue 2-Sep-86 13:48:19 EDT
Date: Tue, 2 Sep 86 13:48 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Test message
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860902134808.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

This is a test message, please ignore it.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 16:33:14 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 02 SEP 86 12:34:24 PDT
Return-Path: <@SAIL.STANFORD.EDU:snyder%hplsny@hplabs.HP.COM>
Redistributed: CommonLoopsInternal↑.x
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 02 SEP 86
 10:37:24 PDT
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 2 Sep 86
 09:48:35 PDT
Received: from hplsny by hplabs.HP.COM ; Tue, 2 Sep 86 09:46:44 pdt
Received: by hplsny ; Tue, 2 Sep 86 09:47:18 pdt
From: Alan Snyder <snyder%hplsny@hplabs.HP.COM>
Message-Id: <8609021647.AA27100@hplsny>
Date: Tue, 2 Sep 86 09:47:07 PDT
Subject: nested class definitions
To: cl-object-oriented-programming@su-ai.ARPA
X-Mailer: NMail [$Revision: 2.6 $]

Has anyone thought about nested class definitions (should we support them and
what should they mean)?  Given that Common Lisp is (claimed to be) a lexically
scoped language, we should consider this issue.  The Simula people contend
that lexically scoped classes are useful, both for "privacy" and for
dynamically generated classes (analogous to closures, which are dynamically
generated functions).  An example of the latter is creating a new "token"
class to represent the tokens of one specific "grammar" (by a parser
generator).

If we don't want to tackle this issue now, we should make nested classes
illegal to give us room for future extensions.

  Alan

-------

∨
Received: from Xerox.COM by AI.AI.MIT.EDU  2 Sep 86 12:23:29 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 02 SEP 86 09:18:25 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 02 SEP 86 07:54:27 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 71903;
 Tue 2-Sep-86 10:51:49 EDT
Date: Tue, 2 Sep 86 10:57 EDT
From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>
Subject: Re: declaring the name of slot accessors
To: Gregor.pa@Xerox.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <860828-113939-236@Xerox>
Message-ID: <860902105746.2.DLW@CHICOPEE.SCRC.Symbolics.COM>

I think I see what you're trying to do here.  The advantage of this
syntax is that you only need one option, namely :accessor-prefix, rather
than having two options, one used for putting a uniform prefix onto all
the accessor names and another used for assigning specific names to
specific accessors.  Have I correctly induced the motivation?

Note that you have to make a rule saying that any number of options of
the form
  (:accessor-prefix xxx yyy)
are allowed, but only one option of the form
  (:accessor-prefix xxx)
is allowed.  This is a reflection of the fact that the two options that
I referred to above are not syntactically completely symmetrical.

Another attribute of this proposal is that a specific name for an
accessor must have the name of the slot as its suffix: there's no way to
have a slot named x and an accessor for it named foo-y, unless you code
up the accessor yourself.  I'm not sure whether I think this is a
problem or not.

I would tend to prefer having two separate options, but I don't think I
can offer any very strong argument.  I tend to prefer keeping separate
things separate, instead of "overloading" things, and this proposal just
slightly edges into the realm of "overloading".  I admit that this is
mainly a matter of taste and I don't have any kind of strong argument.

I also still tend to favor names such as "readable" and "writable"
rather than "accessible" or "accessor", because it's not clear from the
word "access" whether "access" means just reading, or both reading and
writing.  I don't care precisely what words are used as long as the
words themselves specify clearly whether we're talking about reading or
writing.

By the way, do we really want to introduce a new feature for :read-only
slots?  Presumably this means that (setf (get-value 'r-o-slot) x) is
defined to signal an error, or something like that?  (This isn't on the
topic of declaring the name of slot accessors.)  It sounds like a
reasonable idea, but let's not slip it in without considering it
explicitly.  From an implementation point of view, it seems that the
error could be detected at compile time for almost all cases (except for
debugging tools and things like that, in which high speed doesn't
matter).  (I'm not an implementation-meister so I'm not confident that
I'm right about this.)

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 29 Aug 86 22:23:40 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 29 AUG 86 19:20:53 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 29 AUG 86
 19:20:40 PDT
Date: 29 Aug 86 18:20 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Progress So Far    
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860829-192053-1150@Xerox>


As you all know, Linda DeMichel, Gregor, and I - sometimes with
Danny Bobrow - have been meeting to get the first pre-draft of
the specification written. The new document is in two parts,
the first being the user-level functions and the second being the
meta-object protocol.

We have made reasonably good progress on the first chapter and have
a start on the second. Primarily we have been working on the wording
of definitions of terms, such as `generic function' and `metaclass.'

Also, we have worried a little about the ontology of generic functions.
The current implementation of PCL admits the term `generic function' only
in the sense that various aspects of the code and data structures taken
together form a set of things that could be called a `generic function.'

We have tentatively decided that generic functions are objects
which are first-class objects and which are FUNCALLable. This admits
closures being made specializable. 

We have also made a pass at DEFCLASS syntax.

The class precedence list is being defined to follow the New Flavors
rules.

We are making a pass through the declarative method combination
stuff, using New Flavors as the model. 

We plan to have the pre-draft of part 1 ready by the end of next week,
and we will be sending that out. The idea is to have the whole of the
part written so that a critique a something intended to be self-consistent
can be made. Then we wil finish up part 2, which is, in some ways, easier
to deal with.
			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 29 Aug 86 18:29:47 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 29 AUG 86 14:31:36 PDT
Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 29 AUG 86 14:28:04 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 71110;
 Fri 29-Aug-86 16:21:20 EDT
Date: Fri, 29 Aug 86 16:27 EDT
From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>
Subject: Re: [Guy Steele <gls@THINK-AQUINAS.ARPA>: Common LOOPS]
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860828164226.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <860829162702.3.DLW@CHICOPEE.SCRC.Symbolics.COM>

I agree with your analysis and this general approach, if we're going to
allow discimination on optional arguments.  I like that there is a clear
two-step process, in which first the values of the unsupplied arguments
are determined, and then the normal discrimination algorithm is applied.
This is important, because normal discimination is hairy enough as it
is, and most important because it's something that can be extended and
altered, and it must be kept clear how a customized discimination
function acts in the presence of optional arguments.  (Not to mention
keyword arguments.)

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 28 Aug 86 17:46:39 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 AUG 86 14:29:05 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 28 AUG 86 14:11:00 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 70404;
 Thu 28-Aug-86 17:10:01 EDT
Date: Thu, 28 Aug 86 17:09 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Compile Time Class Definition
To: CommonLoopsCore↑.PA@Xerox.COM
References: <8608281952.AA07618@hplabsc>
Message-ID: <860828170955.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

The referenced message was sent by Jim Kempf to the commonloops.pa@Xerox
mailing list.  It raises an issue that we should discuss, although I
suspect the answer to his problem is to make available the underlying
primitive that in Symbolics Common Lisp is named FDEFINE, to separate the
act of defining a particular method specifier to call a particular function
from the act of defining the body of that function.

New Flavors keeps separate compile-time and run-time environments
(bindings of names to meta-objects: flavor names to flavors, method
names to methods, and generic function names to generic functions).

Actually the environments aren't completely separate; if a name has no
binding in the compile-time environment, and does have a binding in the
run-time environment, and the run-time binding was not established by
a file that was compiled as part of the compilation that established the
compile-time environment, then the run-time binding is inherited by the
compile-time environment.

This works moderately well, certainly much better than effectively
putting eval-when compile around things, which is what Old Flavors did.

Should the standard for Common Lisp classes incorporate this type of
mechanism?  Is it possible to define it in a way that is independent
of unwarranted assumptions about the programming environment?  (Bobrow
should be in a good position to think about the latter question, having
done Definition Groups, a different model from files).

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 28 Aug 86 17:46:28 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 AUG 86 14:24:42 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 28 AUG 86 13:57:47 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 70388;
 Thu 28-Aug-86 16:56:44 EDT
Date: Thu, 28 Aug 86 16:56 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: MetaClass Discriminators?
To: CommonLoopsCore↑.PA@Xerox.COM
In-Reply-To: <8608281953.AA07624@hplabsc>
Message-ID: <860828165639.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 28 Aug 86 12:53:33 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    In the process of implementing a CommonObjects interface to
    CommonLoops, I came across the need for a new kind of discriminator
    type. For lack of a better term, I'll call it a "metaclass discriminator".
    What a metaclass discriminator would do is to discriminate on the
    *metaclass* of the first argument, rather than on its class. This
    is useful for methods which should be executed on all objects of
    a particular metaclass, but which the class should still be free to
    specialize. An example from the CommonObjects interface are universal
    methods, which every class gets a unique set of. These could be
    simulated in CommonLoops by having a metaclass discriminator with
    the method on it, and have the metaclass keep track of classes
    which have undefined the method.

I think this is an example of discriminating on a predication, rather than a
class.  I have some thoughts on how to think clearly about discriminating
on predications that I haven't sent you yet.  I guess I'm waiting for Sonya
to get back from vacation and help me write my various notes up in a coherent
form.  I'm pretty sure I completely understand discriminating on predications
now, but what I'm not sure about is whether or not the feature belongs in the
standard at this time.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 28 Aug 86 17:46:20 EDT
Received: from Salvador.ms by ArpaGateway.ms ; 28 AUG 86 13:48:38 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.pa
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 28 AUG 86 13:43:40 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 70376;
 Thu 28-Aug-86 16:42:37 EDT
Date: Thu, 28 Aug 86 16:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: [Guy Steele <gls@THINK-AQUINAS.ARPA>: Common LOOPS]
To: CommonLoopsCore↑.pa@Xerox.COM
In-Reply-To: <860827-111911-1310@Xerox>
Message-ID: <860828164226.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 27 Aug 86 11:18 PDT
    From: Gregor Kiczales <Gregor.pa@Xerox.COM>

    As near as I can tell, Guy's interpretation of optional arguments is the
    same as Proposal 2.

I don't think so.  Proposal 2 is that an unsupplied optional argument
does not match any type specifier whatever.  Steele suggests
	(defmethod foo (a b &optional (c x) (d y)) body)
is simply an abbreviation for
	(defmethod foo (a b) (let ((c x) (d y)) body))
	(defmethod foo (a b c) (let ((d y)) body))
	(defmethod foo (a b c d) body)
and doesn't say anything about what happens if a type specifier is
attached to an optional argument.  I assume he would suggest that
	(defmethod foo (a b &optional ((c type) x)) body)
is simply an abbreviation for
	(defmethod foo (a b) (let ((c x)) body))
	(defmethod foo (a b (c type)) body)
and in this case we see that (foo arg1 arg2) invokes this method
even though there was a type specifier attached to the unsupplied
optional argument.  Thus Steele's proposal appears to be that an
unsupplied optional argument matches all type specifiers, exactly
the opposite of proposal 2.

I think the rule that the argument list for all the methods of a generic
function must have the same shape is quite important for
understandability, so Steele's proposal in its current form won't fly on
those grounds, but that should be fairly easy to fix.  But let's look
at this more closely, maybe the fact that Steele's proposal and Proposal
2 are opposites shows that they are both wrong:

Perhaps it would be better for
	(defmethod foo (a b &optional ((c type) x)) body)
to be an abbreviation for
	(defmethod foo (a b)
	  (let ((c x))
	    (assert (typep c 'type))
	    body))
	(defmethod foo (a b (c type)) body)
On the other hand, perhaps if (not (typep x 'type)) then the method
should not have been selected at all.  To take a specific example,
think about
        (defmethod draw ((object pinwheel)
			 &optional ((stream window) *standard-output*))
	  body)
Obviously (draw a-pinwheel) should invoke this method if and only
if the current value of *standard-output* is a window.  What else could
the writer of this method have meant?

I suspect that a different approach is called for.  What you're trying
to accomplish is to allow method selection based on optional arguments
to generic functions.  What you really care about is the interface that
the caller of the generic function sees, and a secondary consideration
is what is the best syntax for the method writer to express this.  It's
a lot easier to understand if the model is that the discriminating
function does the method selection based on the actual arguments after
defaulting.  The big problem occurs when different methods have
different default value forms for an optional argument that is used for
discrimination.  I see two approaches to fixing this.  One is to require
that defgeneric be used to specify the default value form for any
optional argument that is used for discrimination.  These arguments
would be defaulted by the discriminating function and would appear as
required arguments to the methods.  This has modularity problems and
doesn't generalize well to &key.

The other approach is to allow methods to have type specifiers on
optional arguments, but require that whenever an optional argument is
used for discrimination, all default value forms (in both defmethod and
defgeneric) must be equal.  This is a generalization of the requirement
that all methods have the same arglist shape.  This generalizes to &key
very nicely and is easy to implement.

When there are two &optional arguments and the second is used for
discrimination but the first is not, are different methods allowed to
have different default value forms for the first?  This seems desirable,
but is difficult to implement without either evaluating default value
forms twice (once in the discriminating function and again in the method)
or recognizing this situation and transforming the methods' arglists
to use &key.

. . . . .

I can't figure out how you reconcile proposal 2 with the fact that an
untyped argument is the same as a typed argument with type T.  (This is
a fact, isn't it?  I can't find any clear enough documentation to verify
or falsify it)

    From: Ken Kahn <Kahn.pa@Xerox.COM>
    What do people think of &rest
    and &key as in Guy's proposal?  I think keywords combined with the
    ability in defgeneric to give the argument specificity ordering aught to
    work fine.  I feel less comfortable with &rest.  It gets into a whole
    unexplored area of having type specifications on parts of lists.
    
Discriminating on &key arguments seems straightforward.

I don't see any immediate applications for discrimination on &rest parameters
so I suggest it would be better to disallow that for the time being.  Nothing
rules out adding it as an extension later.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 28 Aug 86 16:10:51 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 AUG 86 13:00:04 PDT
Return-Path: <kempf%hplabsc@hplabs.HP.COM>
Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 28 AUG 86
 12:55:08 PDT
Received: from hplabsc by hplabs.HP.COM ; Thu, 28 Aug 86 12:53:16 pdt
Received: by hplabsc ; Thu, 28 Aug 86 12:53:33 pdt
Date: Thu, 28 Aug 86 12:53:33 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8608281953.AA07624@hplabsc>
To: commonloops.pa@Xerox.COM
Subject: MetaClass Discriminators?

In the process of implementing a CommonObjects interface to
CommonLoops, I came across the need for a new kind of discriminator
type. For lack of a better term, I'll call it a "metaclass discriminator".
What a metaclass discriminator would do is to discriminate on the
*metaclass* of the first argument, rather than on its class. This
is useful for methods which should be executed on all objects of
a particular metaclass, but which the class should still be free to
specialize. An example from the CommonObjects interface are universal
methods, which every class gets a unique set of. These could be
simulated in CommonLoops by having a metaclass discriminator with
the method on it, and have the metaclass keep track of classes
which have undefined the method.

Alternatively, if a means of having a discriminator exclude certain
classes could be incorporated, when a class undefines the universal
method, it could simply be put on the argument selector exclusion
list.

Perhaps there are already facilities in CommonLoops for achieving
these two pieces of functionality?

		Jim Kempf	hplabs!kempf
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 28 Aug 86 16:10:35 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 AUG 86 12:56:23 PDT
Return-Path: <kempf%hplabsc@hplabs.HP.COM>
Received: from hplabs.HP.COM ([192.5.58.10]) by Xerox.COM ; 28 AUG 86
 12:54:20 PDT
Received: from hplabsc by hplabs.HP.COM ; Thu, 28 Aug 86 12:52:42 pdt
Received: by hplabsc ; Thu, 28 Aug 86 12:52:59 pdt
Date: Thu, 28 Aug 86 12:52:59 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8608281952.AA07618@hplabsc>
To: commonloops.pa@Xerox.COM
Subject: Compile Time Class Definition

During the implementation of a CommonObjects interface to
the CommonLoops kernel, I came across the following problem.
CommonObjects types have associated with them a set of 
"universal methods" of which each type gets a unique set
when the type is defined. Examples are :print, :describe, etc.
The methods are unique to a type so that a type can undefine
them or redefine them in a type specific way, if the universal
behavior is somehow inadequate.

The type definition macro generates code which looks something
like this:

	(eval-when (load eval)
          (load-time-define-type <args>)
	  (defmeth universal-method-1 <args>
		<body>
          )
	  (defmeth universal-method-2 <args>
		<body>
	  )
	        .
		.
		.
       )

which seemed to be the obvious way on the face of it to generate
the methods.

Problem is, defmeth requires a full class definition at compile time.
This means that the load-time-define-type (which installs the new
Common Loops class definition) needs to be executed at compile time
as well, if the method definitions are to macroexpand correctly.

An alternative solution would have been to generate the universal
methods as default Common Loops methods, which would take any
Common Objects object as the first argument. This solution works
well if the Common Objects type needs to redefine the universal
method, but doesn't work so well if the user tries to undefine
the default method on a type. In that case, the obvious (but
definitely kludgy) solution is to define a method whose first
argument is specialized to the undefining type, with the method
signalling an error saying that the method is really undefined.

Fully defining a class at compile time could also have serious
consequences for interactively making changes to the programming
environment, since redefining a class used in a compiler may
cause the compiler to break.

An alternative solution to the immediate problem might be "metaclass
discriminators", but that is the subject of another note.

Any comments?
		Jim Kempf		hplabs!kempf
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 28 Aug 86 16:10:22 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 AUG 86 12:52:22 PDT
Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
 Xerox.COM ; 28 AUG 86 12:51:56 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
 ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 70334;
 Thu 28-Aug-86 15:50:53 EDT
Date: Thu, 28 Aug 86 15:50 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: A name for this thing
To: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860828155049.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

We should hand something out at the OOPSLA conference that explains
what we're doing and what our goals are, and contains whatever early
draft proposal we have by then.  In order to talk about what we're
doing we need to have a name for it.  I think now is a good time
to pick a name.

I don't think it should be called after its antecedents, CommonLoops
and New Flavors, because it isn't either of those.  It partakes of
both.  Furthermore Loops sounds like it has something to do with
iteration and Flavors sounds like it has something to do with eating.
We need a different name, free of misleading connotations.

If we look at CLtL, there are chapters with names like "Symbols",
"Arrays", "Sequences", and "Structures".  Why not call this new thing
"Classes"?  This name seems to be parallel with the way Common Lisp is
already set up and named.  You define a structure with DEFSTRUCT; you
define a class with DEFCLASS, and so on.  I think the term "class"
is standard enough that no one will think we're talking about school.
When necessary to be more specific, we can call it "Common Lisp Classes"
to distinguish it from class systems for other languages.

So what we're designing is the class system for Common Lisp,
"Common Lisp Classes."  What do you think?

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 28 Aug 86 14:43:31 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 AUG 86 11:39:56 PDT
Redistributed: CommonLoopsCore↑.PA
Received: from Cabernet.ms by ArpaGateway.ms ; 28 AUG 86 11:39:39 PDT
Date: 28 Aug 86 11:39 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: declaring the name of slot accessors
In-reply-to: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>'s
 message of Mon, 25 Aug 86 22:40 EDT
To: DLW@QUABBIN.SCRC.Symbolics.COM
cc: CommonLoopsCore↑.PA@Xerox.COM
Message-ID: <860828-113956-2368@Xerox>

Here is another try at the right mix between convenience and
cleanliness in automatically generated accessors in defclass.

Example 1:  Define setf'able accessors for all the slots using the
"conc-name" "FOO-".

(defclass foo ()
  ((a 1)
   (b 2))
  (:accessor-prefix foo-))


Example 2:  Define setfable accessors for all the slots, the conc-name
for the slot a is FOO- for b it is BAR-

(defclass foo ()
  ((a 1)
   (b 2))
  (:accessor-prefix foo- a)
  (:accessor-prefix bar- b))

Example 3: Define setfable accessors for all the slots.  The conc-name
for a is FOO-.  For all the others it is BAR-.

(defclass foo ()
  ((a 1)
   (b 2)
   (c 3))
  (:accessor-prefix foo- a)
  (:accessor-prefix bar-))

The :non-setfable-accessor-prefix option works the same way, but
defines non-setfable accessors.

The :read-only option would still exist, but it affects the low-level
slot access code.  Not the generation of methods.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 15:47:01 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 12:44:24 PDT
Date: 27 Aug 86 12:44 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Steele's comment   
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 27 Aug 86
 12:07 PDT
To: RPG@SAIL.STANFORD.EDU
cc: commonloopscore↑.pa@Xerox.COM
Message-ID: <860827-124424-1411@Xerox>

    Yes, but it has the presentation advantage of being understandable.

At least when it arrived here, your message had no in-reply-to field.
As a result, I could not resolve the "it" to figure out what you meant
was more understandable.

If you mean Steele's presentation, that is something to think about
since his presentation violates the rule that the argument list for all
the methods of a generic function must have the same shape.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 15:11:22 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 12:07:51 PDT
Return-Path: <RPG@SAIL.STANFORD.EDU>
Redistributed: commonloopscore↑.pa
Received: from SAIL.STANFORD.EDU (SU-AI.ARPA) by Xerox.COM ; 27 AUG 86
 12:07:41 PDT
Date: 27 Aug 86 12:07 PDT
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Subject: Steele's comment   
To: commonloopscore↑.pa@Xerox.COM 
Message-ID: <860827-120751-1367@Xerox>

Yes, but it has the presentation advantage of being understandable.
			-rpg-

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 14:36:43 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 11:34:23 PDT
Date: 27 Aug 86 11:34 PDT
Sender: Kahn.pa@Xerox.COM
Subject: Re: [Guy Steele <gls@THINK-AQUINAS.ARPA>: Common LOOPS]
In-reply-to: Gregor Kiczales <Gregor.pa>'s message of 27 Aug 86 11:18
 PDT
To: Gregor.pa@Xerox.COM
cc: Kahn.pa@Xerox.COM, CommonLoopsCore↑.pa@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860827-113423-1329@Xerox>

Yes Proposal 2 is like Guy's proposal.  What do people think of &rest
and &key as in Guy's proposal?  I think keywords combined with the
ability in defgeneric to give the argument specificity ordering aught to
work fine.  I feel less comfortable with &rest.  It gets into a whole
unexplored area of having type specifications on parts of lists.


----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 14:35:27 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 11:33:04 PDT
Date: 27 Aug 86 11:31 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: Defclass should be approximately upwards compatible with
 Defstruct
In-reply-to: Ken Kahn <Kahn.pa>'s message of 27 Aug 86 09:32 PDT
To: Kahn.pa@Xerox.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Line-fold: NO
Message-ID: <860827-113304-1326@Xerox>

(defstruct foo (a 1) (b 2)) 

Would get turned into something like:

(defclass foo () ((a 1) (b 2)) (:accessor-prefix foo-))

    There is another criterion in designing defclass which seems to be getting
    too little attention. That is that people do write small programs and some
    people do not want to learn about every feature.

I agree that this is important and the we should have this as a design goal.

    This would argue, for example, that (:conc-name nil) is the default.

But I also think that defclass should encourage good programming style.  Since
no default value of conc-name is really right, we have leaned towards not having
a default value for conc-name.  If you want accessors, you say
(:accessor-prefix <conc-name>).
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 14:23:56 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 11:19:11 PDT
Date: 27 Aug 86 11:18 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Re: [Guy Steele <gls@THINK-AQUINAS.ARPA>: Common LOOPS]
In-reply-to: Ken Kahn <Kahn.pa>'s message of 27 Aug 86 09:41 PDT
To: Kahn.pa@Xerox.COM
cc: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860827-111911-1310@Xerox>

As near as I can tell, Guy's interpretation of optional arguments is the
same as Proposal 2.
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 12:46:16 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 09:43:24 PDT
Date: 27 Aug 86 09:41 PDT
Sender: Kahn.pa@Xerox.COM
Subject: [Guy Steele <gls@THINK-AQUINAS.ARPA>: Common LOOPS]
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Kahn.pa@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860827-094324-1190@Xerox>

The following is abbreviated message from Guy about discrimination on
&optional and &rest args.

     ----- Begin Forwarded Messages -----
Date: Wed, 14 Aug 85 11:59 EDT
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Subject: Common LOOPS
To: cl-object-oriented-programming@SU-AI.ARPA

I am delighted to learn that there will be a meeting during IJCAI-85 to
discuss
object-oriented programming in Common Lisp. ...

Yesterday I received in the mail a draft specification of Common LOOPS,
by
Bobrow, Kahn, Kiczales, Masinter, Stefik, and Zdybel. 
I have a couple of specific technical comments that you may want to take
into
account:

(1) ...


(2) Section II.I presents an example that purports to be an anomalous
case, but
I find it quite clear-cut.  The second method for FOO clearly cannot
accept
three arguments under any circumstances, and therefore is not eligible
to
handle a three-argument call.

I think that the semantics of &optional and &rest parameters are easily
dealt
with by viewing them as an abbreviation mechanism for multiple methods.

	(defmethod foo (a b &optional (c x) (d y)) body)

is simply an abbreviation for

	(defmethod foo (a b) (let ((c x) (d y)) body))
	(defmethod foo (a b c) (let ((d y)) body))
	(defmethod foo (a b c d) body)

Similarly,

	(defmethod foo (x &rest y) body)

is simply an abbreviation for

	(defmethod foo (x) (let ((y (list))) body))
	(defmethod foo (x y1) (let ((y (list y1))) body))
	(defmethod foo (x y1 y2) (let ((y (list y1 y2))) body))
	(defmethod foo (x y1 y2 y3) (let ((y (list y1 y2 y3))) body))
	...

I would suggest that a type specifier attached to a &rest parameter
be construed as applying to EACH of the arguments encompassed by that
parameter.

Keyword parameters can be handled in much the same manner, although
the question of which is to the left of another in multiple definitions
(for purposes of establishing method precedence) is problematical.

--Guy


     ----- End Forwarded Messages -----


----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 12:37:04 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 09:32:25 PDT
Date: 27 Aug 86 09:32 PDT
Sender: Kahn.pa@Xerox.COM
Subject: Defclass should be approximately upwards compatible with
 Defstruct
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Kahn.pa@Xerox.COM
From: Ken Kahn <Kahn.pa@Xerox.COM>
Message-ID: <860827-093225-1180@Xerox>

About 15 months ago CommonLoops switched from Defclass to Defstruct.
The major reason we did it was that we thought it important that people
with existing Common Lisp programs that heavily used Defstruct could,
with minimum effort, incrementally move over to object-oriented
programming. We felt this was worth putting up with syntax and features
that were not quite appropriate.  As I read some of the defclass stuff,
I worry that this goal is being lost.  I realize that any good
environment should let one point to a defstruct and defclassify it
(unless it uses the :type option) but it still seems as if the
transition is getting more awkward.  

For example, would

(defstruct foo (a 1) (b 2)) 

get turned into

(defclass foo ((a 1 :accessible nil) (b 2 :accessible nil)) ()
(:conc-name foo-))

?

There is another criterion in designing defclass which seems to be
getting too little attention. That is that people do write small
programs and some people do not want to learn about every feature.  This
would argue, for example, that (:conc-name nil) is the default.  When
explaining defclass to a student I don't want to have to get into
conc-names at all.  I agree that any serious programmer writing large
programs should use the :conc-name feature explicitly but that doesn't
mean a default that is friendly to less experienced programmers should
be excluded.

----- ken
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 27 Aug 86 12:28:10 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 AUG 86 08:51:25 PDT
Date: 27 Aug 86 08:50 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Type specifiers on optional args
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Message-ID: <860827-085125-1147@Xerox>

Yesterday, we discussed the issue of allowing type specifiers on
optional arguments.  We came up with two proposals.  They are presented
below.

The following is true of both proposals:

- The arglists of all the methods of a generic function must have the
"same shape".  That is to say they must each accept the same number of
required arguments, the same number of optional arguments and either
accept a rest argument or not.  

- A form (like defgeneric) can be used to specify the "arglist shape" of
the generic function, but in that arglist it is not possible to specify
default values for optional arguments.  So the following is NOT legal:

  ;; FOO's first argument should be a moving-object, the second
  ;; argument, if not supplied defaults to *standard-output*.
  ;;
  (defgeneric foo (moving-object &optional (stream *standard-output*)))

(I have a separate proposal which would make specifying default value
for optional arguments in the defgeneric possible.  I will send it a
later message.)

Proposal 1:

Methods may only have type specifiers on required arguments.

Proposal 2:

Type specifiers are allowed on required and optional arguments.  During
method-lookup, an unsupplied optional argument matches no type specifier
whatsoever.

For a method like:

  (defmeth foo ((p plane) &optional ((q boat) *default-boat* q-p))
     ...)

If the generic function foo is called with only one argument, this
method will never be called.

Whenever this method is called, there must have been two arguments, so
*default-boat* will never be used and q-p will always be t.

∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Aug 86 17:35:48 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 26 AUG 86 13:09:02 PDT
Date: 26 Aug 86 13:08 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: [David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>: Minutes
 of our 8 Aug 86 meeting]
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Message-ID: <860826-130902-1706@Xerox>

I am forwarding this so everyone will have it and it will be archived.

     ----- Begin Forwarded Messages -----

Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
Xerox.COM ; 11 AUG 86 16:19:28 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 60229;
Fri 8-Aug-86 23:31:16 EDT
Date: Fri, 8 Aug 86 23:31 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Minutes of our 8 Aug 86 meeting
To: Bobrow.PA@XEROX.ARPA, Gregor.PA@XEROX.ARPA,
Moon@STONY-BROOK.SCRC.Symbolics.COM, DLW@STONY-BROOK.SCRC.Symbolics.COM
File-References: SCRC|Q:>moon>greenhouse>flavor>8-Aug-86-Meeting.text
Message-ID: <860808233109.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

Here is the contents of the referenced file.  Should we send this to
RPG?  Will anyone who wasn't at the meeting be able to figure out
these cryptic notes?

Notes from meeting of 8 August 1986 with Daniel Bobrow, Gregor Kiczales,
David Moon, Daniel Weinreb.  Action items at the end.


Blackboard list of Flavors / CommonLoops features:

  Things we basically agree on, with small differences in name and/or
semantics:
    Need for a flavor: package for things that don't belong in the lisp:
package
    define-method-combination
      :arglist, :order
    define-simple-method-combination
    compile-flavor-methods (e.g. for bootstrapping, for delivery
environment)
    call-component-method
    call-component-methods
    transform-instance
    change-instance-class
    which-operations    (multi-methods issue)
    operation-handled-p (multi-methods issue)
    defflavor options
      :conc-name
      :constructor
      :initable-instance-variables
      :readable-instance-variables
      :writable-instance-variables
      :documentation
    defgeneric :method-combination option
    print-object     issue with being generic on the stream vs. generic
on
    describe-object  the object, maybe soluble with multi-methods plus a
		     defgeneric :order option to control the order of specificity
    :daemon, :and, :or, ...
    :init-keywords   (PCL doesn't exactly have, but already want to add)
    :default-init-plist (..)
    specializable-p  (implem-dependent, NIL for things that compile
inline specially)
    remove-method  (Symbolics doesn't need this, just use fundefine of a
function-spec)
    remove-class
    make
    vanilla   (CL calls this object, and it's different from t,
               which is object+builtin types)
    class-named  (flavor:find-flavor)
    type-of
    typep
    class-of
    classp  (perhaps this is superseded by typep)
    describe-instance (either this separate function is needed or the
describe
             function should take a level-of-abstraction argument which
is
             respected by the methods for describe-object)

  Issues we need to think about:

    Are we going for minimum features or for user-convenient notation?

    whoppers and run-super aren't the same because defwhopper implies
    a different method-ordering, just using run-super doesn't imply
that.

    defun-in-flavor      a labels around everything plus puts its body
"in a with"
    defmacro-in-flavor   a macrolet around everything
      Can you put a labels/macrolet around a defun in Common Lisp?

  Contentious:  (Danny didn't see why these were needed)

    defflavor :method-combination
    defflavor :component-order

  Possible to do with meta-objects, but is that how we want to do them:

    defgeneric :function option
    defgeneric :optimize option
    defflavor :no-vanilla-flavor option
    define-method-combination :method-transformer option
    defflavor :abstract-flavor option

  Purely syntactic sugar:

    multiple-value-prog2
    defgeneric :method option

  Error-checking, i.e. "protocol" enforcing:

    :required-methods, :required-flavors, :required-instance-variables
    :required-init-keywords [not really the same category as previous
three]
    defgeneric :method-arglist option

Some issues randomized over lunch:

  default for :conc-name
    Do we want to encourage <protocol>-<operation> naming convention?
    Should we flush :conc-name and instead require that
    :readable-instance-variables give the accessor name explicitly?
  An inheritable :default-conc-name would be nice, but it's impossible
    because of forward-reference problems.
  with and with* are direct and via-accessor interface to instance
slots, or vice versa
  Which style of accessing instance variables do we want?
  Defmethod syntax
    Flavors syntax doesn't work for multimethods
    CommonLoops syntax is clumsier
    Do we want two defmethod syntaxes both in the standard, or what?
  Two opposing motherhood statements:
    Shorter things should be more general, use a longer name for special
cases
    Shorter things should be more efficient, so programmers' intuition
works

CommonLoops things that aren't in the CL/F intersection:

  meta-object protocols
  class variables & other variable-allocation stuff
  multi-methods
  methods on individuals
  classes for builtin types
  get-function [said to be superfluous]
  syntax [I don't know why this is on this list --Moon]
  [is this list complete? --Moon]

Classes for builtin types:

  Should the set of classes be limited to a set of predefined builtin
  types or should the user be allowed to put methods on any predication
type?

  We said the former, to avoid issues of classes that have instances
  in common but do not have a subtype/supertype relationship.  This does
  not solve the problem of NIL, which is in both the SYMBOL and the LIST
class,
  and VECTOR, which is a subclass of both ARRAY and SEQUENCE.  Currently
  PCL contains this, does it need any tweaking?

  [Later I realized that allowing methods on individuals but not
allowing
   methods on predications is rather inconsistent --Moon]

  The COMMON type is poorly-defined and it's not clear that we should
  be making a class for it.  The issue is does it make sense to define
  methods on COMMON.

Agenda:

  Gregor & Bobrow are to figure out what the interaction of run-super
with
  method-combination (i.e. non-primary methods) ought to be.  Currently
  in PCL it doesn't work, I think the conclusion of the discussion was
  that it's believed to always cause a stack overflow.
Method-combination
  also may not work gracefully with multi-methods and methods on
individuals
  and a detailed proposal for fixing that needs to be made.

  Bobrow is to write something that could turn into a spec, as a focus
  for discussion, around the beginning of September.
  Actually we should all do that and then we should compare them.

  Symbolics should figure out meta-object protocol, relation to Flavors,
  relation to our architecture, but defer that for now.

  Gregor has to fix some things in PCL (conform to the document he just
  wrote) and then all four have to use that version of PCL to play
around.
  PCL needs to be brought up in Release 7.  Either Symbolics does that
  (Gregor has to give us the latest PCL) or Symbolics has to give Gregor
  access to Release 7 (just for a few hours?  PA?  SF?)

  Gregor has to send Moon a copy of his OOPSLA paper.

  Moon has to send Gregor a copy of his OOPSLA paper.


     ----- End Forwarded Messages -----
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Aug 86 17:35:24 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 26 AUG 86 13:10:32 PDT
Date: 26 Aug 86 13:10 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: [Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>: declaring
 the name of slot accessors]
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Message-ID: <860826-131032-1711@Xerox>

>>CoveringMessage<<

     ----- Begin Forwarded Messages -----

Return-Path: <DLW@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Redistributed: CommonLoopsCore↑.PA@XEROX.ARPA
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
Xerox.COM ; 25 AUG 86 19:36:15 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by
ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 68460;
Mon 25-Aug-86 22:35:09 EDT
Date: Mon, 25 Aug 86 22:40 EDT
From: Daniel L. Weinreb <DLW@QUABBIN.SCRC.Symbolics.COM>
Subject: declaring the name of slot accessors
To: CommonLoopsCore↑.PA@XEROX.ARPA
Message-ID: <860825224023.8.DLW@CHICOPEE.SCRC.Symbolics.COM>

I've just been studying a large recently-written program that uses New
Flavors, written by one of our software developers.  It has about eight
protocols and thirty flavors.  The developer used the explicit
:conc-name option in just about every defflavor.  The names of the
flavors were things of the form basic-foo, local-foo, remote-foo,
recoverable-foo-mixin, and the the accessors were named things like
foo-this, foo-that, foo-the-other.  That's because "foo" is effectively
the name of the protocol.  I belive that this is the appropriate style
for this program, and probably for most programs.  So I would like to
see an explicit conc-name option, but not by default.

Regarding the name "slot", well, I guess we can't say "instance
variable", and "slot" is pretty obvious.  Re Moon's comment about
whether we want people to think it's related to Frames, I'm not sure I
care.  It certainly is at least somewhat related to Frames; you can do
some of the classic Frames-y things naturally.  I don't think anyone's
likely to be seriously confused by expecting all Frames-y things to be
included in this.

	(defclass foo
	    ((a 1 :accessor foo-a)
	     (b 2 :accessor ship-b))
	  ())
    
    This is good if we can find a nice way to convey setf'ability.

One possible way:

(defclass foo
    ((a 1 :accessible foo-a)
     (b 2 :readable ship-b))
  ())

On the other hand, you have to figure out how this works with conc-name.
A more likely example, in my mind, is:

(defclass laser-printer-foo
    ((a 1 :accessible foo-a)
     (b 2 :readable foo-b))
  ())

You could say 

(defclass laser-printer-foo
    ((a 1 :accessible nil)
     (b 2 :readable nil))
  ()
  (:conc-name foo-))

You unfortunately need those nils, or something, as placeholders, so
that other per-slot options can fit syntactically.  Syntax is such a
pain in the neck.  So maybe doing it as an option after the component
classes would work out better.

I'm not sure how I feel about "accessible".  I agree that it's not as
specific as readable and writable.  On the other hand, lots of Flavors
users never really learned that writable implies readable, and so they'd
put in both, which was a bit verbose and seemingly inconvenient.
Apparently it's not immediately obvious that "writable" must mean
"readable and writable".  (The experiences I'm thinking about are
actually from Old Flavors, in which the terminology was actually
:gettable and :settable, but I'm guessing that the same logic would
carry over.)


     ----- End Forwarded Messages -----
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Aug 86 17:35:06 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 26 AUG 86 13:10:10 PDT
Date: 26 Aug 86 13:10 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: [David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>: declaring
 the name of slot accessors]
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Message-ID: <860826-131010-1710@Xerox>

 

     ----- Begin Forwarded Messages -----

Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
Xerox.COM ; 25 AUG 86 18:15:13 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 68423;
Mon 25-Aug-86 21:13:39 EDT
Date: Mon, 25 Aug 86 21:13 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: declaring the name of slot accessors
To: Gregor.pa
cc: DLW@STONY-BROOK.SCRC.Symbolics.COM, Bobrow.PA,
Moon@STONY-BROOK.SCRC.Symbolics.COM,
SKeene@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <860813102744.1.GREGOR@AVALON.XEROX-PARC>
Message-ID: <860825211331.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 13 Aug 86 10:27 PDT
    From: Gregor.pa@Xerox.COM

    (I have stuck with the name slots for now; I realize that this is
one of
    the things we have to decide).

Perhaps we should base that on whether we do or do not want people who
don't
know very much about this to think that it is related to Frames.

    Here is a first pass at the mechanism for declaring the names of
    accessors for instance slots.  I haven't thought this out in detail,
its
    just what I thought the thing we were talking about Friday was like.
I
    think flushing :conc-name is a good idea, so I would like to get
some
    agreement about this mechanism so I can put it in the PCL sources.

    The basic idea is that for each slot, the programmer must explicitly
    declare whether an accessor should be generated, and if so what it
    should be called.  Here are some examples:

    (defclass foo
	((a 1)
	 (b 2))
      ()
      (:accessible-slots (a foo-a) (b ship-b)))

In Flavors we put the accessor name before the variable name, but you
have it after.  Unless there is a good reason for the change we should
be compatible.

"Access" is such a general term that it's unclear what it means; that's
why we changed from "accessible" to "readable/writable" in going from
Old Flavors to New Flavors.

    Defines a class named foo, with two slots.  The accessor for the a
slot
    is FOO-A, the accessor for the B slot is SHIP-B.  These accessors
are
    setf'able.

    (defclass foo
	((a 1)
	 (b 2))
      ()
      (:accessible-slots a (b ship-b)))

    The same as above except the accessor for the slot named A is named
    A.  I would be inclined to flush this abbreviation.

I agree; it can only cause confusion.  Also I thought we agreed that
that
syntax meant something else; see below.

    (defclass foo
	((a 1)
	 (b 2))
      ()
      (:readable-slots a (b ship-b)))

    The same as above except the accessor's are not setf'able.  An
alternate
    way to do this is with a :read-only option in the slot description
    itself, something like:

    (defclass foo
	((a 1 :read-only t)
	 (b 2 :read-only t))
      ()
      (:accessible-slots a (b ship-b)))

I have a problem with this.  One way to look at it is that this is
inheriting some confusion from defstruct.  Not being a modern
object-oriented programming system, defstruct has no concept of the
difference between a module's implementation and its interface.  Saying
that you can't use setf with an accessor function is different from
saying that the value of the slot can't change.  To me :read-only as a
slot-option means the latter.  It's talking about the implementation,
but here you want to talk about the interface.

    Note that a wordier way to say :accessible-slots is:

    (defclass foo
	((a 1 :accessor foo-a)
	 (b 2 :accessor ship-b))
      ())

This is good if we can find a nice way to convey setf'ability.

. . . . .

What I thought we were discussing doing with :conc-name was not
eliminating the ability to "conc names", but rather eliminating the
default for this option, since we tentatively decided that users ought
to think harder about what they want to name their accessors.  Thus
there would be three allowed syntaxes for specifying slot accessors.  In
decreasing order of generality and increasing order of brevity, they
are:

   1  (:whatever (function-name slot-name)...)
   2  (:whatever slot-name...)
   3  (:whatever) or :whatever

Syntaxes 2 and 3 are invalid unless (:conc-name prefix) was specified,
and they use (INTERN (STRING-APPEND prefix slot-name) *PACKAGE*) as
function-name.  The reason for having syntaxes 2 and 3 is that they give
a great increase in brevity in what turns out to be the most common
case.

Footnote: string-append is missing from Common Lisp, use
(defun string-append (&rest args)
  (apply #'concatenate 'string (mapcar #'string args)))
[although this definition is not actually correct in systems such as
Symbolics' that have more than one kind of string].


     ----- End Forwarded Messages -----
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Aug 86 17:34:51 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 26 AUG 86 13:09:45 PDT
Date: 26 Aug 86 13:09 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: [David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>: First
 pass at defgeneric]
To: CommonLoopsCore↑.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM
Message-ID: <860826-130945-1709@Xerox>



     ----- Begin Forwarded Messages -----

Return-Path: <Moon@ELEPHANT-BUTTE.SCRC.Symbolics.COM>
Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM ([192.10.41.41]) by
Xerox.COM ; 25 AUG 86 17:57:04 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 68417;
Mon 25-Aug-86 20:49:42 EDT
Date: Mon, 25 Aug 86 20:49 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: First pass at defgeneric
To: Gregor.pa
cc: DLW@QUABBIN.SCRC.Symbolics.COM, edsel!lgd@navajo.stanford.edu,
Bobrow.PA, Moon@STONY-BROOK.SCRC.Symbolics.COM,
SKeene@STONY-BROOK.SCRC.Symbolics.COM
In-Reply-To: <860822102902.1.GREGOR@AVALON.XEROX-PARC>
Message-ID: <860825204929.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Fri, 22 Aug 86 10:29 PDT
    From: Gregor.pa@Xerox.COM

    Here is a *first* pass at defgeneric for the spec.  At the end there
    are some questions.

    (defgeneric <name> <arguments>
      . <options>)

    Options include

    (:documentation "a string goes here")

OK (see comments in earlier message about this syntax versus a naked
string).

    (:specialized-arguments . <arg-names>)

    This is used to specify which arguments are going to be specialized
by
    methods.  This is entirely optional.  Otherwise, the default for
this
    will come from the first defmeth evaluated.  Putting this here acts
as a
    kind of documentation.

:specialized-arguments is a poor choice of name, since the phrase is
ambiguous.
What's a specialized argument?  Before I can say anything more about
this I
need to understand why this option would be used.  I thought the whole
point
of multi-methods was that this was completely automatic.

    (:method-combination <name> . <args>)

    Used to specify the method combination type, just like in Flavors.

OK.

    (:dispatch . arg-names)

    This is used to specify the "order of precedence" of the arguments
    during method lookup.  The default is just the left to right order
of
    the arguments.

:dispatch is a poor choice of name since Flavors uses this to mean
something
else.  Using this name will cause unnecessary compatibility problems.
How about :order?  :Order is the name I had been assuming for this.

What happens if some arguments are left out of this?  Do they go at the
end,
or does it become illegal to use them to select methods, or is it an
error to
write a defgeneric that doesn't order its entire arglist?

    (:discriminator-class <discriminator-class-name>)

    Used to specify the class of the discriminator which should be used
for this generic function.

OK.  I hope the :class option I saw once in defmeth will be renamed
:method-class
and the :class option in defclass will be renamed :meta-class, since I
always found
the unqualified :class extremely confusing (there are so many classes
running around).

    This must be a sub-class of the class discriminator.

Some capitalization or fonting would make this sentence less ambiguous,
I had to read it twice.  The last word is a Lisp symbol, I assume.  More
to the point, do you mean discriminator or essential-discriminator?

    Some examples:

    (defgeneric speed (moving-object)
      (:documentation  "Returns the speed of the moving object."))

    (defgeneric speed (moving-object)
      (:documentation
	"Returns two values, the first is the speed of the moving object, the
	 second is the maximum speed of that moving object."))

    (defgeneric draw (thing place)
      (:documentation "Draws thing on the display stream place.")
      (:dispatch place thing))

    (defgeneric draw-boat (boat place)
      (:documentation "Draws a boat on the display stream place.")
      (:specialized-arguments place))

This doesn't help me figure out what is a specialized argument.

    (defgeneric total-fuel-supply (military-group fuel-type)
      (:documentation 
	"Returns today's total fuel supply of the given type of fuel.")
      (:method-combination-type :sum))

Delete "-type" from the last line.

    - Does this seem like the right sub-set of flavors' defgeneric
options?
      Plus the right extensions for multi-methods.

I think we should allow declarations in defgeneric, even if the set of
declarations in the common standard is empty initially.  Actually I
don't
think it will be empty, because type declarations for the arguments seem
as valid for generic functions as for ordinary functions, in
implementations
that like to make use of type declarations.

The other options on my list are :function and :method-arglist.
You might have been misled by the fact that some uses of :function in
our
current version of New Flavors are simply simulating methods on
primitive
types, and those uses can go.  The key feature provided by these
options,
which appears to be still needed in the Common Lisp Class system, is the
ability to modify the arguments before dispatching to the methods.  I
don't
see any other clean way to do this yet.  I don't like the auxiliary
function
technique (i.e. (defun interface (args) (interface-aux (f args)))
(defmethod interface-aux (args') ...)) because it means there are two
names
that have to be known as part of the interface, one for callers and the
other
for method-definers, for no good reason.  Perhaps I should ask in this
connection what you think of New Flavors' initialization protocol versus
Common Loops' initialization protocol.


     ----- End Forwarded Messages -----
∨
Received: from Xerox.COM by AI.AI.MIT.EDU 26 Aug 86 13:04:04 EDT
Received: from Cabernet.ms by ArpaGateway.ms ; 26 AUG 86 10:00:52 PDT
Date: 26 Aug 86 09:52 PDT
Sender: Gregor.pa@Xerox.COM
From: Gregor Kiczales <Gregor.pa@Xerox.COM>
Subject: Archive for this list
To: CommonLoopsCore↑.pa@Xerox.COM
Message-ID: <860826-100052-1479@Xerox>

This mailing list is archived in the file AI:Gregor;spec text.
∨
ββ