perm filename CLOOPS.3[COM,LSP]1 blob sn#846575 filedate 1987-10-03 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00468 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00070 00002	
C00071 00003	∂17-Apr-87  1011	@ALDERAAN.SCRC.Symbolics.COM:jlb@WAIKATO.S4CC.Symbolics.COM 	"Object" System    
C00074 00004	∂17-Apr-87  1149	Moon@ALDERAAN.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)
C00085 00005	∂17-Apr-87  1244	Moon@STONY-BROOK.SCRC.Symbolics.COM 	(long) CLOS Declaration Proposal Text 
C00089 00006	∂20-Apr-87  1331	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
C00098 00007	∂20-Apr-87  1355	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)  
C00101 00008	∂20-Apr-87  1449	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
C00103 00009	∂21-Apr-87  0812	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
C00107 00010	∂21-Apr-87  1049	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)  
C00111 00011	∂22-Apr-87  1348	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00121 00012	∂22-Apr-87  1448	Gregor.pa@Xerox.COM 	CL types --> classes    
C00124 00013	∂22-Apr-87  1533	Pavel.pa@Xerox.COM 	Re: CL types --> classes 
C00126 00014	∂22-Apr-87  1637	Gregor.pa@Xerox.COM 	note about clos instance disjointness  
C00128 00015	∂22-Apr-87  1639	Gregor.pa@Xerox.COM 	funcallable-standard-class   
C00130 00016	∂22-Apr-87  1729	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00138 00017	∂23-Apr-87  0953	kempf%hplabsc@hplabs.HP.COM 	Re: CLOS Type Cleanup
C00140 00018	∂23-Apr-87  1225	kempf%hplabsc@hplabs.HP.COM 	Re: (long) CLOS Declaration Proposal Text
C00147 00019	∂23-Apr-87  1249	kempf%hplabsc@hplabs.HP.COM 	Re: Object Creation Discussion (at last!)
C00160 00020	∂23-Apr-87  1456	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: CLOS Declaration Proposal    
C00162 00021	∂23-Apr-87  1722	kempf%hplabsc@hplabs.HP.COM 	Re: CLOS Declaration Proposal  
C00164 00022	∂23-Apr-87  2020	Gregor.pa@Xerox.COM 	Re: Object Creation Discussion (at last!)   
C00170 00023	∂23-Apr-87  2132	Moon@STONY-BROOK.SCRC.Symbolics.COM 	CL types --> classes   
C00175 00024	∂26-Apr-87  2231	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
C00200 00025	∂27-Apr-87  1329	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
C00214 00026	∂29-Apr-87  1836	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
C00216 00027	∂06-May-87  0936	kempf%hplabsc@hplabs.HP.COM 	Printing Objects
C00218 00028	∂06-May-87  1142	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Printing Objects    
C00221 00029	∂06-May-87  1304	kempf%hplabsc@hplabs.HP.COM 	Re: Printing Objects 
C00224 00030	∂06-May-87  2024	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Printing Objects   
C00230 00031	∂06-May-87  2202	Masinter.pa@Xerox.COM 	Re: Printing Objects  
C00233 00032	∂06-May-87  2235	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Printing Objects   
C00238 00033	∂07-May-87  0851	kempf%hplabsc@hplabs.HP.COM 	Re: Printing Objects 
C00244 00034	∂13-May-87  1131	kempf%hplabsc@hplabs.HP.COM 	Object Printing Discussion
C00254 00035	∂13-May-87  1323	Gregor.pa@Xerox.COM 	Re: Object Printing Discussion    
C00259 00036	∂13-May-87  1444	DLW@ALDERAAN.SCRC.Symbolics.COM 	Object Printing Discussion 
C00263 00037	∂14-May-87  1322	kempf%hplabsc@hplabs.HP.COM 	Re: Printing Objects 
C00268 00038	∂15-May-87  1110	Gregor.pa@Xerox.COM 	optimization versus constructors  
C00272 00039	∂15-May-87  1240	kempf%hplabsc@hplabs.HP.COM 	Why is MAKE-INSTANCE not generic?   
C00274 00040	∂15-May-87  1315	kempf%hplabsc@hplabs.HP.COM 	Re: Why in MAKE-INSTANCE not generic?    
C00276 00041	∂15-May-87  1648	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Why in MAKE-INSTANCE not generic? 
C00278 00042	∂15-May-87  1715	Moon@STONY-BROOK.SCRC.Symbolics.COM 	optimization versus constructors 
C00282 00043	∂20-May-87  1934	Pavel.pa@Xerox.COM 	CLOS vs. subtypes of FLOAT    
C00294 00044	∂21-May-87  1228	Pavel.pa@Xerox.COM 	Re: CLOS vs. subtypes of FLOAT
C00296 00045	∂21-May-87  1227	Masinter.pa@Xerox.COM 	Re: CLOS vs. subtypes of FLOAT  
C00298 00046	∂21-May-87  1338	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: CLOS vs. subtypes of FLOAT   
C00301 00047	∂21-May-87  1909	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00318 00048	∂22-May-87  0627	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: CLOS vs. subtypes of FLOAT   
C00323 00049	∂22-May-87  0725	DLW@ALDERAAN.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!) 
C00327 00050	∂22-May-87  1002	kempf%hplabsc@hplabs.HP.COM 	Arguments to CALL-NEXT-METHOD  
C00329 00051	∂22-May-87  1116	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00332 00052	∂22-May-87  1635	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00339 00053	∂23-May-87  0414	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
C00341 00054	∂23-May-87  1622	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00344 00055	∂23-May-87  1839	Bobrow.pa@Xerox.COM 	Object creation discussion (at last!)  
C00361 00056	∂25-May-87  0816	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
C00364 00057	∂25-May-87  1754	masinter.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD    
C00366 00058	∂25-May-87  1818	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00368 00059	∂26-May-87  1724	Masinter.pa@Xerox.COM 	Re: CLOS vs. subtypes of FLOAT  
C00371 00060	∂26-May-87  2253	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD
C00377 00061	∂26-May-87  2259	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)  
C00386 00062	∂26-May-87  2335	kempf%hplabsc@hplabs.HP.COM 	Re: CLOS vs. subtypes of FLOAT 
C00388 00063	∂27-May-87  0803	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00392 00064	∂27-May-87  1057	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD
C00394 00065	∂27-May-87  1122	RPG  	OOPSLA Lisp and Object-Oriented Programming Workshop  
C00396 00066	∂27-May-87  1124	RPG  	Floats   
C00410 00067	∂27-May-87  1331	Masinter.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD    
C00413 00068	∂27-May-87  1604	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00415 00069	∂27-May-87  1604	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00417 00070	∂27-May-87  1605	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00421 00071	∂27-May-87  1753	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD  
C00423 00072	∂27-May-87  1909	kahn.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD   
C00425 00073	∂27-May-87  1910	Gregor.pa@Xerox.COM 	OK, I stand corrected   
C00429 00074	∂27-May-87  1910	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00432 00075	∂27-May-87  1910	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00434 00076	∂28-May-87  0413	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
C00435 00077	∂28-May-87  0804	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
C00437 00078	∂28-May-87  0856	kempf%hplabsc@hplabs.HP.COM 	Re:  Floats
C00443 00079	∂28-May-87  1158	Masinter.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD    
C00445 00080	∂28-May-87  1251	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
C00447 00081	∂28-May-87  1458	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00449 00082	∂28-May-87  1511	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
C00451 00083	∂28-May-87  1532	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
C00453 00084	∂28-May-87  2159	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD
C00456 00085	∂29-May-87  1418	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
C00470 00086	∂29-May-87  1430	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
C00487 00087	∂29-May-87  1818	Bobrow.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00492 00088	∂29-May-87  2300	RPG  	Object Creation (at last!)   
C00494 00089	∂31-May-87  1313	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00503 00090	∂31-May-87  1439	masinter.pa@Xerox.COM 	Re: Object Creation (at last!)  
C00505 00091	∂31-May-87  1644	RPG  	Object creation discussion (at last!)  
C00529 00092	∂01-Jun-87  2132	Moon@STONY-BROOK.SCRC.Symbolics.COM 	object / cleanup subcommittee interaction  
C00531 00093	∂02-Jun-87  1029	RPG  	object / cleanup subcommittee interaction   
C00533 00094	∂02-Jun-87  1203	Bobrow.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction    
C00535 00095	∂02-Jun-87  1642	kempf%hplabsc@hplabs.HP.COM 	Re:  object / cleanup subcommittee interaction
C00537 00096	∂02-Jun-87  2022	Bobrow.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00543 00097	∂03-Jun-87  1220	Bobrow.pa@Xerox.COM 	Re: Floats    
C00547 00098	∂03-Jun-87  1221	Gregor.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction    
C00549 00099	∂03-Jun-87  1455	kempf%hplabsc@hplabs.HP.COM 	Re: object / cleanup subcommittee interaction 
C00551 00100	∂03-Jun-87  1709	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00568 00101	∂03-Jun-87  2020	RPG  	My Message of May 29    
C00571 00102	∂04-Jun-87  1004	kempf%hplabsc@hplabs.HP.COM 	SETF- method names   
C00574 00103	∂04-Jun-87  1525	kempf%hplabsc@hplabs.HP.COM 	Re: object creation / initialization discussion    
C00579 00104	∂05-Jun-87  2359	Masinter.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction       
C00586 00105	∂06-Jun-87  1219	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
C00593 00106	∂06-Jun-87  1350	RPG  	Order of Initialization 
C00600 00107	∂06-Jun-87  1624	kempf%hplabsc@hplabs.HP.COM 	Re:  Order of Initialization   
C00605 00108	∂06-Jun-87  1636	RPG  	Order of Initialization      
C00606 00109	∂08-Jun-87  1907	Bobrow.pa@Xerox.COM 	Open Issues in 87-002   
C00613 00110	∂09-Jun-87  0719	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Open Issues in 87-002
C00615 00111	∂09-Jun-87  0803	kempf%hplabsc@hplabs.HP.COM 	I. Formal Specification of Gen. Fcn. Invocation    
C00622 00112	∂09-Jun-87  0804	kempf%hplabsc@hplabs.HP.COM 	II. Formal Specification of Gen. Fcn. Invocation   
C00627 00113	∂09-Jun-87  0804	kempf%hplabsc@hplabs.HP.COM 	III. Formal Specification of Gen. Fcn. Invocation  
C00633 00114	∂09-Jun-87  0805	kempf%hplabsc@hplabs.HP.COM 	IV. Formal Specification of Gen. Fcn. Invocation   
C00642 00115	∂09-Jun-87  0854	kempf%hplabsc@hplabs.HP.COM 	Re:  Order of Initialization   
C00645 00116	∂09-Jun-87  0934	kempf%hplabsc@hplabs.HP.COM 	Re:  Open Issues in 87-002
C00654 00117	∂09-Jun-87  1008	kahn.pa@Xerox.COM 	Re: Open Issues in 87-002 
C00656 00118	∂09-Jun-87  1035	Bobrow.pa@Xerox.COM 	Re: Open Issues in 87-002    
C00658 00119	∂09-Jun-87  1050	kempf%hplabsc@hplabs.HP.COM 	Re: Open Issues in 87-002 
C00660 00120	∂09-Jun-87  1104	Bobrow.pa@Xerox.COM 	Re:  Order of Initialization 
C00664 00121	∂09-Jun-87  1136	Bobrow.pa@Xerox.COM 	Re: I. Formal Specification of Gen. Fcn. Invocation   
C00669 00122	∂09-Jun-87  1743	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Object creation discussion (at last!)  
C00675 00123	∂09-Jun-87  1819	Moon@STONY-BROOK.SCRC.Symbolics.COM 	SETF- method names
C00680 00124	∂09-Jun-87  1832	Moon@STONY-BROOK.SCRC.Symbolics.COM 	object / cleanup subcommittee interaction       
C00683 00125	∂09-Jun-87  1852	Moon@STONY-BROOK.SCRC.Symbolics.COM 	SETF- method names
C00689 00126	∂09-Jun-87  1921	Moon@STONY-BROOK.SCRC.Symbolics.COM 	object / cleanup subcommittee interaction  
C00695 00127	∂09-Jun-87  2044	Moon@STONY-BROOK.SCRC.Symbolics.COM 	I. Formal Specification of Gen. Fcn. Invocation 
C00699 00128	∂09-Jun-87  2234	kempf%hplabsc@hplabs.HP.COM 	Re:  SETF- method names   
C00702 00129	∂09-Jun-87  2349	Masinter.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction  
C00704 00130	∂10-Jun-87  0934	kempf%hplabsc@hplabs.HP.COM 	Re: I. Formal Specification of Gen. Fcn. Invocation
C00719 00131	∂10-Jun-87  1006	RPG  	CLOS Document 
C00720 00132	∂10-Jun-87  1114	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Concepts chapter on standard type classes
C00728 00133	∂10-Jun-87  1117	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Design Rationale section on standard type classes  
C00739 00134	∂10-Jun-87  1412	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: I. Formal Specification of Gen. Fcn. Invocation    
C00741 00135	∂10-Jun-87  1627	Bobrow.pa@Xerox.COM 	Re: SETF- method names  
C00744 00136	∂10-Jun-87  2132	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object Creation Discussion  
C00746 00137	∂10-Jun-87  2338	RPG  	    
C00750 00138	∂11-Jun-87  0746	kempf%hplabsc@hplabs.HP.COM 	Re: SETF- method names    
C00752 00139	∂11-Jun-87  0819	kempf%hplabsc@hplabs.HP.COM 	Re:  Order of Initialization   
C00757 00140	∂11-Jun-87  1120	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: SETF- method names 
C00762 00141	∂11-Jun-87  1243	kempf%hplabsc@hplabs.HP.COM 	Re: SETF- method names    
C00766 00142	∂12-Jun-87  1002	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Metaclass Protocol
C00773 00143	∂12-Jun-87  1204	Bobrow.pa@Xerox.COM 	Re:  Order of Initialization 
C00775 00144	∂15-Jun-87  1118	Gregor.pa@Xerox.COM 	new new initialization protocol blues  
C00783 00145	∂15-Jun-87  1920	Bobrow.pa@Xerox.COM 	Re: new new initialization protocol blues   
C00788 00146	∂23-Jun-87  2114	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation   
C00802 00147	∂24-Jun-87  1045	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object Creation   
C00807 00148	∂24-Jun-87  1155	RPG  	Request to Moon for Thursday's Discussion   
C00808 00149	∂25-Jun-87  0901	RPG  	Random Thoughts Concerning Initialization   
C00812 00150	∂02-Jul-87  0911	kempf%hplabsc@hplabs.HP.COM 	ECOOP Reaction to CLOS    
C00816 00151	∂03-Jul-87  0843	Moon@STONY-BROOK.SCRC.Symbolics.COM 	ECOOP Reaction to CLOS 
C00818 00152	∂06-Jul-87  1130	RPG  	ECOOP Reaction
C00823 00153	∂08-Jul-87  0928	RPG  	First Try at Terminology
C00837 00154	∂08-Jul-87  0938	RPG  	Category Errors    
C00840 00155	∂08-Jul-87  1643	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Class redefinition and class-changed. 
C00844 00156	∂09-Jul-87  1207	Bobrow.pa@Xerox.COM 	Re: Class redefinition and class-changed.   
C00847 00157	∂09-Jul-87  1326	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS
C00854 00158	∂09-Jul-87  1327	kempf%hplabsz@hplabs.HP.COM 	Re: Category Errors  
C00858 00159	∂09-Jul-87  1329	kempf%hplabsz@hplabs.HP.COM 	Re: First Try at Terminology   
C00862 00160	∂09-Jul-87  1333	kempf%hplabsz@hplabs.HP.COM 	Re: Metaclass Protocol Goals   
C00870 00161	∂09-Jul-87  1355	Kahn.pa@Xerox.COM 	Re: Category Errors  
C00872 00162	∂09-Jul-87  1431	kempf%hplabsz@hplabs.HP.COM 	Re: Category Errors  
C00875 00163	∂09-Jul-87  1933	Bobrow.pa@Xerox.COM 	Re: Metaclass Protocol Goals 
C00877 00164	∂10-Jul-87  1026	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
C00882 00165	∂13-Jul-87  1039	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Metaclass Protocol Goals
C00892 00166	∂15-Jul-87  1000	kempf%hplabsz@hplabs.HP.COM 	Re: Class redefinition and class-changed.
C00895 00167	∂16-Jul-87  0752	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
C00898 00168	∂22-Jul-87  0639	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Category Errors    
C00905 00169	∂22-Jul-87  1014	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Category Errors        
C00909 00170	∂23-Jul-87  1812	Gregor.pa@Xerox.COM 	initialization meeting notes 
C00916 00171	∂23-Jul-87  1917	Bobrow.pa@Xerox.COM 	Re: Category Errors     
C00918 00172	∂23-Jul-87  1941	Bobrow.pa@Xerox.COM 	Re: Class redefinition and class-changed.   
C00921 00173	∂24-Jul-87  0623	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
C00924 00174	∂24-Jul-87  0854	Bobrow.pa@Xerox.COM 	Re: Class redefinition and class-changed.   
C00927 00175	∂24-Jul-87  1133	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Category Errors    
C00931 00176	∂24-Jul-87  1136	RPG  	Category Errors    
C00935 00177	∂24-Jul-87  1420	Bobrow.pa@Xerox.COM 	Re: Category Errors     
C00939 00178	∂24-Jul-87  1421	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
C00942 00179	∂24-Jul-87  1427	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Category Errors    
C00945 00180	∂24-Jul-87  1436	Moon@STONY-BROOK.SCRC.Symbolics.COM 	initialization meeting notes
C00948 00181	∂24-Jul-87  1437	Moon@STONY-BROOK.SCRC.Symbolics.COM 	First Try at Terminology    
C00951 00182	∂24-Jul-87  1459	RPG  	Category Errors    
C00953 00183	∂24-Jul-87  1645	RPG  	Class Redefinition 
C00957 00184	∂25-Jul-87  0719	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Category Errors        
C00960 00185	∂25-Jul-87  0720	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Class redefinition and class-changed. 
C00984 00186	∂27-Jul-87  0930	kempf%hplabsz@hplabs.HP.COM 	Re: Class Redefinition    
C00986 00187	∂27-Jul-87  0933	kempf%hplabsz@hplabs.HP.COM 	Technical corrections in 87-002
C00993 00188	∂27-Jul-87  1001	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Name That Class   
C00995 00189	∂27-Jul-87  1001	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Class Redefinition     
C00999 00190	∂27-Jul-87  1046	Bobrow.pa@Xerox.COM 	Re: Name That Class
C01001 00191	∂27-Jul-87  1159	RPG  	Name That Class    
C01002 00192	∂27-Jul-87  1224	RPG  	Class Redefinition 
C01003 00193	∂27-Jul-87  1700	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class Redefinition 
C01011 00194	∂27-Jul-87  1905	Moon@STONY-BROOK.SCRC.Symbolics.COM 	initialization meeting notes
C01017 00195	∂27-Jul-87  2012	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
C01042 00196	∂28-Jul-87  1447	Bobrow.pa@Xerox.COM 	Re: Category Errors     
C01045 00197	∂28-Jul-87  1527	Bobrow.pa@Xerox.COM 	Re: Class Redefinition  
C01049 00198	∂28-Jul-87  1550	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
C01054 00199	∂28-Jul-87  1642	Gregor.pa@Xerox.COM 	Re: Class Redefinition  
C01056 00200	∂28-Jul-87  1648	Gregor.pa@Xerox.COM 	Re: Class Redefinition  
C01058 00201	∂28-Jul-87  1751	Bobrow.pa@Xerox.COM 	Re: initialization meeting notes  
C01060 00202	∂28-Jul-87  1907	Gregor.pa@Xerox.COM 	Re: initialization meeting notes  
C01065 00203	∂28-Jul-87  1922	Gregor.pa@Xerox.COM 	Re: Name That Class     
C01069 00204	∂28-Jul-87  2126	RPG  	Partial Orderings  
C01070 00205	∂29-Jul-87  1025	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Miscellaneous decisions taken or to be taken
C01073 00206	∂29-Jul-87  1034	skeene@STONY-BROOK.SCRC.Symbolics.COM 	updated documentation
C01076 00207	∂29-Jul-87  1415	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Class redefinition and class-changed. 
C01086 00208	∂30-Jul-87  0021	kempf%hplabsz@hplabs.HP.COM 	Re: Miscellaneous decisions taken or to be taken   
C01114 00209	∂30-Jul-87  0612	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Miscellaneous decisions taken or to be taken 
C01124 00210	∂30-Jul-87  1306	Bobrow.pa@Xerox.COM 	Re: Name That Class     
C01126 00211	∂31-Jul-87  0939	kempf%hplabsz@hplabs.HP.COM 	Re: Miscellaneous decisions taken or to be taken   
C01132 00212	∂31-Jul-87  1110	kempf%hplabsz@hplabs.HP.COM 	TRACE Proposal (Version 1)
C01143 00213	∂02-Aug-87  1725	RPG  	Miscellenia   
C01146 00214	∂03-Aug-87  1656	kempf%hplabsz@hplabs.HP.COM 	Re: Miscellenia 
C01150 00215	∂04-Aug-87  2243	kempf%hplabsz@hplabs.HP.COM 	Re: Technical corrections in 87-002 
C01156 00216	∂05-Aug-87  1751	Kelley.pa@Xerox.COM 	Re: ECOOP Reaction to CLOS   
C01162 00217	∂06-Aug-87  1249	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellenia       
C01165 00218	∂06-Aug-87  1249	Moon@STONY-BROOK.SCRC.Symbolics.COM 	TRACE Proposal (Version 1)  
C01171 00219	∂06-Aug-87  1914	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Name That Class    
C01177 00220	∂06-Aug-87  1929	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
C01210 00221	∂09-Aug-87  1514	Gregor.pa@Xerox.COM 	Miscellaneous decisions taken or to be taken
C01234 00222	∂10-Aug-87  1122	kempf%hplabsz@hplabs.HP.COM 	Re: Name That Class  
C01241 00223	∂10-Aug-87  1145	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Name That Class 
C01244 00224	∂10-Aug-87  1419	kempf%hplabsz@hplabs.HP.COM 	Re: TRACE Proposal (Version 1) 
C01252 00225	∂11-Aug-87  1504	kempf%hplabsz@hplabs.HP.COM 	Re: Name That Class  
C01266 00226	∂13-Aug-87  0928	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Name That Class    
C01271 00227	∂17-Aug-87  2133	kempf%hplabsz@hplabs.HP.COM 	Environments, Naming, and CLOS (was Re: Name that Class)
C01281 00228	∂18-Aug-87  0820	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Names to Objects and Compiler-environment  
C01289 00229	∂18-Aug-87  1136	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS     
C01300 00230	∂18-Aug-87  1146	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Agenda for September meeting
C01306 00231	∂18-Aug-87  1522	Moon@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination    
C01310 00232	∂18-Aug-87  1534	Kelley.pa@Xerox.COM 	Re: ECOOP Reaction to CLOS   
C01314 00233	∂18-Aug-87  1615	DLW@ALDERAAN.SCRC.Symbolics.COM 	short form of define-method-combination   
C01317 00234	∂18-Aug-87  1707	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: ECOOP Reaction to CLOS  
C01325 00235	∂18-Aug-87  1728	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Names to Objects and Compiler-environment  
C01332 00236	∂19-Aug-87  0632	skeene@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination  
C01335 00237	∂19-Aug-87  0745	DLW@ALDERAAN.SCRC.Symbolics.COM 	short form of define-method-combination   
C01337 00238	∂19-Aug-87  1020	Moon@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination    
C01341 00239	∂19-Aug-87  1123	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Names to Objects and Compiler-environment
C01343 00240	∂19-Aug-87  1349	DLW@ALDERAAN.SCRC.Symbolics.COM 	short form of define-method-combination   
C01347 00241	∂19-Aug-87  1455	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Names to Objects and Compiler-environment   
C01359 00242	∂19-Aug-87  1737	Gregor.pa@Xerox.COM 	meeting place 
C01361 00243	∂19-Aug-87  1830	Moon@STONY-BROOK.SCRC.Symbolics.COM 	meeting place
C01363 00244	∂20-Aug-87  0928	Moon@STONY-BROOK.SCRC.Symbolics.COM 	proposed syntactic cleanups in defmethod   
C01376 00245	∂20-Aug-87  1010	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
C01416 00246	∂20-Aug-87  1525	kempf%hplabsz@hplabs.HP.COM 	Re: Agenda for September meeting    
C01421 00247	∂21-Aug-87  0828	kempf%hplabsz@hplabs.HP.COM 	Re: proposed syntactic cleanups in defmethod  
C01431 00248	∂22-Aug-87  0004	Masinter.pa@Xerox.COM 	Re: proposed syntactic cleanups in defmethod   
C01433 00249	∂22-Aug-87  0033	Masinter.pa@Xerox.COM 	Re: TRACE Proposal (Version 1)  
C01435 00250	∂22-Aug-87  1837	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: proposed syntactic cleanups in defmethod    
C01438 00251	∂24-Aug-87  1146	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS     
C01447 00252	∂24-Aug-87  1254	LGD  	updated spec on SAIL    
C01448 00253	∂24-Aug-87  1304	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS     
C01454 00254	∂24-Aug-87  1644	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: proposed syntactic cleanups in defmethod    
C01458 00255	∂24-Aug-87  1701	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: short form of define-method-combination
C01463 00256	∂26-Aug-87  1916	Gregor.pa@Xerox.COM 	Re: proposed syntactic cleanups in defmethod
C01467 00257	∂26-Aug-87  2033	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: proposed syntactic cleanups in defmethod    
C01470 00258	∂27-Aug-87  0952	kempf%hplabsz@hplabs.HP.COM 	Solutions to Name/Object Mapping for Generic Functions  
C01478 00259	∂27-Aug-87  1656	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Solutions to Name/Object Mapping for Generic Functions
C01482 00260	∂27-Aug-87  1908	kempf%hplabsz@hplabs.HP.COM 	Re: Names to Objects and Compiler-environment 
C01509 00261	∂28-Aug-87  0150	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Re: Agenda for September meeting    
C01512 00262	∂28-Aug-87  1912	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Another try on object creation   
C01534 00263	∂30-Aug-87  1946	RPG  	Class Precedence List   
C01539 00264	∂30-Aug-87  2009	RPG  	Miscellaneous decisions taken or to be taken
C01541 00265	∂30-Aug-87  2017	RPG  	Agenda   
C01543 00266	∂30-Aug-87  2024	RPG  	Name That Class!   
C01550 00267	∂30-Aug-87  2054	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Class Precedence List       
C01552 00268	∂31-Aug-87  0802	kempf%hplabsz@hplabs.HP.COM 	Re: Agenda for September meeting    
C01556 00269	∂31-Aug-87  1914	MLY@AI.AI.MIT.EDU 	RPG's recent typo.   
C01557 00270	∂01-Sep-87  1150	Gregor.pa@Xerox.COM 	Re: Name That Class!    
C01560 00271	∂01-Sep-87  1258	RPG  	Name That Class!   
C01563 00272	∂01-Sep-87  1300	RPG  	Anonymous Generic Function Proposal (Draft 1)    
C01567 00273	∂01-Sep-87  1823	Bobrow.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 1)     
C01569 00274	∂01-Sep-87  2317	RPG  	Anonymous Generic Function Proposal (Draft 2)    
C01574 00275	∂02-Sep-87  1149	Bobrow.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 2)     
C01576 00276	∂02-Sep-87  1224	Pavel.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 2) 
C01578 00277	∂02-Sep-87  1534	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Another try on object creation    
C01581 00278	∂02-Sep-87  2013	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Another try on object creation    
C01587 00279	∂03-Sep-87  1414	Bobrow.pa@Xerox.COM 	Re: Another try on object creation
C01592 00280	∂03-Sep-87  1705	kempf%hplabsz@hplabs.HP.COM 	Re: Solutions to Name/Object Mapping for Generic Functions   
C01603 00281	∂03-Sep-87  1838	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Another try on object creation    
C01605 00282	∂04-Sep-87  1058	Bobrow.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 2)     
C01609 00283	∂04-Sep-87  1112	Lanning.pa@Xerox.COM 	WITH-SLOTS, "virtual" slots, and the meta-object protocol 
C01612 00284	∂08-Sep-87  1221	RPG  	WITH-ADDED-METHODS 
C01614 00285	∂09-Sep-87  1124	Bobrow.pa@Xerox.COM 	Updating Obsolete Instances  
C01621 00286	∂09-Sep-87  1630	Bobrow.pa@Xerox.COM 	Re: proposed syntactic cleanups in defmethod
C01626 00287	∂09-Sep-87  2114	Moon@STONY-BROOK.SCRC.Symbolics.COM 	User control of the CPL
C01640 00288	∂10-Sep-87  1101	kempf%hplabsz@hplabs.HP.COM 	Meeting on Sept. 17-18    
C01642 00289	∂10-Sep-87  1250	Bobrow.pa@Xerox.COM 	Re: Meeting on Sept. 17-18   
C01644 00290	∂10-Sep-87  2248	kempf%hplabsz@hplabs.HP.COM 	Trace Proposal (Version 2)
C01658 00291	∂11-Sep-87  0827	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken  
C01662 00292	∂11-Sep-87  1023	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
C01666 00293	∂11-Sep-87  1034	skeene@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination  
C01670 00294	∂11-Sep-87  1154	Bobrow.pa@Xerox.COM 	[kempf%hplabsz@hplabs.HP.COM: Re: Updating Obsolete Instances ] 
C01681 00295	∂11-Sep-87  1154	Bobrow.pa@Xerox.COM 	Re: Updating Obsolete Instances   
C01692 00296	∂11-Sep-87  1204	skeene@STONY-BROOK.SCRC.Symbolics.COM 	proposal for arguments for call-next-method   
C01696 00297	∂11-Sep-87  1314	Bobrow.pa@Xerox.COM 	Deoptimizing Slot Access
C01701 00298	∂11-Sep-87  1335	Bobrow.pa@Xerox.COM 	Re: User control of the CPL  
C01704 00299	∂11-Sep-87  1447	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: User control of the CPL 
C01706 00300	∂11-Sep-87  1641	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Updating Obsolete Instances  
C01710 00301	∂11-Sep-87  1657	Bobrow.pa@Xerox.COM 	Re: User control of the CPL  
C01713 00302	∂11-Sep-87  2030	Bobrow.pa@Xerox.COM 	Re: User control of the CPL  
C01716 00303	∂11-Sep-87  2057	Bobrow.pa@Xerox.COM 	Re: Updating Obsolete Instances   
C01721 00304	∂11-Sep-87  2057	Bobrow.pa@Xerox.COM 	Re: Miscellaneous decisions taken or to be taken 
C01724 00305	∂11-Sep-87  2058	Bobrow.pa@Xerox.COM 	Re: short form of define-method-combination 
C01729 00306	∂14-Sep-87  1346	Gregor.pa@Xerox.COM 	Re: Miscellaneous decisions taken or to be taken 
C01732 00307	∂14-Sep-87  1439	Bobrow.pa@Xerox.COM 	Uninitialized Slots
C01734 00308	∂14-Sep-87  1446	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Miscellaneous decisions taken or to be taken
C01737 00309	∂14-Sep-87  1510	Gregor.pa@Xerox.COM 	Re: Miscellaneous decisions taken or to be taken 
C01740 00310	∂14-Sep-87  1511	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Uninitialized Slots    
C01743 00311	∂14-Sep-87  1532	kempf%hplabsz@hplabs.HP.COM 	Re: User control of the CPL    
C01753 00312	∂14-Sep-87  1547	Masinter.pa@Xerox.COM 	Re: Uninitialized Slots    
C01755 00313	∂14-Sep-87  1642	Bobrow.pa@Xerox.COM 	Re: Agenda for September meeting  
C01758 00314	∂14-Sep-87  2058	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Agenda for September meeting 
C01763 00315	∂14-Sep-87  2129	Bobrow.pa@Xerox.COM 	Re: Names to Objects and Compiler-environment    
C01767 00316	∂15-Sep-87  0923	RPG  	Uninitialized Slots
C01769 00317	∂15-Sep-87  0935	RPG  	Proposals
C01770 00318	∂15-Sep-87  1009	kempf%hplabsz@hplabs.HP.COM 	Re: Proposals   
C01772 00319	∂15-Sep-87  1356	Bobrow.pa@Xerox.COM 	Re: Uninitialized Slots 
C01775 00320	∂15-Sep-87  1627	kempf%hplabsz@hplabs.HP.COM 	Re: Updating Obsolete Instances (and CHANGE-CLASS) 
C01780 00321	∂15-Sep-87  1916	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Another try on object creation 
C01784 00322	∂15-Sep-87  2006	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Anonymous Generic Function Proposal (Draft 2)      
C01788 00323	∂20-Sep-87  1904	Gregor.pa@Xerox.COM 	fixing our problems with setf
C01791 00324	∂21-Sep-87  0911	Bobrow.pa@Xerox.COM 	Re: fixing our problems with setf 
C01794 00325	∂21-Sep-87  1109	RPG  	Issues on Dynamic Extent for CALL-NEXT-METHOD    
C01804 00326	∂21-Sep-87  1121	RPG  	New Trivial Issue: Implicit Blocks in Methods    
C01807 00327	∂21-Sep-87  1159	Moon@STONY-BROOK.SCRC.Symbolics.COM 	New Trivial Issue: Implicit Blocks in Methods        
C01812 00328	∂21-Sep-87  1231	Bobrow.pa@Xerox.COM 	Re: New Trivial Issue: Implicit Blocks in Methods     
C01815 00329	∂21-Sep-87  1232	Bobrow.pa@Xerox.COM 	Re: Issues on Dynamic Extent for CALL-NEXT-METHOD     
C01817 00330	∂21-Sep-87  1246	Masinter.pa@Xerox.COM 	Re: fixing our problems with setf    
C01819 00331	∂21-Sep-87  1312	Gregor.pa@Xerox.COM 	Re: fixing our problems with setf 
C01821 00332	∂21-Sep-87  1334	Moon@STONY-BROOK.SCRC.Symbolics.COM 	fixing our problems with setf    
C01826 00333	∂21-Sep-87  1555	Gregor.pa@Xerox.COM 	Re: New Trivial Issue: Implicit Blocks in Methods     
C01828 00334	∂21-Sep-87  1611	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: New Trivial Issue: Implicit Blocks in Methods    
C01832 00335	∂21-Sep-87  1615	Masinter.pa@Xerox.COM 	Re: Issues on Dynamic Extent for CALL-NEXT-METHOD        
C01835 00336	∂21-Sep-87  2135	RPG  	Issues on Dynamic Extent for CALL-NEXT-METHOD    
C01836 00337	∂22-Sep-87  1417	Moon@MEAD.SCRC.Symbolics.COM 	SLOT-BOUNDP or SLOT-BOUND-P   
C01838 00338	∂22-Sep-87  1802	Bobrow.pa@Xerox.COM 	Re: Issues on Dynamic Extent for CALL-NEXT-METHOD     
C01840 00339	∂22-Sep-87  2004	Moon@STONY-BROOK.SCRC.Symbolics.COM 	September version of object-creation  
C01864 00340	∂22-Sep-87  2008	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Status of CLOS decisions    
C01924 00341	∂23-Sep-87  0427	skeene@STONY-BROOK.SCRC.Symbolics.COM 	draft of built-in method combination types    
C01931 00342	∂23-Sep-87  0851	Bobrow.pa@Xerox.COM 	Terminology: Shared versus class local versus instance    
C01935 00343	∂23-Sep-87  0907	Bobrow.pa@Xerox.COM 	Re: September version of object-creation    
C01939 00344	∂23-Sep-87  1022	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: September version of object-creation   
C01941 00345	∂23-Sep-87  1240	skeene@Riverside.SCRC.Symbolics.COM 	the new DEFMETHOD syntax    
C01946 00346	∂23-Sep-87  1330	Bobrow.pa@Xerox.COM 	Re: the new DEFMETHOD syntax 
C01947 00347	∂23-Sep-87  2202	RPG  	September version of object-creation (More nits) 
C01948 00348	∂23-Sep-87  2218	RPG  	Returning From a Generic Function 
C01949 00349	∂24-Sep-87  0856	Bobrow.pa@Xerox.COM 	no-applicable-method    
C01954 00350	∂24-Sep-87  0907	Bobrow.pa@Xerox.COM 	next-methods  
C01956 00351	∂24-Sep-87  0915	Bobrow.pa@Xerox.COM 	Redefining Classes 
C01963 00352	∂24-Sep-87  0919	Bobrow.pa@Xerox.COM 	DRAFT:  Changing Names of Built-in classes  
C01965 00353	∂24-Sep-87  0919	Bobrow.pa@Xerox.COM 	Unbound Slots 
C01968 00354	∂24-Sep-87  0927	Bobrow.pa@Xerox.COM 	slot-missing  
C01972 00355	∂24-Sep-87  0937	Moon@STONY-BROOK.SCRC.Symbolics.COM 	September version of object-creation (More nits)     
C01977 00356	∂24-Sep-87  0942	Moon@MEAD.SCRC.Symbolics.COM 	Terminology: Shared versus class local versus instance
C01980 00357	∂24-Sep-87  0951	Bobrow.pa@Xerox.COM 	Re: September version of object-creation (More nits)  
C01982 00358	∂24-Sep-87  0957	Moon@STONY-BROOK.SCRC.Symbolics.COM 	slot-missing 
C01985 00359	∂24-Sep-87  1001	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: September version of object-creation (More nits) 
C01987 00360	∂24-Sep-87  1021	Bobrow.pa@Xerox.COM 	Re: Terminology: Shared versus class local versus instance
C01990 00361	∂24-Sep-87  1051	Masinter.pa@Xerox.COM 	Re: next-methods 
C01992 00362	∂24-Sep-87  1124	RPG  	NEXT-METHODS  
C01993 00363	∂24-Sep-87  1142	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: next-methods  
C01996 00364	∂24-Sep-87  1458	Gregor.pa@Xerox.COM 	Re: next-methods   
C01998 00365	∂24-Sep-87  1549	Masinter.pa@Xerox.COM 	Re: next-methods 
C02000 00366	∂24-Sep-87  2035	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Redefining Classes
C02013 00367	∂25-Sep-87  1208	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Exact type   
C02016 00368	∂25-Sep-87  1258	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: fixing our problems with setf
C02020 00369	∂25-Sep-87  1841	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Amendments requiring additional writing    
C02027 00370	∂26-Sep-87  1639	Masinter.pa@Xerox.COM 	Re: Amendments requiring additional writing    
C02030 00371	∂28-Sep-87  0623	muehle%orion@cs.utah.edu 	remove me from the list 
C02031 00372	∂28-Sep-87  0842	kempf%hplabsz@hplabs.HP.COM 	Various Topics Discussed Last Week  
C02044 00373	∂28-Sep-87  0922	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Amendments requiring additional writing
C02051 00374	∂28-Sep-87  1006	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Various Topics Discussed Last Week    
C02060 00375	∂28-Sep-87  1026	Bobrow.pa@Xerox.COM 	key argument versus keyword argument   
C02062 00376	∂28-Sep-87  1048	Moon@STONY-BROOK.SCRC.Symbolics.COM 	lambda-list congruence 
C02066 00377	∂28-Sep-87  1107	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: draft of built-in method combination types  
C02069 00378	∂28-Sep-87  1117	RPG  	Shared/localclass/instance  
C02071 00379	∂28-Sep-87  1120	Moon@STONY-BROOK.SCRC.Symbolics.COM 	key argument versus keyword argument  
C02074 00380	∂28-Sep-87  1114	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Revised draft of object creation proposal  
C02101 00381	∂28-Sep-87  1154	Bobrow.pa@Xerox.COM 	Re: Shared/localclass/instance   
C02105 00382	∂28-Sep-87  1254	kempf%hplabsz@hplabs.HP.COM 	Re: Exact type  
C02110 00383	∂28-Sep-87  1336	Bobrow.pa@Xerox.COM 	Re: Amendments requiring additional writing 
C02116 00384	∂28-Sep-87  1355	Moon@STONY-BROOK.SCRC.Symbolics.COM 	fixing our problems with setf    
C02129 00385	∂28-Sep-87  1407	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Various Topics Discussed Last Week    
C02133 00386	∂28-Sep-87  1419	Bobrow.pa@Xerox.COM 	Re: fixing our problems with setf 
C02135 00387	∂28-Sep-87  1451	Bobrow.pa@Xerox.COM 	Re: Redefining Classes  
C02148 00388	∂28-Sep-87  1546	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Amendments requiring additional writing
C02159 00389	∂28-Sep-87  1549	kempf%hplabsz@hplabs.HP.COM 	Re: draft of built-in method combination types     
C02162 00390	∂28-Sep-87  1556	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: fixing our problems with setf
C02165 00391	∂28-Sep-87  1612	kempf%hplabsz@hplabs.HP.COM 	Re: Various Topics Discussed Last Week   
C02170 00392	∂28-Sep-87  1648	Bobrow.pa@Xerox.COM 	Re: Various Topics Discussed Last Week 
C02174 00393	∂28-Sep-87  1651	Bobrow.pa@Xerox.COM 	Re: Various Topics Discussed Last Week 
C02178 00394	∂28-Sep-87  1734	kempf%hplabsz@hplabs.HP.COM 	Re: fixing our problems with setf   
C02180 00395	∂28-Sep-87  1800	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Various Topics Discussed Last Week
C02184 00396	∂28-Sep-87  1804	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: fixing our problems with setf     
C02186 00397	∂28-Sep-87  1836	RPG  	Shared/localclass/instance  
C02189 00398	∂28-Sep-87  1918	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Redefining Classes 
C02207 00399	∂29-Sep-87  0859	Bobrow.pa@Xerox.COM 	Re: Amendments requiring additional writing 
C02213 00400	∂29-Sep-87  0928	RPG  	Various Decisions  
C02214 00401	∂29-Sep-87  0945	Gregor.pa@Xerox.COM 	Re: Issues on Dynamic Extent for CALL-NEXT-METHOD     
C02217 00402	∂29-Sep-87  1124	kempf%hplabsz@hplabs.HP.COM 	Re: Various Decisions     
C02219 00403	∂29-Sep-87  1150	Bobrow.pa@Xerox.COM 	Re: Shared/localclass/instance   
C02221 00404	∂29-Sep-87  1150	Bobrow.pa@Xerox.COM 	Re: Various Decisions   
C02223 00405	∂29-Sep-87  1222	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Various Decisions  
C02227 00406	∂29-Sep-87  1300	kempf%hplabsz@hplabs.HP.COM 	Re: Shared/localclass/instance     
C02230 00407	∂29-Sep-87  1415	Pavel.pa@Xerox.COM 	Re: Various Decisions    
C02231 00408	∂29-Sep-87  1440	kempf%hplabsz@hplabs.HP.COM 	Re: Status of CLOS decisions   
C02233 00409	∂29-Sep-87  1444	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Various Decisions  
C02236 00410	∂29-Sep-87  1514	kempf%hplabsz@hplabs.HP.COM 	Re: Various Decisions     
C02239 00411	∂29-Sep-87  1529	RPG  	Various Decisions  
C02241 00412	∂29-Sep-87  1625	@RELAY.CS.NET:DUSSUD%Jenner@csl.ti.com 	Re: Redefining Classes   
C02255 00413	∂29-Sep-87  1732	DUSSUD%Jenner%csl.ti.com@RELAY.CS.NET 	Re: Various Topics Discussed Last Week   
C02260 00414	∂29-Sep-87  1733	DUSSUD%Jenner%csl.ti.com@RELAY.CS.NET 	Re: Redefining Classes    
C02274 00415	∂29-Sep-87  1733	DUSSUD%Jenner%csl.ti.com@RELAY.CS.NET 	Re: Exact type  
C02278 00416	∂29-Sep-87  1820	Bobrow.pa@Xerox.COM 	Re: Redefining Classes  
C02282 00417	∂29-Sep-87  1931	@RELAY.CS.NET:DUSSUD%Jenner@csl.ti.com 	Re: Exact type 
C02286 00418	∂29-Sep-87  1935	@RELAY.CS.NET:DUSSUD%Jenner@csl.ti.com 	Re: Various Topics Discussed Last Week  
C02291 00419	∂29-Sep-87  1939	@RELAY.CS.NET:DUSSUD%Jenner@csl.ti.com 	Re: Revised draft of object creation proposal
C02294 00420	∂29-Sep-87  1944	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Redefining Classes 
C02298 00421	∂30-Sep-87  0936	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Constructors 
C02320 00422	∂30-Sep-87  1316	kempf%hplabsz@hplabs.HP.COM 	Re: Exact type  
C02324 00423	∂30-Sep-87  1326	kempf%hplabsz@hplabs.HP.COM 	Re: Various Decisions     
C02327 00424	∂30-Sep-87  1410	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Should redefining a class reinitialize shared slots? 
C02335 00425	∂30-Sep-87  1353	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Slot Inheritance  
C02338 00426	∂30-Sep-87  1403	RPG  	NEXT METHOD   
C02341 00427	∂30-Sep-87  1419	Moon@STONY-BROOK.SCRC.Symbolics.COM 	NEXT METHOD       
C02343 00428	∂30-Sep-87  1521	RPG  	Should redefining a class reinitialize shared slots?  
C02345 00429	∂30-Sep-87  1619	Bobrow.pa@Xerox.COM 	class/instance vs shared/local    
C02347 00430	∂30-Sep-87  1619	Bobrow.pa@Xerox.COM 	Re: next-method-p  
C02348 00431	∂30-Sep-87  1719	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Should redefining a class reinitialize shared slots?      
C02351 00432	∂30-Sep-87  1748	kempf%hplabsz@hplabs.HP.COM 	Re: Should redefining a class reinitialize shared slots?     
C02354 00433	∂30-Sep-87  1756	Bobrow.pa@Xerox.COM 	Re: Should redefining a class reinitialize shared slots?   
C02360 00434	∂30-Sep-87  2045	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Amendments requiring additional writing    
C02371 00435	∂30-Sep-87  2352	mcvax!inria.inria.fr!cointe@uunet.UU.NET 	Re: Shared/localclass/instance  
C02373 00436	∂01-Oct-87  0822	Bobrow.pa@Xerox.COM 	Re: Shared/localclass/instance   
C02375 00437	∂01-Oct-87  0834	Bobrow.pa@Xerox.COM 	Re: Amendments requiring additional writing 
C02379 00438	∂01-Oct-87  0836	kempf%hplabsz@hplabs.HP.COM 	Re: Amendments requiring additional writing   
C02381 00439	∂01-Oct-87  0838	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Should redefining a class reinitialize shared slots?  
C02389 00440	∂01-Oct-87  0901	kempf%hplabsz@hplabs.HP.COM 	CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE    
C02392 00441	∂01-Oct-87  0911	Moon@ALLEGHENY.SCRC.Symbolics.COM 	Re: Amendments requiring additional writing  
C02396 00442	∂01-Oct-87  0925	kempf%hplabsz@hplabs.HP.COM 	COERCE (not urgent)  
C02402 00443	∂01-Oct-87  0950	Bobrow.pa@Xerox.COM 	Re: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE   
C02405 00444	∂01-Oct-87  0957	Bobrow.pa@Xerox.COM 	Re: Amendments requiring additional writing 
C02408 00445	∂01-Oct-87  1017	kempf%hplabsz@hplabs.HP.COM 	Re: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE     
C02411 00446	∂01-Oct-87  1117	Bobrow.pa@Xerox.COM 	Can defgeneric provide defaults for &key args    
C02413 00447	∂01-Oct-87  1117	Bobrow.pa@Xerox.COM 	Re: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE   
C02416 00448	∂01-Oct-87  1244	kempf%hplabsz@hplabs.HP.COM 	Re: CLASS-CHANGED and UPDATE-OBSOLETE-INSTANCE     
C02419 00449	∂01-Oct-87  1621	RPG  	Shared/classinstance/local  
C02422 00450	∂01-Oct-87  2100	Bobrow.pa@Xerox.COM 	Re: Shared/classinstance/local   
C02426 00451	∂02-Oct-87  0942	kempf%hplabsz@hplabs.HP.COM 	Re: Constructors     
C02434 00452	∂02-Oct-87  1017	kempf%hplabsz@hplabs.HP.COM 	Re: Can defgeneric provide defaults for &key args  
C02436 00453	∂02-Oct-87  1032	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Can defgeneric provide defaults for &key args   
C02438 00454	∂02-Oct-87  1054	Gregor.pa@Xerox.COM 	no-applicable-method    
C02441 00455	∂02-Oct-87  1102	Moon@STONY-BROOK.SCRC.Symbolics.COM 	no-applicable-method   
C02443 00456	∂02-Oct-87  1132	Bobrow.pa@Xerox.COM 	Re: Constructors   
C02450 00457	∂02-Oct-87  1154	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Constructors  
C02454 00458	∂02-Oct-87  1256	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Constructors  
C02465 00459	∂02-Oct-87  1342	Bobrow.pa@Xerox.COM 	Re: Can defgeneric provide defaults for &key args
C02468 00460	∂02-Oct-87  1400	Bobrow.pa@Xerox.COM 	Re: no-applicable-method
C02471 00461	∂02-Oct-87  1404	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Can defgeneric provide defaults for &key args    
C02473 00462	∂02-Oct-87  1404	@RELAY.CS.NET:DUSSUD%Jenner@csl.ti.com 	Re: Exact type 
C02477 00463	∂02-Oct-87  1417	Gregor.pa@Xerox.COM 	no-applicable-method    
C02479 00464	∂02-Oct-87  1640	Gregor.pa@Xerox.COM 	fixing our problems with setf
C02490 00465	∂03-Oct-87  1149	mcvax!inria.inria.fr!cointe@uunet.UU.NET 	Re: Shared/localclass/instance  
C02492 00466	∂03-Oct-87  1300	Gregor.pa@Xerox.COM 	Constructors  
C02510 00467	∂03-Oct-87  1341	Gregor.pa@Xerox.COM 	Re: Constructors   
C02514 00468	∂03-Oct-87  1451	mcvax!inria.inria.fr!cointe@uunet.UU.NET 	Re: Shared/localclass/instance  
C02516 ENDMK
C⊗;
∂17-Apr-87  1011	@ALDERAAN.SCRC.Symbolics.COM:jlb@WAIKATO.S4CC.Symbolics.COM 	"Object" System    
Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 17 Apr 87  10:00:37 PDT
Received: from FLYING-DOVE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 72959; Fri 17-Apr-87 13:00:56 EDT
Date: Fri, 17 Apr 87 13:01 EDT
From: Jonathan L. Balgley <jlb@WAIKATO.S4CC.Symbolics.COM>
Subject: "Object" System
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <870417130124.4.JLB@FLYING-DOVE.SCRC.Symbolics.COM>

Hi!  I've read the draft version of CLOS standard and gave my comments
through Symbolics' other representatives.  But I have one question:  Why
is it called the "Common Lisp Object System"?  

I understand the desire to be related to the term "object-oriented", but
pure Common Lisp could already be called an "object system".  Indeed,
CLtL dedicates an entire chapter (number 2, "Data Types") to discussing
the "variety of types of data objects".  I believe that the name will
cause unnecessary confusion when trying to describe the facilities that
CLOS provides over pure Common Lisp.  I can hear CL beginners now:  "OK,
you've convinced me that conses and symbols are objects.  How does that
relate to the Common Lisp Object System?" 

So, have other names been proposed and turned down?  Is this name
finalized or will you take other suggestions?  If you will, here's my
idea for a name: "CL Generic Structure System".  Another one, that Sonya
Keene proposed, was "Classes".

At the very least, I hope that the "Design Rationale" chapter will
briefly mention why it's named what it is.  Thanks for listening.


∂17-Apr-87  1149	Moon@ALDERAAN.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)
Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 17 Apr 87  11:49:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 73015; Fri 17-Apr-87 14:49:44 EDT
Date: Fri, 17 Apr 87 14:49 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Object creation discussion (at last!)
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2754594256-919057@Jenner>
Message-ID: <870417144911.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 16 Apr 87  16:04:16 CDT
    From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>

Thanks for the comments.  I hope the others will comment as well (but
I'm certainly willing to wait a few days).

		If multiple initargs that fill the same slot are supplied, which value ends up
		in the slot is indeterminate.  
       
	    In what sense do you mean "indeterminate"?  Do you mean "defined to be
	    one of those values, but not defined as to which of them", such that it
	    would be legal to use a random number generator to decide?
       
	   Yes.  "which value" should be "which of those values".  I certainly won't complain
	   if someone proposes a determinate action here instead.
                                                                                
    We could check, at run time for make-instance that two initargs that fill
    the same slot are not getting a value.
    For the constructors, we can check at compile time that they don't specify in
    their lambda list two initargs filling the same slot. This would be a
    restriction for constructors.

Those are good ideas.  I agree with the constructor one.  I'm not so sure about
the make-instance one, because I just noticed that Common Lisp allows duplicate
keyword arguments in a function call and mandates that the leftmost argument
prevails.  One could argue that this should extend to arguments that have different
names but fill the same slot.

I was concerned about the speed of a runtime check either to do what you
(Patrick) suggested, or to do what I just mentioned above.  However,
after consulting our implementation I see that it is easy to do,
although we are not currently using the mechanism to address the issue
of multiple initargs filling the same slot.  Briefly, you detect at
compile time (or the first time a class is instantiated) that there are
multiple possible initargs, and then you assign a bit in a bit mask to
record whether the given slot has been filled.  If you see an initarg
that fills a slot whose bit is already set, you either ignore it
(leftmost duplicate prevails) or check what keyword was used the
previous time (signal an error except in the case where Common Lisp says
the leftmost duplicate prevails).

Given all this, I added the following to my proposal (philosophy section):

  >> What if multiple initargs that fill the same slot are supplied?
  
  If the same initarg is given more than once in the arguments to make-instance,
  the leftmost occurrence prevails, as required by Common Lisp.
  
  If two different initargs that fill the same slot are given in the arguments
  to make-instance, the leftmost occurrence prevails (alternatively we could
  make this an error, but I think it's simpler to treat it the same as two
  occurrences of the same initarg).
  
  A :constructor option whose lambda-list has more than one parameter that
  fills a single slot signals an error, whether or not the parameter names
  are eq (see proposal below for how it is possible for non-eq parameters
  to fill the same slot).
  
I also added the following related clarification:

  When :default-initargs defaults an initarg that
  fills a slot, it is treated the same as an :initform slot-option for purposes
  of inheritance (note well: the class that specifies the :default-initargs
  may not know whether the initarg fills a slot or not, and indeed this may
  depend on which subclass of that class we are dealing with).  If a single
  class specifies more than one default value for a single slot, via
  :default-initargs or :initform or both, an error is signalled.

Is this agreeable?

    Initargs don't have to be keywords, but the entire object creation might not work
    very well if any of initargs is not a keyword:

    In common Lisp, :allow-other-keys T works only for keyword value pairs. We would
    have to slightly change its meaning for make-instance.

	  In practice this is probably implemented by calling all of the
	  initialize-instance methods with all of the initargs and automatically adding
	  &allow-other-keys to the lambda-list in defmethod.

    This won't work if there is an initarg which is not a key. The methods that
    can be called during object creation (like those on allocate-instance) would be
    easier to code if they knew that they would get keyword-value pairs. (if I
    understand correctly, those methods would get all the arguments supplied to
    make-instance, right?)

I can't understand what you're getting at here.  Could you send a follow-up
message this is more explicit?

	  >> Can step 2 return an existing object instead of allocating storage,
	  aborting the remaining steps?
      
	  No, to do "interning" you must build a higher-level interface around
	  make-instance.  Make-instance always makes.

    I am wondering if you propose to enforce this. What if somebody defines an 
    :around method for ALLOCATE-INSTANCE and does not call-next-method but returns 
    an interned object instead ? Is it an error?

I don't see how it would be possible to enforce a restriction that the value
returned by ALLOCATE-INSTANCE is not EQ to any other object in the world.
However, note that in your example the value returned by ALLOCATE-INSTANCE
is going to have every one of its slots stored into, and is going to have
its INITIALIZE-INSTANCE methods run, so the effect might not be what the user
intended.  What I was really getting at with my philosophy question is "should
a way be provided for the metaclass to be able to completely bypass the
entire action of MAKE-INSTANCE?" and my answer to that is "no".  In my file
copy of the proposal I changed this section to the following:

  >> Can step 2 return an existing object instead of allocating storage,
  aborting the remaining steps?
  
  Step 2 can return anything it wants, but the remaining steps are still
  executed.  To do "interning" you must build a higher-level interface around
  make-instance; make-instance always makes.  No way is provided for the
  metaclass to be able to completely bypass the entire action of MAKE-INSTANCE.

Is this agreeable?

∂17-Apr-87  1244	Moon@STONY-BROOK.SCRC.Symbolics.COM 	(long) CLOS Declaration Proposal Text 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 17 Apr 87  12:44:29 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 118986; Fri 17-Apr-87 15:29:48 EDT
Date: Fri, 17 Apr 87 15:29 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: (long) CLOS Declaration Proposal Text
To: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8704162339.AA22952@hplabsc>
Message-ID: <870417152924.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

This is a good beginning.  Not being a fan of machines that require
declarations, I'm going to keep a low profile in this discussion, but
I do have a couple of comments/criticisms for you.

    5) If method combination is prohibited for a certain method,
    any overhead which is needed to support method combination
    in the general case could be avoided.

I agree that this is a non-issue.

    (CLASS FOO X)

I think (EXACT-CLASS FOO X) has a lot less potential for confusion.

    a user may want to restrict a particular name to be a generic function

I don't see why.  I suggest leaving this out unless there is a good
reason for it (which should be articulated).

When a user creates a subclass of a "staticized" class, rather than
changing the semantics in some unclear way, I suggest signalling an
error if there is a conflict between the semantics frozen into the
superclass and the semantics that would exist if the superclass had not
been "staticized".  The design principle here is that adding a
"staticize" declaration to a working program shouldn't change what it
does, only how fast it does it.

The name MAKE-STATIC isn't the best.  To me, it connotes a function that
returns an object that I can hand to the WRITE-SOUND function and get an
ugly noise from the speaker in my console.  FREEZE-CLASS would be better.

∂20-Apr-87  1331	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 20 Apr 87  13:31:08 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae19504; 20 Apr 87 16:13 EDT
Received: from ti-csl by RELAY.CS.NET id ax17675; 20 Apr 87 16:05 AST
Received: from Jenner (jenner.ARPA) by tilde id AA16384; Mon, 20 Apr 87 14:48:44 cdt
Message-Id: <2754935345-480598@Jenner>
Date: Mon, 20 Apr 87  14:49:05 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Object creation discussion (at last!)
In-Reply-To: Msg of Fri, 17 Apr 87 14:49 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

     Date: Fri, 17 Apr 87 14:49 EDT
     From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
     Subject: Re: Object creation discussion (at last!)
     
     
       >> What if multiple initargs that fill the same slot are supplied?
       
       If the same initarg is given more than once in the arguments to make-instance,
       the leftmost occurrence prevails, as required by Common Lisp.
       
       If two different initargs that fill the same slot are given in the arguments
       to make-instance, the leftmost occurrence prevails (alternatively we could
       make this an error, but I think it's simpler to treat it the same as two
       occurrences of the same initarg).
       
       A :constructor option whose lambda-list has more than one parameter that
       fills a single slot signals an error, whether or not the parameter names
       are eq (see proposal below for how it is possible for non-eq parameters
       to fill the same slot).
       
     I also added the following related clarification:
     
       When :default-initargs defaults an initarg that
       fills a slot, it is treated the same as an :initform slot-option for purposes
       of inheritance (note well: the class that specifies the :default-initargs
       may not know whether the initarg fills a slot or not, and indeed this may
       depend on which subclass of that class we are dealing with).  If a single
       class specifies more than one default value for a single slot, via
       :default-initargs or :initform or both, an error is signalled.
     
     Is this agreeable?

Yes.
     
         Initargs don't have to be keywords, but the entire object creation might not work
         very well if any of initargs is not a keyword:
     
         In common Lisp, :allow-other-keys T works only for keyword value pairs. We would
         have to slightly change its meaning for make-instance.
     
     	  In practice this is probably implemented by calling all of the
     	  initialize-instance methods with all of the initargs and automatically adding
     	  &allow-other-keys to the lambda-list in defmethod.
     
         This won't work if there is an initarg which is not a key. The methods that
         can be called during object creation (like those on allocate-instance) would be
         easier to code if they knew that they would get keyword-value pairs. (if I
         understand correctly, those methods would get all the arguments supplied to
         make-instance, right?)
     
     I can't understand what you're getting at here.  Could you send a follow-up
     message this is more explicit?

Take the following example:

(make-instance 'class-1 'SLOT1 2 :AREA 'class-1-area 'JUNK 3
               :allow-other-keys t)

SLOT-1 is an initarg for a slot, :AREA is a key for an allocate-instance
method, but JUNK is not a valid initarg.  According to your proposal,
:allow-other-keys would tell make-instance to ignore JUNK (ie.  return
without signalling an error).  In Common Lisp :allow-other-keys T
does not apply to non-keywords like JUNK.

Suppose I have a method like:
(defmethod allocate-instance ((class 'class-1) &key :area
                               &allow-other-keys)
   .....)

If we call allocate-instance with all the initarg-value pairs coming
from the make-instance call and if all the initargs are keywords, then
according to Common Lisp, only the :area keyword is not ignored and we
get the intended effect.
Now, if one of the initargs is not a keyword, then Common Lisp says it
is an error... 
My point is, the implementations will have to filter out non keyword
initargs that are not relevant to allocate-instance before calling
allocate-instance if they want strict compliance with CLtL.  Is this
true or did I miss something?


       >> Can step 2 return an existing object instead of allocating storage,
       aborting the remaining steps?
       
       Step 2 can return anything it wants, but the remaining steps are still
       executed.  To do "interning" you must build a higher-level interface around
       make-instance; make-instance always makes.  No way is provided for the
       metaclass to be able to completely bypass the entire action of MAKE-INSTANCE.
     
     Is this agreeable?
Yes.


∂20-Apr-87  1355	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 20 Apr 87  13:55:34 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 120069; Mon 20-Apr-87 16:55:30 EDT
Date: Mon, 20 Apr 87 16:55 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Object creation discussion (at last!)
To: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2754935345-480598@Jenner>
Message-ID: <870420165517.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Mon, 20 Apr 87  14:49:05 CDT
    From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>

	 Date: Fri, 17 Apr 87 14:49 EDT
	 From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
     
	 I can't understand what you're getting at here.

    In Common Lisp :allow-other-keys T
    does not apply to non-keywords like JUNK.

I can't find any evidence for this except at the top of p.62 in CLtL where
it says "It is an error for the first object of each pair to be anything
but a keyword."  I was under the impression that it had been decided a
couple of years ago that the last word in this sentence should have been
"symbol", but perhaps that's not true.  Unfortunately I lost my copy, but
I think this was in the proposed corrections and clarifications Guy Steele
distributed in December 1985.

If only symbols in the keyword package are allowed as keyword argument
names, my object creation proposal falls apart, as does every other one
that has ever been mailed to this list!  I tell you what I'll do; I'll
go find out the format for submissions to the cleanup subcommittee and
send this in.  Let's proceed on the assumption that it will be accepted.

∂20-Apr-87  1449	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 20 Apr 87  14:48:49 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad20964; 20 Apr 87 17:45 EDT
Received: from ti-csl by RELAY.CS.NET id ap18098; 20 Apr 87 17:37 AST
Received: from Jenner (jenner.ARPA) by tilde id AA19015; Mon, 20 Apr 87 16:10:24 cdt
Message-Id: <2754940257-775701@Jenner>
Date: Mon, 20 Apr 87  16:10:57 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Object creation discussion (at last!)

David,

Another small point:

I did a census of :before and :after :init methods on our system:

There are 864 flavors,
          192  :before :init methods,
          336  :after :init methods.

The :after :init methods seem to be more common than :before :init.
Did you come up with a different count?

Patrick.


∂21-Apr-87  0812	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 21 Apr 87  08:12:20 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab05835; 21 Apr 87 11:06 EDT
Received: from ti-csl by RELAY.CS.NET id ab23071; 21 Apr 87 11:00 AST
Received: from Jenner (jenner.ARPA) by tilde id AA02583; Tue, 21 Apr 87 07:44:11 cdt
Message-Id: <2754996278-4141536@Jenner>
Date: Tue, 21 Apr 87  07:44:38 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Object creation discussion (at last!)
In-Reply-To: Msg of Mon, 20 Apr 87 16:55 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

     Date: Mon, 20 Apr 87 16:55 EDT
     From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
     Subject: Re: Object creation discussion (at last!)
     
         Date: Mon, 20 Apr 87  14:49:05 CDT
         From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
     
     	 Date: Fri, 17 Apr 87 14:49 EDT
     	 From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
          
     	 I can't understand what you're getting at here.
     
         In Common Lisp :allow-other-keys T
         does not apply to non-keywords like JUNK.
     
     I can't find any evidence for this except at the top of p.62 in CLtL where
     it says "It is an error for the first object of each pair to be anything
     but a keyword."  I was under the impression that it had been decided a
     couple of years ago that the last word in this sentence should have been
     "symbol", but perhaps that's not true.  Unfortunately I lost my copy, but
     I think this was in the proposed corrections and clarifications Guy Steele
     distributed in December 1985.

I didn't find any reference to this in the clarifications/corrections.
     
     I tell you what I'll do; I'll go find out the format for
     submissions to the cleanup subcommittee and send this in.  Let's
     proceed on the assumption that it will be accepted.

Sounds good.

∂21-Apr-87  1049	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Apr 87  10:49:03 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 120677; Tue 21-Apr-87 13:40:33 EDT
Date: Tue, 21 Apr 87 13:40 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Object creation discussion (at last!)
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2754940257-775701@Jenner>
Message-ID: <870421134012.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Mon, 20 Apr 87  16:10:57 CDT
    From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>

    I did a census of :before and :after :init methods on our system:

    There are 864 flavors,
	      192  :before :init methods,
	      336  :after :init methods.

    The :after :init methods seem to be more common than :before :init.
    Did you come up with a different count?

When I make these counts I try to exclude the window system, because I
don't consider its design representative of how things would be programmed
today.  Unless you've redesigned the MIT window system a lot more than we
have, that's probably true of your system as well.

Here are the make-instance methods I found (in my CLOS object creation
proposal these would be initialize-instance methods, and I have translated
the method qualifiers to the terminology of that proposal):
	224 methods total
	138 unqualified methods
	 81 :after methods
	  5 :around methods

I expected the fraction of :after methods to be lower than 36%.  I suppose
it would be good to study them and see why so many are being used, but that
would take more time than I wish to spend today.  Maybe later.

For completeness, here are the :init counts, but they are mostly window
flavors:
	293 methods total
	 92 :before methods
	 23 unqualified methods
	170 :after methods
	  8 :around methods

There is the same preponderance of :after methods, but because :init uses
:daemon method combination (thus almost anything that uses an unqualified
method is, in fact, broken) and because of the influence of the window
system, I don't think there is much to be learned from these numbers.

∂22-Apr-87  1348	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Apr 87  13:48:21 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 APR 87 13:44:58 PDT
Date: Wed, 22 Apr 87 13:42 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870422134241.3.GREGOR@AVALON.isl.parc.xerox.com>
Line-fold: no


I have a lot of comments and questions about this proposal.  I
originally tried to work them in with the running text, but that proved
too cumbersome given the general nature of my comments.  What's more,
this message itself isn't all that polished.  I thought it would be
better to send it out now so that you would have an idea of what I was
thinking.


My overall comment is that this proposal is a lot more complicated than
either of my previous proposals, in fact it doesn't seem to stress
simplicity at all.

Parts of this proposal provide important, useful and understandable
functionality, which I would like to see in CLOS.  Other parts add
considerable conceptual complexity and don't seem to add significant
functional gain.  The best example of this is the special method
combination type for initialize-instance.

After I send out this message I will begin working on another message
which lays out the framework of a proposal which incorporates all the
things I really like about your proposal.  I think that will be the best
way to make it clear what I have in mind.



My major objections are with:

*** special method combination for the initialize-instance 

The special method combination type for initialize instance adds
considerable conceptual overhead for very little functional gain.

I admit that the basic method combination rule is simple enough to
understand.  But there are other aspects of this method combination
types which will cause people to ask themeselves questions they will
have a hard time answering with any kind of simple model of this thing.

  - if I don't have to say &allow-other-keys here, why do I have to
    say it in the normal kind of method combination?

  - why is it that I can't count on the methods getting all the initargs
    if I use &rest in the lambda-list?  Note that this also robs useful
    functionality which exists everywhere else in Common Lisp.  Specifically,
    it makes the &rest args &allow-other-keys idiom not work.  This idiom
    is very useful for methods which want to process all the initargs in
    the init-plist in ways that makes those initargs interact.

  - If I redefine a initialize-instance method, will that effect the
    interpretation of all the :constructor lambda-lists involved?  Will
    all those :constructors get fixed?



*** the complex rules for interpreting the lambda-list of :constructors

These rules are just plain complicated.  In order to figure out what to
do, you need to know:

  The names of all the slots, inherited and local (simple enough).

  All the mappings to initargs of those slot names.  Inheriting
  this information is simple enough, but name mapping is confusing
  in general.

  All the :default-initargs inherited and local.  Once again,
  understanding the inheritance here is simple enough.

But putting all this together is pretty complicated.  Because it isn't
really three simple inheritance structures that are then combined.  I
don't think?  I think your rules may cover the following case, but I
don't believe its that simple to reason about.

(defclass foo () 
    ()
  (:default-initargs :bazola ()))

(defclass bar (foo)
     ((b :initarg :bazola)))

(defclass baz ()
    ()
  (:constructor make-baz (&key bazola)))

(defmethod initialize-instance ((a-baz baz) &key bazola)
  (setf (slot-value a-baz 'b) (list bazola (slot-value a-baz 'b))))


*** the overemphasis on getting speed out of the :constructors.

This proposal seems to be mostly focused on getting speed out of using
the :constructors.  While I agree that instance creation speed is
important, I am not sure that I like putting so much emphasis on doing
it using :constructors.

For one thing, from the user's point of view, I don't believe it is easy
to understand why constructors should be so much faster.  I don't
believe that the reasons why the :constructors are so much faster are
obvious.

For another thing, the ability to be able to compile the :constructors
into something fast leaks all over.  The rule that says that particular
initialize-instance methods can't count on getting the entire set of
initargs is an excellent example of this "leakage".




Other specific questions:

- what arguments does allocate-instance get?  at one point you say:

    From Moon:
    2. Initargs that control storage allocation are defined by defining an
    allocate-instance method that accepts the initarg as an &key argument.
    For example, in systems with areas :area is an initarg for step 2.
    The standard does not require any initargs to exist for step 2.

but how does this work?  why don't all the allocate instance methods
also have to say &allow-other-keys.




Things that I like and agree with:

Since I have been focusing on things I don't like, it may not be clear
what I do like. Let me try to make explicit some of the major points I
like and agree with.

I like the functionality provided by the :default-initargs option.  The
next proposal I will submit has this feature in a slighltly more
CommonLispy syntax. 

I agree that the initargs to make instance are "more abstract" than slots.

I agree that constructors should call initialization methods.

I agree that it is important for instance creation to be fast.  I agree
that :constructors are the best known way of doing this.

I agree that there should be no defclass option which specifies an
initarg for all the slots.

I probably agree with other, more subtle things that I don't remember
right now.
-------

∂22-Apr-87  1448	Gregor.pa@Xerox.COM 	CL types --> classes    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Apr 87  14:48:35 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 22 APR 87 14:48:02 PDT
Date: Wed, 22 Apr 87 14:46 PDT
From: Gregor.pa@Xerox.COM
Subject: CL types --> classes
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870422144631.4.GREGOR@AVALON.isl.parc.xerox.com>
Line-fold: no


This message is a brief summary of what I believe we decided about which
Common Lisp types could be classes.  This is take from Sonya's very
careful notes and my less careful memory.  If we pass this message back
and forth for a while it could probably become a draft of a section in
the design rationale document.

I plan to send something like this (hopefully after it is improved by
the other people on this list) to the CommonLoops list to explain the
changes I am making in built-in classes in the next release of PCL.



Take table 4-1 from CLtL (page 43).  From that table, the following
types do NOT have corresponding classes:

ATOM

This is a negation type.

STANDARD-CHAR STRING-CHAR BIT FIXNUM BIGNUM

We decided not to do subranges.

COMMON STREAM FUNCTION

Specification in CLtL too vague.  It would be nice if X3J13 fixed stream
and function though.

KEYWORD

Class can change by setf of symbol-package.

SIMPLE-ARRAY SIMPLE-BIT-VECTOR SIMPLE-STRING SIMPLE-VECTOR

?? What is the reason for this ??

PACKAGE READTABLE RANDOM-STATE HASH-TABLE PATHNAME

CLtL only requires that these types be disjoint with each other.  We
would like X3J13 to fix these too.

SHORT-FLOAT LONG-FLOAT SINGLE-FLOAT DOUBLE-FLOAT

I don't believe we excluded these but I believe either Pavel or Patrick
said they would write up the rules about how these work.

-------

∂22-Apr-87  1533	Pavel.pa@Xerox.COM 	Re: CL types --> classes 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Apr 87  15:33:09 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 APR 87 15:19:17 PDT
Date: 22 Apr 87 15:19 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: CL types --> classes
In-reply-to: Gregor.pa's message of Wed, 22 Apr 87 14:46 PDT
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870422-151917-4178@Xerox>

    SHORT-FLOAT LONG-FLOAT SINGLE-FLOAT DOUBLE-FLOAT

    I don't believe we excluded these but I believe either Pavel or
    Patrick said they would write up the rules about how these work.

I indeed said that I would write these up.  I'll be able to get to it later this week.

	Pavel

∂22-Apr-87  1637	Gregor.pa@Xerox.COM 	note about clos instance disjointness  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Apr 87  16:37:24 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 APR 87 16:37:59 PDT
Date: 22 Apr 87 16:37 PDT
From: Gregor.pa@Xerox.COM
Subject: note about clos instance disjointness
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870422-163759-4304@Xerox>

I don't know exactly where this would fit in in the document, but we
need to say that instances of standard-classes have type disjoint with
all other types.  This is kind of obvious of course, but should be made
explicit.

∂22-Apr-87  1639	Gregor.pa@Xerox.COM 	funcallable-standard-class   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Apr 87  16:39:50 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 APR 87 16:40:52 PDT
Date: 22 Apr 87 16:40 PDT
From: Gregor.pa@Xerox.COM
Subject: funcallable-standard-class
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870422-164052-4316@Xerox>

Another note just to record something we all need to think about.

We need to document the metaclass which generic-function classes use.
This is so that people can define their own generic-function classes
(the need to know what :metaclass to specify).

Also, the funcallable-instance functionality is useful enough, and easy
enough to document that I think we should make it generally available.

This note will serve to remind me to mail out a proposal about this
based on what is now in PCL.

∂22-Apr-87  1729	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Apr 87  17:29:01 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 APR 87 17:30:04 PDT
Date: Wed, 22 Apr 87 17:28 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870422172838.5.GREGOR@AVALON.isl.parc.xerox.com>
Line-fold: no


OK, here is a try at a counter proposal which tries to show what I do
and don't like about your proposal.  This isn't finished yet, once again
I thought it would be better to send it out now so that you could see
where I was headed.

Basically, my proposal keeps these features from your proposal:

  :initarg slot option
  :default-initargs defclass option (different syntax)
  make-instance processes slot initargs or evaluates initforms
  constructors can be faster because they can inline stuff

and gets rid of these:
 
  the new method combination type for initialize instance
  using &key in an initialize-instance method augments legal initargs


SO:

The :initarg slot option can be used to teach make-instance the name of
an initarg which can be used to initialize the value of this slot from
the initargs passed to make-instance.  The way to think of this option
is that it implements the abstract initarg name to slot name mapping for
make-instance.  For convenience, specifying an :initarg name in a slot
description also includes that initarg name in the :default-initargs of
the defclass.


The default-initargs defclass option serves two purposes.  It specifies
all the initargs which can be passed to make-instance of this class, and
it specifies default values for some of those initargs.  The syntax of
this option is a lot like the part of a lambda-list following &key
(which serves two similar purposes).  For example:

   (:default-initargs :foo :bar (:baz 3))

says that this class accepts initargs :FOO, :BAR and :BAZ.  Furthermore,
the default value of the :BAZ initarg is 3.  The default values of :FOO
and :BAR are both nil.

So, a defclass form like this:

   (defclass position ()
       ((x :initarg :x)
        (y :initarg :y))
     (:default-initargs (:x 0) (:y 0) :rho :theta))

can be read as saying:  make-instance with a first argument of POSITION
accepts 4 initargs (:x :y :rho :theta).  The default value for :x and :y
is 0; the default value for :rho and :theta is nil.  When make-instance
is called, it sets the value of the x slot of the instance to the value
of the :x initarg ..(same for y and :y).


make-instance calls allocate-instance generic-function with all the
initargs (the ones passed to make-instance plus any defaulted ones).  It
then sets the values of any slots for which initargs appear in the
initargs, it then sets the values of the remaining slots from their
initforms.  It then calls the intialize-instance generic-function with
all the initargs.

constructors can be thought of as providing a "boa" syntax for specific
calls to make-instance.  Because make-instance is a function and not a
generic-function, constructors are allowed to "perform the same actions
calling make-instance would have" rather than calling make-instance
directly.  As a result, in many implementations, constructors are faster
than the corresponding call to make-instance.  To produce the "call to
make-instance" a constructor interprets its lambda-list as follows:

  - if an element of its lambda-list names an initarg acceptable to
    this class, then that initarg pair will appear in the "call to
    make-instance".

  - if an element of the lambda list does not name an initarg, but
    names a slot this is an abbreviation for defining a gensymed initarg
    for that slot and using that gensym.
    [This needs work or perhaps need to be removed.  I want to try
     to make this case be an abbreviation for something that is
     already understood.]

  - if neither of the above are true, calling the constructor signals
    an error.  Some implementations may warn earlier of course.



initialize-instance uses the default kind of method combination.  Note
that all initialize-instance methods should say &allow-other-keys.
Under some programming styles, many initialize-instance methods will be
:before methods.  Under other programming styles they will not be, they
will probably use call-next-method.
-------

∂23-Apr-87  0953	kempf%hplabsc@hplabs.HP.COM 	Re: CLOS Type Cleanup
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 23 Apr 87  09:51:39 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 23 Apr 87 08:13:56 pst
Received: by hplabsc ; Thu, 23 Apr 87 08:14:08 pst
Date: Thu, 23 Apr 87 08:14:08 pst
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8704231614.AA11598@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: CLOS Type Cleanup


Gregor's list looks accurate.

One comment on FUNCTION. If X3J13 fixes this, then a nice solution
about what to do with funcallable instances might be to make them
a subclass of FUNCTION.

		jak

∂23-Apr-87  1225	kempf%hplabsc@hplabs.HP.COM 	Re: (long) CLOS Declaration Proposal Text
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 23 Apr 87  12:25:23 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 23 Apr 87 09:10:55 pst
Received: by hplabsc ; Thu, 23 Apr 87 09:09:09 pst
Date: Thu, 23 Apr 87 09:09:09 pst
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8704231709.AA12554@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: (long) CLOS Declaration Proposal Text

Some additional comments on the declaration discussion,
and Moon's reply. Dick Gabrial, are you still there?

>    5) If method combination is prohibited for a certain method,
>    any overhead which is needed to support method combination
>    in the general case could be avoided.
>
>I agree that this is a non-issue.

OK, then, unless anyone else objects, we can drop any consideration
of declarations for method combination.

>    (CLASS FOO X)
>
>I think (EXACT-CLASS FOO X) has a lot less potential for confusion.

This syntax is fine with me.

>    a user may want to restrict a particular name to be a generic function
>
>I don't see why.  I suggest leaving this out unless there is a good
>reason for it (which should be articulated).

I would like to see this resolved in the context of the GFLET,
GFLABELS, and GLAMBDA proposals discussed earlier. In particular,
I would like the ability to say:

	(MAPCAR <some local generic function> LIST-OF-OBJECTS)

and not have to do a global definition of the methods. A GENERIC-FUNCTION
declaration might allow us to get away without introducing GFLET
and GFLABELS. For example, the following could be legal:

	(DEFUN EXAMPLE (OBJECT-LIST)
	  (FLET
		(FOO ((A FOO-CLASS)) A)
		(FOO ((B BAZ-CLASS)) B)
           )
	   (DECLARE (GENERIC-FUNCTION FOO))

	   (MAPCAR #'FOO OBJECT-LIST)
	)

or some similar syntax. Notice that this will not resolve the problem
of GLAMBDA, however.

>When a user creates a subclass of a "staticized" class, rather than
>changing the semantics in some unclear way, I suggest signalling an
>error if there is a conflict between the semantics frozen into the
>superclass and the semantics that would exist if the superclass had not
>been "staticized".  The design principle here is that adding a
>"staticize" declaration to a working program shouldn't change what it
>does, only how fast it does it.

I agree here.

>The name MAKE-STATIC isn't the best.  To me, it connotes a function that
>returns an object that I can hand to the WRITE-SOUND function and get an
>ugly noise from the speaker in my console.  FREEZE-CLASS would be better.

I like the idea of using FREEZE-<something> for optimization and other
postdevelopment processing. I would suggest the following additions to
the metaobject protocol for this purpose:

FREEZE-REDEFINITION  <class>

Takes a class object as an argument and causes the definition of the
class to be frozen. Any attempt to redefine the class will cause an
error to be signalled. In order for a class's definition to be frozen,
all superclass definitions must be frozen as well. An error will be
signalled if this is not the case.

FREEZE-SLOT-LAYOUT <class>

Causes slots to be located at fixed offsets if the class is used as
a superclass during inheritence. Signals an error if all superclasses
do not have frozen slot layout as well.

FREEZE-CLASS-PRECEDENCE-LIST <class>

The class precedence list for the class argument is calculated (if
it hasn't already been) and the class precedence for subclasses
is frozen. An attempt to define a subclass whose included direct
supers would cause a difference class precedence ordering causes
an error to be signalled. An error is signalled if all superclasses
of the class argument do not have frozen class precedence lists
as well.

	jak

∂23-Apr-87  1249	kempf%hplabsc@hplabs.HP.COM 	Re: Object Creation Discussion (at last!)
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 23 Apr 87  12:48:38 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 23 Apr 87 08:02:47 pst
Received: by hplabsc ; Thu, 23 Apr 87 08:03:20 pst
Date: Thu, 23 Apr 87 08:03:20 pst
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8704231603.AA11434@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Object Creation Discussion (at last!)

Comments on Moon's creation note (and subsequent discussion):

OVERALL COMMENTS:

I agree with Gregor that the proposal needs simplification. The
special method combination type, the overemphasis on constructor
speed (they could be simply declared IN-LINE) and the complex
rules for lambda-list interpretation need some reworking.

In addition, I would like to see the syntax for the :INITFORM, :INITARG,
and :DEFAULT-INITARG options better integrated (see below for addition to 
Gregor's suggestion).

SPECIFICS:

*On symbols as initarg keys:

>  "initargs" (initialization arguments) are a set of named arguments that
>  control object creation and initialization.  Each initarg has a name, which
>  is a symbol (not necessarily a keyword), and a value.  The arguments to
>  make-instance, excepting the first, taken in pairs, are initargs.

Subsequent discussion has cleared up this point as a potential area
of incompatibility which needs a cleanup committee proposal.

*On storage allocation:

>   Also customizable by the metaclass, because the metaclass controls the
>   stored representation of instances.

This should probably be the "recommended" way of doing things.
Though it's probably not a good idea to prohibit it, I think it
should be encouraged for portability reasons. The metaobject protocol
should be the lowest level, portable interface into the object system.
Anything below should be system dependent.

*On the proposed additional slot and class definition options:

>3. Customizable by slot-description, which specifies a default value for the
>   slot and whether the slot can be filled with a value specified by the
>   client; if so, the slot-description specifies the name of the initarg
>   whose value is stored into the slot.
>The :default-initargs defclass option is followed by alternating initarg
>names and forms.  If an initarg is not specified by the client nor by
>a :default-initargs option in a more specific class, the form is evaluated
>in the lexical environment of the defclass and the resulting value is used
>for the initarg.

From subsequent discussion, it seems as if an additional DEFCLASS
option, :DEFAULT-INITARGS is being proposed. I wonder if this
is needed, considering that a user can already specify an initialization
value via the :INITFORM option? Perhaps the metaclass ought to 
attend to this? Or the :INITFORM and :DEFAULT-INITARGS options should
be merged?

In particular:

>So, a defclass form like this:
>
>	(defclass position ()
>	  ((x :initarg :x)
>	   (y :initarg :y))
>	   (:default-initargs (:x 0) (:y 0) :rho :theta))
>

Consider what the syntax would be if you wanted to specify an initform
as well:

	(defclass position ()
	  ((x :initarg :x :initform 0)
	   (y :initarg :y :initform 0))
	   (:default-initargs (:x 0) (:y 0) :rho :theta))

So why not simplify this as:

	(defclass position ()
	  ((x :initarg (:x 0))
	   (y :initarg (:y 0)))
	   ( <some appropriate key> :rho :theta)
	)

Semantics are:

1) If MAKE-INSTANCE is called without an initialization list,
the initialization values of X and Y are set to zero.

2) If initialization values are supplied in the initialization list,
then they are used.

3) :RHO and :THETA are valid as keys for initargs to MAKE-INSTANCE in
any case. If no value is given, then they are NIL.

A suggestion for <some appropriate key> would be :ADDITIONAL-INITARGS.

*On MAKE-INSTANCE and modules:

>>> Is make-instance an intra-module or inter-module interface?
>
>Both.
>
>>> Do the arguments to make-instance correspond directly to actual stored
>slots, or are they a more abstract concept, whose implementation in terms
>of slots or in terms of something else is hidden from the caller?
>
>More abstract, because make-instance is often used as an inter-module

I don't understand. What is understood here by the word "module"?
Has it any relation to *MODULES* on pg. 188 and thus to the
PROVIDE/REQUIRE mechanism?

*On constructors:

>>> What is the lambda-list of a constructor created by a :constructor
>option with no lambda-list specified?
>
>It accepts the same arguments as make-instance, excepting the first.
>
>>> Do constructors call initialization methods?
>
>Yes.
>
>>> Why do we have a :constructor option to defclass?
>
>For speed; make-instance is interpretive, while constructors are compiled,
>since they know the exact class that they are constructing, and since they can
>be automatically recompiled if the class or any of its superclasses changes.

I'm not quite sure how this fits in with the metaclass protocol.
What if a user defines a constructor function to make an object out
of a list, or to return a symbol? If the constructor function tries
to call initializaton methods, then what will be the result? Also,
if the initialization succeeds, method definition and lookup might
do the wrong thing if the low level structure of an instance is
not what is expected. As an example, say the constructor function
returns an integer, and there are two methods on a generic function,
one with an INTEGER selector and one with the same class as the
erring constructor function. 

In addition, I think the IN-LINE declaration could help getting speed
out of a constructor.

*On the context in which an initialization is run:

>The :initarg slot-option specifies that this slot can be filled in, and
>specifies the initarg name.  This slot-option can be given more than once.
>
>There is no defclass option that specifies initargs for all the slots,
>because that would endorse a particular convention for naming initargs.
>

Are the initforms run in the context of INITIALIZE-INSTANCE? Is WITH-SLOTS
acceptable within an initform?


I think this proposal would satisfy Dave Martin's request for initialization
hooks. I'm enclosing his message on this below.

	jak

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

Well, what we currently have is the following:

defmethod initialize ((self new-object) init-plist)
	(initialize-from-defaults self)
	(initialize-from-init-plist self init-plist)
	(apply #'new-instance self init-plist))

Where the new-instance function is defined to do nothing for new-object but
takes an arbitrary list of keywords (generally including slot names) to
set the values.

What I would *like* to see is the function initialize (or some other name)
initialize from the defaults, and then initialize from the init-plist only
on slots keywords (this is what we do, I rewrote initialize-from-init-plist
to ignore non-keyword slots) and then call a class specific function to
do the remaining setup.  It would be nice if slots which were read-only
were still settable inside the initialization code (e.g. the resource id of
a window object should be read-only, but I can't set it until the new-instance
function is called).

I was thinking about changing the initialize function to do the following:
1) initialize from the default value of each keyword slot; 2) use the setf
function for setting from the init-plist argument for any keywords which 
correspond to slots; and 3) call a user-specifiable routine (i.e. have a slot
in the class called initialize-method) which would be mandatory for each class
and would be hacked to allow call-next-method to find the appropriate method
for the super classes even if the method name differed.

With this setup we avoid having to set aside new-instance as a reserved 
name, allow the system to set slot values appropriately (using the setf method
should be a flaggable option), and hopefully be able to reduce the size
of the new-instance function.

∂23-Apr-87  1456	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: CLOS Declaration Proposal    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Apr 87  14:56:52 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 123315; Thu 23-Apr-87 17:53:57 EDT
Date: Thu, 23 Apr 87 17:53 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: CLOS Declaration Proposal
To: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8704231709.AA12554@hplabsc>
Message-ID: <870423175345.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

The only problem with using functions, rather than defclass options,
to freeze attributes of classes is how to make these functions take
effect at compile time, which is when they have to take effect to be
of any use.  Propose something.

∂23-Apr-87  1722	kempf%hplabsc@hplabs.HP.COM 	Re: CLOS Declaration Proposal  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 23 Apr 87  17:22:03 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 23 Apr 87 15:38:10 pst
Received: by hplabsc ; Thu, 23 Apr 87 15:27:22 pst
Date: Thu, 23 Apr 87 15:27:22 pst
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8704232327.AA18524@hplabsc>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, kempf%hplabsc@hplabs.HP.COM
Subject: Re: CLOS Declaration Proposal
Cc: common-lisp-object-system@sail.stanford.edu

I understand the problem. I can see two possible solutions. 

1) Introduce a declaration which invokes the metaclass functions.
Something like:

	(PROCLAIM '(FREEZE-CLASS-PRECEDENCE-LIST FOO))

in the DEFSYS file would cause the class precedence list to be
frozen.

2) Leave it up to use of (EVAL-WHEN (COMPILE EVAL)  ... ) to
do it.

I don't like either of these much, but like a defclass option even
less, since there are already so many.

I'll give it some more thought. Thanks for pointing this out.

		jak

∂23-Apr-87  2020	Gregor.pa@Xerox.COM 	Re: Object Creation Discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Apr 87  20:20:33 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 APR 87 18:24:27 PDT
Date: 23 Apr 87 18:24 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object Creation Discussion (at last!)
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Thu,
 23 Apr 87 08:03:20 pst
To: kempf%hplabsc@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870423-182427-1534@Xerox>

    Date: Thu, 23 Apr 87 08:03:20 pst From: Jim Kempf
    <kempf%hplabsc@hplabs.HP.COM>

    From subsequent discussion, it seems as if an additional
    DEFCLASS option, :DEFAULT-INITARGS is being proposed. I wonder if
    this is needed, considering that a user can already specify an
    initialization value via the :INITFORM option? Perhaps the
    metaclass ought to  attend to this? Or the :INITFORM and
    :DEFAULT-INITARGS options should be merged?

I don't think we have reduced initialization to its fundamental
components yet.  In this message I am trying to attack some of our
assumptions to see if that can help us get at those fundamental
components.


What if we got rid of :initform??  

What is the purpose of :initform anymore?  You only need it when you
want to specify the default value for a slot that isn't set by any
initarg.  This means that we have two mechanisms which do almost the
same thing -- initargs which set slots are almost a superset of
initforms.  This is a sure sign of bad modularity.  

Let's just pretend you didn't have initforms but that you did want to be
able to have some slots which had "default values" but which weren't
initable from the initargs passed to make-instance.

(in the terminology of all previous proposals:
   (defclass position () ((x 0) (y 0)))


now, adopting a slighlty different syntax for :default-initargs, you
could say:

(defclass position ()
    (x
     y)
  (:default-initargs (:moosefish1 0 x)
                     (:moosefish2 0 y)))

(apologies to Alan Snyder)

This new syntax for default-initargs reads:

  ":moosefish1 is an initarg whose default value is 0 and which
make-instance
    uses to set the value of the x slot..."

:moosefish1 is some name which is chosen to be weird enough that no-one
will ever use it.  So, "in-effect" the slots are not initable in the
call to make-instance.  When the initialize-instance generic-function is
called (whether that call is open coded or not) the values of the x and
y slots are sure to be 0.

:moosefish1 is silly of course (more apologies to Alan), but what about
something like:

(defclass position ()
    (x
     y)
  (:default-initargs (nil 0 x)
                     (nil 0 y)))

What I am trying to do is seperate what I perceive as the separate parts
of what is going on into separate places.

  1. the structure of the instance is specified, the slots and their
allocation.
  2. the legal initarg names are specified
  3. the default values for the initargs are specified
  4. automatic initialization of the values of some of the slots by
     make instance is specified.


the slot descriptions specify 1 (the structure of the instance)
the cars of the :default-initargs option arguments specify the legal
initarg names
the cadrs specify the default value
the caddrs specify which slots are set from the value.

think of the :default-initargs syntax as being something like the syntax
of what follows &key in a lambda list except reversed, so each can be
one of:

   initarg | (initarg default-value) | (initarg default-value slot-name)

∂23-Apr-87  2132	Moon@STONY-BROOK.SCRC.Symbolics.COM 	CL types --> classes   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Apr 87  21:32:39 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 123676; Fri 24-Apr-87 00:32:46 EDT
Date: Fri, 24 Apr 87 00:32 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: CL types --> classes
To: Common-Lisp-Object-System@Sail.Stanford.edu
In-Reply-To: <870422144631.4.GREGOR@AVALON.isl.parc.xerox.com>
Message-ID: <870424003237.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 22 Apr 87 14:46 PDT
    From: Gregor.pa@Xerox.COM

My notes generally agree with your message.  Here are the differences
and extensions:

They say COMPILED-FUNCTION is in the same boat with FUNCTION.

    KEYWORD

    Class can change by setf of symbol-package.

There was an argument about whether Common Lisp allows setf of
symbol-package, but I think we came up with a way to use IMPORT to
change something that isn't a keyword into a keyword.  Traditionally
the type of an object is something you can't change.  Does the
existence of CHANGE-CLASS mean that KEYWORD should be a class?
I feel like leaving out KEYWORD on the basis that extra classes
shouldn't be put in if they aren't clearly useful, but this is an
issue that could go either way.

    SIMPLE-ARRAY SIMPLE-BIT-VECTOR SIMPLE-STRING SIMPLE-VECTOR

    ?? What is the reason for this ??

Subrange is scrawled next to these on my notes.  If these are
subranges then KEYWORD is too.

    PACKAGE READTABLE RANDOM-STATE HASH-TABLE PATHNAME

    CLtL only requires that these types be disjoint with each other.  We
    would like X3J13 to fix these too.

There are probably a lot of implementations in which one or more of these
is a subtype of ARRAY.  That might be hard to fix efficiently?

No list type-specifier names a class and no deftype names a class, say
my notes.

    SHORT-FLOAT LONG-FLOAT SINGLE-FLOAT DOUBLE-FLOAT

    I don't believe we excluded these but I believe Pavel
    said he would write up the rules about how these work.

The issue was that if there are methods defined for both
SHORT-FLOAT and SINGLE-FLOAT, but these types are collapsed into
one, the precedence order of the methods is not well-defined.
The only thing we thought of in the meeting was to signal an error
when this happens, but I suspect that would be unsatisfactory in
practice.

In the precedence relationships for built in classes with
multiple direct superclasses, I think we decided on

(defclass null (list symbol) ...)
(defclass vector (array sequence) ...)
(defclass list (cons sequence) ...)

Are we ready to write this up yet?

∂26-Apr-87  2231	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 Apr 87  22:30:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 124868; Mon 27-Apr-87 01:31:17 EDT
Date: Mon, 27 Apr 87 01:30 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object creation discussion (at last!)
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870416002258.1.MOON@EUPHRATES.SCRC.Symbolics.COM>,
             <870421134012.6.MOON@EUPHRATES.SCRC.Symbolics.COM>,
             <870422134241.3.GREGOR@AVALON.isl.parc.xerox.com>,
             <870422172838.5.GREGOR@AVALON.isl.parc.xerox.com>,
             <8704231603.AA11434@hplabsc>,
             <870423-182427-1534@Xerox>
Message-ID: <870427013057.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

I can see from the misunderstanding in the mail that I did an abysmal job
of communicating my ideas.  I'll try to send a more comprehensible essay
tomorrow, but for now I would like to just clarify a couple of points and
then make some comments on excerpts from the mail in places where they
might help communication.

Complexity and simplicity are partly matters of taste, and largely matters
of point of view.  I try to take the point of view of the majority of
programmers, who are using the outer interfaces of the system without
necessarily understanding everything that's going on inside.  No matter how
beautifully we explain it, most programmers simply won't read beyond the
point where they think they know everything they need to know to get their
immediate job done.  Now, it may be that we will decide that we would
rather make life more complicated for people writing initialization methods
in order to make the conceptual explanation shorter.  That would be okay
with me if it's done for good reasons, but we shouldn't just dismiss the
other way without understanding it and understanding why I proposed it.  I
have a feeling this message isn't going to explain it adequately either,
and if that happens I will apologize and follow up with a more carefully
written explanation.

One key point that I was trying to convey, and I think partially succeeded,
was the need for information hiding (abstraction) in the arguments to
make-instance and in relations among the various initialization
specifications attached to a class and its superclasses.

Another key point, which I don't think came through, was that each initarg
should be explicitly defined, and should be defined in exactly one place.
This is simply good modularity.

Some aspects of what I proposed were reacting to user complaints about the
way Flavors does it.  I have the ambition of making this new standard
better than Flavors.

All this leads to the idea that initargs of types 2 and 4 (in the
nomenclature of my 16 Apr message) should be defined by methods, since
their meaning is implemented by methods.  Similarly, type 3 should be
defined by slot-options, since their meaning is entirely involved with
slots.  In Flavors, type 4 have the ugly property that they have to be
defined in two places, once in the method that implements them and again in
a defflavor form; it's easy to get these two places out of sync.  Hence the
proposal to use the lambda-list of a defmethod as the way to define these
initargs.  Along with this, I tried to eliminate clunky syntax from
initialization methods, hence the elimination of &allow-other-keys and the
elimination of having to write :before all the time.  If this is too
confusing, we could invent a new syntax that both defines initargs and
defines the method that implements them.  Clearly this is the weakest part
of my proposal.

We could obviously simplify things a lot by getting rid of the :constructor
option to defclass.  I didn't put it in, at least not this year.  I do think
it ought to remain, in spite of its inherent complexity in any initialization
proposal (previous ones I've seen have glossed over this rather than solving
it), because I believe many users will find it quite useful.

    Date: Wed, 22 Apr 87 13:42 PDT
    From: Gregor.pa@Xerox.COM

    The special method combination type for initialize instance adds
    considerable conceptual overhead for very little functional gain.

The goal was not functional gain, that is, the ability to program something
you couldn't program before, but rather syntactic simplicity.  Perhaps in
the end we'll decide it's not worth it, but I'd like us to keep considering
the question a bit longer.

    I admit that the basic method combination rule is simple enough to
    understand.  But there are other aspects of this method combination
    types which will cause people to ask themeselves questions they will
    have a hard time answering with any kind of simple model of this thing.

      - if I don't have to say &allow-other-keys here, why do I have to
	say it in the normal kind of method combination?

True, this is a problem.

      - why is it that I can't count on the methods getting all the initargs
	if I use &rest in the lambda-list?  Note that this also robs useful
	functionality which exists everywhere else in Common Lisp.  Specifically,
	it makes the &rest args &allow-other-keys idiom not work.  This idiom
	is very useful for methods which want to process all the initargs in
	the init-plist in ways that makes those initargs interact.

I can't figure out precisely all you're saying here, but I think this just
stems from a half-baked idea that I wouldn't have included in the proposal
if I had spent more time thinking about it before sending it.  I was trying
to do an efficiency optimization involving not consing lists of slot-filling
initargs that have been defaulted, and I now think that was premature.  We
can revisit the question after the major framework is agreed upon, plus I
always (except when I fall from grace) believe in the principle that designs
should first consider what is right, and optimizations should be subordinate
to that, fitting into an existing framework rather than distorting it.

      - If I redefine a initialize-instance method, will that effect the
	interpretation of all the :constructor lambda-lists involved?  Will
	all those :constructors get fixed?

Of course the constructors have to get fixed if you change something in a
way that changes the compiled code that was supposed to have been generated
for them.  I think that fact is independent of details of all object
creation proposals.  The specific example that I think you were thinking
about is when a positional parameter of a constructor is changed from
something that only fills a slot and isn't cared about by initialize
methods, to something that both fills a slot and is seen by initialize
methods.  In my proposal, adding an initialize-instance method could do
this.  In your most recent one, evaluating a defclass could do this.

    *** the complex rules for interpreting the lambda-list of :constructors
    .... example elided ....

I don't see any problem here that I added.  The lambda-list syntax of
constructors is like defstruct, not like defun, but that's already in
87-002.

Your example also touches upon the lambda-list of initialize-instance
methods.  Here the default for an argument that is already defaulted by
defclass options would never be used, because all calls that reached the
initialize-instance method would necessarily have to supply that argument. 
But I don't think there's anything new to Common Lisp in that.

    - what arguments does allocate-instance get?  

allocate-instance was intended to work exactly like initialize-instance,
however the latter turns out.

    Date: Wed, 22 Apr 87 17:28 PDT
    From: Gregor.pa@Xerox.COM

    The default-initargs defclass option serves two purposes.  It specifies
    all the initargs which can be passed to make-instance of this class, and
    it specifies default values for some of those initargs.  

This is an important modularity mistake, in my opinion.  By combining these
two things, which ought to be separate, you have lost the ability for one
class to specify a default value for an initarg defined by another class. 
If specifying a default value always defines an initarg, there is no way to
check the consistency of the set of initargs with default values specified
against the set of initargs actually defined.  If there is a misspelling,
the default value will simply be discarded, since no method will receive it
and do something with it.

    constructors can be thought of as providing a "boa" syntax for specific
    calls to make-instance.  

This can't work as long as constructors are allowed to fill slots that
make-instance is not allowed to fill, which I think is an important ability
because it gives the programmer more control over interfaces.

    Date: Thu, 23 Apr 87 08:03:20 pst
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    From subsequent discussion, it seems as if an additional DEFCLASS
    option, :DEFAULT-INITARGS is being proposed. I wonder if this
    is needed, considering that a user can already specify an initialization
    value via the :INITFORM option? Perhaps the metaclass ought to 
    attend to this? Or the :INITFORM and :DEFAULT-INITARGS options should
    be merged?

This indicates that I completely failed to convey what :default-initargs is
about, and that in turn may possibly indicate that :default-initargs should
be flushed.  In my proposal there are two ways to specify a default for an
initarg: at the point of definition, and remotely.  To explain: when
defining an initarg one can specify right there, locally, a default value
form.  For initargs that fill slots, this is the existing :initform
slot-option; no need to invent anything new there.  For initargs that are
implemented by methods, this is the existing defaulting mechanism in the
lambda-list; again, no need to invent anything new.  Now for remote
defaulting: here the idea is that one class defines what an initarg means,
while a second class specifies a default for it; this is :default-initargs.
When you mix the two classes together, the default meets up with the
implementation and things work.  The reason remote defaulting is desirable
is twofold: (1) it's often useful when mixing classes together for one
class to customize another class by specifying initialization options, in
addition to the existing ability to customize a class by shadowing or
wrapping methods; (2) for modularity reasons, when class A customizes class
B by specifying an initarg that class B defines, class A shouldn't have to
know whether the initarg fills a slot or is implemented by a method.  If
not for reason (2), remote defaulting wouldn't require a new mechanism,
because it could be implemented using the existing mechanism of :initform
for slot initargs plus call-next-method-with-arguments (proposed but not
yet accepted) for method initargs.  But I think reason (2) is important.

    I don't understand. What is understood here by the word "module"?
    Has it any relation to *MODULES* on pg. 188 and thus to the
    PROVIDE/REQUIRE mechanism?

No relation.  I meant the general computer-science concept of modules as
subdivisions of a program that have some independence from each other, not
something realized as an object in an implementation.

    What if a user defines a constructor function to make an object out
    of a list, or to return a symbol? If the constructor function tries
    to call initializaton methods, then what will be the result? Also,
    if the initialization succeeds, method definition and lookup might
    do the wrong thing if the low level structure of an instance is
    not what is expected. As an example, say the constructor function
    returns an integer, and there are two methods on a generic function,
    one with an INTEGER selector and one with the same class as the
    erring constructor function. 

    In addition, I think the IN-LINE declaration could help getting speed
    out of a constructor.

By "constructor", I meant the functions defined by the :constructor option
to defclass.  The syntax of that option doesn't admit any of the above
possibilities.

I wonder if you were getting at a different issue: what if the value
returned by the allocate-instance method is not an instance of the exact
class being instantiated?  If the caller of allocate-instance simply
assumes the type of this value is correct, all kinds of terrible things
could happen, especially if slot-filling is open-coded in constructors. 
Danny's chapter 3 speaks of "recognizable blocks of storage", and I think
we need to say something like that here.  I think this issue is largely
independent of the other details of object creation proposals, and needs to
be resolved on its own.  It's hard for me to say much about it since I don't
understand why anyone would need to customize allocate-instance.

    Are the initforms run in the context of INITIALIZE-INSTANCE? 

We agreed some time ago that they are in the lexical environment in which
the defclass was evaluated.

    Is WITH-SLOTS acceptable within an initform?

WITH-SLOTS works everywhere (although it works more efficiently in some
places).  However, the object being created is not lexically available in
the environment of initforms, so it isn't possible to access its slots.

Some people have proposed that the object and the initargs be lexically
available to initforms, and this does open some intriguing expressive
possibilities.  However, I think I prefer to say that anything this
complicated should be done in initialize-instance methods instead.

    Date: 23 Apr 87 18:24 PDT
    From: Gregor.pa@Xerox.COM

    What is the purpose of :initform anymore?  You only need it when you
    want to specify the default value for a slot that isn't set by any
    initarg.  This means that we have two mechanisms which do almost the
    same thing -- initargs which set slots are almost a superset of
    initforms.  This is a sure sign of bad modularity.  

On the contrary, I think it's a sign of good modularity!  The two
mechanisms do almost the same thing inside the implementation, but from the
point of view of someone on the outside who doesn't know the information
that is supposed to be hidden from him by modular abstraction, they do
rather different things.  I could give a longer explanation of what I mean,
but it's late, this message is already too long to ask anyone to read
carefully, and I think I would just be repeating what I said a bit earlier.

    (defclass position ()
	(x
	 y)
      (:default-initargs (nil 0 x)
			 (nil 0 y)))

    What I am trying to do is seperate what I perceive as the separate parts
    of what is going on into separate places.

The reason I don't like this is that the information about a slot is no
longer all in one place.  Another way of saying it is that I think that
information in defclass should be organized spatially rather than
temporally, i.e. information pertaining to one slot should be together,
rather than putting information pertaining to one phase of object creation
together.  One of the ways that I think defclass is better than defflavor
is that it has done a better job of spatial organization by putting more
of the information about a slot into slot options instead of scattering it
around in various options some of which refer back to the slot by name.

∂27-Apr-87  1329	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Object creation discussion (at last!)   
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 27 Apr 87  13:29:14 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab26381; 27 Apr 87 16:20 EDT
Received: from ti-csl by RELAY.CS.NET id ah07490; 27 Apr 87 16:17 EDT
Received: from dsg (juliett.ARPA) by tilde id AA04504; Mon, 27 Apr 87 14:27:09 cdt
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 27 Apr 87  14:28:46 CDT
Message-Id: <2755538893-1609268@Jenner>
Date: Mon, 27 Apr 87  14:28:13 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Object creation discussion (at last!)
In-Reply-To: Msg of Mon, 27 Apr 87 01:30 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

     Date: Mon, 27 Apr 87 01:30 EDT
     From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
     Subject: Object creation discussion (at last!)
     
     I can see from the misunderstanding in the mail that I did an abysmal job
     of communicating my ideas.  I'll try to send a more comprehensible essay
     tomorrow, but for now I would like to just clarify a couple of points and
     then make some comments on excerpts from the mail in places where they
     might help communication.
     
     Complexity and simplicity are partly matters of taste, and largely matters
     of point of view.  I try to take the point of view of the majority of
     programmers, who are using the outer interfaces of the system without
     necessarily understanding everything that's going on inside.  No matter how
     beautifully we explain it, most programmers simply won't read beyond the
     point where they think they know everything they need to know to get their
     immediate job done.  Now, it may be that we will decide that we would
     rather make life more complicated for people writing initialization methods
     in order to make the conceptual explanation shorter.  That would be okay
     with me if it's done for good reasons, but we shouldn't just dismiss the
     other way without understanding it and understanding why I proposed it.  I
     have a feeling this message isn't going to explain it adequately either,
     and if that happens I will apologize and follow up with a more carefully
     written explanation.
     
     One key point that I was trying to convey, and I think partially succeeded,
     was the need for information hiding (abstraction) in the arguments to
     make-instance and in relations among the various initialization
     specifications attached to a class and its superclasses.
     
     Another key point, which I don't think came through, was that each initarg
     should be explicitly defined, and should be defined in exactly one place.
     This is simply good modularity.
     
     Some aspects of what I proposed were reacting to user complaints about the
     way Flavors does it.  I have the ambition of making this new standard
     better than Flavors.
     
     All this leads to the idea that initargs of types 2 and 4 (in the
     nomenclature of my 16 Apr message) should be defined by methods, since
     their meaning is implemented by methods.  Similarly, type 3 should be
     defined by slot-options, since their meaning is entirely involved with
     slots.  In Flavors, type 4 have the ugly property that they have to be
     defined in two places, once in the method that implements them and again in
     a defflavor form; it's easy to get these two places out of sync.  Hence the
     proposal to use the lambda-list of a defmethod as the way to define these
     initargs.

I would stress this point further by saying that an object system is
going to be appreciated for its ease of use during program development.
Adding a new method is a normal thing to do and will be easier
(faster,...) on most implementation than DEFCLASS redefinition which is
a more traumatic operation (potential obsolescence of class...).  Adding
a new initarg keyword to make-class for 2 or 4 does not make the class
obsolete. We shouldn't be forced to reevaluate DEFCLASS for such a small
and upwardly compatible change.

     
         Date: Thu, 23 Apr 87 08:03:20 pst
         From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
     
         From subsequent discussion, it seems as if an additional DEFCLASS
         option, :DEFAULT-INITARGS is being proposed. I wonder if this
         is needed, considering that a user can already specify an initialization
         value via the :INITFORM option? Perhaps the metaclass ought to 
         attend to this? Or the :INITFORM and :DEFAULT-INITARGS options should
         be merged?
     
     This indicates that I completely failed to convey what :default-initargs is
     about, and that in turn may possibly indicate that :default-initargs should
     be flushed.  In my proposal there are two ways to specify a default for an
     initarg: at the point of definition, and remotely.  To explain: when
     defining an initarg one can specify right there, locally, a default value
     form.  For initargs that fill slots, this is the existing :initform
     slot-option; no need to invent anything new there.  For initargs that are
     implemented by methods, this is the existing defaulting mechanism in the
     lambda-list; again, no need to invent anything new.  Now for remote
     defaulting: here the idea is that one class defines what an initarg means,
     while a second class specifies a default for it; this is :default-initargs.
     When you mix the two classes together, the default meets up with the
     implementation and things work.  The reason remote defaulting is desirable
     is twofold: (1) it's often useful when mixing classes together for one
     class to customize another class by specifying initialization options, in
     addition to the existing ability to customize a class by shadowing or
     wrapping methods; (2) for modularity reasons, when class A customizes class
     B by specifying an initarg that class B defines, class A shouldn't have to
     know whether the initarg fills a slot or is implemented by a method.  If
     not for reason (2), remote defaulting wouldn't require a new mechanism,
     because it could be implemented using the existing mechanism of :initform
     for slot initargs plus call-next-method-with-arguments (proposed but not
     yet accepted) for method initargs.  But I think reason (2) is important.
     
     
         Date: 23 Apr 87 18:24 PDT
         From: Gregor.pa@Xerox.COM
     
         What is the purpose of :initform anymore?  You only need it when you
         want to specify the default value for a slot that isn't set by any
         initarg.  This means that we have two mechanisms which do almost the
         same thing -- initargs which set slots are almost a superset of
         initforms.  This is a sure sign of bad modularity.  
     
     On the contrary, I think it's a sign of good modularity!  The two
     mechanisms do almost the same thing inside the implementation, but from the
     point of view of someone on the outside who doesn't know the information
     that is supposed to be hidden from him by modular abstraction, they do
     rather different things.  I could give a longer explanation of what I mean,
     but it's late, this message is already too long to ask anyone to read
     carefully, and I think I would just be repeating what I said a bit earlier.
     
         (defclass position ()
     	(x
     	 y)
           (:default-initargs (nil 0 x)
     			 (nil 0 y)))
     
         What I am trying to do is seperate what I perceive as the separate parts
         of what is going on into separate places.
     
     The reason I don't like this is that the information about a slot is no
     longer all in one place.  Another way of saying it is that I think that
     information in defclass should be organized spatially rather than
     temporally, i.e. information pertaining to one slot should be together,
     rather than putting information pertaining to one phase of object creation
     together.  One of the ways that I think defclass is better than defflavor
     is that it has done a better job of spatial organization by putting more
     of the information about a slot into slot options instead of scattering it
     around in various options some of which refer back to the slot by name.


I see :default-initargs being on the client side (make-instance and
such) and :initform being on the implementor side. One will supersede the
other, but conceptually they are different and should be kept different.


∂29-Apr-87  1836	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Apr 87  18:35:58 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 127851; Wed 29-Apr-87 21:36:13 EDT
Date: Wed, 29 Apr 87 21:36 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object creation discussion (at last!)
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870427013057.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <870429213604.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Mon, 27 Apr 87 01:30 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    I can see from the misunderstanding in the mail that I did an abysmal job
    of communicating my ideas.  I'll try to send a more comprehensible essay
    tomorrow....

As you can see, I didn't get to it.  I'm not going to be allowed that kind of
time for this until some time next week, so if you have comments but you were
waiting for that before sending them, open fire.

∂06-May-87  0936	kempf%hplabsc@hplabs.HP.COM 	Printing Objects
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 6 May 87  09:35:59 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Wed, 6 May 87 09:33:39 pdt
Received: by hplabsc ; Wed, 6 May 87 09:34:12 pdt
Date: Wed, 6 May 87 09:34:12 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705061634.AA12121@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Printing Objects

Looking through the PRINT-OBJECT specification, there is no read macro
specified for allowing an object printed out to be read back in. 
Since DEFSTRUCT has the #S read macro, it seems as if something similar
should be available for instances of classes of the default metaclass.
#O comes to mind first, but, of course, that is used by octal numbers.

Why not #@? From CLTL, pg. 352, this one looks free. 

		Jim Kempf	kempf@hplabs.hp.com

∂06-May-87  1142	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Printing Objects    
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 6 May 87  11:42:06 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa15417; 6 May 87 14:35 EDT
Received: from ti-csl by RELAY.CS.NET id ab23481; 6 May 87 14:31 EDT
Received: from Jenner (jenner.ARPA) by tilde id AA17350; Wed, 6 May 87 13:09:25 cdt
Message-Id: <2756311822-982351@Jenner>
Date: Wed, 6 May 87  13:10:22 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Jim Kempf <kempf%hplabsc@hplabs.hp.com>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Printing Objects
In-Reply-To: Msg of Wed, 6 May 87 09:34:12 pdt from Jim Kempf <kempf%hplabsc@hplabs.hp.com>

     Date: Wed, 6 May 87 09:34:12 pdt
     From: Jim Kempf <kempf%hplabsc@hplabs.hp.com>
     Subject: Printing Objects
     
     Looking through the PRINT-OBJECT specification, there is no read macro
     specified for allowing an object printed out to be read back in. 
     Since DEFSTRUCT has the #S read macro, it seems as if something similar
     should be available for instances of classes of the default metaclass.
     #O comes to mind first, but, of course, that is used by octal numbers.
     
     Why not #@? From CLTL, pg. 352, this one looks free. 
     
     		Jim Kempf	kempf@hplabs.hp.com

I don't see why #S couldn't be extended to read instances. Since #S
can only read "typed" structures (those that define a common lisp type),
the semantics wouldn't get changed.

∂06-May-87  1304	kempf%hplabsc@hplabs.HP.COM 	Re: Printing Objects 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 6 May 87  13:03:08 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Wed, 6 May 87 13:00:01 pdt
Received: by hplabsc ; Wed, 6 May 87 13:00:33 pdt
Date: Wed, 6 May 87 13:00:33 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705062000.AA15399@hplabsc>
To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET, kempf%hplabsc@hplabs.hp.com
Subject: Re: Printing Objects
Cc: common-lisp-object-system@SAIL.STANFORD.EDU

>     Date: Wed, 6 May 87 09:34:12 pdt
>     From: Jim Kempf <kempf%hplabsc@hplabs.hp.com>
>     Subject: Printing Objects
>     
>     Looking through the PRINT-OBJECT specification, there is no read macro
>     specified for allowing an object printed out to be read back in. 
>     Since DEFSTRUCT has the #S read macro, it seems as if something similar
>     should be available for instances of classes of the default metaclass.
>     #O comes to mind first, but, of course, that is used by octal numbers.
>     
>     Why not #@? From CLTL, pg. 352, this one looks free. 
>     
>     		Jim Kempf	kempf@hplabs.hp.com
>
>I don't see why #S couldn't be extended to read instances. Since #S
>can only read "typed" structures (those that define a common lisp type),
>the semantics wouldn't get changed.
>

That would be OK too. Looking at the specification of #S, it could
be extended to anything with a constructor. The important point is
that the extension be noted in the CLOS specification, so it doesn't
get lost.

		Jim Kempf	kempf@hplabs.hp.com

∂06-May-87  2024	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Printing Objects   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 May 87  20:24:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 133775; Wed 6-May-87 23:22:56 EDT
Date: Wed, 6 May 87 23:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Printing Objects
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8705062000.AA15399@hplabsc>
Message-ID: <870506232253.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 6 May 87 13:00:33 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    >     Date: Wed, 6 May 87 09:34:12 pdt
    >     From: Jim Kempf <kempf%hplabsc@hplabs.hp.com>
    >     
    >     Looking through the PRINT-OBJECT specification, there is no read macro
    >     specified for allowing an object printed out to be read back in. 
    >
    >I don't see why #S couldn't be extended to read instances. Since #S
    >can only read "typed" structures (those that define a common lisp type),
    >the semantics wouldn't get changed.

    That would be OK too. Looking at the specification of #S, it could
    be extended to anything with a constructor. The important point is
    that the extension be noted in the CLOS specification, so it doesn't
    get lost.

If we wanted a thing like #S for instances of standard classes, we would
certainly use #S rather than inventing another read macro that does the
same thing as #S.  However, there are some problems with #S.

Since we seem to be agreeing that the technique for creating objects
will not make the physical slots directly visible, but instead will add
a layer of abstraction, there is the issue that this transformation
may not be reversible:  It may not be self-evident how to convert the
slot-values of an object into a set of arguments to make-instance that
will create an object with the same slot-values.  Suppose that not all
of the slots have initargs that can initialize them.

If instead we made #S bypass make-instance's abstraction and specify
the physical slots directly, it would be a terrible violation of
modularity.  What this really shows, I think, is that only a method
for the class in question can know what is the proper way to create
an equivalent instance.

In addition to this issue of slot values, I don't think the concept
of "allowing an object printed out to be read back in" is well-defined,
because the concept of reading "the same object" is not well-defined.
In the simplest cases, creating an object of the same class with
slot values "printed out and read back in" will do the job, but only
in the simplest cases.  In general, an object is part of a data structure
and ripping the object out of that data structure and jamming it
into a world by itself may not be meaningful.  This is the same reason
why we don't provide a general copy-object function.

I think it would make sense to have a standardized mixin class for
those simple objects whose semantics are defined entirely by the
values of their initializable slots.  This class would define a
print-object method that used either #S(...) or #.(make-instance ...),
and would probably also define methods for copying and for dumping
into binary files output by compilers.  This is fine; the thing I
want to be very cautious about is assuming that -all- objects should
have these methods.  It's much better to package them in a mixin that
is there if you want it and not otherwise.  Any suggestions for a
good name for this class?  simple-object?

∂06-May-87  2202	Masinter.pa@Xerox.COM 	Re: Printing Objects  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 May 87  22:02:34 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 06 MAY 87 22:00:14 PDT
Date: 6 May 87 22:01 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Printing Objects
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 6 May 87 23:22 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870506-220014-1229@Xerox>

Of the alternatives:

a) All objects print out as #S, if you want different behavior, you
override it

b) By default, objects can't print themselves, and you have to provide a
print function or else mixin a standard class


Consider three cases:

1) object wants to print out as #S...
2) object cannot be printed really -- it doesn't make sense to "read" it
3) object wants to be printed in a special way


Case 1: a is preferable, since what you want to do is already the
default

Case 2: b is only marginally better. In alternative a, you have to
supply an error-if-you-print-me method or else you will get printing
when you shouldn't really   --if your erroneously print something and
try to read it back in, alternative b gives you an error at print time,
while alternative a gives you an error later on in your program. 

Case 3: it makes no difference, since you're supplying a print method.


I think Case 1 is the most common in most of the program's I've seen
anyway.


∂06-May-87  2235	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Printing Objects   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 May 87  22:35:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 133838; Thu 7-May-87 01:33:56 EDT
Date: Thu, 7 May 87 01:33 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Printing Objects
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <870506-220014-1229@Xerox>
Message-ID: <870507013351.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 6 May 87 22:01 PDT
    From: Masinter.pa@Xerox.COM

    Of the alternatives:

    a) All objects print out as #S, if you want different behavior, you
    override it

    b) By default, objects can't print themselves, and you have to provide a
    print function or else mixin a standard class

This is misleading.  87-002 requires that the implementation provide a default
method.  The issue in question is not whether objects can print themselves,
but what happens you feed the output of that to read.  Thus alternative b
should be stated as "By default, objects print something that signals an error
when read."  If I wanted to be parallel to that, but biased, I would state
alternative a as "By default, objects print something that creates a bogus
object when read."

    Consider three cases:

    1) object wants to print out as #S...
    2) object cannot be printed really -- it doesn't make sense to "read" it
    3) object wants to be printed in a special way

    Case 1: a is preferable, since what you want to do is already the
    default

    Case 2: b is only marginally better. In alternative a, you have to
    supply an error-if-you-print-me method or else you will get printing
    when you shouldn't really   --if your erroneously print something and
    try to read it back in, alternative b gives you an error at print time,
    while alternative a gives you an error later on in your program. 

Not so, since Common Lisp is missing the :readably argument to WRITE.
Alternative b gives you an error at read time, not print time.

    Case 3: it makes no difference, since you're supplying a print method.

    I think Case 1 is the most common in most of the program's I've seen
    anyway.

Not in the programs I've seen.  Leaving aside endless arguments about who's
seen what programs, and turning to design rationales: I think it is better
to signal an error when there is some question what people might want,
and provide a way for them to say what they want, than to lead them down
a garden path that ends up in a mysterious blowout because the system
guessed their intention wrong.  This is a general principle, but I think
it applies to this case.

∂07-May-87  0851	kempf%hplabsc@hplabs.HP.COM 	Re: Printing Objects 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 7 May 87  08:50:58 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 7 May 87 07:49:32 pdt
Received: by hplabsc ; Thu, 7 May 87 07:49:54 pdt
Date: Thu, 7 May 87 07:49:54 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705071449.AA25199@hplabsc>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM,
        common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Printing Objects

Leaving aside the question of whether to use #S and how to match
reading to MAKE-INSTANCE, couldn't the *PRINT-ESCAPE* switch play
a role about whether an object is printed out in a form which
is readable again? My reading of the description of *PRINT-ESCAPE*
on pg. 370 of CLtL is not clear. The first paragraph seems to 
imply that this switch is supposed to primarily affect printing
of symbols with strange print names, the second paragraph seems
to imply that it serves a more general function in controlling
whether a "structure" (and by this I interpret CLtL to mean
any Common Lisp data structure, not just a DEFSTRUCT) gets printed
in a way which makes it readable again. Perhaps this switch could
be used for controlling whether the instance is printed in a
readable or nonreadable form.

Returning to the more general question, while I agree about the
desirability for compiling objects into a binary form and writing
them out, and other forms of saving objects, these will all be
machine dependent. Looking at other object-oriented languages,
one of the most attractive aspects of Objective-C to many programmers
is the Filer, a way of writing an object out in ASCII form. It provides
a kind of "lowest common denominator" persistence, and is a debugging
aid too. A programmer can send a Filer generated representation of
an Objective-C object around a local area network of diverse machines
without much extra code to do conversion from one form to another.

On the question of reading violating abstraction and who should
know how to print out an object, I think it is the metaclass rather
than the class which should know about how to print an object and
read it again. The metaclass controls the low level representation
of the object, thus should have the knowledge to decompose and write
it out, and read it in again. For FUNCALLABLE-STANDARD-CLASS, for
example, the metaclass method could do the same thing as is done
for a fundef. For STANDARD-CLASS, a default method could be provided
to read and write the object. Other metaclasses would need to supply
their own methods. 

This should not, however, preclude a programmer from defining a method
on a class which writes an object in some nonreadable form.

I also agree that any read macro should go through MAKE-INSTANCE, to
avoid violating the class/object abstraction. Maybe some combination
of #S and #. could play a role, or maybe the default is simply:

	#.(make-instance (class-named <name of class> <init-plist))

I think that it is important for this issue to be put into the
language spec once we have resolved it. With current Common Lisp,
there are a number of nonstandard read macros for creating the
underspecified types (e.g. #P for pathnames), which are
springing up due to need.


		Jim Kempf	kempf@hplabs.hp.com

∂13-May-87  1131	kempf%hplabsc@hplabs.HP.COM 	Object Printing Discussion
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 13 May 87  11:30:14 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Wed, 13 May 87 08:56:07 pdt
Received: by hplabsc ; Wed, 13 May 87 08:56:15 pdt
Date: Wed, 13 May 87 08:56:15 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705131556.AA06328@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Object Printing Discussion

Continuing the object printing discussion, I'd like to address 
some points brought up by Moon, and summarize things so far.

Before going further, however, I'd like to provide some 
motivation for continuing
this discussion. As mentioned in a previous note, the Objective-C Filer has
proven to be a useful tool for Objective-C programmers, even though it does
have some serious disadvantages as a mechanism for storing objects. 
Additionally, CommonObjects never defined a default 
storage mechanism (primarily because
the issues of abstraction violation were not fully thought out) and it has
proven to be a perennial problem. Binary storage mechanisms based on compiler
modifications, databases and the like are all interesting, but some base
level hooks and a simple default storage mechanism using existing Common Lisp
read macros where possible and ASCII text can simplify applications development
and provide backward compatibility with DEFSTRUCT. I'm sure, if it is
not provided, someone will to question why DEFSTRUCT's have
a readable storage representation and objects do not.

On to the discussion:

>Since we seem to be agreeing that the technique for creating objects
>will not make the physical slots directly visible, but instead will add
>a layer of abstraction, there is the issue that this transformation
>may not be reversible:  It may not be self-evident how to convert the
>slot-values of an object into a set of arguments to make-instance that
>will create an object with the same slot-values.  Suppose that not all
>of the slots have initargs that can initialize them.

I agree with the need for a layer of abstraction, however, the level of
MAKE-INSTANCE may be too high. In particular, if, as Moon's comments indicate,
the defined initialization protocol for the class will not accomodate 
initializing an object with the current slot value when read back in,
it would not be possible to write out an object's slot values and read
them back in using MAKE-INSTANCE. An example would be when no initarg
is defined for a slot (i.e., it is not initializable from MAKE-INSTANCE).

>In addition to this issue of slot values, I don't think the concept
>of "allowing an object printed out to be read back in" is well-defined,
>because the concept of reading "the same object" is not well-defined.
>In the simplest cases, creating an object of the same class with
>slot values "printed out and read back in" will do the job, but only
>in the simplest cases.  In general, an object is part of a data structure
>and ripping the object out of that data structure and jamming it
>into a world by itself may not be meaningful.  This is the same reason
>why we don't provide a general copy-object function.

I think you could make this argument for any Lisp data structure, including
lists, vectors, or what have you. Perhaps more strongly for objects, since
they tend to be more highly structured. I certainly agree it may not be
meaningful to write out an object and read it back in, but, in the default
case, I think the metaclass could provide some kind of meaning, which
could then be customized on a class by class (or metaclass by metaclass)
basis. In cases where it is not possible to provide meaning (like
writing out packages and fundefs in Common Lisp), the #< read macro
can be used to prohibit reading the representation back in.

>I think it would make sense to have a standardized mixin class for
>those simple objects whose semantics are defined entirely by the
>values of their initializable slots.  This class would define a
>print-object method that used either #S(...) or #.(make-instance ...),
>and would probably also define methods for copying and for dumping
>into binary files output by compilers.  This is fine; the thing I
>want to be very cautious about is assuming that -all- objects should
>have these methods.  It's much better to package them in a mixin that
>is there if you want it and not otherwise.  Any suggestions for a
>good name for this class?  simple-object?

As mentioned in a previous note, I think that control of object representation
should be left to the metaclass, and therefore this functionality should
be part of the metaobject protocol. The metaobject protocol controls how
objects and classes get created within memory, and thus it seems logical
that it should also control how objects move out to disc. 

	.	.	.	.	.	.

Lacking any concensus on object creation, it's difficult to outline a 
detailed proposal as to what should be done. Here's a summary of
my thinking on the issue so far:

1) CLOS should specify a default printable object representation which
is readable again, if only because programmers find it useful.

2) This representation should be ASCII and should use existing Common Lisp 
read macros where possible, to facilitate portability and backward 
compatibility.

3) The abstraction level should be below MAKE-INSTANCE, so that slots
which are not initable through MAKE-INSTANCE initargs can still be
initialized, but above the level of simply setting the slot, so the
class can customize initialization from a dumped object if desired.

4) The hooks should be part of the metaobject protocol, since the
metaobject protocol controls the representation of classes and
instances.

With regard to 3) and 4), possibly the issue of conversion of slot
values could be dealt with via a method on the STANDARD-SLOT-DESCRIPTION
class. However, I'll forgo any detailed proposals until hearing whether
there is any agreement about the overall issues.

		Jim Kempf		kempf@hplabs.hp.com

∂13-May-87  1323	Gregor.pa@Xerox.COM 	Re: Object Printing Discussion    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 May 87  13:22:56 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 MAY 87 12:51:11 PDT
Date: 13 May 87 12:50 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object Printing Discussion
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Wed,
 13 May 87 08:56:15 pdt
To: kempf%hplabsc@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870513-125111-2498@Xerox>

Be warned, I am going to (mostly) dump on using printing for dumping.

The reason defstruct has a readable representation for printed objects
is because defstruct is broken in this (and many other) regard.  I
believe the default printed representation of defstruct types lulls
programmers into a false sense of believing that the problem of dumping
and restoring has been solved for them when in fact, that is not at all
true.

In my mind, printing an object for the user read its 'printed
representation' and dumping an object so that some other program can
restore it later are two completely different operations.  In addition,
depending on the application or mode, there may be many different ways
to do each of these.

Lets just look at dumping/restoring, what are some of the issues:

- circularity, how to deal with it?
- pointers to special "ground" objects which shouldn't be dumped but
which
  should be "re-grounded" when the object is restored.
- restoring an object but not all the objects it points to

None of these questions is terribly hard, but they all have very
different answers depending on the specific application.  Whats more,
none of these have to do with efficiency per se.  I can add efficeincy
as another problem, it only makes this more complicated.

- efficiency of dump format.  Certainly the #S format is about the least
efficient
  dump format imaginable.  It takes a lot of space, and it takes a lot
of work at
  dump and restore time.


So I guess my opinion is that it would be a mistake to try to
standardize a 'generally useful for dumping' print function.  Certainly
any class or metaclass which wants to can provide a different method for
print-object which would be the base of a whole dumping/restoring
sub-protocol.  So the hook is there for people to do whatever they want.
But I think we would be doing them a diservice to pretend that we had
provided them a general solution to this problem.

Here is a related question?

What happens if an object appears as a constant in a piece of code that
is being compiled to a file?  CLtL certainly is not clear on what
happens if a defstruct-defined structure appears in such a place.  Is
print-object what you would like to call here??

∂13-May-87  1444	DLW@ALDERAAN.SCRC.Symbolics.COM 	Object Printing Discussion 
Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 13 May 87  14:44:22 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 81287; Wed 13-May-87 17:31:55 EDT
Date: Wed, 13 May 87 17:31 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Object Printing Discussion
To: kempf%hplabsc@hplabs.HP.COM, common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8705131556.AA06328@hplabsc>
Message-ID: <870513173115.5.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: Wed, 13 May 87 08:56:15 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    1) CLOS should specify a default printable object representation which
    is readable again, if only because programmers find it useful.

The point is that it's not clear what "readable" means, and how useful
it is.  You'd have to be more careful about how this is defined.  What
if the value of one of the slots is a compiled code object?  But even if
all the values are symbols, you still have to make sure that people
realize that reading this printed representation can only be said to
"create a new instance which, in some respects, is like the instance
that got printed", which isn't really guaranteeing very much.

    2) This representation should be ASCII and should use existing Common Lisp 
    read macros where possible, to facilitate portability and backward 
    compatibility.

(Not ASCII, but the CL character set, which is more restrictive than
that.  Portability to the 370, remember.)

    4) The hooks should be part of the metaobject protocol, since the
    metaobject protocol controls the representation of classes and
    instances.

I don't agree with this; it would be a real pain in the neck, and
overkill, to have to define a whole new metaclass just to say how an
instance is printed.  Defining a method is far easier.

∂14-May-87  1322	kempf%hplabsc@hplabs.HP.COM 	Re: Printing Objects 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 14 May 87  13:22:01 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 14 May 87 13:21:05 pdt
Received: by hplabsc ; Thu, 14 May 87 13:21:23 pdt
Date: Thu, 14 May 87 13:21:23 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705142021.AA26108@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Printing Objects
Cc: kempf%hplabsc@hplabs.HP.COM

From Gregor:

>Be warned, I am going to (mostly) dump on using printing for dumping.
>
>The reason defstruct has a readable representation for printed objects
>is because defstruct is broken in this (and many other) regard.  I
>believe the default printed representation of defstruct types lulls
>programmers into a false sense of believing that the problem of dumping
>and restoring has been solved for them when in fact, that is not at all
>true.

From Dan Weinreb:

>    4) The hooks should be part of the metaobject protocol, since the
>    metaobject protocol controls the representation of classes and
>    instances.
>
>I don't agree with this; it would be a real pain in the neck, and
>overkill, to have to define a whole new metaclass just to say how an
>instance is printed.  Defining a method is far easier.

Yow! Ok, let's forget it then. The default PRINT-OBJECT can print
out in a nonreadable form, and it's up to the user to take care
of printing in a class or metaclass specific way.

From Gregor:

>Here is a related question?
>
>What happens if an object appears as a constant in a piece of code that
>is being compiled to a file?  CLtL certainly is not clear on what
>happens if a defstruct-defined structure appears in such a place.  Is
>print-object what you would like to call here??

In fact, CLtL doesn't specify how a constant ANYTHING gets compiled into
file. It doesn't even specify that two references to a constant 
which are EQ during compilation will be EQ after the compiled file
is loaded. The only thing which my reading of CLtL seems to indicate
will be EQ is an interned symbol, and then only if the package exists
in the load environment.

I don't think you can realistically expect PRINT-OBJECT to be of use
here, since everyone will have a different low level representation
within compiled code files. The motivation for having a readable format
was for easy exchange of objects between machines, and the ability
to store objects in some default format, like DEFSTRUCT. But, as was
pointed out, a general solution is probably still a research question.
For examining the internals of an object, DESCRIBE (87-002, pg. 2-37)
or INSPECT (CLtL, pg. 442, but not in 87-002) could be used.

		Jim Kempf	kempf@hplabs.hp.com

∂15-May-87  1110	Gregor.pa@Xerox.COM 	optimization versus constructors  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 15 May 87  11:10:32 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAY 87 11:07:52 PDT
Date: 15 May 87 11:07 PDT
From: Gregor.pa@Xerox.COM
Subject: optimization versus constructors
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870515-110752-4939@Xerox>

Danny and I have been thinking about initialization and are picking away
at parts of the problem we don't understand.  Specifically, I was trying
to remember what the :constructor option was really for.  I remembered
that:

- it isn't really just an abbreviation for a defun and a call to
make-instance since it can set slots which are not settable by initargs.

- even if it was just an abbreviation for a defun with a call to
make-instance, the constructors generated by the :constructor option
would be much faster than the ones defined by calling make-instance by
hand.


This message addresses the second of these 2 points.  Specifically, I
will show a simple (even trivial) technique which reduces optimizing
calls to make-instance to exactly the same problem as optimizing
constructors produced by :constructor option.  This is important because
it means that we can think about constructors only in terms of their
behavior, they are not needed for performance anymore.


The basic idea is that a call to make-instance with a constant first
argument and constant key (even numbered) args can be treated as a
dynamic definition of an :constructor with some gensymed name.

So that in the form

 (progn ..  (make-instance 'boat :speed 10)  ..)

the call to make-instance can be converted to something like:

 (progn ..  (#:G001 10) ..)

and the class gets updated as if it had had a :constructor option
(:constructor #:g001 (speed)).

This shows that whatever optimization can be gotten from the
:constructor option can also be gotten from calls to make-instance (at
least the calls to make-instance for which you could have used a
constructor).

∂15-May-87  1240	kempf%hplabsc@hplabs.HP.COM 	Why is MAKE-INSTANCE not generic?   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 15 May 87  12:40:34 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Fri, 15 May 87 12:39:40 pdt
Received: by hplabsc ; Fri, 15 May 87 12:39:32 pdt
Date: Fri, 15 May 87 12:39:32 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705151939.AA11025@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Why is MAKE-INSTANCE not generic?


87-002 says that MAKE-INSTANCE is a function, and not a generic
function. Why is this? In particular, a metaclass may want
to specialize MAKE-INSTANCE to a particular metaclass-dependent
instance creation procedure. The instance "creation" procedure
might not fit into the ALLOCATE-INSTANCE/INITIALIZE pattern
which MAKE-INSTANCE currently uses. I realize that instance
creation is, as yet, not completely specified, but wanted to
bring up the point anyway.

		Jim Kempf	kempf@hplabs.hp.com

∂15-May-87  1315	kempf%hplabsc@hplabs.HP.COM 	Re: Why in MAKE-INSTANCE not generic?    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 15 May 87  13:15:24 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Fri, 15 May 87 13:14:28 pdt
Received: by hplabsc ; Fri, 15 May 87 13:14:48 pdt
Date: Fri, 15 May 87 13:14:48 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705152014.AA11627@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Why in MAKE-INSTANCE not generic?

There seems to be a slight discrepency between 87-002 and 87-003 on
this point. 87-002, pg. 2-44 implies that MAKE-INSTANCE is a programmer
interface function, 87-003, pg. 3-7 implies that it is a method
which is part of the metaobject protocol.
		Jim Kempf	kempf@hplabs.hp.com

∂15-May-87  1648	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Why in MAKE-INSTANCE not generic? 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 15 May 87  16:48:43 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 141322; Fri 15-May-87 19:37:40 EDT
Date: Fri, 15 May 87 19:36 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Why in MAKE-INSTANCE not generic?
To: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8705152014.AA11627@hplabsc>
Message-ID: <870515193649.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Fri, 15 May 87 13:14:48 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    There seems to be a slight discrepency between 87-002 and 87-003 on
    this point. 87-002, pg. 2-44 implies that MAKE-INSTANCE is a programmer
    interface function, 87-003, pg. 3-7 implies that it is a method
    which is part of the metaobject protocol.

As you may have noticed, the protocol for creating objects hasn't been
defined yet.  Anything that's in the documents now can't be relied upon.

∂15-May-87  1715	Moon@STONY-BROOK.SCRC.Symbolics.COM 	optimization versus constructors 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 15 May 87  17:15:05 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 141385; Fri 15-May-87 20:14:21 EDT
Date: Fri, 15 May 87 20:13 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: optimization versus constructors
To: Common-Lisp-Object-System@Sail.Stanford.edu
In-Reply-To: <870515-110752-4939@Xerox>
Message-ID: <870515201336.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 15 May 87 11:07 PDT
    From: Gregor.pa@Xerox.COM

    Danny and I have been thinking about initialization and are picking away
    at parts of the problem we don't understand.  Specifically, I was trying
    to remember what the :constructor option was really for.
    ....
    This shows that whatever optimization can be gotten from the
    :constructor option can also be gotten from calls to make-instance (at
    least the calls to make-instance for which you could have used a
    constructor).

I agree that the :constructor mechanism could be replaced by a complicated
mechanism involving compile time optimizations of recognized patterns of
constant arguments to make-instance, with some way to get around the fact
that constructors can initialize any slot but we don't want make-instance
to be able to do that.  There is some trickiness required to make this
compile-time optimized code get recompiled whenever the class's structure
is changed.

I don't remember who put constructors in, but I assume the idea was that
the other way of doing it was too complicated.  It's probably a good model
for thinking about the semantics and making sure that constructors and
make-instance behave consistently, but we probably don't want to require
implementations to work that way.

∂20-May-87  1934	Pavel.pa@Xerox.COM 	CLOS vs. subtypes of FLOAT    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 May 87  19:34:14 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 20 MAY 87 18:52:30 PDT
Date: Wed, 20 May 87 18:52:23 PDT
From: Pavel.pa@Xerox.COM
Subject: CLOS vs. subtypes of FLOAT
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
Cc: Pavel.pa@Xerox.COM
Message-ID: <870520-185230-2840@Xerox>

Here it is, finally, my proposal(s) for the treatment of the subtypes of
FLOAT for discrimination in CLOS.

The issue, to refresh folks' memories, is what to do with code like the
following:

	(defmethod foo ((x single-float)) ...)
	
	(defmethod foo ((x double-float)) ...)

There are three major questions:
  1) Is this code legal at all?  That is, is it okay to discriminate on
     the subtypes of FLOAT?
  2) What is the effect of such code in an implementation that does not
     represent the two types differently (such as one that has only one
     representation of floating-point numbers)?  Is it legal in such
     implementations?
  3) Which of the symbols naming subtypes of FLOAT also name classes?
     Can this vary from implementation to implementation?

I have come up with three different proposals to answer these questions.
I will first lay them out and then discuss their relative advantages and
disadvantages.

Proposal 1 "NONE":
   It is illegal to discriminate on any of the subtypes of FLOAT.  None
of them name classes at all, in any implementation.
   
Proposal 2 "SOME":
   In a given implementation, exactly as many of the subtype-symbols
name classes as there are different representations of floating-point
numbers.  The ones that name classes are derived from the list of
allowable representation-naming schemes given on pages 18-19 of CLtL:

   -- If there is only one representation, then SINGLE-FLOAT names a
      class.
   -- If there are exactly two representations, then either SHORT-FLOAT
      and SINGLE-FLOAT, or SINGLE-FLOAT and DOUBLE-FLOAT, name classes.
   -- If there are exactly three representations, then either
      SHORT-FLOAT and SINGLE-FLOAT and DOUBLE-FLOAT, or SINGLE-FLOAT
      and DOUBLE-FLOAT and LONG-FLOAT, name classes.
   -- If four representations exist, then all four symbols name classes.

The classes named by such symbols are all subclasses of FLOAT.  Clearly,
those symbols that do not name classes cannot be used for
discrimination.

Proposal 3 "ALL":
   All of the subtype-symbols name classes, and all of those classes are
subclasses of FLOAT.  In some implementations, some of the classes named
by those symbols are "synonyms" for other classes, according to the
following scheme (again derived from pages 18-19 of CLtL):

   -- If there is only one representation, then the classes named by
      SHORT-FLOAT, DOUBLE-FLOAT and LONG-FLOAT are all synonyms for the
      class named by SINGLE-FLOAT.
   -- If there are exactly two representations, then either
      - the classes named by DOUBLE-FLOAT and LONG-FLOAT are synonyms
        for the class named by SINGLE-FLOAT, or
      - the class named by SHORT-FLOAT is a synonym for the class named
        by SINGLE-FLOAT and the class named by LONG-FLOAT is a synonym 
        for the class named by DOUBLE-FLOAT
   -- If there are exactly three representations, then either
      - the class named by LONG-FLOAT is a synonym for the class named
        by DOUBLE-FLOAT, or
      - the class named by SHORT-FLOAT is a synonym for the class named
        by SINGLE-FLOAT
   -- If there are four representations, then no classess are synonyms
      of others. 

If a class A is a synonym of another class B, then A and B are not EQ,
they have different names, and they may have different metaclasses.  No
instances may exist of class A.  Defining a method on a generic function
F that discriminates on A has the same general effect as defining one
that discriminates on B.  However, if a method already exists on F that
discriminates on B or a different synonym of B (i.e., not A), then a
correctable error is signalled, allowing the user to choose which one of
the two methods will remain on F.

Under the NONE proposal, the pair of DEFMETHOD's above would be illegal
in all implementations.

Under the SOME proposal, the pair would be legal in those
implementations that had distinct representations called SINGLE-FLOAT
and DOUBLE-FLOAT.  In other implementations, an "Unknown class name"
error would be signalled.

Under the ALL proposal, the pair would compile and evaluate quietly and
correctly in those implementations that had distinct representations
called SINGLE-FLOAT and DOUBLE-FLOAT.  In other implementations, a
correctable error would be signalled upon encountering the second
DEFMETHOD and the user would have to choose between the two methods.


I have been convinced by conversations with a number of floating-point
users around here that algorithms exist that can go much more quickly if
they can be guaranteed a certain minimum amount of precision in the
numbers.  These algorithms would have to make checks for certain
conditions only if less precision is available.  While these programs
would have to be conditionalized (using #+/#-) for different
implementations to patch in the name of the sufficiently-precise
representation (since CLtL does not give a required bit count for each
representation), this isn't very hard to do and should be allowed.

One can also imagine users who wish to use the very same source code for
some floating-point-intensive computation in two methods, one for
SINGLE-FLOAT arguments and one for DOUBLE-FLOAT arguments.  The idea
here is that the compiler could generate much better code given the
implicit declaration of the argument type.  Each of the two copies might
perform much better than an undeclared version.  This user would be
letting the object system make a single check upon entry to the generic
function before dispatching to the representation-specific version of
the code.

I am convinced by arguments like these that reasonable uses exist for
discrimination on subtypes of FLOAT.  Thus, I believe that the NONE
proposal is a bad idea.

The SOME proposal is very easy to implement, but has the (perhaps only
aesthetic) flaw that the existence of classes for certain built-in types
would vary between implementations.  I find this notion disturbing and
would prefer not to see it.

The ALL proposal solves this problem but introduces, for almost all
implementations, the extra mechanism implied by the synonym classes.  It
may be that this could be very easily implemented, but Gregor would
probably know better.  An alternative to synonym classes would be making
the name -> class mapping be many-to-one.  Gregor claims that this
cannot be allowed, but I'm not sure that I understand why.  Another way
to avoid synonyms is to make the classes that would be synonyms into
subclasses of the other class.  This, on the other hand, has the problem
that methods defined on such classes would never be called, since no
instances of them can be created.  It also establishes an asymmetric
subclass relation for pairs with a symmetric subtype relation.


This is getting pretty long for such a relatively minor issue.  I'll
stop here and see if anyone can make any sense of this.

	Pavel

∂21-May-87  1228	Pavel.pa@Xerox.COM 	Re: CLOS vs. subtypes of FLOAT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 May 87  12:27:47 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 21 MAY 87 12:20:51 PDT
Date: Thu, 21 May 87 12:20:50 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: CLOS vs. subtypes of FLOAT
In-reply-to: "Masinter's message of 21 May 87 12:07 PDT"
To: Masinter.pa@Xerox.COM
Cc: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <870521-122051-1382@Xerox>

	Date: 21 May 87 12:07 PDT
	From: Masinter.pa

	You omitted the possibility where all the classes
	exist in all implementations, but that some of the
	classes might be empty (have no instances) in some
	implementations.

In putting together the proposals, I had two (unfortunately unstated) design criteria:

   1) Discrimination on the subtypes of FLOAT should be allowed
   2) Discriminations that cannot work in a given implementation
      (due to collapsing together some of the subtypes) should signal
      an error so that the user doesn't lose quietly.

Proposal NONE loses on the first criterion and your proposal violates the second.

	Pavel

∂21-May-87  1227	Masinter.pa@Xerox.COM 	Re: CLOS vs. subtypes of FLOAT  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 May 87  12:27:38 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 MAY 87 12:08:02 PDT
Date: 21 May 87 12:07 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: CLOS vs. subtypes of FLOAT
In-reply-to: Pavel.pa's message of Wed, 20 May 87 18:52:23 PDT
To: Pavel.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <870521-120802-1365@Xerox>

You omitted the possibility where all the classes exist in all
implementations, but that some of the classes might be empty (have no
instances) in some implementations.


∂21-May-87  1338	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: CLOS vs. subtypes of FLOAT   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 May 87  13:38:33 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 146801; Thu 21-May-87 16:37:36 EDT
Date: Thu, 21 May 87 16:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: CLOS vs. subtypes of FLOAT
To: Common-Lisp-Object-System@SAIL.Stanford.Edu
In-Reply-To: <870521-120802-1365@Xerox>
Message-ID: <870521163738.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 21 May 87 12:07 PDT
    From: Masinter.pa@Xerox.COM

    You omitted the possibility where all the classes exist in all
    implementations, but that some of the classes might be empty (have no
    instances) in some implementations.

Unfortunately this elegant-sounding choice can't be taken without
changing Common Lisp incompatibly.  The problem is that Common Lisp
specifies (CLtL p.19) that in an implementation without short-floats,
(typep x 'short-float) does the same thing as (typep x 'single-float),
rather than always returning nil.  We want to keep typep consistent
with class-instance relationships, to avoid giving Common Lisp too
subtly-incompatible type systems.

∂21-May-87  1909	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 May 87  19:08:50 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 MAY 87 18:22:41 PDT
Date: 21 May 87 18:22 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 27 Apr 87 01:30 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870521-182241-1963@Xerox>

I have elided parts of your message which I am not going to comment on
directly.

    Date: Mon, 27 Apr 87 01:30 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    Complexity and simplicity are partly matters of taste, and
    largely matters of point of view.

I think this notion of what complexity and simplicity are is very
important to this discussion so, despite the fact that this is a
potential tarpit, I will try to make some comments about this.

                                     I try to take the point of view
    of the majority of programmers, who are using the outer interfaces
    of the system without necessarily understanding everything that's
    going on inside.  No matter how beautifully we explain it, most
    programmers simply won't read beyond the point where they think
    they know everything they need to know to get their immediate job
    done. 

I agree.

          Now, it may be that we will decide that we would rather make
    life more complicated for people writing initialization methods in
    order to make the conceptual explanation shorter.

Another way of saying this is "it may be that we will decide that we
would rather make it syntactically more complicated for people writing
initialization methods in order to make the conceptual explanation of
the system simpler".  Let me try to explain why I would say it that way.

Because I agree with you that people will not read any more of the
documentation than they think they can get away with, I think it is
important for people to be able to develop mental models of the system
which have significant predictive power.  By predictive power I mean
(among other things) it should be possible for a user to figure out how
to do something they haven't done before based on what they already
know.  This means I believe it is often more important for a user to be
able to figure out how to do something than it is for there to be some
concise abbreviation for doing this 'new trick'.

Thus I believe that an important measure of a system's simplicity is the
ease with which users can develop a model of the system which has this
kind of predictive power.

In the example of initialization methods, my esthetic says that it would
be better for someone to be able to figure out how to write
initialization methods based on what they already know about ordinary
methods (without having to read any additional documentation) than it
would be for there to be some concise syntax for defining initialization
methods.

Note that this biases 'ease' away from the expert programmer.  For the
record, I acknowledge this and this is consistent with my belief that it
is very difficult for an expert programmer to design something which is
really easy to understand.  Expert programmers tend to design things
which have lots of 'bells and whistles' which make things simpler for
the expert user, but more complicated for everyone else.  I will cite as
examples the Interlisp-D and LispM systems.

    One key point that I was trying to convey, and I think
    partially succeeded, was the need for information hiding
    (abstraction) in the arguments to make-instance and in relations
    among the various initialization specifications attached to a class
    and its superclasses.

I agree that this is important, and your message does a good job of
collecting a lot of the reasons why this abstraction is important.
Remote initarg defaulting is related to this and your message does a
good job of describing why that is important. 

    Another key point, which I don't think came through, was that
    each initarg should be explicitly defined, and should be defined in
    exactly one place. This is simply good modularity.

I am not sure I agree with this.  In fact, there are places later in
your message where you seem to disagree with this for the same reasons I
do.

Specifically, its not entirely clear to me what it means to 'define an
initarg'.  Defining an initarg can mean specifying that this is a legal
initarg for a class (and its subclasses), or it can mean specifying what
the implementation of the processing this initarg should be.  This is
like the protocol/implementation distinction.  It would certainly be
'clean' for some sense of clean to require that legal initargs for a
class be specified in on option, and then there be other independent
mechanisms for specifying the implementation of those initargs
(corresponding to your types 1-4).  One might argue that this is
cumbersome, but its important to understand that it would be simpler in
some senses.
--- reference  ---
For reference, I am including the part of your message of April 16th
which defines initarg types 1-4.
        From: David A. Moon
        Date: Thu, 16 Apr 87 00:22 EDT

        1. :allow-other-keys serves its usual function, as in all
           &key argument lists.  It isn't possible to define
           additional initargs for step 1.
  
        2. Initargs that control storage allocation are defined
           by defining an allocate-instance method that accepts
           the initarg as an &key argument.  For example, in
           systems with areas :area is an initarg for step 2.
           The standard does not require any initargs to exist
           for step 2.
  
        3. Initargs that fill slots are defined by the :initarg
           slot-option.
  
        4. Initargs for initialization methods are defined by
           defining an initialize-instance method that accepts
           the initarg as an &key argument.
--- reference ---

    All this leads to the idea that initargs of types 2 and 4 (in
    the nomenclature of my 16 Apr message) should be defined by
    methods, since their meaning is implemented by methods.  Similarly,
    type 3 should be defined by slot-options, since their meaning is
    entirely involved with slots.  In Flavors, type 4 have the ugly
    property that they have to be defined in two places, once in the
    method that implements them and again in a defflavor form; it's
    easy to get these two places out of sync.  Hence the proposal to
    use the lambda-list of a defmethod as the way to define these
    initargs.

As I said above, 'defining' in this paragraph can have two meanings.
The part of 'defining' which implements the behavior of the initarg
should definitely be close to 'the place that behavior affects or
happens'.  So, slot setting initargs should have their behavior defined
in slots, initargs handled by methods should be in methods etc.
 
               Along with this, I tried to eliminate clunky syntax from
    initialization methods, hence the elimination of &allow-other-keys
    and the elimination of having to write :before all the time.  If
    this is too confusing, we could invent a new syntax that both
    defines initargs and defines the method that implements them. 
    Clearly this is the weakest part of my proposal.

As I said in my comments on what constitutes simplicity, I don't
necessarily agree that minor improvements in syntax (like removing
&allow-other-keys) always make for improvements in simplicity.

    We could obviously simplify things a lot by getting rid of the
    :constructor option to defclass.  I didn't put it in, at least not
    this year.  I do think it ought to remain, in spite of its inherent
    complexity in any initialization proposal (previous ones I've seen
    have glossed over this rather than solving it), because I believe
    many users will find it quite useful.

I don't know whether I like constructors yet or not.  In my message last
week I tried to show that I think constructors are deceptively confsuing
because they contain a hidden performance optimization.  I also think
they are deceptively confusing because the rules for breaking the
lambda-list down into initargs and setf of slot-value(s) are
complicated.  Because :constructors are just an abbreviation for a defun
with a make instance and some setf of slot-values, I have separated them
from the rest of initialization for the time being.  I want to think
about putting them back once we understand the rest better.

        Date: Wed, 22 Apr 87 13:42 PDT
        From: Gregor.pa@Xerox.COM

        The special method combination type for initialize
        instance adds considerable conceptual overhead for very little
        functional gain.

    The goal was not functional gain, that is, the ability to
    program something you couldn't program before, but rather syntactic
    simplicity.  Perhaps in the end we'll decide it's not worth it, but
    I'd like us to keep considering the question a bit longer.

My description of simplicity at the beginning of this message shows why
I think this extra method-combination type is not a net gain.

        Date: Wed, 22 Apr 87 17:28 PDT
        From: Gregor.pa@Xerox.COM

        The default-initargs defclass option serves two
        purposes.  It specifies all the initargs which can be passed to
        make-instance of this class, and it specifies default values
        for some of those initargs.  

    This is an important modularity mistake, in my opinion.  By
    combining these two things, which ought to be separate, you have
    lost the ability for one class to specify a default value for an
    initarg defined by another class.  If specifying a default value
    always defines an initarg, there is no way to check the consistency
    of the set of initargs with default values specified against the
    set of initargs actually defined.  If there is a misspelling, the
    default value will simply be discarded, since no method will
    receive it and do something with it.

I agree with this reasoning.  This is the reasoning I was making
reference to earlier in this message when I said that there were reasons
not to 'define' initargs in one place.

                 

∂22-May-87  0627	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: CLOS vs. subtypes of FLOAT   
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 22 May 87  06:27:38 PDT
Received: from relay2.cs.net by RELAY.CS.NET id af20247; 22 May 87 9:21 EDT
Received: from ti-csl by RELAY.CS.NET id aj07513; 22 May 87 9:16 EDT
Received: by tilde id AA13337; Fri, 22 May 87 08:10:19 CDT
Message-Id: <2757676277-14030516@Jenner>
Date: Fri, 22 May 87  08:11:17 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Pavel.pa@XEROX.COM
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: CLOS vs. subtypes of FLOAT
In-Reply-To: Msg of Wed, 20 May 87 18:52:23 PDT from Pavel.pa@xerox.com

     Date: Wed, 20 May 87 18:52:23 PDT
     From: Pavel.pa@xerox.com
     Subject: CLOS vs. subtypes of FLOAT
     

I agree with you that proposal 1(NONE) is not desirable. If we pick 1, then
the choice of making float subtypes classes will be left to each
implementation, creating confusion for users.

Proposal 2(SOME), while OK on one implementation, will portable
applications make hard to develop.  Users will have to conditionalize
the whole definition of some methods and the name of the float
specializers for some others.

Proposal 3(ALL), makes life of the user easier, but confront us to a new
problem, do we want to introduce class-synonyms. If we are to adopt 3,
then I think that class-synonyms should be standardized for general use.

Pavel brushes up two ways to address class-synonyms:

A:
     If a class A is a synonym of another class B, then A and B are not EQ,
     they have different names, and they may have different metaclasses.  No
     instances may exist of class A.  Defining a method on a generic function
     F that discriminates on A has the same general effect as defining one
     that discriminates on B.  However, if a method already exists on F that
     discriminates on B or a different synonym of B (i.e., not A), then a
     correctable error is signalled, allowing the user to choose which one of
     the two methods will remain on F.
B:
     An alternative to synonym classes would be making the name -> class
     mapping be many-to-one.

B: seems a lot simpler than A:.  It does not affect class objects, just
the name space.  It opens up some issues for class-redefinition though.

I don't like 3A: 
     Another way to avoid synonyms is to make the classes
     that would be synonyms into subclasses of the other class.  This, on the
     other hand, has the problem that methods defined on such classes would
     never be called, since no instances of them can be created.  It also
     establishes an asymmetric subclass relation for pairs with a symmetric
     subtype relation.

Because it would break the subtypep-subclassp identity.

Patrick.




∂22-May-87  0725	DLW@ALDERAAN.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!) 
Received: from [192.10.41.109] by SAIL.STANFORD.EDU with TCP; 22 May 87  07:25:35 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 84672; Fri 22-May-87 10:07:17 EDT
Date: Fri, 22 May 87 10:06 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: Object creation discussion (at last!)
To: Gregor.pa@Xerox.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870521-182241-1963@Xerox>
Message-ID: <870522100649.2.DLW@CHICOPEE.SCRC.Symbolics.COM>
Line-fold: No

    Date: 21 May 87 18:22 PDT
    From: Gregor.pa@Xerox.COM
 
        From: Moon
		   Along with this, I tried to eliminate clunky syntax from
	initialization methods, hence the elimination of &allow-other-keys
	and the elimination of having to write :before all the time.  If
	this is too confusing, we could invent a new syntax that both
	defines initargs and defines the method that implements them. 
	Clearly this is the weakest part of my proposal.

    As I said in my comments on what constitutes simplicity, I don't
    necessarily agree that minor improvements in syntax (like removing
    &allow-other-keys) always make for improvements in simplicity.

This kind of thing is a real bear.  I think you're both right.  I've
been caught on the horns of this dilemma many times before.  It's
frustrating, because I always feel that you're damned if you do and
damned if you don't.  Either you have to put in special-case material
that increases conceptual complexity, or you have to make everybody put
up with a clumsy syntax.  This seems to be one of those cases where it's
hard to avoid one evil or the other.  I don't see any decision criterion
that's clearly overriding.  If anyone has any new insights into this
generic problem, I'd love to hear them.

∂22-May-87  1002	kempf%hplabsc@hplabs.HP.COM 	Arguments to CALL-NEXT-METHOD  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 22 May 87  10:02:03 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Fri, 22 May 87 10:01:28 pdt
Received: by hplabsc ; Fri, 22 May 87 10:00:54 pdt
Date: Fri, 22 May 87 10:00:54 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705221700.AA01346@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Arguments to CALL-NEXT-METHOD


The ANSI 87-002 CLOS spec, pg. 2-6-2-7 states that rebinding of
argument parameters for CALL-NEXT-METHOD is not permitted, but
that a proposed extension is to allow it to accept arguments.
I would like to inquire about the reason for not allowing
parameter rebinding, and propose that, if no important arguments
against it are forthcoming, the proposed extension be accepted.
The reason is that, in the process of implementing COOL, I have
found need to do this.

		Jim Kempf	kempf@hplabs.hp.com

∂22-May-87  1116	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 May 87  11:16:33 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 MAY 87 11:04:43 PDT
Date: 22 May 87 11:04 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Fri,
 22 May 87 10:00:54 pdt
To: kempf%hplabsc@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870522-110443-2785@Xerox>

    The ANSI 87-002 CLOS spec, pg. 2-6-2-7 states that rebinding of
    argument parameters for CALL-NEXT-METHOD is not permitted, 

Actually, what it says is:  

 "Neither argument defaulting, nor using setq, nor rebinding variables
with the same
  names as parameters of the method affects the values call-next-method
passes to the
  method it calls."

By which it means the following is legal:

(defmethod foo ((b boat) x y)
  (let ((x (1+ x))
        (y (1+ y)))
    (call-next-method)))

But that the next method will be called with the original values of x
and y, not one plus those values.

    The reason is that, in the process of implementing COOL, I have
    found need to do this.

Having made the clarification above, I would ask:  Have you found the
need to rebind the parameters of the method or alter the values passed
by call-next-method?  I would guess the latter since that is whats
really interesting and the only thing you couldn't get around by
renaming variables.

We should probably work this out so that it is possible to pass
arguments to call-next-method.  As I remember, the problems were
specifying what happens if you change the arguments passed in such a way
that the current method itself would no longer be applicable.

∂22-May-87  1635	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 May 87  16:35:04 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 MAY 87 16:10:34 PDT
Date: 22 May 87 16:10 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 27 Apr 87 01:30 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870522-161034-1060@Xerox>

This message talks only about the things that I think happen with
initargs in Moon's proposal.  Most of what I am going to say is just a
re-interpretation of Moon's description of his proposal.  In Moon's
proposal there are lots of different declarations which involve
initargs, I am trying to understand just what those declarations really
say.

It seems to me that there are 3 different kinds of primitive
declarations involving initargs.

  1) DECLARATION of Legality
     This is a statement that in a call to make-instance of this class
     or a subclass of this class it is legal to provide this initarg.
     This primitive declaration does not exist in isolation in in Moon's
     proposal, more on that later.

  2) SPECIFICATION of how to process certain kinds of initargs.
     This is a statement telling the system how to process a particular
     initarg.  In Moon's proposal, initargs which set slots are one
     example of SPECIFICATION.  Using the :initarg slot-option tells the
     system that when that initarg is supplied the associated slot
     should be set to the initargs value.

     Another, more subtle, example of SPECIFICATION is the &key keywords
     in initialize-instance method lambda-lists.  These specify that a
     given parameter in the method body should be bound to the value of
     the initarg.

  3) DEFAULTING the value of an initarg.
     This provides a default value for an initarg be it an initarg which
     is DECLARED in this class or one which is DECLARED in a superclass
     of this class.

Moon's proposal tends to fold one or more of these primtive declarations
together in other declarations.  That is probably appropriate, and I
would expect that our final design will do so as well.  I am making
these distinctions now so that we can have some more precise mechanism
for talking about the kinds of things that can be done with initargs.

In Moon's proposal:

:initarg slot-options        combines DECLARATION and SPECIFICATION
&key in initialize-instance  combines DECLARATION and SPECIFICATION
:default-initargs            combines DECLARATION (and DEFAULTING I
think)


Now lets look for a minute at how initargs are processed at
make-instance time.  This breakdown also helps justify the breakdown I
used above.

Note that this is a naive model of how they are processed.  Any
implementation would optimize this.

1.   defaulting
     the initargs supplied in the call to make-instance are combined
     with the inherited initarg default values to get the full set of initargs.

2.   declaration checking (error checking)
     the full set of initargs is error checked to make sure they are all
     legal

3a.  specification implementation for slot initargs
     the initargs which specify slot values are used to set slot values,
     (slots not set in this way are set from their initforms)

3b.  specification implementation for other initargs
     call initialize-instance with the instance and the initargs.


Let me re-iterate the point of this message.  I am just trying to flesh
out the primitive language of statements about initargs which I think
underlies Moon's proposal.  I am not necessarily suggesting that this
primitive language is appropriate for use in the system, it may be that
we will want to continue using combined declarations.  But I think this
language can be used to describe Moon's proposal, my earlier proposal
and one that Danny has been working on.  As such I think it might be
helpful to us in trying to talk about these proposals.

∂23-May-87  0414	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 23 May 87  04:13:58 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Fri, 22 May 87 14:22:05 pdt
Received: by hplabsc ; Fri, 22 May 87 14:18:53 pdt
Date: Fri, 22 May 87 14:18:53 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705222118.AA05249@hplabsc>
To: Gregor.pa@Xerox.COM, kempf%hplabsc@hplabs.HP.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
Cc: common-lisp-object-system@sail.stanford.edu

The problem required altering the values passed by CALL-NEXT-METHOD.

Passing arguments which would make the current method not be applicable
is certainly a problem which would need some thought. Off the top
of my head, two solutions I could think of would be to only allow
parameters to be passed which are not specialized in the lambda
list of the method or simply signal an error if no method exists.

I don't think there is any way to make this work with method combination
either, since the :AROUND method depends on CALL-NEXT-METHOD, according
to 87-001, pg. 1-24.

		Jim Kempf	kempf@hplabs.hp.com

∂23-May-87  1622	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 May 87  16:22:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 MAY 87 16:22:03 PDT
Date: 23 May 87 16:21 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Fri,
 22 May 87 14:18:53 pdt
To: kempf%hplabsc@hplabs.HP.COM
cc: Gregor.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Message-ID: <870523-162203-1587@Xerox>

    Passing arguments which would make the current method not be
    applicable is certainly a problem which would need some thought.
    Off the top of my head, two solutions I could think of would be to
    only allow parameters to be passed which are not specialized in the
    lambda list of the method or simply signal an error if no method
    exists.

The model I prefer is that call-next-method arguments that are used for
method discrimination must have the SAME class as the supplied value.
This should be checked at run-time and an error signalled if not true.
If the compiler can PROVE that the new parameter will have the same
class then as an optimization the check may be skipped.  Thus changing
some arguments, but passing down the input parameters which are not
special and have not been rebound fall in that category.  

Of course, undiscriminated arguments can be changed freely. 
  

∂23-May-87  1839	Bobrow.pa@Xerox.COM 	Object creation discussion (at last!)  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 May 87  18:39:20 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 MAY 87 18:35:30 PDT
Date: 23 May 87 18:35 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Object creation discussion (at last!)
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
cc: Bobrow.pa@Xerox.COM
Message-ID: <870523-183530-1635@Xerox>

The following is another proposal for instance allocation.  Consider it
as a thought exercise to try to understand what might be possible. It
tries to provide the same functional capabilities as Moon's, but takes a
different point of view with respect to simplicity   --  by trying to
adding the smallest number of new features .  The messages by Moon and
Gregor have been most clarifying on these diffeent views of simplicity.
This proposal builds both their previous proposals, but is more in the
spirit of Gregor's.  After the specification, I respond to issues that
have come up in previous messages.


The proposal

1) provides a specializable, error-checkable intermodule mechanism for
creating instances (make-instance).

2) divides the instance creation specification between internal and
interface parts (:initargs option).  The external part specifies
allowable arguments to make-instance.

3) assumes optimization of specific calls to make-instance with quoted
arguments so that creating instances can be fast (see Gregor's recent
message), thus allowing removal of the :constructor option.

----

PROPOSAL:

The defclass class options no longer include a :constructor option.

The defclass class options are extended to include:

(:initargs (<initarg-name>
              [:slotname <slot-specifier>]
              [:default-value-form <form>])*)

Each <initarg-name> is a symbol specified to be a legal argument to
make-instance.
<initarg-name> is an abbreviation for (<initarg-name>).  

  :slotname  <slot-specifier>
     <slot-specifier> is <symbol> or (<symbol>*)
If <initarg-name> is used as a keyword argument to make-instance, then
the slot named <symbol> is initialized to the value provided for the
<initarg-name> argument. If <slot-specifier> is a list of <symbol>s,
then all those named slots are initialized with the same provided value.
An error is signalled for any <symbol> that does not name a slot of the
class.   


  :default-value-form <form> 
If :default-value-form is provided, and if <initarg-name> is not
supplied explicitly in the call to make-instance, then the value of
<form> is used by make-instance as though it were provided.  The
:default-value-form is evaluated in the lexical context of the defclass
form.

In the following, we say that an <initarg-name> has a "provided value"
if either
  1) it is provided in the call to make-instance
  2) the <initarg-name> has a :default-value-form


   Multiple occurrences of <initarg-name>
If the same <initarg-name> appears more than once in the :initargs list,
it is equivalent to a single appearance of this symbol with the union of
the values of all the :slotname options, and the first (leftmost)
:default-value-form option.

   Inheritance
The effective :initargs list for any class is the concatenation of lists
from all of the classes in its class-precedence-list in that order (most
to least specific).  The multiple occurrence rule defines the behavior
for multiple occurrences of <initarg-name>.

   Multiple occurrences of <slotname>
If more than one <initarg-name> is specified to initialize a particular
slot, then all of them CAN be used to initialize the slot.  The leftmost
provided value (leftmost in the effective :initargs list) will be used
to initialize the slot.    

   Interaction with slot initforms
If an <initarg-name> has a provided value, then that provided value is
used to initialize the slot, else it is initialized as specified in the
slot :initform option.


EXAMPLES:

(defclass point ()
    ((x :initform 0)
     (y :initform 0))
  (:init-args 
     (:x :slotname x)
     (:y :slotname y)
     :rho
     :theta)

  The keywords :x, :y, :rho and :theta are legal arguments to
make-instance.  Values provided for :x and :y initialize slots x and y
respectively.  If there are no provided values, x and y are initialized
to 0.


(defclass picture (point)
    (bitmap
     saved-bitmap)
  (:init-args
    (:y :default-value-form *screen-top*)
    (:image :slotname (bitmap saved-bitmap)))) 
 
:x, :y, :rho, :theta, and :image are legal arguments to make-instance. A
value provided for :image will initialize both slots bitmap and
saved-bitmap.  If a call to make-instance does not specify a value for
:y, then the slot y will be initialized to *screen-top*, and
initialize-instance will see a provided value of *screen-top* for :y. 


GENERIC FUNCTION INVOLVED IN OBJECT CREATION

  MAKE-INSTANCE kind &rest init-plist
is a generic function that provides the external interface to object
creation.  Methods exist for symbol and standard-class.  
 
Method on SYMBOL

It finds the class of that name, and calls the generic-function on the
class.  It signals an error if no such class is found.

Method on STANDARD-CLASS

This method checks the init-plist.  It ensures that init-plist contains
only <initarg-name>s that are allowed by the class, else signals an
error.  For each <initarg-name> that has a <default-value-form>, and
does not appear in the init-plist, it appends <initarg-name>
<value-of-form> to init-plist.

This method then calls allocate-instance with the class, and the
extended init-plist.

On the object returned from allocate-instance, this method first
initializes all slots that have an associated <initarg-name> and a
provided value, and then initializes the rest of the slots from their
slot-option :initform.

This method then calls initialize-instance on the object, and the
extended init-plist. 


  ALLOCATE-INSTANCE class &key &allow-other-keys.
returns a new uninitialized instance of the specified class.

  INITIALIZE-INSTANCE instance &key &allow-other-keys
is the user's procedural handle on initialization.  It uses
standard-method-combination.  The primary method on standard-object just
returns the instance.  One standard way of using initialize will be to
have :before methods, so that all these methods will be fired. 

   CLASS-INITARGS class &optional local-only
returns the initargs for a standard-class.  setf works with
class-initargs when local-only is T.

----
ISSUES raised in messages:

1) Lexical proximity (ie why not have an :initarg slot option)
   The criterion for simplicity used here is that there should be
exactly one way of specifying legal initargs-names.  This simplifies
code for readers who minimize reading of documentation.  Another
argument is that specifying initargs is part of the interface, not the
implementation, and hence does not belong with the slot.

I also believe that it is the environment's responsibility to provide
useful views of the class in addition to the text view in the file; for
example, allowing one to see the set of all slots in a class and all
their effective slot-options.  Another such view should show the names
of initarg-names that can be used to initialize particular slots.


2) Can methods specify legal :initargs not in the class :initargs
option?
   No, because the specification is part of the class definition.  The
method is an implementation of part of the specification.  


3) How should methods and initargs be kept in synch
   Again I believe this is something that a good environment will help
with. No later than the time when the first instance is created, the
environment can warn the user about :initarg-names that are not used for
methods or slot initialization, and methods with illegal argument names.


4) Why get rid of constructors?
   This again calls on the simplicity criterion of having only one way
to do something.  Also, I found the rules for matching constructor
argument names with slotnames and initarg-names were very complicated
and confusing.

The two arguments for constructors were:
  1) Optimized code can be written for the constructors.  But Gregor
showed how this can be done for an equivalent set of calls to
make-instance with quoted arguments.  These calls can even be compiled
in-line if desirable.
  2) Constructors can initialize slots that have no external interface.
But so can user functions that call make-instance.   


5) Why keep :initforms?
  Gregor has suggested that we eliminate the slot :initform option.  I
have not suggested this because I believe that :initforms are part of
the internal specification of the class, and :default-value-form is part
of the external specification.

6) Why is make-instance a generic function?
   This allows the user to specialize make-instance for different
meta-classes, thus avoiding any of the initialization protocol.  I could
also imagine using it for objects that I want to create only if I
couldn't find an existing object with the a given unique-identifier.
The only argument I remember against make-instance as a generic function
was that constructors didn't call make-instance, so it was the wrong
level to have a generic function.  I take this to be an argument against
having constructors.

7) What about a more compact syntax?

Since there are only two options for an initarg-name, we could use
positional notation, with
  (<initarg-name> <slot-specifier> <default-value-form>).
We could then use 
  (<initarg-name> <slot-specifier>)
if no <default-value-form> is to be given, and
  (<initarg-name> NIL <default-value-form>)
if no <slot-specifier> is to be given, and
  <initarg-name>
for no options. 


8) Must the user specify &allow-other-keys and :before for
initialize-instance?
  A simple macro can add the first or both of these. 

I believe that this is another example where the standard should be
augmented by a STANDARD library of useful extensions endorsed by the
committee.  Other things in that category for me are the macro for
defining simple-method-combination, and the standard simple
method-combination forms (and, or etc.).  This is a fourth layer for the
standard.  

∂25-May-87  0816	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 25 May 87  08:16:14 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Mon, 25 May 87 08:15:08 pdt
Received: by hplabsc ; Mon, 25 May 87 08:14:20 pdt
Date: Mon, 25 May 87 08:14:20 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705251514.AA22567@hplabsc>
To: Bobrow.pa@Xerox.COM, kempf%hplabsc@hplabs.HP.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
Cc: Gregor.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu

>The model I prefer is that call-next-method arguments that are used for
>method discrimination must have the SAME class as the supplied value.
>This should be checked at run-time and an error signalled if not true.
>If the compiler can PROVE that the new parameter will have the same
>class then as an optimization the check may be skipped.  Thus changing
>some arguments, but passing down the input parameters which are not
>special and have not been rebound fall in that category.  

This would also be acceptable, and would provide even more flexibility,
since the writer of the subclass method would have the option of
passing another object of the same class as one of the specialized
arguments. The capability to alter arguments is typically required
when the writer of the subclass method wants to filter the arguments
before passing them to the superclass method.

		Jim Kempf	kempf@hplabs.hp.com

∂25-May-87  1754	masinter.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 25 May 87  17:54:10 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 25 MAY 87 17:52:57 PDT
From: masinter.pa@Xerox.COM
Date: 25 May 87 17:52:36 PDT
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: kempf%hplabsc@hplabs.HP.COM's message of Mon, 25 May 87
 08:14:20 pdt, <8705251514.AA22567@hplabsc>
To: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
cc: Bobrow.pa@Xerox.COM, Gregor.pa@Xerox.COM,
 common-lisp-object-system@sail.stanford.edu
Message-ID: <870525-175257-2213@Xerox>

Does 3 have the same class as 3333333?

∂25-May-87  1818	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 25 May 87  18:18:38 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 25 MAY 87 18:15:42 PDT
Date: 25 May 87 18:15 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: masinter.pa's message of 25-May-87 17:52:36 PDT
To: masinter.pa@Xerox.COM
cc: kempf%hplabsc@hplabs.HP.COM, Bobrow.pa@Xerox.COM,
 Gregor.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Message-ID: <870525-181542-2236@Xerox>

    Does 3 have the same class as 3333333?

Yes.  Subranges do not have classes. (e.g. fixnums)
  danny

∂26-May-87  1724	Masinter.pa@Xerox.COM 	Re: CLOS vs. subtypes of FLOAT  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 26 May 87  17:24:17 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 26 MAY 87 15:56:56 PDT
Date: 26 May 87 15:47 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: CLOS vs. subtypes of FLOAT
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 21 May 87 16:37 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.Stanford.Edu
Message-ID: <870526-155656-1011@Xerox>


>From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: CLOS vs. subtypes of FLOAT

...
>Unfortunately this elegant-sounding choice can't be taken without
>changing Common Lisp incompatibly.  The problem is that Common Lisp
>specifies (CLtL p.19) that in an implementation without short-floats,
>(typep x 'short-float) does the same thing as (typep x 'single-float),
>rather than always returning nil.  We want to keep typep consistent
>with class-instance relationships, to avoid giving Common Lisp too
>subtly-incompatible type systems.

The conclusion I've reached is that there is no good way to allow
discrimination on subtypes of FLOAT without changing Common Lisp, or at
least the required subtypes of FLOAT.  

I'd vote for adopting Pavel's proposal NONE with the footnote that a
cleanup in the area of floating point classes is required., because the
current floating point types are not sufficiently well specified to
allow any useful discrimination on them. 

∂26-May-87  2253	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 May 87  22:53:13 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 152832; Wed 27-May-87 01:52:38 EDT
Date: Wed, 27 May 87 01:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
To: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <870523-162203-1587@Xerox>
Message-ID: <870527015250.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 23 May 87 16:21 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

	Passing arguments which would make the current method not be
	applicable is certainly a problem which would need some thought.

    The model I prefer is that call-next-method arguments that are used for
    method discrimination must have the SAME class as the supplied value.
    This should be checked at run-time and an error signalled if not true.
    If the compiler can PROVE that the new parameter will have the same
    class then as an optimization the check may be skipped.  Thus changing
    some arguments, but passing down the input parameters which are not
    special and have not been rebound fall in that category.  

    Of course, undiscriminated arguments can be changed freely. 
  
This sounds good.  There are two problems I remember from the last time
we discussed this.  One is that testing the class isn't good enough since
we have method selection by eql as well as by typep.  I guess all this
means is that the -only- way the compiler can prove that the run-time
test isn't needed is when you pass exactly the input parameter; but that
is the important special case.

The other problem is that the issue is not passing arguments which would
make the -current- method not be applicable, so much as passing
arguments which would change which -other- methods are applicable.  This
is particularly easy to see in an implementation model where the generic
function first finds all the applicable methods and sets them up for
call-next-method, and then calls the first method, and call-next-method
just pulls methods off that list.  Because of this problem, you can't do
anything at compile time because you don't know which parameters of the
generic function are used for method selection; they might be more than
just the specialized parameters of the current method.  They might change
long after the current method is compiled, by defining a new method
that specializes a different parameter.

Does anyone think we couldn't get away with this rule, which I think is
the most restrictive possible, short of not being able to change the
arguments at all (as in 87-002):  Call a parameter of the generic
function "discriminating" if -any- method for that generic function
specializes the parameter.  Each argument to call-next-method that
corresponds to a discriminating parameter of the generic function must
be EQL to the argument supplied to the generic function or an error is
signalled.  The other arguments to call-next-method can be changed
freely.  Optimizations of the error checking are possible but they
should be invisible to the programmer.

Less restrictive rules are possible but all I could think of
either were much more complicated to explain, or admitted bugs, or both.

∂26-May-87  2259	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Object creation discussion (at last!)  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 May 87  22:59:38 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 152858; Wed 27-May-87 01:59:04 EDT
Date: Wed, 27 May 87 01:59 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Object creation discussion (at last!)
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870522-161034-1060@Xerox>
Message-ID: <870527015917.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 22 May 87 16:10 PDT
    From: Gregor.pa@Xerox.COM

    This message talks only about the things that I think happen with
    initargs in Moon's proposal.  Most of what I am going to say is just a
    re-interpretation of Moon's description of his proposal.  In Moon's
    proposal there are lots of different declarations which involve
    initargs, I am trying to understand just what those declarations really
    say.

    It seems to me that there are 3 different kinds of primitive
    declarations involving initargs.

      1) DECLARATION of Legality
         This is a statement that in a call to make-instance of this class
         or a subclass of this class it is legal to provide this initarg.
         This primitive declaration does not exist in isolation in in Moon's
         proposal, more on that later.

      2) SPECIFICATION of how to process certain kinds of initargs.
         This is a statement telling the system how to process a particular
         initarg.  In Moon's proposal, initargs which set slots are one
         example of SPECIFICATION.  Using the :initarg slot-option tells the
         system that when that initarg is supplied the associated slot
         should be set to the initargs value.

         Another, more subtle, example of SPECIFICATION is the &key keywords
         in initialize-instance method lambda-lists.  These specify that a
         given parameter in the method body should be bound to the value of
         the initarg.

      3) DEFAULTING the value of an initarg.
         This provides a default value for an initarg be it an initarg which
         is DECLARED in this class or one which is DECLARED in a superclass
         of this class.

I agree with this analysis.

    Moon's proposal tends to fold one or more of these primtive declarations
    together in other declarations.  

Forbidding DECLARATION independently of SPECIFICATION was intended to be
a FEATURE of what I proposed.  That is, the specifications and the
declarations were supposed to be kept consistent automatically by not
having a syntax that could make them inconsistent.

                                     That is probably appropriate, and I
    would expect that our final design will do so as well.  I am making
    these distinctions now so that we can have some more precise mechanism
    for talking about the kinds of things that can be done with initargs.

I agree that this is a good way to proceed.

    In Moon's proposal:

    :initarg slot-options        combines DECLARATION and SPECIFICATION
    &key in initialize-instance  combines DECLARATION and SPECIFICATION

Agreed.

    :default-initargs            combines DECLARATION (and DEFAULTING I
                                 think)

No, that's a persistent misunderstanding (my "at last" writeup was not
very clear on this).  :default-initargs does DEFAULTING only.

    Now lets look for a minute at how initargs are processed at
    make-instance time.  This breakdown also helps justify the breakdown I
    used above.

    Note that this is a naive model of how they are processed.  Any
    implementation would optimize this.

    1.   defaulting
         the initargs supplied in the call to make-instance are combined
         with the
         inherited initarg default values to get the full set of initargs.

    2.   declaration checking (error checking)
         the full set of initargs is error checked to make sure they are all
         legal

    3a.  specification implementation for slot initargs
         the initargs which specify slot values are used to set slot values,
         (slots not set in this way are set from their initforms)

    3b.  specification implementation for other initargs
         call initialize-instance with the instance and the initargs.

I agree with this.

    Let me re-iterate the point of this message.  I am just trying to flesh
    out the primitive language of statements about initargs which I think
    underlies Moon's proposal.  I am not necessarily suggesting that this
    primitive language is appropriate for use in the system, it may be that
    we will want to continue using combined declarations.  But I think this
    language can be used to describe Moon's proposal, my earlier proposal
    and one that Danny has been working on.  As such I think it might be
    helpful to us in trying to talk about these proposals.

Thanks, this is a good framework for focussing the discussion.

∂26-May-87  2335	kempf%hplabsc@hplabs.HP.COM 	Re: CLOS vs. subtypes of FLOAT 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 26 May 87  23:35:06 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 26 May 87 21:00:10 pdt
Received: by hplabsc ; Tue, 26 May 87 20:59:25 pdt
Date: Tue, 26 May 87 20:59:25 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705270359.AA00431@hplabsc>
To: Masinter.pa@Xerox.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: CLOS vs. subtypes of FLOAT
Cc: Common-Lisp-Object-System@SAIL.Stanford.Edu

I agree on adopting the NONE proposal, with cleanup on float subtyping.

∂27-May-87  0803	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  08:03:04 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 08:00:39 PDT
Date: 27 May 87 08:00 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 27 May 87 01:52 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-080039-1739@Xerox>

    Call a parameter of the generic function "discriminating" if
    -any- method for that generic function specializes the parameter. 
    Each argument to call-next-method that corresponds to a
    discriminating parameter of the generic function must be EQL to the
    argument supplied to the generic function or an error is signalled.
     The other arguments to call-next-method can be changed freely. 
    Optimizations of the error checking are possible but they should be
    invisible to the programmer.

You are correct that we must consider all arguments that could be
discriminating.
The appropriate rule is 
 *The set of methods applicable to a changed set of arguments for
call-next-method must be the same as set of applicable methods for the
original arguments to the method".  There are various compilations of
this rule.   

Call any parameter of the generic function that is discriminated on an
individual an "individual discriminated parameter" and the others "class
discriminated parameters".  Then the rule is that one cannot change the
class (even the implementation dependent class) of a class discriminated
argument, nor the identity (EQL) of an individual discriminated
argument.    

Here is an example where one wants to change the value of a class
discriminated parameter.  A gauge is a display device.   Assume
different behaviors for integers and floating point input to the gauge.

(defmethod display-value ((g gauge)(i integer)) 
    (move-display-to-position  g i))            ;; show value whatever
it is

(defclass bounded-gauge (gauge)
   ((max-reading :initform 100)))

(defmethod display-value ((g bounded-gauge) (i integer))
   (with-slots (g)
      (call-next-method g  (min i max-reading))))  

    

∂27-May-87  1057	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 May 87  10:56:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 153591; Wed 27-May-87 13:49:35 EDT
Date: Wed, 27 May 87 13:49 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
To: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <870527-080039-1739@Xerox>
Message-ID: <870527134949.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 27 May 87 08:00 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    The appropriate rule is 
    The set of methods applicable to a changed set of arguments for
    call-next-method must be the same as the set of applicable methods for the
    original arguments to the method".

Okay, I'll buy that.

    Here is an example where one wants to change the value of a class
    discriminated parameter.  A gauge is a display device....

It's a somewhat contrived example, but I get your point.

Shall we call this a decision and record it someplace?

∂27-May-87  1122	RPG  	OOPSLA Lisp and Object-Oriented Programming Workshop  
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

There will be a workshop on Lisp and Object-Oriented Programming on Monday
October 5 from 9am until noon at OOPSLA.  The Common Lisp Object System
(CLOS) will be the highlight of the workshop, with presentations about
CLOS by the designers along with critiques, analyses, and responses to the
Object System, the latter selected based on contributed position papers.

Attendance will be limited to people who know Lisp and are familiar with
existing object-oriented languages.

If you would like to attend, please send me a 1-2 page description of your
position regarding either the Common Lisp Object System or
Lisp/object-oriented programming before August 1; netmail is acceptable.
Invitations will be sent on September 1. Attendance is limited to 35
people.

			Richard P. Gabriel
			Lucid, Inc
			707 Laurel Street
			Menlo Park, CA 94025
			(415)329-8400
			rpg@sail.stanford.edu

∂27-May-87  1124	RPG  	Floats   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

Pavel's note provides a good analysis, but we should take it further.  I
think there are a number of issues at work here: 1. Common Lisp makes it
difficult or impossible to put forward a sensible definition of the class
structure of floats even when only one implementation is considered; 2. a
class structure that parallels the type structure of floats is not useful
to solve the problem of portability of CLOS code among implementations; 3.
CLOS does not provide the sort of expressive machinery to solve these
problems even if we drop the requirement of making the class structure
parallel the type structure.

Let us suppose that if a programmer writes

(defmethod foo ((x single-float))...)
(defmethod foo ((x double-float))...)

he intends that the first method will be used when the internal
representation of the argument to FOO has some limited precision and that
the second method will be used when there is more precision. As Pavel
points out, different programs or even algorithms will be used depending
on the precision of floats available. I will ignore the case that the
programmer is trying to tell the compiler how to improve the code. 
In addition, the programmer is providing additional documentation
of his code by defining the methods like this - the reader knows
that the two methods are carefully chosen to behave well for certain
precisions of floating point.

Issue 1:

I will present a scenario for a valid (and sensible) Lisp implementation
situation in which the implied class structure tends to be nonsensical
because the Common Lisp type system is slightly nonsensical.

Today, there are computers that have only double-precision floating point
hardware.  These vendors often support languages in which variables can be
declared of type SINGLE-FLOAT (in effect), but these languages produce
code that loads the floating point hardware with the values of such
variables by coercing to doubles, operates on them, and then unloads
to the variables, coercing to SINGLE-FLOATs on the way.  People who have
code that is already declared with SINGLE-FLOATs are happy to suffer only
a 10%-20% slowdown over what they would get if they changed their code to
declare DOUBLE-FLOATs.

A Common Lisp for this machine, then, might use only a double-precision
representation throughout. But, according to pages 18-19 of CLtL, this
type would be considered SINGLE-FLOAT, though the types SHORT-FLOAT,
DOUBLE-FLOAT, and LONG-FLOAT are synonymous with it as far as TYPEP is
concerned. FORMAT will consider all floating point numbers to be singles
and output accordingly.

The result is that the programmer who writes FOO as above would not have
an implementation that distinguishes between SINGLE-FLOAT and
DOUBLE-FLOAT. In his implementation, there is only one floating point
representation, and to write a method that invokes the double-precision
code he could write the single method as one of:

1. (defmethod foo ((x float))...)

2. (defmethod foo ((x single-float))...)

3. (defmethod foo ((x double-float))...)

The first and second of these are possibilities under Pavel's SOME
proposal, while the third is a possibility under Pavel's ALL proposal.

The first of these would work because there is only one subclass of FLOAT,
namely SINGLE-FLOAT, and therefore FLOAT and SINGLE-FLOAT are synonymous.
The second of these works because double-precision numbers are of class
(and type) SINGLE-FLOAT. The third of these works if CLASS-OF is allowed
to return DOUBLE-FLOAT or if the class SINGLE-FLOAT is a subclass of
DOUBLE-FLOAT. CLtL doesn't state what TYPE-OF should return, but it seems
to make sense for it to return SINGLE-FLOAT to help FORMAT do its thing.

The first of these alternatives fails to provide the best documentation,
because it seems to be a method defined for a general class of floats,
from SHORT-FLOATs to LONG-FLOATs. The second one is misleading.  The third
of these alternatives possibly forces us into an inconsistency with the
Common Lisp type structure.

None of these alternatives is satisfying.  This argues that CLtL
incorrectly outlines the acceptable type structures for floats.
Basing a rational class structure on an irrational type structure
seems inadvisable.

Issue 2:

Suppose we have two Common Lisp implementations, each with all of the
possible subtypes of FLOAT as distinct types with distinct representations.
Suppose further that the first implementation is on an S3 where a
SHORT-FLOAT is an immediate type with 32 bits of mantissa, a SINGLE-FLOAT
is a boxed type with 64 bits of mantissa, a DOUBLE-FLOAT is a boxed type
with 128 bits of mantissa, and a LONG-FLOAT is a boxed type with 
256 bits of mantissa.

Suppose the second implementation is on a 68020 with special floating-point
hardware where a SHORT-FLOAT is an immediate type with 22 bits of mantissa,
SINGLE-FLOATs are boxed with 28 bits of mantissa, DOUBLE-FLOATs are boxed
with 56 bits of mantissa, and LONG-FLOATS are boxed with 80 bits of mantissa.

Now suppose that the programmer for the second machine has 4 methods,
one for each type of float where each method performs a different
computation based on the convergence properties of each floating point
type. When he tries to port his code to the first machine, the methods
get mapped to the four classes, but his programs are wrong! His SHORT-FLOAT
method is obsolete, the next three shift down one, and he has to think about
a LONG-FLOAT version for the expanded precision.

That is, the names of the types match, but the underlying descriptions of
of the representations do not.

The point is that the proposal to parallel the Common Lisp type structure
with a class structure is based on the belief that programmers want to tailor
code to the floating point formats available on a machine, but the fact
is that programmers who write such code wish to have their methods chosen
on the basis of a description of the floating point precisions and not on some
set of names of floating point types.

As Steele himself points out, there is no guaranteed portability of floating
point code in Common Lisp, and the type breakdown is only a means of providing
an aid for transportation.

Issue 3:

The crux of the matter is the the Common Lisp type system provides an
abstract type system down to some level of specificity, at which point
the type system begins to refer to internal machine-dependent representations.
We see the same problem with floats that exists with fixnums: these types
refer to machine-dependent representations.

One solution to the problem would be to define something like parametric
classes. Instead of writing

(defmethod foo ((x single-float))...)

we would write

(defmethod foo ((x (float 24 56))...)

which would state that x ought to be a floating point number whose
representation has between 24 and 56 bits of mantissa. This solution is
workable to some extent if we limit the paramaters to constants and *,
because there is presumably a mapping between (float x y) and one of the
floating-point type names at defmethod time - the mapping is made upon
``transportation.''

We could make the same argument about fixnums:

(defmethod baz ((x (fixnum 10 *)))...)

indicates that this method ought to be invoked when given a fixed precision
number whose representation has at least 10 bits of information.

When we argue that a programmer wishes to write code that discriminates on
the subtypes of FLOAT, we really argue that he wishes to parameterize his
code based on representation. The CLOS class hierarchy is applicable to
purely abstract types and not to representational types.  To say this
again in a different way, there is no descriptive power in a pure name,
and in the case of floating point numbers, we wish to map a description to
a class name and then discriminate.

One can argue that this points out an inherent limitation of CLOS - that
it operates in the abstract type domain rather than in the
representational domain. In its pristine form, instances in CLOS are dull
DEFSTRUCT-like objects, and many of the aspects of pristine CLOS as well
as the meta-object protocol are based on optimizing the results of this
choice of what instances are.

It therefore only makes sense that when CLOS comes up on a situation where
representational issues dominate that it is found weak.

Selecting the NONE option doesn't solve any problems, it only admits
defeat.

			-rpg-

∂27-May-87  1331	Masinter.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  13:30:46 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 11:09:42 PDT
Date: 27 May 87 11:08 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 27 May 87 13:49 EDT
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-110942-1982@Xerox>

I'm vaguely uneasy about allowing any argument reassignment in
call-next-method; normally lexical variables without any external
reference are insensitive to rebinding them to themselves, e.g.,

(lambda (a b c) ... code ...)

is equivalent to

(lambda (a b c) (let ((a a) (b b) (c c)) ... code ...))


The only precondition for this transformation is that there is no
reference to the variables outside of the scope of the rebinding.

When call-next-method pays attention to reassignment, I presume that it
is only reassignment of the original lexical variables (am I wrong?)

(defmethod frob ((a widget) b c)
   .. (setq a (make-widget ...))
     ...
    (call-next-method) ...))


that this would not be the same as

(defmethod frob ((a widget) b c)
  (let ((a a))
   .. (setq a (make-widget ...))
     ...
    (call-next-method) ...)))


right? 


∂27-May-87  1604	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  16:04:30 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 14:04:08 PDT
Date: 27 May 87 14:03 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Masinter.pa's message of 27 May 87 11:08 PDT
To: Masinter.pa@Xerox.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-140408-2308@Xerox>

I don't believe we are saying that rebinding or changing the value of a
binding would affect call-next-method.  Rather, I think we are talking
about another form of call-next-method which would allow arguments to be
passed to it explicitly.

∂27-May-87  1604	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  16:04:37 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 14:08:28 PDT
Date: 27 May 87 14:08 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Masinter.pa's message of 27 May 87 11:08 PDT
To: Masinter.pa@Xerox.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-140828-2315@Xerox>

I was proposing that call-next-method be given arguments 

(defmethod frob ((a widget) (b integer) c)
  
     ...
    (call-next-method a (sub1 b) c) ...))

where the values given to call-next-method are checked against the
original bindings of the parameters.  (call-next-method) uses the
original parameters, and is insensitive to rebindings.

So (defmethod frob ((a widget) b c)
   .. (setq a (make-widget ...))
     ...
    (call-next-method) ...))


should be the same as

(defmethod frob ((a widget) b c)
  (let ((a a))
   .. (setq a (make-widget ...))
     ...
    (call-next-method) ...)))

∂27-May-87  1605	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  16:05:20 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 15:35:16 PDT
Date: 27 May 87 15:35 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 27 May 87 13:49 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
To: Bobrow.pa@Xerox.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-153516-2470@Xerox>

It seems to me that the whole notion of a 'class discriminated
parameter' is a little problematic.  After all, any parameter which is
not an 'individual discriminated parameter' is class discriminated; the
default discrimination of an argument is T.  This is not a mute point
since there is no rule that says that someone can't make a class which
has no supers at all (hence an entire different root node).


Also it seems that Danny's example is an excellent example of why we
can't compile the rule that you can't change the applicable set of
methods down into the compilations he gives.

Specifically, Danny's "Assume different behaviors for integer and
floating point input to the gauge" finesses too important a point.

If you had a gauge which just had a method like this:

(defmethod display-value ((g gauge) v)
  ... show the value ...)

You would want to implement the bounded gauge method like this:

(defmethod display-value ((g bounded-gauge) v)
  (with-slots (g)
    (call-next-method g (min v max-reading))))

You wouldn't want to have to say:

(defmethod display-value ((g bounded-gauge) v)
  (with-slots (g)
    (call-next-method g (number-coerce v (min v max-reading)))))

The point is that while the first method on bounded gauge might change
the class of the argument (it could change 151.23 to 100) it wouldn't
change the set of applicable methods.  I think this shows why the stated
rule must be:
   "The set of methods applicable to a changed set of arguments for
     call-next-method must be the same as set of applicable methods for
the
     original arguments to the method"

Not any of the proposed compilations of that rule.

Also, we will presumably want APPLY-NEXT-METHOD in addition to
call-next-method.

∂27-May-87  1753	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD  
Received: from [192.10.41.223] by SAIL.STANFORD.EDU with TCP; 27 May 87  17:53:09 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 133080; Wed 27-May-87 20:37:44 EDT
Date: Wed, 27 May 87 20:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
To: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <870527-153516-2470@Xerox>
Message-ID: <870527203752.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 27 May 87 15:35 PDT
    From: Gregor.pa@Xerox.COM

    Also, we will presumably want APPLY-NEXT-METHOD in addition to
    call-next-method.

No, we changed call-next-method from a macro to lexically local function
so that you could just say (apply #'call-next-method ...).

∂27-May-87  1909	kahn.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  19:09:51 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 27 MAY 87 16:18:36 PDT
Date: Wed, 27 May 87 16:18:15 PDT
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
In-Reply-To: <870527-153516-2470@Xerox>
To: Gregor.pa@Xerox.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Bobrow.pa@Xerox.COM,
 common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-161836-2566@Xerox>

>   After all, any parameter which is not an 'individual discriminated
parameter'
>   is class discriminated; the default discrimination of an argument is
>   T.  This is not a mute point since there is no rule that says that
someone
>   can't make a class which has no supers at all (hence an entire
different
>   root node).

Does this mean that PCL is incorrect in its implementation of method
lookup when some of the arguments are specified as instances of T?  The
point is that allowing for another root node can be very expensive.


References
	Gregor's message of Wed, 27 May 87 15:35:00 PDT -- Re: Arguments to
CALL-NEXT-METHOD

∂27-May-87  1910	Gregor.pa@Xerox.COM 	OK, I stand corrected   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  19:10:18 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 18:08:33 PDT
Date: 27 May 87 18:08 PDT
From: Gregor.pa@Xerox.COM
Subject: OK, I stand corrected 
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870527-180833-2712@Xerox>

For the next 3 days, you will find me in my office, writing the
following on my whiteboard 1000 times.

moot n. 1. An ancient English meeting, especially a representative
meeting of the freemen of a shire. 2. An imaginary case argued by law
students as an exercise.  --tr.v. mooted, mooting, moots. 1. a. To offer
as a subject for debate; bring up for discussion. b. To discuss or
debate. 2. To plead or argue (a case) in a moot court.  --adj. 1.
Subject to debate; arguable; unresolved: a moot question. 2. Law.
Without legal significance, through having been previously decided or
settled; of only academic importance. [Middle English mot, moot, Old
English mot, moot, assembly. See mod- in Appendix.] 


mute adj. muter, mutest. 1. Refraining from producing speech or vocal
sound. 2. a. Unable to speak. b. Unable to vocalize, as certain animals.
3. Law. Refusing, as a defendant, to plead either guilty or not guilty
when under arraignment. Used chiefly in the phrase stand mute. 4.
Phonetics. a. Not pronounced; silent, as the e in house. b. Pronounced
with a temporary stoppage of breath, as the sounds of p and b; plosive;
stopped.  --See Synonyms at dumb.  --n. 1. A person incapable of speech;
especially, one both deaf and mute. 2. Law. A defendant who refuses to
plead either guilty or not guilty when under arraignment. 3. Music. Any
of various devices used to muffle or soften the tone of a musical
instrument. 4. Phonetics. a. A silent or unpronounced letter. b. A
plosive; a stop.  --tr.v. muted, muting, mutes. 1. To muffle or soften
the sound of. 2. To soften the tone, color, shade, or hue of. [Middle
English muet, from Old French, diminutive of mu, mute, from Latin mutus,
silent, dumb. See mu- in Appendix.]  --mute"ly adv.  --mute"ness n. 




dyslexics of america
       untie!

∂27-May-87  1910	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  19:10:28 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 18:11:37 PDT
Date: 27 May 87 18:11 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Gregor.pa's message of 27 May 87 15:35 PDT
To: Gregor.pa@Xerox.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Bobrow.pa@Xerox.COM,
 common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-181137-2717@Xerox>

    I think this shows why the stated rule must be:
       "The set of methods applicable to a changed set of
         arguments for call-next-method must be the same as set of
         applicable methods for the original arguments to the method"
    Not any of the proposed compilations of that rule.
I will revise my deinition slightly to try to save my proposed
compilation.

Any parameter that is specialized by any class other than T, and is not
specialized by an individual is "class discriminated".  For any of those
arguments, not changing the class is sufficient to ensure that the set
of applicable methods is not changed.

For my example, in which there was specialization on the class of v was
done, it is necessary to write:
(defmethod display-value ((g bounded-gauge) v)
  (with-slots (g)
    (call-next-method g (number-coerce v (min v max-reading)))))

∂27-May-87  1910	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 May 87  19:09:57 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 87 16:24:04 PDT
Date: 27 May 87 16:23 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Ken Kahn <Kahn.pa>'s message of Wed, 27 May 87 16:18:15 PDT
To: Kahn.pa@Xerox.COM
cc: Gregor.pa@Xerox.COM, Moon@STONY-BROOK.SCRC.Symbolics.COM,
 Bobrow.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Message-ID: <870527-162404-2575@Xerox>

    Date: Wed, 27 May 87 16:18:15 PDT
    From: Ken Kahn <Kahn.pa>

    Does this mean that PCL is incorrect in its implementation of
    method lookup when some of the arguments are specified as instances
    of T?  The point is that allowing for another root node can be very
    expensive.

Uh, sorry.  Right, confusion and stuff.

The rest of my message still applies.  Namely, I think we have to make
the rule that you can't change the set of applicable methods.

∂28-May-87  0413	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  04:13:05 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Wed, 27 May 87 19:10:12 pdt
Received: by hplabsc ; Wed, 27 May 87 18:54:40 pdt
Date: Wed, 27 May 87 18:54:40 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705280154.AA13174@hplabsc>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM,
        common-lisp-object-system@sail.stanford.edu
Subject: Re: Arguments to CALL-NEXT-METHOD

This sounds good. I second the motion to call it a decision.

		jak

∂28-May-87  0804	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  08:03:52 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 28 May 87 08:03:44 pdt
Received: by hplabsc ; Thu, 28 May 87 08:02:57 pdt
Date: Thu, 28 May 87 08:02:57 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705281502.AA19075@hplabsc>
To: Masinter.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Subject: Re: Arguments to CALL-NEXT-METHOD

>I'm vaguely uneasy about allowing any argument reassignment in
>call-next-method; normally lexical variables without any external
>reference are insensitive to rebinding them to themselves, e.g.,
>

My understanding was that rebinding would not be allowed, but
that passing of arguments would. Thus:

(defmethod frob ((a widget) b c)

   (call-next-method (make-widget ...) b c)

)

This would make the arguments explicit, rather than relying on
binding. 

		jak

∂28-May-87  0856	kempf%hplabsc@hplabs.HP.COM 	Re:  Floats
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  08:56:12 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 28 May 87 08:55:34 pdt
Received: by hplabsc ; Thu, 28 May 87 08:54:39 pdt
Date: Thu, 28 May 87 08:54:39 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705281554.AA19596@hplabsc>
To: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re:  Floats

>One solution to the problem would be to define something like parametric
>classes. Instead of writing
>
>(defmethod foo ((x single-float))...)
>
>we would write
>
>(defmethod foo ((x (float 24 56))...)
>
>which would state that x ought to be a floating point number whose
>representation has between 24 and 56 bits of mantissa. This solution is
>workable to some extent if we limit the paramaters to constants and *,
>because there is presumably a mapping between (float x y) and one of the
>floating-point type names at defmethod time - the mapping is made upon
>``transportation.''

Or, alternatively, provide some means to extend STANDARD-TYPE-CLASS
for particular implementations of CLOS so that programmers could
write:

(defmethod foo ((x float-with-24-56-bits-mantissa) ...)

The extension could be done by implementors of CLOS for particular
hardware, and information on it could be provided through the
*FEATURES* flag (CLtL, pg. 448) so it could be used in readtime
conditionals, if necessary.

With regard to paramatetric classes, I think this is opening up
a whole new can of worms, which we may want to think seriously
about opening at this stage of the game. Languages like Eiffel
and (via generic packages) Ada have them, and there is no reason
that they couldn't be added to Common Lisp, but I would be reluctant
to write that into the standard, until the issues are better understood.
In particular, the interaction between multiple inheritance and 
parameterized classes could potentially be quite complex.


>We could make the same argument about fixnums:
>
>(defmethod baz ((x (fixnum 10 *)))...)
>
>indicates that this method ought to be invoked when given a fixed precision
>number whose representation has at least 10 bits of information.

True.


>One can argue that this points out an inherent limitation of CLOS - that
>it operates in the abstract type domain rather than in the
>representational domain. In its pristine form, instances in CLOS are dull
>DEFSTRUCT-like objects, and many of the aspects of pristine CLOS as well
>as the meta-object protocol are based on optimizing the results of this
>choice of what instances are.

The instance creation protocol which is currently being discussed
actually deals with this issue. To a certain extent, the metaobject
protocol is the place for representation to be handled (in my opinion).
STANDARD-TYPE-CLASS is an example of a metaclass with a different
representation than STANDARD-CLASS, as is STANDARD-STRUCTURE-CLASS.
I could imagine a STANDARD-PERSISTENT-CLASS, which has instances
in a database or in the file system, or STANDARD-CD-ROM-CLASS, with
instances which are CD-ROM video or audio images. 

>Selecting the NONE option doesn't solve any problems, it only admits
>defeat.


Well, I wouldn't put it that way. I think Larry's comment was appropriate.
The problem is not so much with CLOS as with how the Common Lisp type
system was put together (as was mentioned earlier in this note). 
In my opinion, that should be where the problem is fixed. 

		jak

∂28-May-87  1158	Masinter.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  11:58:01 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 MAY 87 11:31:40 PDT
Date: 28 May 87 11:30 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Thu,
 28 May 87 08:02:57 pdt
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <870528-113140-3619@Xerox>

I am embarrased that I totally misunderstood the call-next-method
proposal.

What does (call-next-method) do with optional arguments which have been
defaulted? Does it pass down the values as defaulted or does it
re-default them?

What about optionals which are left out of call-next-method?

∂28-May-87  1251	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  12:51:12 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 28 May 87 12:49:46 pdt
Received: by hplabsc ; Thu, 28 May 87 12:33:11 pdt
Date: Thu, 28 May 87 12:33:11 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705281933.AA21877@hplabsc>
To: Masinter.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Subject: Re: Arguments to CALL-NEXT-METHOD


>What does (call-next-method) do with optional arguments which have been
>defaulted? Does it pass down the values as defaulted or does it
>re-default them?

Good question. Off the top of my head, I'd suggest redefaulting. Any
objections?


>What about optionals which are left out of call-next-method?

Again, I'd assume they default. The model is that CALL-NEXT-METHOD
acts like FUNCALL or APPLY of the method, except method lookup is
short-circuited so the next applicable method is used. At least,
that's how I've been looking at it.

			jak

∂28-May-87  1458	Bobrow.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  14:58:25 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 MAY 87 14:56:56 PDT
Date: 28 May 87 14:56 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Thu,
 28 May 87 12:33:11 pdt
To: kempf%hplabsc@hplabs.HP.COM
cc: Masinter.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Message-ID: <870528-145656-3982@Xerox>

      What does (call-next-method) do with optional arguments
      which have been defaulted? Does it pass down the values as
      defaulted or does it re-default them?

    Good question. Off the top of my head, I'd suggest
    redefaulting. Any objections?
Isn't there an efficiency (implementation) argument that makes it much
more expensive to do this.  If Gregor's early suggestion of
"unpassed-argument" as a value were used for values of optional
arguments that were not passed, then things would be different I think.

∂28-May-87  1511	kempf%hplabsc@hplabs.HP.COM 	Re: Arguments to CALL-NEXT-METHOD   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  15:10:56 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 28 May 87 15:10:06 pdt
Received: by hplabsc ; Thu, 28 May 87 15:09:09 pdt
Date: Thu, 28 May 87 15:09:09 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8705282209.AA23894@hplabsc>
To: Bobrow.pa@Xerox.COM, kempf%hplabsc@hplabs.HP.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
Cc: Masinter.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu

      What does (call-next-method) do with optional arguments
      which have been defaulted? Does it pass down the values as
      defaulted or does it re-default them?

    Good question. Off the top of my head, I'd suggest
    redefaulting. Any objections?
Isn't there an efficiency (implementation) argument that makes it much
more expensive to do this.  If Gregor's early suggestion of
"unpassed-argument" as a value were used for values of optional
arguments that were not passed, then things would be different I think.

Yes, it could be more expensive, depending on the implementation
of optionals. 

∂28-May-87  1532	Gregor.pa@Xerox.COM 	Re: Arguments to CALL-NEXT-METHOD 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 May 87  15:32:29 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 MAY 87 15:27:32 PDT
Date: 28 May 87 15:27 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Arguments to CALL-NEXT-METHOD
In-reply-to: Danny Bobrow <Bobrow.pa>'s message of 28 May 87 14:56 PDT
To: Bobrow.pa@Xerox.COM
cc: kempf%hplabsc@hplabs.HP.COM, Masinter.pa@Xerox.COM,
 common-lisp-object-system@sail.stanford.edu
Message-ID: <870528-152732-4022@Xerox>

          What does (call-next-method) do with optional arguments
          which have been defaulted? Does it pass down the values as
          defaulted or does it re-default them?

        Good question. Off the top of my head, I'd suggest
        redefaulting. Any objections?
    Isn't there an efficiency (implementation) argument that makes
    it much
    more expensive to do this.  If Gregor's early suggestion of
    "unpassed-argument" as a value were used for values of optional
    arguments that were not passed, then things would be different
    I think.

The spec is already clear on this point.  The arguments are redefaulted.
I see no reason to change the spec on this.

∂28-May-87  2159	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Arguments to CALL-NEXT-METHOD
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 May 87  21:59:19 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 156444; Fri 29-May-87 00:58:41 EDT
Date: Fri, 29 May 87 00:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Arguments to CALL-NEXT-METHOD
To: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <870528-152732-4022@Xerox>
Message-ID: <870529005850.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 28 May 87 15:27 PDT
    From: Gregor.pa@Xerox.COM

	      What does (call-next-method) do with optional arguments
	      which have been defaulted? Does it pass down the values as
	      defaulted or does it re-default them?

	    Good question. Off the top of my head, I'd suggest
	    redefaulting. Any objections?
	Isn't there an efficiency (implementation) argument that makes
	it much
	more expensive to do this.  If Gregor's early suggestion of
	"unpassed-argument" as a value were used for values of optional
	arguments that were not passed, then things would be different
	I think.

    The spec is already clear on this point.  The arguments are redefaulted.
    I see no reason to change the spec on this.

I strongly agree.  I also don't believe that there is a significant efficiency
cost.

∂29-May-87  1418	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 May 87  14:18:39 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 157396; Fri 29-May-87 17:17:59 EDT
Date: Fri, 29 May 87 17:18 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object creation discussion (at last!)
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870523-183530-1635@Xerox>
Message-ID: <870529171806.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 23 May 87 18:35 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    The following is another proposal for instance allocation....

I have been pondering this for a few days.  We're getting close to agreement,
I think, but there are a few things about your proposal that bother me.
In this message, I will comment on excerpts from your message that bother me.
In the next message, I will send out a succinct description of how I
see things working, divided up into "necessary" and "optional" features,
with places identified where decisions between alternatives need to be made.

I will use the terminology introduced by Gregor in his message of May 22.

    2) divides the instance creation specification between internal and
    interface parts (:initargs option).  The external part specifies
    allowable arguments to make-instance.

I don't think you've completely succeeded in achieving this goal.
Details below.  Actually, I doubt that it is feasible to achieve this
goal without major sacrifices in other goals of the standard.

    3) assumes optimization of specific calls to make-instance with quoted
    arguments so that creating instances can be fast (see Gregor's recent
    message), thus allowing removal of the :constructor option.

I agree that we should defer :constructor until we have figured out the
main part of object creation.  I don't agree that it has yet been
demonstrated that :constructor is not needed.

    The defclass class options are extended to include:

    (:initargs (<initarg-name>
		  [:slotname <slot-specifier>]
		  [:default-value-form <form>])*)

    Each <initarg-name> is a symbol specified to be a legal argument to
    make-instance.
    <initarg-name> is an abbreviation for (<initarg-name>).  

I have two problems with this.  For initargs that initialize slots,
this option contains both the declaration and the specification, but
for initargs implemented by methods, this option contains only the
declaration.  That seems inconsistent to me, and inconsistent with
your goal of separating the internal and external parts.

The inclusion of the :default-value-form here seems redundant.  For
initargs that initialize slots, there is already a way to specify a
default value form in the slot description.  For initargs that are
implemented by methods, there is already a way to specify a default
value form in the method parameter list.  This :default-value-form
may be based on :default-initargs in an earlier proposal of mine,
but that was something different; :default-initargs was decoupled
from the declaration and specification of initargs, and indeed would
normally appear in a different class.  But :default-value-form here
is tightly coupled to the declaration, and to the specification in
the case of initargs that initialize slots.

    For each <initarg-name> that has a <default-value-form>, and
    does not appear in the init-plist, MAKE-INSTANCE appends <initarg-name>
    <value-of-form> to init-plist.

This could be an efficiency problem.  I would prefer it if this did not
have to be done for initargs that have not been specified to be
implemented by methods.  Defaulting of initargs that initialize slots
can be handled more efficiently, with no need to construct an actual
list of them.

       CLASS-INITARGS class &optional local-only
    returns the initargs for a standard-class.  setf works with
    class-initargs when local-only is T.

In my proposal (coming in the next message) I use naming conventions for
this that are more consistent with the 87-003 document.  If you've
changed your mind on what naming conventions should be used for the
meta-object functions, please let me know.

    ISSUES raised in messages:

    1) Lexical proximity (ie why not have an :initarg slot option)
       The criterion for simplicity used here is that there should be
    exactly one way of specifying legal initargs-names.  This simplifies
    code for readers who minimize reading of documentation.  Another
    argument is that specifying initargs is part of the interface, not the
    implementation, and hence does not belong with the slot.

I agree with the philosophy of having only one way to do things, but
these arguments are weak, since your :initargs class-option still mixes
implementation with interface, and since (as you point out just below)
readers of code should find out the legal initarg names through a
suitable tool rather than by blundering through code whose documentation
they haven't read.

In my forthcoming proposal, I went back to the :initarg slot-option because
on the whole I think it comes out simpler and better that way.  Either way,
there is lexically adjacent information that from some points of view should
be separate and lexically remote information that from some points of view
should be together.  I think the congnitive structure is too complex to be
represented in text, and no Lisp syntax can address all points of view.  The
environment tools you suggest below seem like a better answer.

    I also believe that it is the environment's responsibility to provide
    useful views of the class in addition to the text view in the file; for
    example, allowing one to see the set of all slots in a class and all
    their effective slot-options.  Another such view should show the names
    of initarg-names that can be used to initialize particular slots.

I certainly believe in this, and my environment does provide the Flavor
equivalents of these features.  They're quite useful in practice.

    3) How should methods and initargs be kept in synch
       Again I believe this is something that a good environment will help
    with. No later than the time when the first instance is created, the
    environment can warn the user about :initarg-names that are not used for
    methods or slot initialization, and methods with illegal argument names.

On 22 April, Gregor said "why is it that I can't count on the methods
getting all the initargs if I use &rest in the lambda-list?"  Note that
you can't have it both ways; if the environment does this checking, you
can't use &rest to do your own implementation of the &key mechanism, because
the environment wouldn't be able to figure out what initargs that method
implements.

      INITIALIZE-INSTANCE instance &key &allow-other-keys
    is the user's procedural handle on initialization.  It uses
    standard-method-combination.  The primary method on standard-object just
    returns the instance.  One standard way of using initialize will be to
    have :before methods, so that all these methods will be fired. 

    8) Must the user specify &allow-other-keys and :before for
    initialize-instance?
      A simple macro can add the first or both of these. 

Could you explain to my thick skull why

(defmethod-initialize-instance ((x my-class) &key foo bar) ...)

is preferable to and simpler than

(defmethod initialize-instance ((x my-class) &key foo bar) ...)

    I believe that this is another example where the standard should be
    augmented by a STANDARD library of useful extensions endorsed by the
    committee.  Other things in that category for me are the macro for
    defining simple-method-combination, and the standard simple
    method-combination forms (and, or etc.).  This is a fourth layer for the
    standard.  

I think this is a good idea, but I want to warn that we need to be very
careful in how we execute it.  If the standard library is only "endorsed"
and not really part of the standard, it is very easy to fall into a Tower
of Babel situation where everyone has their own slightly incompatible
version of the standard library, programs are not really portable, and
programmers can't really understand each other's code.  It would be a
shame if that happened.  Perhaps if the standard is organized into a
kernel whose description is smaller and can be read in less time, plus
a library, but both are equally well-specified parts of the standard,
it could work.  However, I don't think this approach always works;
sometimes the division between "kernel" and "library" seems arbitrary
and only makes the standard seem more complicated.

∂29-May-87  1430	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation discussion (at last!) 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 May 87  14:30:28 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 157424; Fri 29-May-87 17:29:47 EDT
Date: Fri, 29 May 87 17:29 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object creation discussion (at last!)
To: Common-Lisp-Object-System@sail.stanford.edu
References: <870416002258.1.MOON@EUPHRATES.SCRC.Symbolics.COM>,
            <870422172838.5.GREGOR@AVALON.isl.parc.xerox.com>,
            <870522-161034-1060@Xerox>,
            <870523-183530-1635@Xerox>,
            <870527015917.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <870529172955.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

Object creation seems to divide naturally into eight parts, of which three
are essential and five could optionally be added to provide increased
convenience or customizability.  When I say these are optional, I don't mean
that the standard would allow implementations to implement them or not
implement them at their convenience; I mean that we must decide whether to
include them in the proposed standard to gain convenience or customizability,
or to exclude them to gain simplicity or understandability.

I'll discuss how I see each of the eight parts working.  I'll use the
declaration/specification/defaulting terminology introduced by Gregor in his
message of 22 May.  My language is not precise enough for a final draft, but
I hope the concepts come across clearly this time.  For brevity, I have
omitted motivation and philosophy; they have already been discussed in the
mail and can continue to be discussed as needed.  In places where there
didn't seem to be a concensus I have included a menu of choices with brief
descriptions.

-foo- means the word foo in italics.  FOO means the word foo in boldface.


1. MAKE-INSTANCE and the initarg concept

Objects are created by calling MAKE-INSTANCE.  The first argument is a
class or the name of a class, and the remaining arguments are -initargs-
(initialization arguments).  Each initarg has a -name-, which is a symbol
(not necessarily a keyword), and a -value-.  The arguments to MAKE-INSTANCE,
excepting the first, are alternating names and values of initargs. 
MAKE-INSTANCE returns one value, the object that was created.

A programmer -declares- the names of initargs that are valid for a class,
-specifies- the implementation of those initargs (what is done with their
values), and optionally (part 7) supplies -default value forms- for them.
The set of valid initargs for a class is the union of the initargs declared
by the class and its superclasses.  MAKE-INSTANCE signals an error if an
initarg is supplied that is not valid.

Inheritance of initarg specifications and defaults is discussed in later
sections.

It is valid for an initarg to be declared more than once, and to be
implemented more than once (for example, an initarg could initialize a slot
and also be used by a method).

We say that an initarg -has a value- if the initarg appears in the arguments
to MAKE-INSTANCE, or if the initarg was defaulted (see part 7).

If the same initarg is given more than once in the arguments to MAKE-INSTANCE,
the leftmost occurrence prevails, as required by Common Lisp.

There is one pre-declared initarg in the standard.  Its name is
:ALLOW-OTHER-KEYS, its default is NIL, and its specification is the same as
Common Lisp defines for &KEY argument lists.


2. Initargs that initialize slots

The :INITARG -name- slot-option -declares- an initarg named -name- and
-specifies- that this initarg initializes the slot to which the slot-option is
attached.  If the initarg has a value, the value is stored into the slot and
the slot's :INITFORM, if any, is not evaluated.  If no initarg specified to
initialize a given slot has a value, then the slot is initialized according to
the :INITFORM (if any).

The :INITARG slot-option is inherited from superclasses.  The set of initargs
that initialize a given slot is the union of the initargs declared in :INITARG
slot-options with the same slot name in the class and its superclasses.  If
two different initargs that initialize the same slot are given in the
arguments to MAKE-INSTANCE, we have to decide what happens.

  2a. The leftmost occurrence in the arguments to MAKE-INSTANCE prevails.

  2b. The initarg -declared- by the class that appears earliest in the
  class precedence list prevails.

The :INITARG slot-option may be specified more than once for a given slot.

A single initarg can initialize more than one slot if the same initarg name
appears in more than one :INITARG slot-option.

There is no DEFCLASS option that specifies initargs for all the slots,
because that would endorse a particular convention for naming initargs.


3. Initialization methods

After the slots have been initialized, methods for INITIALIZE-INSTANCE are
called.  The first argument is the instance and the remaining arguments
are initargs.  Defining an INITIALIZE-INSTANCE method that accepts the
value of an initarg with an &KEY parameter -specifies- the implementation
of that initarg.  The parameter specifier can also supply a default value
form in the standard way.  This default value form affects only the method
in which it appears; it is not a substitute for the facility in part 7.

The value returned by an INITIALIZE-INSTANCE method is ignored; these methods
are used for their side-effects only.

We have to decide between two ways of -declaring- initargs whose
implementation is -specified- by INITIALIZE-INSTANCE methods.

  3a. The parameter list of the DEFMETHOD -declares- each &KEY parameter's
  keyword-name as an initarg.

  3b. Initargs that are not -declared- by a :INITARG slot-option must be
  -declared- by a :INITARGS class-option before they can be used.  The
  syntax is (:INITARGS -name1- -name2- ... ).

We have to decide between two ways of inheriting INITIALIZE-INSTANCE methods.

  3c. All INITIALIZE-INSTANCE methods are called, most-specific first.

  3d. Standard method combination is used.  Normally an INITIALIZE-INSTANCE
  method must have a :BEFORE qualifier or use CALL-NEXT-METHOD, otherwise
  it would prevent superclasses' initialization methods from being called.

We have to decide whether &REST parameters are allowed in INITIALIZE-INSTANCE
methods.

  3e. INITIALIZE-INSTANCE methods must have one required parameter and may
  have &KEY parameters; &OPTIONAL and &REST parameters are not permitted.

  3f. An INITIALIZE-INSTANCE method may have an &REST parameter, which sees
  all of the initargs.  ("All" needs to be defined more precisely if the
  optional feature of part 7 is adopted; does it necessarily include defaulted
  initargs?)

We have to decide whether the parameter list of an INITIALIZE-INSTANCE method
must contain the symbol &ALLOW-OTHER-KEYS.

  3g. &ALLOW-OTHER-KEYS is not required.

  3h. &ALLOW-OTHER-KEYS is required at the end of every INITIALIZE-INSTANCE
  method's parameter list.


EVERYTHING BELOW THIS LINE IS OPTIONAL


4. Allocation methods

The allocation of storage for new instances can be customized by
defining a method for the ALLOCATE-INSTANCE generic function.  The
value returned is the instance, with no slot values filled in.  The
arguments to an ALLOCATE-INSTANCE method are the same as the arguments
to an INITIALIZE-INSTANCE method, except that the first argument is
the class rather than the instance.

ALLOCATE-INSTANCE uses standard method combination.

There is a default method for ALLOCATE-INSTANCE that does the appropriate
implementation-dependent allocation.

The answers to the choices given in part 3, except for 3c/3d, are identical
for ALLOCATE-INSTANCE and INITIALIZE-INSTANCE methods.


5. MAKE-INSTANCE as a generic function

There are predefined methods for MAKE-INSTANCE selected when the first
argument is a SYMBOL or a STANDARD-CLASS, which implement the behavior
described in part 1.  Additional methods can be defined to customize
the behavior of MAKE-INSTANCE for different metaclasses.


6. Initarg accessor functions for class objects

CLASS-DIRECT-INITARGS takes a class and returns a list of symbols that are
names of initargs -declared- for the class.

CLASS-ALL-INITARGS takes a class and returns a list of symbols that are names
of valid initargs for the class.

CLASS-DIRECT-SLOT-INITARGS takes a class and returns a list of
(initarg-name slot-name) lists, with one element for each :INITARG
slot-option in the class.

CLASS-ALL-SLOT-INITARGS takes a class and returns a list of
(initarg-name slot-name) lists, with one element for each :INITARG
slot-option in the class and its superclasses.


7. Defaulting of initargs

A -default value form- can be supplied for an initarg, remotely from the
class that -declares- the initarg's validity and -specifies- the initarg's
implementation.

The :DEFAULT-INITARGS class-option is followed by alternating initarg
names and forms.  This class option can appear more than once in a DEFCLASS,
but an error is signalled if an initarg name appears more than once in
:DEFAULT-INITARGS class-options.

This class option is inherited; the set of initargs for a class that are
defaulted is the union of the sets of initargs specified in
:DEFAULT-INITARGS class-options of the class and its superclasses.  When
more than one default value form is supplied for a given initarg, the
default value form supplied by the class that appears earliest in the class
precedence list is used.

If an initarg for a class is defaulted, it always -has a value-.  If the
initarg does not appear in the arguments to MAKE-INSTANCE, the default
value form is evaluated in the lexical environment of the DEFCLASS form
that supplied it and the resulting value is used as the initarg's value.

The CLASS-DIRECT-INITARG-DEFAULTS function takes a class and returns a
list of (initarg-name default-value-form) lists, with one element for each
:INITARG slot-option in the class.

The CLASS-ALL-INITARG-DEFAULTS function takes a class and returns a
list of (initarg-name default-value-form) lists, with one element for each
:INITARG slot-option in the class and its superclasses.


8. Constructors

I think we should defer talking about the details of constructors, or
even deciding whether or not they are needed, until we have settled the
main part of object creation.  So I've deleted part 8 of my discussion.

∂29-May-87  1818	Bobrow.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 29 May 87  18:18:20 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 29 MAY 87 18:17:21 PDT
Date: 29 May 87 18:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Object creation discussion (at last!)
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 29 May 87 17:18 EDT
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870529-181721-1169@Xerox>

Answers to some of the smale questions in your first message:

        8) Must the user specify &allow-other-keys and :before
        for initialize-instance?
          A simple macro can add the first or both of these. 

    Could you explain to my thick skull why

    (defmethod-initialize-instance ((x my-class) &key foo bar) ...)

    is preferable to and simpler than

    (defmethod initialize-instance ((x my-class) &key foo bar) ...)

My belief was that

(defmethod-init ((x-my-class) &key foo) ...)

would be preferable for some people to

(defmethod initialize-instance :before
     ((x-my-class) &key foo &allow-other-keys) ...)
Because of its greater conciseness.  I would be happy to do without,
since I thin the latter is clearer.  Especially since I was not allowing
a new method combination form, and seeing the :before is a useful
reminder.  So this special macro has only weak support from me.

        I believe that this is another example where the
        standard should be augmented by a STANDARD library of useful
        extensions endorsed by the committee.  Other things in that
        category for me are the macro for defining
        simple-method-combination, and the standard simple
        method-combination forms (and, or etc.).  This is a fourth
        layer for the standard. 
 

    I think this is a good idea, but I want to warn that we need to
    be very careful in how we execute it.  If the standard library is
    only "endorsed" and not really part of the standard, it is very
    easy to fall into a Tower of Babel situation where everyone has
    their own slightly incompatible version of the standard library,
    programs are not really portable, and programmers can't really
    understand each other's code.  It would be a shame if that
    happened.  Perhaps if the standard is organized into a kernel whose
    description is smaller and can be read in less time, plus a
    library, but both are equally well-specified parts of the standard,
    it could work.  However, I don't think this approach always works;
    sometimes the division between "kernel" and "library" seems
    arbitrary and only makes the standard seem more complicated.

My idea here is that instead of providing a specification for things in
the library, we provide reference code that is part of the standard.  It
is expected that it is this code OR CODE THAT HAS IDENTICAL EFFECT that
will be provided in the system IF ANYTHING BY THIS NAME IS IN THE
SYSTEM.  

∂29-May-87  2300	RPG  	Object Creation (at last!)   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

In case people care, I am now relatively back in the loop on CLOS.
I have been reading the initialization messages since last weekend
trying to understand them.

I am on the midst of writing a message with an alternative to
Moon's proposal. My proposal is less involved, more radical, more
CLOSsy than Moon's. So that people will not think that I am
lending support to Moon's proposal by my silence, I want to make
clear that I regard Moon's proposal as an abomination. Unless some
revelation comes to me that convinces me it's the right approach
(contrast this with being convinced it's the right thing) adoption
of his proposal is sufficient for me to withdraw my support of CLOS.

			-rpg-

∂31-May-87  1313	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 31 May 87  13:13:45 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 31 MAY 87 13:13:16 PDT
Date: 31 May 87 13:12 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 29 May 87 17:29 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
cc: Gregor.pa@Xerox.COM, Bobrow.pa@Xerox.COM
Message-ID: <870531-131316-1924@Xerox>

This message outlines a different approach for handling initargs which
initialize slot values.  The basic idea is that all initarg processing
should be defined procedurally, and so should be moved into
initialize-instance methods.  An effect of this is that -specification-
as defined in my earlier message disappears from defclass.  In this
'proposal' defclass only does initarg -declaration- and -defaulting-.

I will present this idea in the form of a sketchy proposal and some
comments.  This proposal certainly not fully fleshed out, but I believe
it is well enough worked out that we can use it as a basis for talking
about what it would be like to make all initarg processing be defined in
a procedural way.

In this proposal, there are two defclass options, a new macro called
intialize slots, and make-instance works differently than in previous
proposals.

The two defclass options:

  - :legal-initargs
     This just -declares- the legal initargs for this class.  This
     option is inherited in the obvious simple way.  The set of legal
     initargs for a given class is the union of the legal-initargs of 
     all the classes in the class precedence list. 

  - :default-initargs
    This is used to -default- values for initargs.  Notice that it is
    completely orthogonal to -declaration-.

Here are a couple examples of using defclass with these options:

;;;
;;; position is an abstract class.  It doesn't make sense to make
;;; instance of it all by itself.  It has to be mixed in with a 
;;; class which handles the :x-position and :y-position initargs.
;;;
(defvar *default-position-x* 0)
(defvar *default-position-y* 0)
(defclass position () ()
  (:default-initargs :x-position *default-position-x*
                     :y-position *default-position-y*))

(defclass x-y-position (position) (x y)
  (:legal-initargs :x-position y-position))


The initialize-slots macro is used in initialize-slots methods to help
in processing initargs which initialize slot values.  Here is an example
of using it:

(defmethod initialize-instance :before
           ((p x-y-position) &allow-other-keys &rest initargs)
  (initialize-slots p initargs
    (:x-position x)
    (:y-position y)))

This macro just expands into something like:

(defmethod initialize-instance :before
           ((p x-y-position) &allow-other-keys &rest initargs)
  (apply #'(lambda (&key ((g001 :x-position)) ((g002 :y-position)))
             (setf (slot-value p 'x) g001)
             (setf (slot-value p 'y) g002))
         initargs))


make-instance proceeds by:

1: taking the initargs it is passed and combining them with the
:default-initargs to get the total set of defaulted initargs.

2: calling allocate-instance with the class and the total set of
defaulted initargs to get the new instance.

3: evaluating ALL of the slot :initforms and setting the values of the
slots as specified.

4: calling initialize-instance with the new instance and the complete
set of defaulted initargs.

5: returning the instance.



COMMENTS:

Obviously, the major change in this proposal is that all initarg
processing is defined procedurally using lisp and other primitive
mechanisms of CLOS.  I think this is a significant difference.  It is
the driving force behind this proposal.  Without going into details now,
all the general advantages of using a procedural mechanism based on lisp
rather than a special purpose declarative mechanism apply.

One point I should make is that I don't believe this protocol will run
any slower than previous protocols in cases where the two do the same
work. To be specific, I believe that it is possible, and in fact not
difficult, to make this protocol be as efficient as the new flavors
mechanism for cases where the two are equivalent.  Because this is an
important issue I think we should address it explicitly but I would like
to do so in a different message.

Notice (I am sure you have already) that in this proposal, the
:initforms are ALWAYS evaluated.  My answer to this is that I consider
that a feature of this proposal.  One way of looking at what was
happening before is that there was a declarative mechanism for
specifying that an :initform should not be evaluated if certain initargs
were present.  As with all such declarative mechanisms, only certain
pre-defined patterns of such conditionalization were supported.  In this
new proposal, if you have an internal initial value (:initform) which
you only want to evaluate if certain initargs are not supplied, move it
to the initialize-instance method for that class.  There you can do all
the fancy conditional evaluation you want.


     

∂31-May-87  1439	masinter.pa@Xerox.COM 	Re: Object Creation (at last!)  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 31 May 87  14:39:23 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 31 MAY 87 14:38:53 PDT
From: masinter.pa@Xerox.COM
Date: 31 May 87 14:38:27 PDT
Subject: Re: Object Creation (at last!)
In-reply-to: RPG@SAIL.STANFORD.EDU's message of 29 May 87 23:00 PDT
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870531-143853-1952@Xerox>

Everyone has, as their last resort, the withdrawal of support for the
entire proposal. However, I think that we will arrive at a better
standard if we approach it in the spirit of cooperation. I think there
is a shared sense of uneasiness about any unnecessary complexity. I
don't think you need to threaten us with withdrawal for your alternative
to be heard and considered.

Peace,

Larry

∂31-May-87  1644	RPG  	Object creation discussion (at last!)  
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

I spent a day last weekend reading the discussion about initialization.
I'm not sure I understand the issues very well, and I'm certain I don't
understand them as well as Moon and Gregor.  Nevertheless, I believe that
the whole approach needs to be questioned.  It might turn out that Moon's
approach is the best of a number of lousy alternatives, but let's give
something else a shot.

The problem of creating an instance is a combination of two things:
allocating storage for the instance and then initializing the slots of the
instance.  It makes sense to want to customize various parts of this
process, and a mechanism like the one for changing class seems appropriate
- when an instance is to be created, several generic functions are
invoked, one to allocate storage and the other to initialize the instance;
the user can define methods on those functions. In this message I will
ignore the issue of ALLOCATE-INSTANCE.

DEFCLASS has an :initform slot option, and I imagine that almost everyone
is going to be happy with that. I can imagine adventuresome people will
call the vanilla MAKE-INSTANCE and then do a number of SETF's to get
things right.  The question becomes how often a hairier initialization
protocol will be needed.

The most sophisticated uses of initialization involve inheriting
initialization behavior when that behavior is non-trivial. That is,
there is already a means of inheriting the :initform forms, and we now
are questioning how to inherit more complex behavior.

Generic functions and the class hierarchy are the means CLOS provides
for inheriting behavior. It is powerful and sophisticaed, particularly
in terms of of method combination. Inheritance of slot descriptions is
the means for inheriting structure and description. Because simple 
initialization and nothing more is frequently needed, the :initform option
was provided as part of the description of a class, whereas initialization
is clearly more like a behavior (like SETF) than a description (like
classes having slots).

Another goal of the initialization protocol is to effect some mapping
between the arguments to MAKE-INSTANCE and the allocation/initialization
activities.  During the process we'd like defaulting to happen as well.

I don't see that initialization is a declarative process; furthermore,
considering it to be declarative leads to the use of a
programming-in-keywords style, which is odious. The only sense in which
it ought to be declarative is that that is a more natural means for
achieving goal of literally declaring the valid arguments to MAKE-INSTANCE.
Other than that, the only motivation for making hairy initialization
declarative is that simple initialization is declarative.

There seems to be another goal for the various proposals, which is to
provide a means to specify an external name for a slot, to be used during
initialization, while the internal slot remains hidden.

There is already a feature to provide an alternative name for a slot,
an external name if you will; and that feature is the accessor method.
In fact, with methods and setf methods one can provide a totally
abstract interface to otherwise-uninteresting instance-provided storage.

I believe that the features of a CLOS without an initialization protocol
ought to be powerful enough to write that initialization protocol.

Let's look at a variant of Danny's example; the syntax I use here
to express what the initialization should do is reminiscent of that in the
various proposals:

(defclass point ()
    ((x :initform 0 :initarg :moosebird1)
     (y :initform 0 :initarg :moosebird2))
  (:initargs :rho :theta))

The intention is that X and Y are the internal names of slots and that the
user would prefer to use the more mneumonic names of :MOOSEBIRD1 and
:MOOSEBIRD2 to initialize X and Y.  The :initargs class option indicates
that RHO and THETA might be supplied instead of MOOSEBIRD1 and MOOSEBIRD2.

(defclass picture (point)
 (bitmap saved-bitmap)
 (:initargs 
  (:moosebird2 :default-value-form *screen-top*) 
  (:image :slotname (bitmap saved-bitmap))))

Here we want the creation of an instance of PICTURE to make the Y (MOOSEBIRD2)
coordinate of the POINT to be *screen-top* if it isn't supplied to
MAKE-INSTANCE. If :IMAGE is supplied, it supplies the value of the slots
BITMAP and SAVED-BITMAP. I think this syntax is more like Danny's than
Moon's, but it doesn't matter.

It would seem that generic functions and setf methods ought to be able to
handle the needs of these initialization tasks. One could imagine that a
user would want to write a CLOS program that would classify objects based
on changing hypotheses, and that program would want to perform,
essentially, re-initialization or tasks just like it.  If CLOS is not able
to support programming like initialization at the user level using
methods, I think we will have failed in our language design.

I will now try to express the initialization needs of this setup
using methods rather than options and see what happens. I do this
to explore the degree to which we have failed to provide mechanisms
sufficient to perform initialization.

(defclass point ()
 ((x :initform 0)
  (y :initform 0)))

First we'll need some methods for RHO and THETA because these abstract
slots don't appear in the DEFCLASS:

(defmethod rho ((p point))...)
(defmethod theta ((p point))...)

(defmethod-setf rho ((p point)) (rho)...)
(defmethod-setf theta ((p point)) (theta)...)

Sometimes the user will supply an X and a Y and sometimes a RHO and a
THETA when he calls MAKE-INSTANCE.  However, when the user supplies an X
and a Y, he will use the names MOOSEBIRD1 and MOOSEBIRD2 (we use English
words so we don't have to apologize).

Here's the DEFCLASS for PICTURE:

(defclass picture (point)
 (bitmap saved-bitmap))

When a picture is initialized, we want the Y slot to be initialized
to *screen-top*.

Here's a shot at how this looks if we define methods on INITIALIZE-INSTANCE
ourselves:

(defmethod initialize-instance 
 ((p point) 
  &key (moosebird1 0 mb1-p) 
       (moosebird2 0 mb2-p)
       (rho 0 rho-p)
       (theta 0 theta-p)
       &allow-other-keys)
 ;; Maybe we should worry about mixtures of MOOSEBIRD1/MOOSEBIRD2 and
 ;; RHO/THETA???
 (when mb1-p (setf (x p) moosebird1))
 (when mb2-p (setf (y p) moosebird2))
 ;; Something really ugly is in here:
 (when (or rho-p theta-p) (let (...) (setf (x p) ...)...))))

Now for initializing PICTURE:

(defmethod initialize-instance 
 ((pict picture) 
  &key 
  (moosebird2 *screen-top)
  (image nil image-supplied)
  &allow-other-keys)
 (call-next-method)	;maybe? Or use some method combination?
 (when image-supplied
       (setf (bitmap pict) image)
       (setf (saved-bitmap pict) image))
 (setf (y pict) moosebird2))

Hm, well, I'm not sure this is right, but let's move on to look at
MAKE-INSTANCE:

(defmethod MAKE-INSTANCE 
 ((pict picture) &key moosebird1 moosebird2 rho theta image)
 (let ((instance (allocate-instance (class-named 'picture)))
  (initialize-instance pict moosebird1 moosebird2 rho theta image)))

Well, this seems pretty ugly, plus it's probably wrong.  I suppose Moon's
proposal solves all of these problems.

On the other hand, this approach has to look better than this. Generic
functions are supposed to provide modularity and abstraction. Why can't
we achieve it here?

Also, we expect that generic function discrimination should be able to
help us sort out the keyword arguments we need to specify for the
various methods on INITIALIZE-INSTANCE. We've got a lot of logic in
the method on INITIALIZE-INSTANCE for PICTUREs, and that logic looks a
lot like what someone might write to mimic generic function dispatch
if he didn't have it.

Unfortunately, Common Lisp provides bad language design exactly at the
point where we want to attack the problem.

Consider the nature of parameters to functions. In Common Lisp there are
these two notions: positional arguments and named arguments. In the first
case values are associated with variables depending on the positions in
which the arguments are passed. In the latter case, the binding happens
depending on the names of the arguments, which are passed along with the
arguments.

For example:

(defun f (x y &key a b) ...)

(f 1 2 :b 3 :a 4)

X and Y are positional, and A and B are named.

There is a second pair of notions: required arguments and optional arguments.

Does Common Lisp have all of the combinations of these notions?

         | positional |	named |
-------------------------------
required |    yes     |  no   |
-------------------------------
optional |    yes     |  yes  |
-------------------------------

It doesn't seem so. Keyword arguments combine named and optional.
We discriminate in generic functions based on required arguments. Suppose
we had named required arguments as distinct from named optional arguments,
and suppose we discriminated on the classes of all required arguments
and on the names of the named required arguments.

(defmethod foo (x y &required-key foo bar) `(foobar ,x ,y ,foo ,bar))
(defmethod foo (x y &required-key baz ola) `(bazola ,x ,y ,baz ,ola))

The behavior I imagine is demonstrated here:

(foo 1 2 :foo 3 :bar 4) => (foobar 1 2 3 4)
(foo 1 2 :baz 3 :ola 4) => (bazola 1 2 3 4)
(foo 1 2 :foo 3 :ola 4) => error
(foo 1 2 :foo 3 :bar 4 :ola 5) => error

Of course, required keyword arguments can be discriminated on in the usual
way as well.

Consider a slightly different pair of methods:

(defmethod foo (x y &required-key foo bar &allow-other-keys)
 `(foobar ,x ,y ,foo ,bar))
(defmethod foo (x y &required-key baz ola &allow-other-keys)
 `(bazola ,x ,y ,baz ,ola))

One question is which of the two methods on FOO above is more specific
than the other?  That is, suppose we write

(foo 1 2 :foo 3 :bar 4 :baz 5 :ola 6)

Which method in invoked?

The answer depends on whether one subscribes to the idea that a total
ordering on methods is necessary, once the arguments are known.  I think
it isn't necessary, and I am willing to adopt either one or several
approaches.  One is that the ordering is unspecified and effectively
random. The second is that some ambiguous uses of &required-keys (with
&allow-other-keys or :allow-other-keys t) only might make sense within
certain method combination regimes.  The regime I will use in the examples
below explicitly are indicated with the qualifier :progn - using it, all
applicable methods are applied.

[Aside:

One could go further with this approach, but it isn't needed for the purposes
of doing initialization in the example shown. Here is the extension of this
approach for the curious reader:

Let's also suppose that if no method on a generic function has optional
arguments, discrimination happens only among methods with the corresponding
numbers of supplied arguments:

(defmethod foo (x) 'one-argument)
(defmethod foo (x y) 'two-arguments)
(defmethod foo (x y z) 'three-arguments)

(foo 1) => one-argument
(foo 1 2) => two-arguments
(foo 1 2 3) => three-arguments

Notice that we no longer have a need for optional arguments at all! Here's
an example:

(defun foo (x &optional (y 77 y-supplied))<code>)
=>
(flet ((f (x y y-supplied) <code>))
 (defmethod foo (x y) (f x y t))
 (defmethod foo (x) (f x 77 nil)))

or your favorite alternative. of course, when we add in optional keyword
arguments this can get tiresome.]

One major problem with this approach is that it is a generalization of the
notion of generic function in a direction none of us has ever bought
into before. Currently a generic function is a mechanism for examining the
classes of some of the arguments supplied to it and deciding which
method or methods to invoke and how to combine them if more than one
is invoked. This generalization alters that to be as follows:: A generic
function is a mechanism for examining the arguments supplied to it and
deciding which method or methods etc.

Currently we discriminate on the class or identity of an argument, the latter
being similar to a singleton class. This proposal allows us to discriminate
on the name of an argument, and maybe we don't want to do that.

Now let's look at initialization on the above example using the notion
of &required-keys.

(defclass point ()
 ((x :initform 0)
  (y :initform 0)))

(defmethod initialize-instance :progn
 ((p point) &required-key moosebird1 moosebird2 &allow-other-keys)
 (setf (x p) moosebird1)
 (setf (y p) moosebird2))

I use the method qualifier ``:progn'' to signify that all the methods that
are applicable are run. I suppose this is in most-general to least-general
order.  If some other combination order is correct, that fact is
unimportant to my exploration.  Notice that the &required-keys serve to
map the names MOOSEBIRD1 and MOOSEBIRD2 onto the slots named X and Y.
Additionally, the &required-keys select this method based on the named of
the named arguments.

(defmethod initialize-instance :progn
 ((p point) &required-key rho theta &allow-other-keys)
 (let (...)
  (setf (x p)...)
  (setf (y p)...)))

Either the method for MOOSEBIRD1/MOOSEBIRD2 or the one for RHO/THETA is
selected based on which pair of named arguments are supplied to
MAKE-INSTANCE. If we are willing to expect that any combination might
be supplied, we can write:

(defmethod initialize-instance :progn
  ((p point) &required-key moosebird1 &allow-other-keys)
  (setf (x p) moosebird1))

(defmethod initialize-instance :progn
  ((p point) &required-key moosebird2 &allow-other-keys)
  (setf (y p) moosebird2))

and so on.

Now let's look at PICTURE:

(defclass picture (point)
 (bitmap saved-bitmap))

(defmethod initialize-instance :progn
 ((pict picture) &required-key image &allow-other-keys)
 (setf (bitmap pict) image)
 (setf (saved-bitmap pict) image))

(defmethod initialize-instance :progn
 ((pict picture) &key (moosebird2 *screen-top*) &allow-other-keys)
 (setf (y pict) moosebird2))

Now MAKE-INSTANCE is easy, as it was before:

(defmethod MAKE-INSTANCE
 ((pict picture) &rest all)
 (let ((instance (allocate-instance (class-named 'picture)))
  (apply #'initialize-instance pict all))))

This is definitely more verbose than the other proposals, but it is verbosity
used in rare occasions. Also, the conceptual overhead is lower, because
programmers will already need to know how to write methods and will already
understand how to combine them. Finally, the new aspect of method discrimination
that makes this approach palatable has additional expressive power.

Maybe we don't want to go with an approach like this one, but I think that
the needs of people who would want to write a program whose actions are
like initialization are important enough that we should make sure that
CLOS can handle them.

			-rpg-

∂01-Jun-87  2132	Moon@STONY-BROOK.SCRC.Symbolics.COM 	object / cleanup subcommittee interaction  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 1 Jun 87  21:32:30 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 161293; Tue 2-Jun-87 00:32:04 EDT
Date: Tue, 2 Jun 87 00:32 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: object / cleanup subcommittee interaction
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870602003210.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

Does anyone have a list of the issues that we wanted the cleanup
committee to address?  I remember something about being able to put
generic functions into function cells, a couple of things about cleaning
up the builtin types, the type FUNCTION, and the thing about &key
argument indicators that aren't keywords.  The latter two have been
taken care of, the former two haven't and I'm not sure I remember them
too well.  Were there any others?

∂02-Jun-87  1029	RPG  	object / cleanup subcommittee interaction   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

I assumed that a generic function was a function and so could appear in
a function cell. Doesn't the Concepts chapter state that 

(typep <generic function> 'function) => T

I presume that a generic function is a function under the cleaned-up
definition.

Moon, do you know the date of your message discussing the non-keyword &key
arguments? What are the considerations?

I think there were no other problems except for a recommendation to
design a DEFRECORD facility to replace DEFSTRUCT now that DEFSTRUCT is
sort of obsolete.

			-rpg-

∂02-Jun-87  1203	Bobrow.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Jun 87  12:03:01 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUN 87 11:48:05 PDT
Date: 2 Jun 87 11:48 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: object / cleanup subcommittee interaction   
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 02 Jun 87
 10:29 PDT
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870602-114805-4200@Xerox>

Other cleanup issues:
  Making FUNCTION be a genuine type (distinct from CONS)
  Making PATH-NAME, HASHARRAY etc be distinct from other types so we can
have a class
   (i.e. making these be distinguishable by the type system from an
implementation type e.g. array) 
  

∂02-Jun-87  1642	kempf%hplabsc@hplabs.HP.COM 	Re:  object / cleanup subcommittee interaction
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 2 Jun 87  16:41:55 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 2 Jun 87 16:36:27 pdt
Received: by hplabsc ; Tue, 2 Jun 87 16:35:16 pdt
Date: Tue, 2 Jun 87 16:35:16 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706022335.AA00365@hplabsc>
To: Common-Lisp-Object-System@sail.stanford.edu,
        Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re:  object / cleanup subcommittee interaction

Yes. The need for a LOAD-TIME-EVAL function. Most lisps have this
functionality anyway, to implement #, but it needs to available
from macrogenerated code as well. I use it in COOL and I believe
it is used in CALL-NEXT-METHOD. 

Other than that, something like the LET-PSEUDO which we use in
HP Lisp to implement lexical instance variables would make 
WITH-SLOTS somewhat cleaner, by not requiring a code walk. The
general idea is to have a symbol macro facility, which allows
forms to be substituted for symbols. Careful study would be
required to determine where in the macroexpand-evaluate loop
to insert expansion of symbol macros, however.

		jak

∂02-Jun-87  2022	Bobrow.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Jun 87  20:22:11 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUN 87 20:16:33 PDT
Date: 2 Jun 87 18:37 PDT
From: Bobrow.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)
In-reply-to: Gregor.pa's message of 31 May 87 13:12 PDT
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870602-201633-1444@Xerox>

This message proposes another variant on initialization that has in
common with Gregor's and RPG's that it pushes all initialization into
initialization methods.  It is most like Gregor's, but has NO new class
options and no new mechanism for calling generic functions.  Its
properties are:

1) Legality checking of make-instance arguments is made an environmental
issue.  

2) All :initforms are evaluated (as in Gregor's message);
allocate-instance returns an instance with all the values specified by
:initforms filled in.

3) Default values for initargs are computed a special method

4) Standard initialization methods are :after methods, so that more
specialized methods run after less specialized ones.  Initialization of
slots is done in these :after methods.

5) Standard  macros can provide convenience for the user and allow hooks
into the environment, and probably optimization.  By standard I mean in
the sense of my last message, with a reference implementation.




Here is a cut at a more detailed description:

(defmethod make-instance ((c standard-class) &rest initargs)
  (let ((o (allocate-instance c)))
    ;o is an object with slots filled in by :initforms
  (apply #'initialize-instance o (initial-args o initargs))
   o)

(defmethod initial-args ((o standard-object) initargs)
    initargs)

Suppose for objects of class position one wanted to have
default-initargs :x with default value (compute-x).
  Then one would write a method:

(defmethod initial-args ((o position) initargs)
     (call-next-method o
         (if (get initargs ':x) initargs
             (list* ':x (compute-x) initargs))))

The obvious convenient macro would allow one to write

(defmethod-initial-args position (:x (compute-x) :y (compute-y)...))


Suppose one wanted to have :x set the slot x, and :rho to do something
else.  One would write

(defmethod initialize-instance :after
   ((o position) &key (rho :rho)  (g002 :x g0002-p) 
                 &allow-other-keys)
   (when g0002-p (setf (slot-value x) g002))
    ... ; do rho stuff)) )

An obvious macro for supporting this might allow

(defmethod-init-after  ((o position) &key (rho :rho)) (:x x ...)
     ...  ;do rho stuff)

where defmethod-init-after inserts the :after,  &allow-other-keys, and
the  arguments used for the slot-value setting, as well as generating
the code. 


Arguemnt checking.
I assume here that the set of legal arguments to intialize-instance are
just those that are explicit in some method of initialize-instance, and
some environmental facility will provide appropriate warnings (very fast
hand waving here).

Optimization
I have also ignored any discussion here of how optimized calls to
make-instance could be managed, but I believe it could be done. (more
fast hand waving).       


∂03-Jun-87  1220	Bobrow.pa@Xerox.COM 	Re: Floats    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Jun 87  12:20:41 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 JUN 87 11:01:14 PDT
Date: 3 Jun 87 11:01 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Floats   
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 27 May 87
 11:24 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870603-110114-2066@Xerox>

This problem needs to be solved in several parts:

1) We need a way in CLOS to have more than one name for a particular
class.  A class should have at most one primary name, the one it
provides as value of (class-named class).  I suggest a function
(set-class-name class name &optional primary-name-p)
This will allow us to add names such as FLOAT-24-32 to SHORT-FLOAT

2) We need a mechanism to go from class descriptions to classes,
something like:
  (get-class-from-description superclass-name semantic-description).
 It would use system dependent descriptions of classes, and a matching
procedure.
  e.g. (get-class-from-description 
        'FLOAT 
        (AND (MANTISSA 24 32) (EXPONENT 6 10)))
Classes that need such matching might have a property describing
themselves, and a metaclass that knows how to match descriptions, so the
search could be a recursive tree walk from a super.

3) Methods should be defined on semantic-based classes, e.g.
FLOAT-24-32.  The real problem for a user is when he/she defines methods
on two classes with different names, and they turn out to be defined on
the same class. Thus one mthod replaces the other.  If each method
defined by defmethod remembered the names under which it were defined,
then an appropriate warning could be issued when a replacement of this
kind happened.  

4) This solves the FLOAT problem provided CommonLisp has a reasonable
semantics.  I do not claim to understand this at all.  If it does not,
then this must be solved separately.
  

∂03-Jun-87  1221	Gregor.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Jun 87  12:21:08 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 JUN 87 11:32:13 PDT
Date: 3 Jun 87 11:31 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: object / cleanup subcommittee interaction
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 2 Jun 87 00:32 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870603-113213-2135@Xerox>

Yes, load-time-eval is, I think an important issue for the cleanup
committee.

I also think that providing constructors and accessors for lexical
environments is important.  I don't know what committee that is supposed
to fall under, but it would be good to get it fixed as soon as possible.
As I have said before, I would rather see us do that right than add
symbol macros to the language.

∂03-Jun-87  1455	kempf%hplabsc@hplabs.HP.COM 	Re: object / cleanup subcommittee interaction 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 3 Jun 87  14:55:16 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Wed, 3 Jun 87 14:54:34 pdt
Received: by hplabsc ; Wed, 3 Jun 87 14:53:08 pdt
Date: Wed, 3 Jun 87 14:53:08 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706032153.AA14903@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: object / cleanup subcommittee interaction


I second Gregor's proposal for providing constructors and accessors
for lexical environments. Environments are underspecified in
CLtL, resulting in confusion in implementation. 

∂03-Jun-87  1709	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Jun 87  17:09:26 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 JUN 87 17:00:29 PDT
Date: 3 Jun 87 17:00 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)  
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 31 May 87
 16:44 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870603-170029-2690@Xerox>

In this message I address what I think is an important point which Dick
happened to mention in his message. Specifically,  its important that
whatever the special purpose mechanisms we might want to include in the
initialization protocol are, it should be possible to implement those
using more primitive CLOS.

Specifically, I will look at initarg -defaulting-.  I will show that it
is just a specific instance of a more general problem, and I will show
two different ways that problem can be implemented in CLOS.  I will also
show how the kinds of optimizations which are desirable can be
implemented in CLOS.  

There is a lot of stuff in this message.  A lot of this message is
sample code.  I know that makes it somewhat dense and I apologize, but I
think the points are important.  I hope that at least the following come
across:

  - two different ways of thinking about how default initarg inheritance
    works.

  - how to implement functionality like default initarg inheritance in
CLOS.

  - some more examples of the kinds of things the meta-object protocol
    is good for.



Initarg defaulting is just a specific instance of the more general
problem of computing a value for a class from component values provided
by all the classes in the class precedence list.  Seen as such, there
are two different mechanisms for doing this in CLOS.  I will call these
the "structural" and the "procedural" point of view.

In these sample implementations, I will just implement the collection of
the default initargs for a class.  These implementations do not take
care of merging the initargs provided in the call to make-instance with
the default values to get the 'total, defaulted,  evaluated initargs'.
In a separate message Danny or I will show an interesting way to do that
using the procedural implementation.

In all examples, assume the following class structure, with the
per-class default-initargs as annotated:

      menu              ((:highlighting :invert)
        \                (:expose-near *default-expose-near*))
         \
          \
        color-menu      ((:highlighting *highlight-color*))
            \
             \
           editor-menu  ((:expose-near *editor-window*))

so that the value returned by
  (class-default-initargs (class-named 'editor-menu))
should be
  ((:expose-near *editor-window*) (:highlighting *highlight-color*))



PROCEDURAL IMPLEMENTATION: 
;;;
;;; For each class, define a method on class-default-initargs which
contributes
;;; that class's initargs.  The structure is that the initargs for a
particular
;;; class get consed onto the initargs for its superclasses (using
list*).  The
;;; primary method on OBJECT provides the NIL for the base of the
consing.  The
;;; :around method on OBJECT provides mechanism for removing duplicated
initargs
;;; from the rest of the list.
;;;

(defmethod default-initargs ((c object))
  ())

(defmethod default-initargs :around ((c object))
  (remove-duplicates-from-plist (call-next-method) :from-end 't))


;;;
;;; Here are the methods for the sample classes.
;;;
(defmethod default-initargs ((c menu))
  (list* '(:highlighting :invert)
         '(:expose-near *default-expose-near*)
         (call-next-method)))

(defmethod default-initargs ((c color-menu))
  (list* '(:highlighting *highlight-color*)
         (call-next-method)))

(defmethod default-initargs ((c editor-menu))
  (list* '(:expose-near *editor-window*)))


STRUCTURAL IMPLEMENTATION:
;;;
;;; For classes, define a new class option, :default-initargs, which is
used to
;;; specify the default initargs for that class.  The
class-default-initargs
;;; generic function just goes and collects the contributions from all
the
;;; classes merges them together.
;;;
(defclass my-standard-class (standard-class)
    ((local-default-initargs :initform ()
                             :accessor class-local-default-initargs)))

;;;
;;; Any class which isn't an instance of my-standard-class has local
default
;;; initargs of ().  It is an error to try and set the local default
initargs
;;; of a class which isn't an instance of my-standard-class.
;;;
(defmethod class-local-default-initargs ((class standard-class))
  ())

(defmethod-setf class-local-default-initargs ((class standard-class))
(nv)
  (error "can't set the default initargs of ~S". class))

(defmethod legal-class-option-p ((class my-standard-class) option)
  (eq option ':default-initargs))

(defmethod update-class ((class my-standard-class) &key options
&allow-other-keys)
  (setf (class-local-default-initargs class)
        (getf options :default-initargs))
  (call-next-method))

(defun class-default-initargs (class)
  (remove-plist-duplicates
    (apply #'append
          (mapcar #'class-local-default-initargs
                  (class-precedence-list class))))
    :from-end 't))


An obvious problem with both of these implementations is that every time
the class-default-initargs function is called the value is consed up.
Certainly in initialization we would want to be able to optimize this by
caching the result, and it is reasonable to expect that much user code
might want to do so as well.  This is also easy to do using CLOS.

PROCEDURAL IMPLEMENTATION (cached version):

In this implementation, in order to make things more simple, we use a
special macro define-default-initargs-method to define the special kinds
of methods on default-initargs.  This special macro isn't absolutely
necessary, it just makes the code presented here a little simpler.

(defclass default-initargs-method (standard-method)
    ((initargs :initform nil
               :accessor method-initargs)))

(defmacro define-default-initargs-method (class-name initargs)
  `(define-default-initargs-method-1 ',class-name
                                     ',initargs
                                     #'(lambda (ignore) ',initargs)))

(defun define-default-initargs-method-1 (class-name initargs fn)
  (let* ((class (class-named class-name))
         (specs (list class))
         (old (get-method #'default-initargs () (list (class-named
class-name)) ()))
         (new (make-instance 'default-initargs-method :function fn
                                                      :specializers
specs
                                                      :initargs
initargs)))
    (when old (remove-method #'default-initargs old))
    (add-method #'default-initargs new)))

(defgeneric-options default-initargs (class))

;;;
;;; add a method to compute effective method for default-initargs which
will take care of
;;; producing a special effective method when all the methods are of the
special kind.
;;;
;;; if there are any methods on default-initargs that were defined with
defmethod, we will
;;; just revert to ordinary standard method combination.  In this way,
we get the optimization
;;; when we can have it, but when someone wants to put a method on
default-initargs that needs
;;; to compute that will work just fine.
;;;
(add-named-method 'compute-effective-method
                  '(gfun methods type args)
                  `(',#'default-initargs)
                  #'(lambda (gfun methods ignore ignore)
                      (if (every #'(lambda (m) (typep m
'default-initargs-method))
                                  methods)
                          <make optimized method>
                          (call-next-method))))

Where <make-optimized-method> produces a method which just has all the
constants collected up in it.    

STRUCTURAL IMPLEMENTATION (cached version):

For the structural implementation, much of the code is the same.  We
just use the propagate-class-update generic function to maintain a cache
of the proper value.  Note that this implementation is not the best
possible.  In particular, it recomputes the class-default-initargs
anytime any aspect of a class changes.  This is not hard to fix, I have
just done the simplest of the caching implementations here.  The reason
being that a more spohisticated structural caching implementations would
have the same structure, it would hook itself into the class update
protocol the same way, but it would be harder to read.

;;;
;;; For classes, define a new class option, :default-initargs, which is
used to
;;; specify the default initargs for that class.  The
class-default-initargs
;;; generic function just goes and collects the contributions from all
the
;;; classes merges them together.
;;;
(defclass my-standard-class (standard-class)
    ((local-default-initargs
       :initform ()
       :accessor class-local-default-initargs))
     (default-initargs
       :initform ()
       :reader class-default-initargs)))
                
;;;
;;; A class which isn't an instance of my-standard-class has local and
total
;;; default initargs of ().  It is an error to try and set the local
default
;;; initargs of a class which isn't an instance of my-standard-class.
;;;
(defmethod class-local-default-initargs ((class standard-class))
  ())

(defmethod-setf class-local-default-initargs ((class standard-class))
(nv)
  (error "can't set the default initargs of ~S". class))

(defmethod class-default-initargs ((class standard-class))
  ())


(defmethod legal-class-option-p ((class my-standard-class) option)
  (eq option ':default-initargs))

(defmethod update-class ((class my-standard-class) &key options
&allow-other-keys)
  (setf (class-local-default-initargs class)
        (getf options :default-initargs))
  (call-next-method))

(defmethod propagate-class-update ((class my-standard-class)
                                   new-fully-defined-p
                                   old-fully-defined-p
                                   changed-class
                                   &allow-other-keys)
  (setf (class-default-initargs class)
        (compute-default-initargs class)))


(defun compute-default-initargs (class)
  (remove-plist-duplicates
    (apply #'append
          (mapcar #'class-local-default-initargs
                  (class-precedence-list class))))
    :from-end 't))

       

∂03-Jun-87  2020	RPG  	My Message of May 29    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

In that message I tried to get peoples' attention so that I would make
sure that we did not go too far down the path of something I suspect is an
ad hoc solution to the initialization problem.  The point that Gregor
characterizes as something I ``happened to say'' was the main point I was
trying to make - that message was 9 days in the making.  In order to get
peoples' attention I used the inflammatory phrasing that solving this
problem in this way would cause me to withdraw my support of CLOS.

Upon reflection, that was a mistake - of course I'm not going to withdraw
my support. I flew off the handle because I think that we have put
together a pretty darn good language with CLOS so far (though it's not
perfect), and I want to make sure we live up to the standards we have set
for ourselves with the work we do to complete it.

It might turn out that Moon's proposed solution is the correct one,
but I want us to explore the alternatives and make sure that there
isn't a whole category of programs we are making hard to write by
not looking at those alternatives now.

You all know that I tend to be outrageous at times, and I do it as part of
the rhetorical game. But I think you all know I've only insisted on one
stupid thing in CLOS so far (the name DEFGENERIC-OPTIONS), so the bluster
cannot mean all that much.

Please accept my apologies and let's get on with the thinking!

			-rpg-

∂04-Jun-87  1004	kempf%hplabsc@hplabs.HP.COM 	SETF- method names   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Jun 87  10:03:40 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 4 Jun 87 10:03:07 pdt
Received: by hplabsc ; Thu, 4 Jun 87 10:02:01 pdt
Date: Thu, 4 Jun 87 10:02:01 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706041702.AA04950@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: SETF- method names


The CLOS spec currently says nothing about what the names of the
SETF- generic functions will be, presumably because the intent
is to encourage use of generalized variable reference. However,
since TRACE and other debugging aids require use of a function
name, lack of an easy handle for SETF- generic function names
(in the current implementation) requires that the user type in
a long, nonstandard name in order to get any debugging information.
Would it be appropriate to say anything about the SETF- generic
function name, realizing that nothing is said about such in CLtL?

Places I could see it being introduced into the spec are:

1) As an additional keyword argument to DEFGENERIC-OPTIONS-SETF,
pg. 2-24:2-25. This could be used to specify the prefix for
generating the SETF- generic function name.

2) As an additional function, like GET-SETF-GENERIC-FUNCTION.
The implementation is simply:

	(generic-function-name (get-setf-generic-function <name>))

but would not require the metaobject protocol function GENERIC-FUNCTION-NAME
be used. 

		jak

∂04-Jun-87  1525	kempf%hplabsc@hplabs.HP.COM 	Re: object creation / initialization discussion    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Jun 87  15:25:33 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 4 Jun 87 15:25:31 pdt
Received: by hplabsc ; Thu, 4 Jun 87 15:24:22 pdt
Date: Thu, 4 Jun 87 15:24:22 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706042224.AA09308@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: object creation / initialization discussion


I've hesitated to jump into the brouhaha until I had a chance
to review correspondence, and will limit myself to some general
comments, since I think most points of view have been covered.

In particular, I like Dick's analysis, stressing use of features
in the existing CLOS design rather than addition of new, more
complicated features. It does lead to more verbose code for
more complicated applications, thus some applications programmers
will complain, but the simple cases don't require as much conceptual
overhead. The analysis of positional v.s. named arguments in
Common Lisp was interesting. Dick seems to have identified a hole
in the Common Lisp design, which, if correctly filled, could 
lead to some simplifications.

His analysis did not touch on order of :INITFORM evaluation, nor
the lexical and dynamic context in which :INITFORM evaluation
occurs. A simple selection of context here would be the lexical
context of the class (as suggested by Danny in an earlier message)
and the dynamic context of one of the methods during MAKE-INSTANCE
invocation. Perhaps the dynamic context could be within MAKE-INSTANCE,
or the ALLOCATE-INSTANCE method, as suggested by Gregor? As for order of
evaluation, perhaps this could be determined by the class precedence
list ordering, for inherited slots, and by lexical ordering within
the DEFCLASS form.

As the 87-002 spec currently stands, the :INITFORM initialization
forms have no reference to previously initialized slots in the
object being initialized, nor can they reference the object being
initialized itself. Dick's proposal seems to imply that the INITIALIZE-INSTANCE
method would be the place for initializations dependent on values
of slots previously initialized to be put.  This seems fine with
me. However, I think specifying the order and context of :INITFORM
evaluation is important, for those applications programmers who
feel a need to use side-effects during initialization (however
henious we might find it). If the order and context is not
specified, it will be left up to each implementor to select it,
and thus this aspect of the semantics of initialization will be 
determined by the particular implementation rather than the specification.

			jak

∂05-Jun-87  2359	Masinter.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction       
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Jun 87  23:59:42 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 JUN 87 23:49:40 PDT
Date: 5 Jun 87 23:49 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: object / cleanup subcommittee interaction   
In-reply-to: Danny Bobrow <Bobrow.pa>'s message of 2 Jun 87 11:48 PDT
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870605-234940-2970@Xerox>

The cleanup committee is considering proposals for function-type and
non-keyword &Key arguments.

There is no proposal yet submitted for PATHNAME-HASH-TABLE-TYPE-DISTINCT
		( making pathname, hash-table separate classes.)
There is no proposal yet submitted for SHARP-COMMA-SPECIAL-FORM.
		(load time evaluation function. )

There is no proposal yet submitted for DEFSTRUCT-CLOS. 

There is no proposal yet submitted for LEXICAL-ENVIRONMENT-ACCESSORS. 

A draft of the proposal format is enclosed. Several proposals were
released last X3J13. Stay tuned to X3J13@Sail.stanford.edu for more
samples...

!

Format for proposals to "clean up" Common Lisp.

Version 10 -   5-Jun-87

 Replace the text below in >> double inverted angle-brackets <<. Be
brief; leave testimonials and personal opinions to the discussion at the
end. Be complete; do not expect someone else to fix or redesign parts.
Spell out names (e.g., Masinter rather than LMM) and upcase all Lisp
symbols (DEFUN rather than Defun). I like it better if you write in the
third person rather than first.

Issue: >>A short descriptive label, which starts with a name which
occurs in the index of CLtL, and be a suitable symbol in the Common Lisp
style, e.g., CDR-TERMINATION.   .<<

References:  >>The pages of CLtL which describe the feature being
discussed, or other references..<<

Category:   >>One or more of: CLARIFICATION -- proposal to resolve an
ambiguity or case of under-specified situation in CLtL, where this
ambiguity interferes with portability of code. CHANGE -- proposal for an
incompatible change to the language.  ADDITION -- proposal for a
compatible extension to the language. <<

Edit history: >>Author and date of submission (version 1), and author
and date of subsequent versions.<<

Problem description:  >>Describe the problem being addressed -- why is
the current situation unclear or unsatisfactory? Avoid describing the
proposal here or arguing for its adoption. <<

Proposal (>>issue-label:proposal-label<<): >> Describe as precisely as
possible what you are proposing.  Ideally, this should take the form of
text that could be dropped into CLtL or some new specification document.
If necessary, propose a set of labelled alternatives here, rather than a
single proposal. Each proposal must be a complete design; do not leave
out details.  Avoid arguing for the proposal here, just describe it.<<

Test Case: >>When possible, give a sample of Common Lisp code that
illustrates the issue.<<

Rationale:  >> A brief argument for the proposal. (If more than one
proposal is listed, discuss each issue separately here and in subsequent
sections.)<<

Current practice: >>Do some/many/no Common Lisp implementations already
work this way? Survey independent Common Lisp implementations -
preferably three or more.<<

Adoption Cost: >>What is the cost to implementors of adopting the
proposal?  How much implementation effort is required?  Is public-domain
code available? For pervasive changes, can the conversion be
automated?<<

Cost of non-adoption: >>How serious is it if nothing is done? <<

Benefits: >>What is better if the proposal is adopted? How serious is
the problem if just left as it is? <<

Conversion Cost: >>For incompatible changes, what is the cost to users
of converting existing user code?  To what extent can the process be
automated? How?<<

Esthetics: >>How does this proposal affect the simplicity of the
language, ease of learning, etc.<<

Discussion: >> Additional arguments, discussions, endorsements,
testimonials, etc. should go here. A blow-by-blow account of debates is
not necessary. <<


∂06-Jun-87  1219	Gregor.pa@Xerox.COM 	Re: Object creation discussion (at last!)   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 6 Jun 87  12:18:55 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 06 JUN 87 12:18:29 PDT
Date: 6 Jun 87 12:18 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Object creation discussion (at last!)
In-reply-to: Bobrow.pa's message of 2 Jun 87 18:37 PDT
To: Bobrow.pa@Xerox.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870606-121829-3209@Xerox>

Let me take a stab at simplifying part of Danny's message.  Danny is
proposing that the entire initialization protocol be defined in a
procedural way, using methods that the user defines on specific generic
functions.  In particular, Danny is going one step farther than a couple
of the messages that I sent out in that he is proposing that initarg
defaulting and initarg declaration be done procedurally.  Originally, I
was only proposing that initarg specification be done procedurally.  

I didn't really like this proposal when I first heard it, but I like it
a lot now after thinking about it for a bit more.  This message sketches
out in a bit more detail what it would be like:

initarg DEFAULTING.

There are two generic functions involved.  class-default-initargs and
merge-initargs.

CLASS-DEFAULT-INITARGS, returns the default-initargs for a given class.
It is the collection of the initargs for all the superclasses inherited
in the obvious way.  The class-default-initargs generic function uses
standard method combination.  There are two pre-defined methods on
class-default-initargs, these are as described in a message I sent out
earlier in the week:

(defmethod default-initargs ((c object))
  ())

(defmethod default-initargs :around ((c object))
  (remove-duplicates-from-plist (call-next-method) :from-end 't))


Given these methods, a user can define default initargs for a particular
class using methods like the following (also from my message of last
week):

(defmethod default-initargs ((c menu))
  (list* '(:highlighting :invert)
         '(:expose-near *default-expose-near*)
         (call-next-method)))

(defmethod default-initargs ((c color-menu))
  (list* '(:highlighting ':red)
         (call-next-method)))


MERGE-INITARGS takes the class, the supplied initargs and the default
initargs.  It merges the supplied initargs with the default initargs and
returns a complete set of defaulted initargs with the  values from the
default initargs evaluated.  This value is all set to be passed to the
initialize-instance and allocate-instance generic functions.  The
default implementation of this generic function is something like:

(defmethod merge-initargs ((class object) supplied default)
  (let ((total nil))
    (do-initargs (name val default)
      (unless (getf name supplied)
        (push name total)
        (push (eval val) total)))
    (append supplied (reverse total))))


As I showed in my message of last week, its really easy to optimize all
this to run just as fast as constructors do now, so speed is not an
issue here.

Some of the reasons I like this are:

  It builds on existing mechanism, people can understand it without
having to understand new mechanism.

  Because it builds on documented, primitive mechanism, people can
tailor it new ways.  Specifically, if for a certain class, the presence
of a particular initarg means that several default initargs should not
be included in the merge, it is easy for someone to figure out how to do
that.  They just define their own method on merge-initargs which
implements that rule.



initarg DECLARATION is real simple.

There is one pre-defined method on class-legal-initargs

(defmethod class-legal-initargs ((class object))
  ())

Users define methods like:

(defmethod class-legal-initargs ((class plane))
  (list* ':speed ':engines (call-next-method)))

If a user wants to explicity override some initargs provided by a
superclass they can do that since everything is procedural and under
their control:

(defmethod class-legal-initargs ((class boat))
  (let ((supers (call-next-method)))
    (list* ':speed (remove :color supers))))


∂06-Jun-87  1350	RPG  	Order of Initialization 
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

I thought that we have already specified that the INITFORMs happen
in the lexical context within which the DEFCLASS occurred. If there are
specials in the INITFORMs, I suppose that the dynamic context in which
the MAKE-INSTANCE is evaluated provides the dynamic context.

In terms of the order of evaluation of the INITFORMs, I thought that
the inheritance rules we had for slot descriptions settled which INITFORM
was evaluated to provide the initial value for the slot.

In terms of the order of evaluation of the INITIALIZE-INSTANCE methods, it
always seemed to me that method combination was how we should control
that, but that the most sensible default order was most general to most
specific (that is, like :AFTER).

There are, of course, problems with my &required-key proposal. One is that
unless there is some way to not pass all of the optional arguments, there
is no way to have a function with both required keyword and truly optional
positional arguments.

Suppose someone writes

(defun f (x y &optional a b &key foo bar baz ola)
 (list x y a b foo bar baz ola))

and this form is evaluated:

(f <a1> <a2> <a3> <a4> <a5> <a6> <a7> <a8>)

The binding of the variables in the function definition goes like this:

x is bound to <a1>, y is bound to <a2>, a is bound to <a3>, and b is
bound to <a4>. Now we lift our heads from the sand and look at what
<a5> is. It should be one of :foo, :bar, :baz, or :ola. Now suppose
we had written:

(f 1 2 :foo 4 :bar 5 :baz 6)

Did the user intend for a to be bound to :foo, or did he intend for
a and b to not be supplied?

Here is my proposal for lambda expressions; it includes Moon's
proposal for non-keyword package symbols to be names of arguments:

(lambda ({var}*
         [&optional {var | (var [initform [svar]])}*]
         [&required-key {name}*]
	 [&rest var]
         [&key {var | (name var)} [initform [svar]])}*
               [&allow-other-keys]]
         [&aux {var | (var [initform])}*])
   {declaration | documentation-string}*
   {form}*)

where var, initform, svar are exactly as before, and name is the name of
a keyword argument, which can be a symbol in any package. Parsing an
argument list proceeds as follows:

Let nrp be the number of required positional parameters. The first nrp
supplied arguments are paired with the nrp required positional parameters.
The remaining supplied arguments are scanned left-to-right, starting with
scanning for positional optionals.  If a supplied argument is EQ to one of
the required named parameters, the scanning for positional optionals ends
and all unpaired positional optionals are defaulted according to the
lambda-list specification; then named parameter parsing begins. If a
supplied argument is not EQ to any required named parameter, it is paired
with the next positional optional parameter.

Once the scanning for optional positional parameters has ended, scanning
for named parameters begins.  Named parameter parsing is as in current
Common Lisp, except that if, at the end, there are unsupplied
required named arguments, an error is signaled.

The difference between this parsing algorithm and the current Common Lisp
one is that the occurrence of the first required named parameter stops
parsing of positional optionals. Therefore, the only way to pass the name
of required named parameter is as a required positional or required named
argument. Also, if optional named arguments appear to the left of all
required named arguments, they can be taken as positional optionals.

Examples:

(defun f (x y &optional a b &required-key :foo :bar &key baz ola)
 (list x y a b foo bar baz ola))

(f 1 2 3 4 :foo 5 :bar 6 :baz 7 :ola 8) 
 => (1 2 3 4 5 6 7 8)

(f 1 2 3 :bar 4 :baz 5 :foo 6 :ola 7)
 => (1 2 3 nil 6 4 5 7)

(f 1 2 :baz 3 :foo 4 :bar 5)
 => (1 2 :baz 3 4 5 nil nil)

(f 1 2 :baz :foo 3 :bar 4)
 => (1 2 :baz nil 3 4 nil nil)

Because of Moon's proposal to not require keywords to be in the keyword
package, this proposal introduces some ugliness, but it uses the well-used
design principle: feel free to introduce ugliness and inconsistency for
new users in order to keep old code working.

			-rpg-

∂06-Jun-87  1624	kempf%hplabsc@hplabs.HP.COM 	Re:  Order of Initialization   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 6 Jun 87  16:24:20 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Sat, 6 Jun 87 14:27:50 pdt
Received: by hplabsc ; Sat, 6 Jun 87 14:26:48 pdt
Date: Sat, 6 Jun 87 14:26:48 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706062126.AA01592@hplabsc>
To: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re:  Order of Initialization

>
>I thought that we have already specified that the INITFORMs happen
>in the lexical context within which the DEFCLASS occurred. If there are
>specials in the INITFORMs, I suppose that the dynamic context in which
>the MAKE-INSTANCE is evaluated provides the dynamic context.
>

This sounds fine with me. I didn't remember a decision being reached
on the lexical part. The dynamic context of MAKE-INSTANCE is OK, presumably
just before the INITIALIZE-INSTANCE method is called and just after
ALLOCATE-INSTANCE? Otherwise, either the instance doesn't yet exist,
or the user could have done some potential customized initialization
which would be overwritten.

>In terms of the order of evaluation of the INITFORMs, I thought that
>the inheritance rules we had for slot descriptions settled which INITFORM
>was evaluated to provide the initial value for the slot.

My reading of the 87-002 document is that the initialization form
which is run for a particular slot is the first one which is encountered,
searching up the class precedence list. This says nothing, however, about
the order in which the initialization forms for all the slots are run.
This is what I meant. I would suggest that the lexical ordering of
slots within a class determine the order in which the initialization
forms are run for the slots defined by that class, and that the
order of the class precedence list determine the order for the entire
instance.

>In terms of the order of evaluation of the INITIALIZE-INSTANCE methods, it
>always seemed to me that method combination was how we should control
>that, but that the most sensible default order was most general to most
>specific (that is, like :AFTER).

In fact, the rules for method combination and initialization on
pg. 1-21:1-25 could determine this. I can't see any reason to
special case INITIALIZE-INSTANCE.


I'll postpone comments on the &REQUIRED-KEY proposal and Gregor's
proposal for a functional interface to initialization until I've
had a chance to study them.

				jak

∂06-Jun-87  1636	RPG  	Order of Initialization      
To:   Common-lisp-object-system@SAIL.STANFORD.EDU    

Jak sez:

``This says nothing, however, about the order in which the initialization
forms for all the slots are run.''

I respond:

This say everything about how stupid I am when I read messages about CLOS.

The two choices must be some ordering depending on the textual order
within a DEFCLASS and on the CPL for inherited slots, or else it is
an error to depend on it.

			-rpg-

∂08-Jun-87  1907	Bobrow.pa@Xerox.COM 	Open Issues in 87-002   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 8 Jun 87  19:07:03 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 JUN 87 18:38:46 PDT
Date: 8 Jun 87 18:38 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Open Issues in 87-002
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870608-183846-1250@Xerox>

I was reading over the spec the last few days, and have found the
following open issues that need to be resolved (or issues that I would
like to open).  Comments please.

p1-12 Should defclass be allowed to change the metaclass of an existing
class? Under what conditions should a subclass of standard-class have
the same properties wrt instance updating as standard class?  Gregor,
what is the answer in PCL right now?

p1-13 What is the initial class hierarchy in CLOS?  I recall a message
by Sonya implying she was working on capturing our agreement at Ricky's.
Is there a rewritten section on this?  

p1-17 "It is currently under discussion whether to provide constructs
for giving generic functions local names."  Do we want to have this
discussion, or to punt on this syntax. I recall we did come up with some
reasonble semantics for a GFLET and GFLABELS. 

p1-18 It is not specified whether get-setf-generic-function is a
setf-able form.  I suggest that it be made so.  This would allow one to
trace setf-generic-function's without having to know their names.

p1-19 "... Common Lisp be modified to include the following semantics
for quote in a type specifier:
 (deftype quote (object) '(member ,object)))"

Has any proposal for this been given to the cleanup committee? 

p1-24 Sshould we have a call-next-method? which calls such a next method
if it exists, else returns nil (rather than signalling an error?).  This
seems useful rather than having to define many base methods on object.

p1-20 Reference to type system correspondence to class system.

------

p2-3 Functions underlying the commonly used macros is neither complete
nor correct.  The generic-functions add-method, get-method,
get-setf-generic-function, and remove-method should be in the
metaobjects chapter.  make-method (p45)and make-generic-function (p42)
should be removed as soon as we have the initialization protocol set.

p2-6 I think we have reached agreement on the extension to
call-next-method to take arguments.  Do I hear a volunteer to write up
this page.

2-13(?) The generic function class-name is not written up.  It returns a
name for the class as argument.  I believe that (class-name class)
should be setf-able. Can a class have more than one name? Should
class-name then return a second argument -- the rest of the names this
class is known by.  
Comments? 

p2-16 We have agreed that we don't yet know whether the :constructor
option should be part of defclass.

p2-19 Values: I thought we agreed that all top level forms should return
the object.  It says here "returns the name of the class"

p2-22 Same comment as 2-19

p2-26  I believe that short form method combination ought to be a macro
in the standard library, and documented there, not in the basic
principles.  I think the standard combinations :append, :and, :or, ...
should also be put in the standard library too.
  
p2-35 The argument order of the setf method ought to be documented here.
Gregor proposed that new-value be the first argument.  Any problem with
this?

p2-39 Arguments: "list of t's" should be replaced by "list of classes
named t" since get-method only takes specializers, not names of
specializers.

p2-40 Should be specified that get-setf-generic-function is set-able
(see 1-18

p2-44 INITIALIZATION PROTOCOL for make-instance.

p2-46 Last line:  If call-next method is extended ..."  I see no reason
for additional keyword arguments.  

p2-51 print-object should take a depth argument.

p2-54 slot-missing should be documented

∂09-Jun-87  0719	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Open Issues in 87-002
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Jun 87  07:19:39 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 168008; Tue 9-Jun-87 10:18:45 EDT
Date: Tue, 9 Jun 87 10:18 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Open Issues in 87-002
To: Bobrow.pa@Xerox.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <870608-183846-1250@Xerox>
Message-ID: <870609101827.6.SKEENE@JUNCO.SCRC.Symbolics.COM>
Line-fold: No

    Date: 8 Jun 87 18:38 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    I was reading over the spec the last few days, and have found the
    following open issues that need to be resolved (or issues that I would
    like to open).  Comments please.

    p1-13 What is the initial class hierarchy in CLOS?  I recall a message
    by Sonya implying she was working on capturing our agreement at Ricky's.
    Is there a rewritten section on this?  

It's almost done.   I'll finish it up this week and send it to the list.   

∂09-Jun-87  0803	kempf%hplabsc@hplabs.HP.COM 	I. Formal Specification of Gen. Fcn. Invocation    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  08:03:35 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 08:03:22 pdt
Received: by hplabsc ; Tue, 9 Jun 87 08:02:18 pdt
Date: Tue, 9 Jun 87 08:02:18 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706091502.AA00446@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: I. Formal Specification of Gen. Fcn. Invocation

For some time now, I have been somewhat bothered by the lack of
precision in the 87-002 specification of method invocation. While
the rest of the document (particularly the inheritance algorithm)
is fairly precisely worded, the section of Part 1 on method combination
and calculation of the effective method is fairly loose and informal.
Until recently, I've been involved in getting an attractively performing
prototype of CLOS up for our internal applications developers, and
so have not had any time to look at the issue in any detail. However,
having reached a checkpoint in that effort, I decided to revisit the
issue and attempt a formal specification of method invocation and
combination.

I will post the results in a series of three notes which deal with
the three aspects of calculating the effective method:

1) Determining the set of applicable methods,
2) Sorting the set of applicable methods by precedence order,
3) Calculating the effective method from the sorted set of
   applicable methods.

I would hope that one of the committee members with interest and
inclination would check through the specification and offer any
corrections or additions, and that the 87-002 document could be
amended to include the result. If amending the document turns out
to be not possible, perhaps some other medium could be found for
presenting the result.

As an "executive summary", here is a short overview of the result:

1) Only one major inconsistency was found in the specification.
The requirement at the bottom of pg. 1-24 that the invocation of
CALL-NEXT-METHOD in the least specific :AROUND method would return
the effective method invocation result to the continuation (caller)
requires that CALL-NEXT-METHOD in the least specific :AROUND method
behave fundamentally differently than in other instances. It also
contradicts the statement in the middle of the page that the
most specific :AROUND method provides the value for the invocation.
I suspect it is a typo, and would suggest that the statement in
the middle of the page prevail.

2) The case of having two EQL specializers on the same parameter 
which differ during sorting of applicable methods cannot occur.
It is forbidden by the way in which the set of applicable methods
is constructed. An ambiguous statement in the second paragraph at
the top of pg. 1-22 implies that it can, however.

3) The least formal aspect of this specification is Part 3). 
I think that some form of temporal logic would be needed to
do this correctly (I may be wrong, however), and so, rather
than go to that machinery, I simply made some general observations
and reasoned somewhat informally. Ultimately, it might be worth
doing the exercise.

Walter Olthoff, in our lab, has done some preliminary work to
cast the specification into the Axis executable formal specification
language, and we may continue this effort as an additional check
on accuracy.

I've also made some initial notes on an application of how this
specification could be used (for anyone who thinks its a waste
of time). In particular, it is possible to derive conditions on
the actual parameters which limit changes in the set of applicable
methods, changes in the sorted list of applicable methods, or both,
it arguments are allowed for CALL-NEXT-METHOD. These conditions
may be useful in construction compile time optimizations, for example.

Finally, the restriction to standard character sets has required
the use of bizarre (for formal methods) notation. For this, I
apologize. One of these days e-mail will support enough bandwith
that we can send around bitmaps.

		jak

∂09-Jun-87  0804	kempf%hplabsc@hplabs.HP.COM 	II. Formal Specification of Gen. Fcn. Invocation   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  08:03:59 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 08:03:55 pdt
Received: by hplabsc ; Tue, 9 Jun 87 08:02:47 pdt
Date: Tue, 9 Jun 87 08:02:47 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706091502.AA00451@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: II. Formal Specification of Gen. Fcn. Invocation

	Formation of the Set of Applicable Methods

Given, a generic function invocation:

	(gf a(1) a(2) a(3) ... a(n) )

where:

	gf = generic function name
	a(j) = jth actual parameter
Let:
	A = { a(j) }, j=1 ... n
	M = { m(i) | m(i) is a method function for gf}
	m = number of required parameters for gf

We seek to form the set of applicable methods, MA. The 87-002
wording about how this is done is rather vague:

	Given a generic function and a set of arguments, the
	applicable methods are all methods for that generic
	function whose parameter specializers are satisfied
	by their corresponding arguments.

A suggested rewording, which would tighten up the specification
is:

	Given a generic function invocation, the applicable
	methods are all methods all of whose formal parameter
	specializers satisfy Relationship R with respect to
	the corresponding actual parameters.

We now define Relationship R.

Let:

	F(i)={ f(j) | f(j) is a formal parameter specializer for m(i) }
		1 <= j <= m

Note that the F(i) are ordered sets, whose elements match one for one
with the elements of A. In cases where there are more required parameters
than specialized parameters, we extend F(i) using T as the specializer,
indicating that any actual parameter will match the formal parameter
specializer.

Define c(j) as the class of actual parameter a(j). With apologies
to Knuth, define Algorithm I as the algorithm used to calculate
the class precedence list for c(j), and cpl(j) as the result of
applying Algorithm I to c(j). Since the class precedence list is
a totally ordered set, we can define the index operator to return
the index of c(l) in the class precedence list:

	index: class-object x cpl -> nat*  (* is needed for error case)

This operation will be needed during sorting.

The following predicates map elements of f(j) into booleans:

	eql-specializer-p = true if f(j) is a quoted object
			    false otherwise
	class-specializer-p = true if f(j) is a class object
			      false otherwise

Relationship R is satisfied for one of the F(i) if and ony if, for
all (f(j), a(j) ), j = 1 ... n, either:

	eql-specializer-p(f(j)) AND a(j) = f(j)
			OR
	class-specializer-p(f(j)) AND f(j) element cpl(j) 

We denote the set of applicable methods as MA, and go on to
specifying the sorting algorithm.

			jak

∂09-Jun-87  0804	kempf%hplabsc@hplabs.HP.COM 	III. Formal Specification of Gen. Fcn. Invocation  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  08:04:29 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 08:04:28 pdt
Received: by hplabsc ; Tue, 9 Jun 87 08:03:24 pdt
Date: Tue, 9 Jun 87 08:03:24 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706091503.AA00467@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: III. Formal Specification of Gen. Fcn. Invocation

		Sorting the Set of Applicable Methods

Let:

	MA = { ma(i) | ma(i) is an applicable method }
	F(i) = { f(j) | f(j) is a formal parameter specializer for ma(i) }

Define the predicate

 class-equal-p: class-object x class-object -> boolean

as:

	class-equalp(f(l),f(m)) = true if f(l) and f(m) represent
					the "same" class
				  false otherwise

We assume that the F(i) are totally ordered, with the ordering determined
by the :ARGUMENT-PRECEDENCE-ORDER for the generic function (default
being left to right).

Taking the F(i) pairwise, we define the equivalence relationship
"qualifier equal" (denoted =(q) ) on the corresponding ma(i)
as follows.

Let f(i,k) and f(j,k) be the kth elements from F(i) and F(j), respectively.
Then ma(i) =(q) ma(j) if and only if:

	( eql-specializer-p(f(i,k)) AND eql-specializer-p(f(j,k))
		AND f(i,k) = f(j,k)
	)
				OR
	( class-specializer-p(f(i,k)) AND class-specializer-p(f(j,k))
		AND class-equal-p(f(i,k),f(j,k))
	)
	for all (f(i,k),f(j,k)), k = 1 ... n

Note that =(q) groups the ma(i) into equivalence classes, with the
members of an equivalence class being distinguishable only by virtue
of their method qualifiers.

Let MAQ be the set of equivalence classes formed by applying =(q)
to MA. We impose a total ordering on MAQ by the following procedure.

For all maq(i), maq(j), i != j, select an ma(i) and ma(j) and
let F(i) and F(j) be the respective sets of ordered formal parameter
specializers.

Since ma(i) and ma(j) are from different equivalence classes, 
there will a least k, 1 <= k <= n, for which the f(.,k) are
not equal, with the f(.,k) being ordered with respect to the ordering
imposed by the generic function.

For that k, let cpl(k) be the class precedence list for the
class c(k) of the matching formal parameter a(k). Define the
following predicate:

    cpl-precedes-p: class-object x class-object x cpl -> boolean

as:

	cpl-precedes-p(c(l),c(m),cpl) = true if index(c(l),cpl) <=
						index(c(m),cpl)
					false otherwise

We say that maq(i) is more specific than maq(j)
(written maq(i) <(p) maq(j) ) if and only if one of the following
is true:

1) eql-specializer-p(f(i,k))

2) class-specializer-p(f(i,k)) AND (NOT (eql-specializer-p(f(j,k)))
   AND cpl-precedes-p(f(i,k),f(j,k),cpl(k))

Otherwise maq(j) <(p) maq(i).

Note that we need not even consider the case in which:

	eql-specializer(f(i,k)) AND eql-specializer(f(j,k))

since construction of the set of applicable methods assures that
f(i,k) = f(j,k) if this true, in which case ma(i) and ma(j) would
be in the same equivalence class, or would not differ on specializer
k.

We denote the totally ordered set of qualifier equivalence classes
as MAQS and go on to specify the calculation of the effective
method.

		jak

∂09-Jun-87  0805	kempf%hplabsc@hplabs.HP.COM 	IV. Formal Specification of Gen. Fcn. Invocation   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  08:05:04 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 08:04:50 pdt
Received: by hplabsc ; Tue, 9 Jun 87 08:03:47 pdt
Date: Tue, 9 Jun 87 08:03:47 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706091503.AA00472@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: IV. Formal Specification of Gen. Fcn. Invocation


		Calculation of the Effective Method

Given the totally ordered set of method equivalence classes, MAQS,
the effective method (what actually gets executed) needs to be
formed.

In the general case, nothing can be said formally about how to
calculate the effective method, because the metaclass function
COMPUTE-EFFECTIVE-METHOD can return any Lisp form, if user
defined method combination is applicable.

We therefore restrict consideration to standard method combination.
We now need to break down the equivalence classes in MAQS and
sort out the methods based on their qualifiers.

From the sorting calculation, we remember that two applicable methods
are qualifier equivalent (written =(q)) if they are the same, except
for their method qualifiers. Applicable methods which are =(q) form
equivalence classes, which are sorted by precedence order, with
the precedence order being designated by <(p).

Define the following predicates:

	primary-p: method -> boolean

	primary-p(m) = true if m is an unqualified (primary) method
		       false otherwise

	around-p: method -> boolean

	around-p(m) = true if m is an :AROUND qualifed method
		      false otherwise

	before-p: method -> boolean

	before-p(m) = true if m is a :BEFORE qualified method
		      false otherwise
	after-p: method -> boolean

	after-p(m) = true if m is a :AFTER qualified method
		     false otherwise

Note that restriction to standard method combination means that
the following:

	NOT (primary-p(ma(i)) OR around-p(ma(i)) OR before-p(ma(i))
		OR after-p(ma(i))
	    )

cannot occur, for ma(i) element of MA, the set of applicable methods.

Given an ma(i), let the function:

	preceedes-p: method x method x sorted-=(q)-set -> boolean

take two methods and the sorted set of =(q) equivalence classes
and return true if the equivalence class of the first argument is
more specific than that of the second.

Form the following four sets:

	MR = { ma(i) | ma(i) element MA AND around-p(ma(i)) AND
		preceeds-p(ma(i),ma(j),MAQS) if i < j
	     }
	MP = { ma(i) | ma(i) element MA AND primary-p(ma(i)) AND
		preceeds-p(ma(i),ma(j),MAQS) if i < j
	     }
	MB = { ma(i) | ma(i) element MA AND before-p(ma(i)) AND
		preceeds-p(ma(i),ma(j),MAQS) if i < j
	     }
	MF = { ma(i) | ma(i) element MA AND after-p(ma(i)) AND
		preceeds-p(ma(i),ma(j),MAQS) if i < j
	     }

Specification of standard method combination requires that the
execution sequence for the four sets be ordered as follows:

	MR -> MB -> MP -> MF -> {mr(1) | mr(m), m = cardinality(MR) }

Complete execution of MB and MF is guaranteed, if either MR = {}
or mr(m) calls CALL-NEXT-METHOD, so transferring control to mb(1).
In general, unless the method body is coded otherwise, only mr(1)
need be completely executed. However, mp(1) must exist (even if
it is not executed) or an error occurs. (Aside: was this the
intended behavior? It seems to me that making control transfer
from the :AROUND method to the primary method dependent on
whether or not the user codes the least specific :AROUND method
with a CALL-NEXT-METHOD makes the :AROUND method more like a
primary, in the qualitative sense.)

The end sequence of effective method execution is ambiguously
specified. The middle of pg. 1-24 implies that, given MR exists,
then the return value is determined by mr(1), the most specific
:AROUND method, while the bottom of the page implies that,
given a sequence of execution transfers occurs in which execution
leaves MR through the least specific method (mr(m), m = cardinality(MR)),
then control transfers back to the calling continuation 
for the entire generic function invocation, rather than
through return of the CALL-NEXT-METHODs to mr(1). I believe this is a typo.

As a solution, I would suggest that CALL-NEXT-METHOD in mr(m) behave
exactly the same as in other cases. The "next" method in this case 
would be one of mb(1) (the first :BEFORE method) or mp(1) (the first
primary), depending on whether or not MB = {} (i.e., if there are
any :BEFORE methods). When CALL-NEXT-METHOD returns, control returns
to mr(m-1), and, eventually, to mr(1), which then controls the return
value.


In any event, control transfer from MR to MB can occur only via
a CALL-NEXT-METHOD in mr(m). Once control transfer to MB has occured,
MB is fully executed, then (at least) mp(1) and any other mp(j) via
CALL-NEXT-METHOD. After execution of the MP, MF is fully executed,
and control returns to mp(m). Depending on whether you believe
the middle or bottom of 1-24, mp(m) either returns the primary
value directly to the generic function calling continuation,
or the CALL-NEXT-METHOD in mp(m) returns the value 
to its continuation, etc., until mp(1) is reached,
where the value is returned to the gf's continuation.

Additional rules on pg. 1-25 spell out where CALL-NEXT-METHOD can
be used, and the logic behind standard method combination.

		jak

∂09-Jun-87  0854	kempf%hplabsc@hplabs.HP.COM 	Re:  Order of Initialization   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  08:54:10 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 08:53:45 pdt
Received: by hplabsc ; Tue, 9 Jun 87 08:52:15 pdt
Date: Tue, 9 Jun 87 08:52:15 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706091552.AA01177@hplabsc>
To: Common-lisp-object-system@SAIL.STANFORD.EDU, RPG@SAIL.STANFORD.EDU
Subject: Re:  Order of Initialization


>Jak sez:
>
>``This says nothing, however, about the order in which the initialization
>forms for all the slots are run.''
>
>I respond:
>
>This say everything about how stupid I am when I read messages about CLOS.
>

It's difficult to maintain continuity in a discussion when the lag in
a reply is a day. Not your fault.

>The two choices must be some ordering depending on the textual order
>within a DEFCLASS and on the CPL for inherited slots, or else it is
>an error to depend on it.
>
>

As I see it, Common Lisp does one of three things when the order of
evaluation matters:

1) Specifies the order, as is the case with the order of evaluation
of function arguments, or PROGN,

2) Gives the programmer a construct in which the order is specified
and one in which it is not, as in LET and LET*.

3) Does not specify in what order evaluation occurs. DEFSTRUCT is
in this category (except for the statement that initialization
forms are evaluated in the lexical context of the DEFSTRUCT
definition). This would leave it up to the implementation.

I think 1) should be the case. This avoids making it implementation
dependent (case 3) and avoids having to introduce extra syntatic
machinery (case 2).

			jak

∂09-Jun-87  0934	kempf%hplabsc@hplabs.HP.COM 	Re:  Open Issues in 87-002
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  09:33:42 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 09:33:41 pdt
Received: by hplabsc ; Tue, 9 Jun 87 09:32:24 pdt
Date: Tue, 9 Jun 87 09:32:24 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706091632.AA02166@hplabsc>
To: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re:  Open Issues in 87-002


Some opinions on the open issues note which Danny posted.

>p1-12 Should defclass be allowed to change the metaclass of an existing
>class? 

I think DEFCLASS shouldn't be allowed to change the metaclass, since
the representation for instances of classes with the two different
metaclasses might be radically different.


>p1-17 "It is currently under discussion whether to provide constructs
>for giving generic functions local names."  Do we want to have this
>discussion, or to punt on this syntax. I recall we did come up with some
>reasonble semantics for a GFLET and GFLABELS. 

There have been a couple times when I've thought this would be handy.
On the other hand, we may ultimately be accused of junking up the
standard with things that some people don't need. On the presumption
that someone will accuse us of that anyway, it would probably be a good idea
to look into this. I believe there was some discussion of a GLAMBDA
in addition? Perhaps this functionality could be achieved by providing
a GFUNCTION special form (like the FUNCTION special form), which takes
a list of lambda expressions and produces a generic function object.
I suppose we'll need a reader macro for this as well, like #'.
Arguments for these constructs are that it integrates generic functions
more smoothly into the language. Arguments against are that generic
functions are a higher level modularity mechanism than functions. My
opinion is that the former is probably more relevant, since the package
system is really the fundamental modularity mechanism for organizing
medium scale structure in Common Lisp.

>p1-18 It is not specified whether get-setf-generic-function is a
>setf-able form.  I suggest that it be made so.  This would allow one to
>trace setf-generic-function's without having to know their names.

I vote yes on this one. We are already having trouble tracing 
SETF- generic functions, and need some kind of handle.

>p1-24 Sshould we have a call-next-method? which calls such a next method
>if it exists, else returns nil (rather than signalling an error?).  This
>seems useful rather than having to define many base methods on object.

I think this would be a good idea, however, we need to consider the
performance tradeoff. If CALL-NEXT-METHOD is viewed as a means of
modifying the flow of control in the effective method, rather than
a fast way of invoking the next least specific method, I think this
would be useful (although a compiler would be free to optimize, if
it so chooses). In the most general case, the conditions determining
whether the set of applicable methods are still valid would need
to be re-checked on each invocation of CALL-NEXT-METHOD with parameters.

>p2-3 Functions underlying the commonly used macros is neither complete
>nor correct.  The generic-functions add-method, get-method,
>get-setf-generic-function, and remove-method should be in the
>metaobjects chapter.  make-method (p45)and make-generic-function (p42)
>should be removed as soon as we have the initialization protocol set.

Yes. Do people feel the initialization issues are well enough 
understood that a proposed addition can be generated in Boston?

>p2-6 I think we have reached agreement on the extension to
>call-next-method to take arguments.  Do I hear a volunteer to write up
>this page.

I'll do it, if nobody objects. I won't be able to do it by Boston,
however.

>2-13(?) The generic function class-name is not written up.  It returns a
>name for the class as argument.  I believe that (class-name class)
>should be setf-able. Can a class have more than one name? Should
>class-name then return a second argument -- the rest of the names this
>class is known by.  

I think the class name should be changable, I don't think it should
have more than one name (at least, not for the default metaclass).
But I'm open to hearing some discussion on it, if anybody has any
ideas why it should be done.

>p2-19 Values: I thought we agreed that all top level forms should return
>the object.  It says here "returns the name of the class"

This sounds like a typo. It should return the class object.


>p2-22 Same comment as 2-19

Ibid.


>p2-26  I believe that short form method combination ought to be a macro
>in the standard library, and documented there, not in the basic
>principles.  I think the standard combinations :append, :and, :or, ...
>should also be put in the standard library too.

I agree.

  
>p2-35 The argument order of the setf method ought to be documented here.
>Gregor proposed that new-value be the first argument.  Any problem with
>this?

I've gotten some complaints from my users that they would rather see
it as the second argument, and also the second argument to the
SETF- generic function. Personally, I don't particularly care, but
I thought I'd just pass this along.

>p2-44 INITIALIZATION PROTOCOL for make-instance.

Yes, this needs to be resolved.


>p2-51 print-object should take a depth argument.

Yes, this is needed. I think we need to maintain some compatibility
with DEFSTRUCT on this.


∂09-Jun-87  1008	kahn.pa@Xerox.COM 	Re: Open Issues in 87-002 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  10:08:17 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 09 JUN 87 10:07:51 PDT
Date: Tue, 9 Jun 87 10:07:35 PDT
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: Open Issues in 87-002
In-Reply-To: <870608-183846-1250@Xerox>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870609-100751-1086@Xerox>

>   p1-18 It is not specified whether get-setf-generic-function is a
setf-able
>   form.  I suggest that it be made so.  This would allow one to trace
setf-generic-function's
>   without having to know their names.

Maybe I'm confused, but how would it help tracing unless one re-compiled
all the setf's using the generic function?  And how is the problem of
tracing setf's in CLOS any different than the general Common Lisp
problem?


References
	Bobrow's message of Mon, 8 Jun 87 18:38:00 PDT -- Open Issues in 87-002

∂09-Jun-87  1035	Bobrow.pa@Xerox.COM 	Re: Open Issues in 87-002    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  10:35:13 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUN 87 10:33:13 PDT
Date: 9 Jun 87 10:33 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Open Issues in 87-002
In-reply-to: Ken Kahn <Kahn.pa>'s message of Tue, 9 Jun 87 10:07:35 PDT
To: Kahn.pa@Xerox.COM
cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870609-103313-1143@Xerox>

    >p1-18 It is not specified whether get-setf-generic-function
    >is a setf-able form.  I suggest that it be made so.  This would
    >allow one to trace setf-generic-function's without having to
    >know their names.

    Maybe I'm confused, but how would it help tracing unless one
    re-compiled all the setf's using the generic function?  And how is
    the problem of tracing setf's in CLOS any different than the
    general Common Lisp problem?
This is the same problem as tracing setf's of functions in CommonLisp.
But we have no two argument defsetf.  Will someone who knows tell us how
that is done in some Common Lisps.
  danny

∂09-Jun-87  1050	kempf%hplabsc@hplabs.HP.COM 	Re: Open Issues in 87-002 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  10:48:58 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 10:48:36 pdt
Received: by hplabsc ; Tue, 9 Jun 87 10:47:25 pdt
Date: Tue, 9 Jun 87 10:47:25 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706091747.AA03141@hplabsc>
To: Bobrow.pa@Xerox.COM, Kahn.pa@Xerox.COM
Subject: Re: Open Issues in 87-002
Cc: common-lisp-object-system@SAIL.STANFORD.EDU

Here's how I do it:

	(macroexpand '(setf <form> b))

then take whatever the name is from the macroexpansion. Turns out
that the names for things like SVREF are mostly well behaved
(LISP::SETF-SVREF) so I can guess most of the time in our Lisp.

This may be an issue for the cleanup committee (perhaps they are
already looking at it?).
		jak

∂09-Jun-87  1104	Bobrow.pa@Xerox.COM 	Re:  Order of Initialization 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  11:03:59 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUN 87 10:55:03 PDT
Date: 9 Jun 87 10:54 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re:  Order of Initialization
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Tue, 9
 Jun 87 08:52:15 pdt
To: kempf%hplabsc@hplabs.HP.COM
cc: Common-lisp-object-system@SAIL.STANFORD.EDU, RPG@SAIL.STANFORD.EDU
Message-ID: <870609-105503-1199@Xerox>

jak says
    As I see it, Common Lisp does one of three things when the
    order of evaluation matters:

    1) Specifies the order, as is the case with the order of
    evaluation of function arguments, or PROGN,

    2) Gives the programmer a construct in which the order is
    specified and one in which it is not, as in LET and LET*.

    3) Does not specify in what order evaluation occurs. DEFSTRUCT
    is in this category (except for the statement that initialization
    forms are evaluated in the lexical context of the DEFSTRUCT
    definition). This would leave it up to the implementation.

    I think 1) should be the case. This avoids making it
    implementation dependent (case 3) and avoids having to introduce
    extra syntatic machinery (case 2).

I think one should not depend on the order.  Consider the ambiguity
resulting from two class definitions:

(defclass c1 ()
   ((x :initform (initx1))
    (y :initform (inity))))

(declass c2 (c1)
   ((x :initform (initx2)))

These can be in a file in either order.  Which order for eveluation of
(initx2) and (inity) do you think is correct.  I can think of arguments
for both.  Further, consider

(defclass c3 (c1)
   ((z :initform (initz))
    (y :initform (inity2))
    (x :initform (initx3))))
 
So my choice is 3, the user should not depend on the order.
  danny

∂09-Jun-87  1136	Bobrow.pa@Xerox.COM 	Re: I. Formal Specification of Gen. Fcn. Invocation   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  11:36:41 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUN 87 11:35:01 PDT
Date: 9 Jun 87 11:34 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: I. Formal Specification of Gen. Fcn. Invocation
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Tue, 9
 Jun 87 08:02:18 pdt
To: kempf%hplabsc@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870609-113501-1274@Xerox>

    1) Only one major inconsistency was found in the specification.
    The requirement at the bottom of pg. 1-24 that the invocation of
    CALL-NEXT-METHOD in the least specific :AROUND method would return
    the effective method invocation result to the continuation (caller)
    requires that CALL-NEXT-METHOD in the least specific :AROUND method
    behave fundamentally differently than in other instances. It also
    contradicts the statement in the middle of the page that the most
    specific :AROUND method provides the value for the invocation. I
    suspect it is a typo, and would suggest that the statement in the
    middle of the page prevail.

You must have a different reading of the words than I do.  In the middle
of the page it says:
* If there are any :around methods, the most specific :around method is
called.  It supplies the value for the method.

At the bottom it uses the phrase "If no :around methods were invoked"
This means that there are no :around methods.  In this case, the value
is the value returned from what I will call the "effective primary
method" which will be the value returned by the most specific primary
method.  The "effective primary method" is the method constructed
approximately as
(PROG2 (PROGN before1  .. beforen) primary1 (PROGN aftern ... after1))
where index 1 is more specific method than one with 2, ...

call-next-method always works on a list of effective methods, and always
calls the next in the list.  The list for standard method combination is

(around1 ... aroundn effective-primary-method)
and hence there is no difference in what call-next-method does in the
two cases.  The value is of course the value of the first method on this
list.  I am not sure I understand your  statement:
    "  the invocation of CALL-NEXT-METHOD in the least specific
    :AROUND method would return the effective method invocation result
    to the continuation (caller)"  

Further in your formal description, you talk about control passing to
the before methods, without building a construct like
effective-primary-method.  I think this is a mistake, since it loses the
nesting of the methods, and how values are returned.


-----

    2) The case of having two EQL specializers on the same
    parameter  which differ during sorting of applicable methods cannot
    occur.
I read the statement on page 1-22 as a proof of this statement.  

∂09-Jun-87  1743	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Object creation discussion (at last!)  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 9 Jun 87  17:43:30 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac03830; 9 Jun 87 20:24 EDT
Received: from ti-csl by RELAY.CS.NET id ag02593; 9 Jun 87 20:18 EDT
Received: by tilde id AA10877; Tue, 9 Jun 87 16:47:43 CDT
Message-Id: <2759261775-6137078@Jenner>
Date: Tue, 9 Jun 87  16:36:15 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Bobrow.pa@XEROX.COM
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Object creation discussion (at last!)
In-Reply-To: Msg of 2 Jun 87 18:37 PDT from Bobrow.pa@xerox.com

My message has two parts, the first one is about specifics and the
second one is about the general instance creation problem.

Part I:

I am trying to comment on the Gregor/Bobrow proposal as I see it after pasting
all the parts together:

from Bobrow:
     (defmethod make-instance ((c standard-class) &rest initargs)
       (let ((o (allocate-instance c)))
         ;o is an object with slots filled in by :initforms
       (apply #'initialize-instance o (initial-args o initargs))
        o)
     

This is not enough, we need to be able to pass initargs to allocate-instance as
well. 

Thus I think I would rewrite this (using Gregor's part):

(defmethod make-instance ((c standard-class) &rest initargs)
   (let* ((init-args (merge-initargs initargs (default-initargs c)))
          (o (apply #'allocate-instance c init-args)))
         ;o is an object with slots filled in by :initforms
       (apply #'initialize-instance o (initial-args o initargs))
        o))

Is this correct?

Now, who checks the legality of init-args? It seems it would be merge-initargs.

One thing I am not thrilled about with this proposal is that the legality check,
the defaulting and the merging of the initargs are done in three places. Here
is an example of what I don't like:

      If a user wants to explicity override some initargs provided by a
      superclass they can do that since everything is procedural and under
      their control:
      
      (defmethod class-legal-initargs ((class boat))
	(let ((supers (call-next-method)))
	  (list* ':speed (remove :color supers))))

Now, if default-initargs is left to its usual form, it gets out of sync. We can
produce a default-init-args plist that would contain non legal initargs.



Part II:

Thinking about instance creation, it seems that we have a three
dimensional problem and we try to solve it using two dimensional
projections:

The first dimension is the class hierarchy.
The second is the initargs dimension.
the third is the operations dimension (legality check, defaulting,
side-effect).

Bobrow/Gregor tries to project the problem along the operation dimension,
thus losing the ability to do all the operations at the same place.

Dick tries to project the problem along the initargs dimension, losing
the ability to do legality check simply( which requires a global view
of the initargs).

The basic CLOS generic function mechanism is inherently two dimensional.
We have the class  hierarchy dimension and the generic function dimension.
It seems normal that we run into problems if we try to use CLOS generic
function mechanism to model a three dimensional problem.

An ad-hoc solution like moon's can ignore such constraints and can do a 
better job at preserving locality and modularity. 

My opinion is that we should try to go back to an ad-hoc solution, maybe
as streamlined as it needs to make everybody comfortable with, instead
of trying to force fit instance creation into generic function calling
and adding few macros on top of it.

Patrick.


∂09-Jun-87  1819	Moon@STONY-BROOK.SCRC.Symbolics.COM 	SETF- method names
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Jun 87  18:18:47 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 168871; Tue 9-Jun-87 21:16:13 EDT
Date: Tue, 9 Jun 87 21:16 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: SETF- method names
To: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8706041702.AA04950@hplabsc>
Message-ID: <870609211606.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 4 Jun 87 10:02:01 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    The CLOS spec currently says nothing about what the names of the
    SETF- generic functions will be, presumably because the intent
    is to encourage use of generalized variable reference. 

The intent was that they would not have names at all, if I remember
correctly.

							   However,
    since TRACE and other debugging aids require use of a function
    name, lack of an easy handle for SETF- generic function names
    (in the current implementation) requires that the user type in
    a long, nonstandard name in order to get any debugging information.
    Would it be appropriate to say anything about the SETF- generic
    function name, realizing that nothing is said about such in CLtL?

    Places I could see it being introduced into the spec are:

    1) As an additional keyword argument to DEFGENERIC-OPTIONS-SETF,
    pg. 2-24:2-25. This could be used to specify the prefix for
    generating the SETF- generic function name.

You seem to be assuming that for any setf generic function, there will
be some symbol such that SYMBOL-FUNCTION of that symbol yields the setf
generic function.  I don't see why.  The Symbolics and TI
implementations, to take two examples, do not have any such symbols.
In addition, CLOS has some support for anonymous generic functions,
and presumably setf generic functions would be just one example of
such anonymous generic functions.  I don't know how this was intended
to fit into TRACE and other debugging aids.

    2) As an additional function, like GET-SETF-GENERIC-FUNCTION.
    The implementation is simply:

	    (generic-function-name (get-setf-generic-function <name>))

    but would not require the metaobject protocol function GENERIC-FUNCTION-NAME
    be used. 

If we're going to standardize on a way to name setf generic functions,
it should be a way to name methods as well.  After all, you'd like to be
able to trace methods.  I firmly believe that it should be based on the
"function spec" system used by Symbolics and TI, not on some scheme of
symbols with generated names.  However in the past whenever I have
proposed "function specs" to the Common Lisp community, I got a lot of
abuse, so I'm tired of bothering.

∂09-Jun-87  1832	Moon@STONY-BROOK.SCRC.Symbolics.COM 	object / cleanup subcommittee interaction       
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Jun 87  18:32:35 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 168878; Tue 9-Jun-87 21:31:51 EDT
Date: Tue, 9 Jun 87 21:31 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: object / cleanup subcommittee interaction   
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 2 Jun 87 13:29 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870609213148.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 02 Jun 87  1029 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    I assumed that a generic function was a function and so could appear in
    a function cell. Doesn't the Concepts chapter state that 

    (typep <generic function> 'function) => T

    I presume that a generic function is a function under the cleaned-up
    definition.

This is all true, but I think the actual issue was something else.  It's
starting to come back to me: it's separating what the SYMBOL-FUNCTION
function does from what the implementation actually stores, so no one
can object on efficiency grounds.  This is more of an implementation
note than a language specification.

    Moon, do you know the date of your message discussing the non-keyword &key
    arguments? What are the considerations?

I don't know the date, but the proposal name was KEYWORD-ARGUMENT-NAME-PACKAGE.
I'll send you the newest copy of it that I have, under separate cover (and
just to Dick).

∂09-Jun-87  1852	Moon@STONY-BROOK.SCRC.Symbolics.COM 	SETF- method names
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Jun 87  18:52:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 168882; Tue 9-Jun-87 21:52:18 EDT
Date: Tue, 9 Jun 87 21:52 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: SETF- method names
To: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8706041702.AA04950@hplabsc>
Supersedes: <870609211606.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: Added comment about tracing functions rather than tracing function-names.
Message-ID: <870609215209.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 4 Jun 87 10:02:01 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    The CLOS spec currently says nothing about what the names of the
    SETF- generic functions will be, presumably because the intent
    is to encourage use of generalized variable reference. 

The intent was that they would not have names at all, if I remember
correctly.

							   However,
    since TRACE and other debugging aids require use of a function
    name, lack of an easy handle for SETF- generic function names
    (in the current implementation) requires that the user type in
    a long, nonstandard name in order to get any debugging information.
    Would it be appropriate to say anything about the SETF- generic
    function name, realizing that nothing is said about such in CLtL?

    Places I could see it being introduced into the spec are:

    1) As an additional keyword argument to DEFGENERIC-OPTIONS-SETF,
    pg. 2-24:2-25. This could be used to specify the prefix for
    generating the SETF- generic function name.

You seem to be assuming that for any setf generic function, there will
be some symbol such that SYMBOL-FUNCTION of that symbol yields the setf
generic function.  I don't see why.  The Symbolics and TI
implementations, to take two examples, do not have any such symbols.
In addition, CLOS has some support for anonymous generic functions,
and presumably setf generic functions would be just one example of
such anonymous generic functions.  I don't know how this was intended
to fit into TRACE and other debugging aids.

CLtL's discussion of TRACE is very vague, so maybe the following doesn't
belong in the standard anyway.  But is there any reason why TRACE
couldn't accept functions as arguments, rather than only accepting
function names?  The main limitation seems to be that TRACE is a macro
and doesn't evaluate its subforms.

    2) As an additional function, like GET-SETF-GENERIC-FUNCTION.
    The implementation is simply:

	    (generic-function-name (get-setf-generic-function <name>))

    but would not require the metaobject protocol function GENERIC-FUNCTION-NAME
    be used. 

If we're going to standardize on a way to name setf generic functions,
it should be a way to name methods as well.  After all, you'd like to be
able to trace methods.  I firmly believe that it should be based on the
"function spec" system used by Symbolics and TI, not on some scheme of
symbols with generated names.  However in the past whenever I have
proposed "function specs" to the Common Lisp community, I got a lot of
abuse, so I'm tired of bothering.

∂09-Jun-87  1921	Moon@STONY-BROOK.SCRC.Symbolics.COM 	object / cleanup subcommittee interaction  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Jun 87  19:21:37 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 168903; Tue 9-Jun-87 22:21:01 EDT
Date: Tue, 9 Jun 87 22:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: object / cleanup subcommittee interaction
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870602003210.7.MOON@EUPHRATES.SCRC.Symbolics.COM>,
             The message of 2 Jun 87 13:29 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>,
             <870602-114805-4200@Xerox>,
             <8706022335.AA00365@hplabsc>,
             <870603-113213-2135@Xerox>,
             <8706032153.AA14903@hplabsc>,
             <870605-234940-2970@Xerox>
Message-ID: <870609222055.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

Thanks for all the input.  This is the summary I came up with:

This file is a list of things that the CLOS committee would like to see
cleaned up.  I have tried to keep it brief.  Where proposals have been
submitted to the Cleanup committee, the proposal name is listed as
"PROPOSAL: name".  Where the Cleanup committee has assigned an issue
name, but there is no proposal yet, it is listed as "ISSUE: name".

1. PROPOSAL: FUNCTION-TYPE
   Making FUNCTION be a genuine type (distinct from CONS).

2. PROPOSAL: KEYWORD-ARGUMENT-NAME-PACKAGE
   Allowing keyword argument indicators to be non-keyword symbols.

3. ISSUE: DEFSTRUCT-CLOS
   A recommendation to design a DEFRECORD facility to replace the part
   of DEFSTRUCT that is not replaced by DEFCLASS.

4. ISSUE: PATHNAME-HASH-TABLE-TYPE-DISTINCT
   Mandating a bunch of types (I don't have the complete list right now)
   to be disjoint from a bunch of other types (again I don't have a
   complete list right now) so that they can all be made into classes
   without establishing any implementation-dependent subclass relationships.

5. PROPOSAL: SHARP-COMMA-SPECIAL-FORM
   (in some Cleanup documents this is called LOAD-TIME-EVAL)
   A macro should be able to include in its expansion the same sort
   of thing that the #, reader-macro produces, enabling load-time
   evaluation.

6. ISSUE: LEXICAL-ENVIRONMENT-ACCESSORS
   Providing constructors and accessors for lexical environments.
   This is somehow related to or a substitute for a symbol macro
   facility [I don't understand the connection --Moon]

7. (no issue name)
   Implementation note: clarify that the value returned by SYMBOL-FUNCTION,
   and the value accepted by SETF of SYMBOL-FUNCTION, are not necessarily
   what the implementation actually stores for purposes of function calling.
   Specifically, (SETF (SYMBOL-FUNCTION x) gf), where gf is a generic function,
   might create compiled code for method dispatching and store it in a place
   associated with x, so that a call to x will compile as a call to that
   compiled code, and will never touch the generic function object.  However,
   even if an implementation uses this technique, (SYMBOL-FUNCTION x) must
   return the value gf, not the internal compiled code.  Furthermore,
   (FUNCALL gf ...) must produce the correct effect; it is permissible for
   it to be slower than calling the internal compiled code.

8. (no issue name)
   Require (deftype quote (object) `(member ,object)) to be built-in.

9. (no issue name)
   Class objects must be acceptable to TYPEP and SUBTYPEP as type-specifiers.
   This is probably part of CLOS rather than anything for the Cleanup committee.

∂09-Jun-87  2044	Moon@STONY-BROOK.SCRC.Symbolics.COM 	I. Formal Specification of Gen. Fcn. Invocation 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Jun 87  20:44:17 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 168962; Tue 9-Jun-87 23:43:37 EDT
Date: Tue, 9 Jun 87 23:43 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: I. Formal Specification of Gen. Fcn. Invocation
To: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8706091502.AA00446@hplabsc>
Message-ID: <870609234334.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Tue, 9 Jun 87 08:02:18 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    ....I will post the results in a series of three notes which deal with
    the three aspects of calculating the effective method....

I found that I was unable to comprehend any of this.  I'll try again
some time when I have several hours available and no distractions.

I'm sure that the language in the document could be clearer and
less ambiguous, especially if it wasn't written by a committee, but
right now I'm not sure whether a more formal approach would make the
document easier to understand or would simply obfuscate it and end
up making errors more difficult to uncover.

    1) Only one major inconsistency was found in the specification.
    The requirement at the bottom of pg. 1-24 that the invocation of
    CALL-NEXT-METHOD in the least specific :AROUND method would return
    the effective method invocation result to the continuation (caller)

I am unable to find any such requirement.  All I see is that the value
returned by the invocation of CALL-NEXT-METHOD in the least specific
:AROUND method is controlled by the most specific primary method.
Are you looking at an old version of the document perhaps?

    2) The case of having two EQL specializers on the same parameter 
    which differ during sorting of applicable methods cannot occur.
    It is forbidden by the way in which the set of applicable methods
    is constructed. An ambiguous statement in the second paragraph at
    the top of pg. 1-22 implies that it can, however.

This typo ("quoted" for "equal") was corrected in the corrections
handed out in March.

∂09-Jun-87  2234	kempf%hplabsc@hplabs.HP.COM 	Re:  SETF- method names   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  22:34:10 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Tue, 9 Jun 87 22:32:55 pdt
Received: by hplabsc ; Tue, 9 Jun 87 22:31:45 pdt
Date: Tue, 9 Jun 87 22:31:45 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706100531.AA10636@hplabsc>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, kempf%hplabsc@hplabs.HP.COM
Subject: Re:  SETF- method names
Cc: common-lisp-object-system@sail.stanford.edu

>If we're going to standardize on a way to name setf generic functions,
>it should be a way to name methods as well.  After all, you'd like to be
>able to trace methods.  I firmly believe that it should be based on the
>"function spec" system used by Symbolics and TI, not on some scheme of
>symbols with generated names.  However in the past whenever I have
>proposed "function specs" to the Common Lisp community, I got a lot of
>abuse, so I'm tired of bothering.
>

Not being familiar with "function specs", I'm not in a position to
comment on them; however, I think the current situation is pretty
tenuous. As mentioned in the "Open Issues" note and subsequent 
discussion, the way I usually trace SETF- functions is by macroexpanding
a form to see what the function name is. Admittedly, one could argue
this is an environmental thing, but since CLtL specifies the TRACE
function, there should be some means of doing this. Tracing methods
would also be nice. Maybe it would be best to defer this for the
moment, since it seems to be a more general problem of SETF-, and
can be solved in PCLOS/PCL (kludgily) by simply generating a more
tractable name, thus keeping my users happy.

			jak

∂09-Jun-87  2349	Masinter.pa@Xerox.COM 	Re: object / cleanup subcommittee interaction  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jun 87  23:49:17 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUN 87 23:48:32 PDT
Date: 9 Jun 87 23:48 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: object / cleanup subcommittee interaction
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 9 Jun 87 22:20 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870609-234832-2213@Xerox>

I'll assign a random proposal name if you like:

8) ISSUE: TYPE-MEMBER-SINGLETON  (issue is that (member t) is awkward
when there's only one)
 Proposal TYPE-MEMBER-SINGLETON:QUOTE 

As you say,  point 7 (SYMBOL-FUNCTION may not be what's stored) is
really  an implementation note rather than any language specification
change.  I don't see that it requires a cleanup, for that reason. 

I agree that your point 9 (TYPEP takes class object) really is more part
of the CLOS than a cleanup, (Without CLOS, there are no class objects,
and the issue is moot.)

∂10-Jun-87  0934	kempf%hplabsc@hplabs.HP.COM 	Re: I. Formal Specification of Gen. Fcn. Invocation
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Jun 87  09:33:46 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Wed, 10 Jun 87 09:32:47 pdt
Received: by hplabsc ; Wed, 10 Jun 87 09:31:14 pdt
Date: Wed, 10 Jun 87 09:31:14 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706101631.AA15389@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: I. Formal Specification of Gen. Fcn. Invocation
Cc: kempf%hplabsc@hplabs.HP.COM

Comments from Dave Moon:

>I'm sure that the language in the document could be clearer and
>less ambiguous, especially if it wasn't written by a committee, but
>right now I'm not sure whether a more formal approach would make the
>document easier to understand or would simply obfuscate it and end
>up making errors more difficult to uncover.

Yes, a more formal approach may make the spec require more effort to follow.
What I hoped to avoid is a case like some Common Lisp implementations, 
where an implementor picks up on one or two ambiguous phrases, interprets them
in a way which the majority of the implementers interpreted differently,
and thereby makes portablility of application code a lot harder to
achieve. Additionally, with a more formal approach, I think we may have
a better chance at convincing the ISO Committee at looking favorably 
on CLOS semantics (even if they don't like the syntax), and perhaps the
Scheme community as well. As far as the object subcommittee's work goes, if
the consensus is that just now is not the time to introduce more
formalism, we can defer discussion until later. I'm planning on pursuing
the problem, since I think it is an interesting and important one, but
I'll avoid posting the details and only post questions or suggested
corrections, if people prefer.

>Are you looking at an old version of the document perhaps?

I have the version which was distributed at the March ANSI meeting,
along with the corrections distributed at the same meeting. If
the on-line version on SAIL or PARCVAX has corrections beyond
those, then I need to take a look at them. We have troubles
getting FTP connections here.

Danny Bobrow's comments:

>    2) The case of having two EQL specializers on the same
>    parameter  which differ during sorting of applicable methods cannot
>    occur.
>I read the statement on page 1-22 as a proof of this statement.  

The problem is the following. On page 1-21, last paragraph, there 
is a description of the sorting process:

	Compare the corresponding parameter specializers. When
	a pair of parameter specializers are equal, proceed to
	the next pair and compare them for equality. If all
	corresponding parameter specializers are equal, the two
	methods must have different qualifiers; in this case, either
	method can be selected to precede the other (Comment:
	this is also not strictly true, since they will actually
	be in the same equivalence class. One could be a :BEFORE
	and the other a :AFTER method, for example. In fact,
	the two methods are incomparable with regard to precedence.)
	If not all corresponding parameter specializers are equal,
	the first pair of parameter specializers that are not
	equal determines the precedence.

At this point, we move to pg. 1-22, and I'm assuming the rest
of the section deals with how to determine precedence. Determining
precedence for class specifiers is in the next paragraph, then the second last 
paragraph in the section discusses EQL precedence:

	If just one parameter is (QUOTE <object>), the method
	with that parameter specializer preceeds the other
	method. (Comment: Here comes the condition which cannot
	occur.) If both parameter specializers are quoted
	objects, the specializers must be quoted objects
	(otherwise the two methods would not both have been	
	applicable for this argument).

In fact, at this point, it is not possible for both parameter
specializers to be quoted objects, because, if a specializer is
a quoted object, it must be EQL to the actual parameter for
the method, to even be an applicable method. If it is EQL to
the actual parameter, then two methods cannot differ on that
specializer, because all methods with an EQL specializer at
that parameter position will have the same specializer.

>    1) Only one major inconsistency was found in the specification.
>    The requirement at the bottom of pg. 1-24 that the invocation of
>    CALL-NEXT-METHOD in the least specific :AROUND method would return
>    the effective method invocation result to the continuation (caller)
>    requires that CALL-NEXT-METHOD in the least specific :AROUND method
>    behave fundamentally differently than in other instances. It also
>    contradicts the statement in the middle of the page that the most
>    specific :AROUND method provides the value for the invocation. I
>    suspect it is a typo, and would suggest that the statement in the
>    middle of the page prevail.
>
>You must have a different reading of the words than I do.  In the middle
>of the page it says:
>* If there are any :around methods, the most specific :around method is
>called.  It supplies the value for the method.
>
>At the bottom it uses the phrase "If no :around methods were invoked"
>This means that there are no :around methods.  In this case, the value
>is the value returned from what I will call the "effective primary
>method" which will be the value returned by the most specific primary
>method. 

I'm not arguing with the case of no :AROUND methods, but rather
with the case of a CALL-NEXT-METHOD in the least specific :AROUND
method which causes control transfer to the effective primary
method. The statement in my copy of the spec says:

	Otherwise, the value or values returned by the most
	specific primary method are those returned by the invocation
	of CALL-NEXT-METHOD in the least specific :AROUND
	method.

My reading was that the following sequence of events occurs:

generic function invocation context:

  most specific :AROUND
	CALL-NEXT-METHOD -----------> to next most specific

    next most specific :AROUND
	CALL-NEXT-METHOD------------> to next next most specific

	....

	in least specific :AROUND:

		CALL-NEXT-METHOD -------> transfer of control to
					   primary method
					  and execution of it. 
					  Upon completion, transfer
				          back to least specific
	        THROW to generic <------- :AROUND method
	        function invocation
	        context.

In fact, on a closer reading (and looking at the following comments
about how to construct the effective primary method), I agree
that this interpretation is faulty.

> The "effective primary method" is the method constructed
>approximately as
>(PROG2 (PROGN before1  .. beforen) primary1 (PROGN aftern ... after1))
>where index 1 is more specific method than one with 2, ...
>
>call-next-method always works on a list of effective methods, and always
>calls the next in the list.  The list for standard method combination is
>
>(around1 ... aroundn effective-primary-method)
>and hence there is no difference in what call-next-method does in the
>two cases.  The value is of course the value of the first method on this
>list.  I am not sure I understand your  statement:
>    "  the invocation of CALL-NEXT-METHOD in the least specific
>    :AROUND method would return the effective method invocation result
>    to the continuation (caller)"  
>

My initial reading of the bottom of 1-24 resulted in the interpretation of
the execution sequence as listed above. This is what I meant by
the statement.

>Further in your formal description, you talk about control passing to
>the before methods, without building a construct like
>effective-primary-method.  I think this is a mistake, since it loses the
>nesting of the methods, and how values are returned.

I agree. I think the concept of the effective primary method is a
good one and it clarifies the concepts. Additionally, I think my
reading of the bottom of pg. 1-24 was confused by the fact that
I was interpreting the return value of the primary method with the
the return value of the generic function, since the first sentence
of the paragraph deals with the latter, and the second with the
former. It might be helpful to seperate out these two concepts,
in language something like:

	The process of generic function invocation is completed
	by returning value(s) to the invocation context. If
	no :AROUND methods were invoked, then the most specific
	primary method supplies the value(s) returned
	by the generic function. If the most specific :AROUND
	method was invoked, but control transfer to the
	effective primary method via CALL-NEXT-METHOD in the
	least specific :AROUND method does not occur, then
	the return value(s) of the most specific :AROUND method
	are the value(s) returned by the generic function. If
	control transfer to the effective primary method does
	occur, then the value(s) returned by the effective
	primary method are potentially modifiable by the
	:AROUND methods, and, again, the most specific :AROUND
	method supplies the return value(s) for the generic
	function invocation.

In the meantime, I'll look into incorporating the idea of an
effective primary method into the formalism.

			jak

∂10-Jun-87  1006	RPG  	CLOS Document 
To:   common-lisp-object-system@SAIL.STANFORD.EDU    
The version of the document on SAIL has the true errata corrected.
			-rpg-

∂10-Jun-87  1114	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Concepts chapter on standard type classes
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Jun 87  11:14:14 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 169429; Wed 10-Jun-87 14:13:43 EDT
Date: Wed, 10 Jun 87 14:13 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Concepts chapter on standard type classes
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <870610141334.1.SKEENE@JUNCO.SCRC.Symbolics.COM>


Below is a proposed section to go into the Concepts part of the document.
I'll also be sending a draft section to go into the Design Rationale
part of the document.    


\beginSection{Integrating Types and Classes} 

The \CLOS\ maps the Common Lisp type space into the space of classes.
Every class that has a name has a corresponding type with the same 
name.  {\bf defclass} and {\bf defstruct} define both types and classes.  

The name of every class is a valid type specifier.   In addition, every
class object is a valid type specifier.  Thus the expression {\tt (typep 
{\it object class\/})} evaluates to true if the class of {\it object\/} 
is {\it class\/} itself or a subclass of {\it class}.  The evaluation of
the expression {\tt (subtypep {\it class1 class2\/})} returns the
values {\bf t t} if {\it class1\/} is a subclass of {\it class2\/} or if they
are the same class; otherwise it returns the values {\bf nil t}. 

Many but not all of the predefined Common Lisp type specifiers have a
corresponding class with the same name as the type.  For 
example, the type {\bf array} has a corresponding class named {\bf array}.  
A class that corresponds to a predefined Common Lisp type is called a
{\bit standard type class\/}.  Each standard type class has the class
{\bf standard-type-class} as a metaclass.  It is not allowed to make an
instance of a standard type class with {\bf make-instance} nor to include
a standard type class as a superclass of a class.

The purpose for specifying that many of the standard Common Lisp types
have a corresponding class is to allow users to write methods that
discriminate on these types.  The hierarchical relationships among   
the Common Lisp types are maintained by the classes corresponding to  
those types.   Thus the existing type hierarchy is used for determining  
the class precedence lists for each standard type class.    

Method selection requires that a class precedence list can be
determined for each class, ordering the class and its superclasses from 
most to least specific.  In some cases, {\it Common Lisp:  the 
Language\/} does not specify a subtype/supertype relationship for two 
supertypes of a given type.   For example, {\bf null} is a subtype of
{\bf symbol} and {\bf list}, but {\it Common Lisp:  the Language\/} does
not specify whether {\bf symbol} is more or less specific than {\bf
list}.  The \CLOS\ specification defines those relationships for all
standard type classes. 

The following table lists the set of standard type classes required by
\CLOS\.  The superclasses of each standard type class are presented in
order from most specific to most general: 

    STANDARD TYPE CLASS		SUPERCLASSES 

    array			t
    bit-vector			vector, array, sequence, t
    character			t
    complex			number, t
    cons			sequence, t
    float			number, t
    integer			rational, number, t
    list			cons, sequence, t 
    null			list, cons, symbol, sequence, t
    number			t
    ratio			rational, number, t
    rational			number, t
    sequence			t
    string			vector, array, sequence, t
    symbol			t
    t
    vector			array, sequence, t
 
Note that instances of standard classes are type disjoint with all other
types.

Individual implementations can allow other type specifiers to have a 
corresponding class.  Also individual implementations can add additional
subclass relationships as long as they do not violate {\it Common Lisp:
the Language\/}.  

Creating a type by means of {\bf defstruct} also creates a class in the
space of Common Lisp classes.  Such a class is an instance of {\bf
structure-class} and a direct subclass of the class that corresponds to
the included structure, if any.

No type specifier that is a list, such as {\tt (vector double-float 
100)}, has a corresponding class.   No type defined by {\bf deftype} has 
a corresponding class. 

For a discussion on some of the design decisions underlying this aspect
of \CLOS\, see the section "Design Theories of the Integration of Types
and Classes".

\endSection%{Integrating Types and Classes}


∂10-Jun-87  1117	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Design Rationale section on standard type classes  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Jun 87  11:17:11 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 169433; Wed 10-Jun-87 14:16:24 EDT
Date: Wed, 10 Jun 87 14:16 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Design Rationale section on standard type classes
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <870610141615.2.SKEENE@JUNCO.SCRC.Symbolics.COM>


\beginSection{Design Theories of the Integration of Types and Classes}  

This section explains some of the design decisions regarding the
integration of the existing Common Lisp type system with the \CLOS\
class system.   For background information, see the section 
``Integrating Types and Classes''. 

This section answers the following questions:

\beginlist

\item{\bull} Why do some of the standard Common Lisp types have a 
corresponding class?   

\item{\bull} Why don't all of the standard Common Lisp types have a
corresponding class?   

\item{\bull} What were the guidelines for choosing which types would
have a class, and which would not?

\endlist

Question:  Why do some of the standard Common Lisp types have a 
corresponding class?   

The purpose for specifying that many of the standard Common Lisp types  
have a corresponding class is to allow users to write methods that  
discriminate on these types; this is a powerful programming tool.  

The standard type specifiers fit neatly into the method selection
model, but they are not suited to the complete \CLOS\ model, with respect
to building classes from superclasses, creating instances, and changing 
the class of an instance.  It is useful to discuss the practical and 
conceptual distinctions between standard type classes and standard 
classes.   (A standard class is a user-defined class.)  Standard type
classes have the following restrictions:

\beginlist

\item{\bull} A standard type class cannot be used as superclasses.

The difference between standard type classes and standard classes is
in the implementation of instances.  Instances of a standard type class
are implemented in a specialized way that does not permit subclassing.

In some implementations some classes documented as standard type classes
might in fact be implemented as standard classes, but portable
programs cannot assume this.    

\item{\bull} {\bf make-instance} cannot be used to create an instance
of a standard type class. 

The capability of using {\bf make-instance} for standard type classes
gives no extra power or utility to the programmer.  Also, the \CLOS\
model does not extend gracefully in this direction.   Standard
classes have slots, but standard type classes have values of other 
sorts (such as the value of an integer or the elements of an array)
which do not fit the {\bf make-instance} model. 

\item{\bull} You cannot change the class of an instance of a standard
type class.    

The semantics of changing an instance of a standard type class are not
at all clear.   This is a basic difference between standard type
classes and standard classes.  

\endlist

Question:  Why don't all of the standard Common Lisp types have a
corresponding class?   

It would be useful to extend the standard type classes to encompass the 
full generality of Common Lisp type specifiers, but this raises  
theoretical issues that are not yet appropriate for standardization.  
These issues include:  

\beginlist

\item{\bull} Deciding what to do when an argument is an instance of two 
types, both of which have methods, but neither is a subtype of the
other.   Some of the types in {\it Common Lisp:  the Language\/} 
have no constraints on their precedence relations to other types.   

\item{\bull} The types that specify subranges present similar problems.  
It is unclear how to determine the relative precedence of two 
subranges of the same type.

\item{\bull} Dealing with Boolean combinations, such as negation, {\bf
and}, and {\bf or} presents problems with determinging relative 
precedence order.   For more information, see ``Boolean Classes'' by D.
McAllester and R. Zabih, a paper presented at the 1986 ACM First Annual
Conference on Object-Oriented Programming Systems, Languages, and
Applications.

\item{\bull} Some Common Lisp type specifiers are not defined clearly
enough in {\it Common Lisp:  the Language\/} to be useful as classes.
Until the specification of these types is clarified, it would be 
counterproductive to have corresponding classes for the types.  

\item{\bull}  Some types cannot be used for discrimination, such as {\bf
nil} and {\bf values}.   No object can be an instance of these types 
so there is no advantage to having classes for them. 

\endlist 

The \CLOS\ specification intentionally leaves room for adding more
standard type classes when these issues are resolved.   For example,
when and if the Common Lisp Cleanup Committee provides a relative
precedence order on the types that currently lack them, these types 
could have corresponding classes.   Similarly, classes could be added
for the types whose specifications are currently too vague, whenever
the types are more rigorously defined. 

Question:  What were the guidelines for choosing which types would
have a class, and which would not?

The general guidelines were given above.  The reasons for excluding
each individual type are given here:

{\it Boolean combinations and negation:\/} 

  {\bf and}
  {\bf atom} - Negation {\bf (not cons}}. 
  {\bf or}
  {\bf not} 

{\it Subranges:\/}

  {\bf bignum} 
  {\bf bit}
  {\bf fixnum}
  {\bf keyword} 
  {\bf member} - Subrange, if more than one argument is given.
  {\bf mod} -  Subrange of {\bf integer}. 
  {\bf satisfies} - Unclear subtype relations.
  {\bf simple-array}
  {\bf simple-bit-vector}
  {\bf simple-string}
  {\bf simple-vector}
  {\bf standard-char}
  {\bf string-char}
 
{\it The specification of these types is too vague:\/}

  {\bf common}
  {\bf stream}
  {\bf function}
  {\bf compiled-function}:     

{\it No constraints on the precedence relations to other types:\/}  

  {\bf package}
  {\bf readtable}
  {\bf random-state}
  {\bf hash-table}
  {\bf pathname}

{\it No object can be an instance of this type:\/}

  {\bf nil}
  {\bf values}

{\it The meaning and existence of these types is 
implementation-dependent:\/}
 
  {\bf short-float}
  {\bf long-float}
  {\bf single-float}
  {\bf double-float}

\endSection%{Design Theories of the Integration of Types and Classes}   


∂10-Jun-87  1412	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: I. Formal Specification of Gen. Fcn. Invocation    
Received: from [192.10.41.223] by SAIL.STANFORD.EDU with TCP; 10 Jun 87  14:12:08 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 136747; Wed 10-Jun-87 16:45:41 EDT
Date: Wed, 10 Jun 87 16:44 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: I. Formal Specification of Gen. Fcn. Invocation
To: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8706101631.AA15389@hplabsc>
Message-ID: <870610164436.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 10 Jun 87 09:31:14 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    >Are you looking at an old version of the document perhaps?

    I have the version which was distributed at the March ANSI meeting,
    along with the corrections distributed at the same meeting.

That's the same version that I have, so we're all right on that score.

∂10-Jun-87  1627	Bobrow.pa@Xerox.COM 	Re: SETF- method names  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 10 Jun 87  16:27:36 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 10 JUN 87 16:04:43 PDT
Date: 10 Jun 87 16:04 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: SETF- method names
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 9 Jun 87 21:16 EDT
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <870610-160443-1086@Xerox>


	Kempf says:						   However,
    since TRACE and other debugging aids require use of a function
    name, lack of an easy handle for SETF- generic function names
    (in the current implementation) requires that the user type in
    a long, nonstandard name in order to get any debugging information.
    Would it be appropriate to say anything about the SETF- generic
    function name, realizing that nothing is said about such in CLtL?

There are two issues here.  
1) SETF forms do not guarantee to call a function, and hence there is no
level of indirection one can count on to smash to build a tracing
facility. 

2) With generic functions, there is such a level of indirection without
using a name, namely the generic function object.  If TRACE were a
generic function that had an implementation dependent method on
GENERIC-FUNCTION, it would wqork fine.  So again no names are needed. 

∂10-Jun-87  2132	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object Creation Discussion  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Jun 87  21:31:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 169962; Wed 10-Jun-87 23:34:53 EDT
Date: Wed, 10 Jun 87 23:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object Creation Discussion
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870610233442.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

In case you're wondering why you haven't heard from me recently: I'm carrying around
a 70-page sheaf of printout of the recent mail on the subject, which is gradually
getting notes written on it, but I haven't reached any conclusions worth repeating yet.

∂10-Jun-87  2338	RPG  	    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    
Ad Hoc Solutions

Patrick has provided a good analysis of the problems with initialization.
Let me add a little more to it and then let's think about how to proceed.

Initialization is an exemplar of a category of programs, some of which
will be things that users will want to write for themselves. For example,
suppose someone wants to write a DISPLAY-INSTANCE function that will take
a number of arguments; some of those arguments will be used to
supply information for the positioning of the displayed instance, others will
alter defaults that are normally supplied by the classes in the
class precedence list, where these defaults determine how the display will
look (icons, text, texture, background colors, feature colors, sound,
animation, etc). The end-user will want to customize the display by
defining methods on generic functions that get invoked by DISPLAY-INSTANCE.

In this example, we have the problem of determining the defaults as
contributed from the classes in the class precedence list, the problem
of checking the legality of the arguments, and the problem of distributing
the arguments to the right methods.

These are the same problems as in initialization, and the programmer will
need to define his own methodology for solving them if we use an ad hoc
approach for initialization.  Assuming a declarative solution, I can even
imagine a programmer using the initialization mechanism to accomplish his
needs in the DISPLAY-INSTANCE problem.

My question is: Is this category of programs large enough that we need to
work Patrick's third dimension into CLOS? Or should we admit the weakness in
CLOS, because the category is too small or is not important? I don't know the
answer to this, and all I wanted to do was explore whether or not there was
a simple way to add the functionality to CLOS so that the decision is a
no-brainer.

			-rpg-

∂11-Jun-87  0746	kempf%hplabsc@hplabs.HP.COM 	Re: SETF- method names    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Jun 87  07:46:20 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 11 Jun 87 07:46:18 pdt
Received: by hplabsc ; Thu, 11 Jun 87 07:45:01 pdt
Date: Thu, 11 Jun 87 07:45:01 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706111445.AA28326@hplabsc>
To: Bobrow.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Subject: Re: SETF- method names

>2) With generic functions, there is such a level of indirection without
>using a name, namely the generic function object.  If TRACE were a
>generic function that had an implementation dependent method on
>GENERIC-FUNCTION, it would wqork fine.  So again no names are needed. 
>

A this would solve the problem nicely, for those cases where the
funcallable object is well defined (fundefs, generic functions,
symbols w. function cell bound, methods, etc.). 

The problem remains with SETF forms which take generalized variable
references, like SVREF, since there is currently no way to obtain
the funcallable object corresponding to the SETF "method" (to use
CLtL terminology). 

			jak


∂11-Jun-87  0819	kempf%hplabsc@hplabs.HP.COM 	Re:  Order of Initialization   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Jun 87  08:19:31 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 11 Jun 87 08:17:56 pdt
Received: by hplabsc ; Thu, 11 Jun 87 08:16:39 pdt
Date: Thu, 11 Jun 87 08:16:39 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706111516.AA28670@hplabsc>
To: Bobrow.pa@Xerox.COM, kempf%hplabsc@hplabs.HP.COM
Subject: Re:  Order of Initialization
Cc: Common-lisp-object-system@SAIL.STANFORD.EDU, RPG@SAIL.STANFORD.EDU

>I think one should not depend on the order.  

I agree, however, there may be cases where the order does matter.

>Consider the ambiguity
>resulting from two class definitions:
>
>(defclass c1 ()
>   ((x :initform (initx1))
>    (y :initform (inity))))
>
>(declass c2 (c1)
>   ((x :initform (initx2)))
>
>These can be in a file in either order.  Which order for eveluation of
>(initx2) and (inity) do you think is correct.  I can think of arguments
>for both.  Further, consider
>
>(defclass c3 (c1)
>   ((z :initform (initz))
>    (y :initform (inity2))
>    (x :initform (initx3))))
> 

In this particular example, the class precedence list for C1
would be:
	(C1 STANDARD-OBJECT T)

the initializer for the X slot would be INITX2, and the initializer for 
the Y slot would be INITY.
For C2, the class precedence list would be:

	(C2 C1 STANDARD-OBJECT T)

and, according to the rules on pg. 1-8:1-9 of 87-002 (and
provided it is decided to stick with them), the initializer
for X would be INITX2 and that for Y would be INITY. If
one uses the class precedence list to impose a global ordering
on initialization, and the lexical order within the class
to impose a local ordering, one could argue that the initialization
order INITX2, INITY would make sense.

>So my choice is 3, the user should not depend on the order.

The kind of example I'm thinking about where the order of
initialization can matter is where some global information is
propagated from one initform to the other via a special, or
initialization of one slot requires previous slots to be initialized.
Like:

	(defvar *screen-file-descriptor*)

	(defclass window ()
	  (
	    (file-info (open-screen-file))

		...
	  )
	)

and initialization of the rest of the slots requires the special to
be bound.


I think that if the INITIALIZE-INSTANCE (or whatever is
ultimately agreed to be the name) user customizable method could be
designated the right place to put special initialization needs,
like the requirement for initialization to proceed in a particular
order, then the need for specifying the order within the class
itself goes away. However, it is important that the spec specifically
state that the user cannot depend on the order of initialization
for :INITFORMs, otherwise, someone is bound to do so.

			jak

∂11-Jun-87  1120	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: SETF- method names 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Jun 87  11:03:38 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 170333; Thu 11-Jun-87 14:02:24 EDT
Date: Thu, 11 Jun 87 14:02 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: SETF- method names
To: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8706111445.AA28326@hplabsc>
Message-ID: <870611140213.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 11 Jun 87 07:45:01 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    >2) With generic functions, there is such a level of indirection without
    >using a name, namely the generic function object.  If TRACE were a
    >generic function that had an implementation dependent method on
    >GENERIC-FUNCTION, it would wqork fine.  So again no names are needed. 
    >

Actually this opens its own can of worms.  I can't figure out from CLtL
whether TRACE is intended to be an operation on function names, or on
functions.  Perhaps it is intentionally left to the discretion of the
particular programming environment.  All I know is that in Maclisp and
Zetalisp it was defined to be an operation on function names; but making
it operate on generic-function and method objects would make it an
operation on functions.  Here's an example to show what I mean by the
distinction:

(defun foo (x) (print x))
(let ((f (function foo)))
  (trace foo)
  (funcall f 105))

If TRACE is an operation on function names, this just prints 105.  If it's
an operation on functions, it generates tracing output as well.

    A this would solve the problem nicely, for those cases where the
    funcallable object is well defined (fundefs, generic functions,
    symbols w. function cell bound, methods, etc.). 

    The problem remains with SETF forms which take generalized variable
    references, like SVREF, since there is currently no way to obtain
    the funcallable object corresponding to the SETF "method" (to use
    CLtL terminology). 

You actually mean the funcallable object called by the form that is
returned by the SETF "method"; those type of SETF-"methods" are macros,
unlike CLOS setf-methods, which are functions.

Yes, this is a problem and I don't know of any good answers to it; after
all, the SETF form might well expand into a call to a different function
depending on seemingly minor variations in details of the arguments.
Not a problem for CLOS, just a problem for CL.  Your technique of
macroexpanding a sample form and assuming that the function that appears
there is the one that is going to be called is probably as good as any.

∂11-Jun-87  1243	kempf%hplabsc@hplabs.HP.COM 	Re: SETF- method names    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Jun 87  12:42:47 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 11 Jun 87 12:41:51 pdt
Received: by hplabsc ; Thu, 11 Jun 87 12:40:41 pdt
Date: Thu, 11 Jun 87 12:40:41 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8706111940.AA02450@hplabsc>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM,
        common-lisp-object-system@sail.stanford.edu
Subject: Re: SETF- method names

>    Date: Thu, 11 Jun 87 07:45:01 pdt
>    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
>
>    >2) With generic functions, there is such a level of indirection without
>    >using a name, namely the generic function object.  If TRACE were a
>    >generic function that had an implementation dependent method on
>    >GENERIC-FUNCTION, it would wqork fine.  So again no names are needed. 
>    >
>
>Actually this opens its own can of worms.  I can't figure out from CLtL
>whether TRACE is intended to be an operation on function names, or on
>functions.  Perhaps it is intentionally left to the discretion of the
>particular programming environment.  All I know is that in Maclisp and
>Zetalisp it was defined to be an operation on function names; but making
>it operate on generic-function and method objects would make it an
>operation on functions.  Here's an example to show what I mean by the
>distinction:
>
>(defun foo (x) (print x))
>(let ((f (function foo)))
>  (trace foo)
>  (funcall f 105))
>
>If TRACE is an operation on function names, this just prints 105.  If it's
>an operation on functions, it generates tracing output as well.
>

True, it could complicate implementations. The typical way of dealing
with tracing via names is to wrap the fundef with a wrapper function,
and hang the wrapper off the symbol's function cell. This doesn't demand
anything special of the fundef or symbol, since symbols are typically
writable. If TRACE becomes an operation on fundefs, it's got to modify
the fundef object, perhaps (extrapolating from the implementation
I'm aware of) putting a jump to the trace function as the first instruction
in the fundef. This may get difficult, if fundefs are in restricted
parts of memory, like nonwritable, which often is used for sharing
executable code between processes in different address spaces (again,
in the implementation I know best).


			jak

∂12-Jun-87  1002	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Metaclass Protocol
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 12 Jun 87  10:02:05 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad01370; 12 Jun 87 12:54 EDT
Received: from ti-csl by RELAY.CS.NET id ag22147; 12 Jun 87 12:49 EDT
Received: by tilde id AA18373; Fri, 12 Jun 87 11:11:18 CDT
Message-Id: <2759501598-3981583@Jenner>
Date: Fri, 12 Jun 87  11:13:18 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Metaclass Protocol


This message is a first-cut attempt at a design rationale for the
metaclass protocol.  The metaclass protocol being quite large, it will
be easier if we discuss and agree on the design rationale first.


We want to standardize the metaclass protocol to meet these objectives:

- Allow for portable compatible extensions to the CLOS model.  
1)Some might change the instances representation/behavior while
retaining a compatible top-level interface; Persistent objects systems
and Distributed objects systems are some examples.
2)Some might extend the model by changing the classes behavior like
Delegation instead of Inheritance or they can implement another object
system for backward compatibility reasons (like Flavors, Common
Objects...).  It would be desirable to allow a certain degree of
coexistence between classes belonging to different metaclasses.


- Allow for generic high level tools(Inspectors, generators, analyzers).
As a number of extensions will become available, there will be a need
for a single set of tools able to deal equally well with those
extensions. 


Requirements:

The metaclass protocol should allow the implementation to pick the best
optimization strategy (in terms of code generation and instance
representation).

The metaclass protocol should allow for any programming development
styles.  The idea is that an implementation should be able to support
both smooth incremental development and efficient wholesale file
compilation.

The metaclass protocol should support first class objects and anonymous
generic functions.


- Class behavior and instance behavior are othorgonal in CLOS.  The
metaclass protocol must preserve this orthoganality.  The metaclass
protocol should be as modular as possible.  I would want to be able to
write a Persistent-mixin metaclass and then mix it with STANDARD-CLASS
to get a persistent standard-class or with FLAVORS to get a persistent
flavors metaclass, instead of having to implement a full-blown metaclass
for every case.

I think those objectives and requirements open up some specific issues:

- The side effects on CLOS objects (Classes, generic-functions, methods)
that spead across object links should be exposed.
Compute-class-precedence-list is a good example.

- It should be possible to access some exposed slots of a CLOS object
without side-effect.  An inspector may need to access the
Class-precedence-list slot of a class without triggering
compute-class-precedence-list on the class.  I think that means we need
to have a way to indicate when a slot contains valid data.

- We probably need to care about the compile environment.  We don't have
to specify what it is but where, in our protocol it should be looked up
or side effected.  At least we must make sure that we don't go against
the following statements:
1)Compile-file does not side effect the running environment.
2)It is possible to implement a cross loader (Something that loads files
in order to make some class definitions, etc  that will affect 
the compilation but not the running environment).


The list of requirement and issues is far from being complete, but it
probably covers enough  to get the discussion started.

Patrick.

∂12-Jun-87  1204	Bobrow.pa@Xerox.COM 	Re:  Order of Initialization 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Jun 87  12:04:07 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 12 JUN 87 11:38:02 PDT
Date: 12 Jun 87 11:37 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re:  Order of Initialization
In-reply-to: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>'s message of Thu,
 11 Jun 87 08:16:39 pdt
To: Common-lisp-object-system@SAIL.STANFORD.EDU, RPG@SAIL.STANFORD.EDU
Message-ID: <870612-113802-1764@Xerox>

    I think that if the INITIALIZE-INSTANCE (or whatever is
    ultimately agreed to be the name) user customizable method could be
    designated the right place to put special initialization needs,
    like the requirement for initialization to proceed in a particular
    order, then the need for specifying the order within the class
    itself goes away. However, it is important that the spec
    specifically state that the user cannot depend on the order of
    initialization for :INITFORMs, otherwise, someone is bound to do so.
RIGHT (Meaning I agree)
  

∂15-Jun-87  1118	Gregor.pa@Xerox.COM 	new new initialization protocol blues  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 15 Jun 87  11:17:55 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 JUN 87 11:06:40 PDT
Date: 15 Jun 87 11:06 PDT
From: Gregor.pa@Xerox.COM
Subject: new new initialization protocol blues
To: Common-Lisp-Object-System@Sail.Stanford.edu
cc: Bobrow.pa@Xerox.COM, Gregor.pa@Xerox.COM
Message-ID: <870615-110640-1411@Xerox>

Here is another example of a fully procedural initialization protocol.
This message also includes an example of using that protocol to solve
the x-y-rho-theta problem.

In this protocol, make-instance, compute-initargs,
class-default-initargs and class-legal-initargs are documented generic
functions.

The method for make-instance on standard-class is documented to call
compute-initargs and allocate-instance.  The method for
allocate-instance on standard-class is documented to allocate storage
and evluate and store all the initforms.  The method for
compute-initargs on object is documented to call class-default-initargs
and class-legal-initargs and do the kind of defaulting we have all come
to expect.

Many users will just want to define methods on class-default-initargs
and class-legal-initargs.  Users trying to deal with problems like the
x-y-rho-theta problem will usually have to define methods on
compute-initargs as well.

(defmethod make-instance ((class symbol) &rest supplied-initargs)
  (apply #'make-instance (class-named symbol) supplied-initargs))

(defmethod make-instance ((class standard-class) &rest
supplied-initargs)
  (let* ((proto (class-prototype class))
	 (total-initargs (compute-initargs proto supplied-initargs))
	 (instance (apply #'allocate-instance class total-initargs)))
    (apply #'initialize-instance instance total-initargs)
    instance))

(defmethod compute-initargs ((object object) supplied-initargs)
  (let* ((default (class-default-initargs object))
	 (legal (class-legal-initargs object))
	 (total supplied-initargs)
	 (magic-value (list nil)))
    (do ((prop default (cddr prop))
	 (val (cdr default) (cddr val)))
	((null prop))
      (when (eq (getf total prop magic-value) magic-value)
	(push (eval val) total)
	(push prop total)))
    (do ((prop total (cddr prop)))
	((null prop))
      (unless (member prop legal)
	(error "~S is not a legal initarg for the class ~S"
	       prop
	       (class-of object))))
    total))

(defgeneric-options class-legal-initargs (class)
  (:method-comination-type append))

(defmethod class-legal-initargs ((class object)) '(:allow-other-keys))

(defgeneric-options class-default-initargs (class)
  (:method-combination-type append))

(defmethod class-default-initargs ((class object)) ())


;;;
;;; Here is an example of all this in use to solve the notorious
;;; x-y-rho-theta problem.
;;; We define a class named position, which can be mixed into
;;; a class that implements either x-y-position primitives or
;;; rho-theta-position primitives.  This class takes care of providing
;;; the other set of primitives, and more importantly takes care of
;;; handling the :x :y :rho :theta defaulting properly.
;;; 
(defclass position () ())

(defmethod class-legal-initargs ((pos position))
  '(:rho :theta :x :y))

(defmethod class-default-initargs ((pos position))
  '((:x 0) (:y 0) (:rho 0) (:theta 0)))

(defmethod compute-initargs ((pos position) supplied)
  (let ((x-p (memq ':x supplied))
	(y-p (memq ':y supplied))
	(r-p (memq ':rho supplied))
	(t-p (memq ':theta supplied))
	(defaults (class-default-initargs class)))
    (when (and (or x-p y-p) (or r-p t-p))
      (error "make up your mind loser"))
    (cond ((and x-p y-p))
	  ((and r-p t-p))
	  (x-p
	   (setf (getf supplied :y)
		 (eval-default-initarg (getf defaults :y))))
	  (y-p
	   (setf (getf supplied :x)
		 (eval-default-initarg (getf defaults :x))))
	  (r-p
	   (setf (getf supplied :theta)
		 (eval-default-initarg (getf defaults :theta))))
	  (t-p
	   (setf (getf supplied :rho)
		 (eval-default-initarg (getf defaults :rho)))))
    (call-next-method pos supplied)))

(defmethod x-position ((p position))
  (convert-rho-theta-to-x (rho-position p)
			  (theta-position p)))

(defmethod y-position ((p position))
  (convert-rho-theta-to-y (rho-position p)
			  (theta-position p)))

(defmethod rho-position ((p position))
  (convert-x-y-to-rho (x-position p)
		      (y-position p)))

(defmethod theta-position ((p position))
  (convert-x-y-to-theta (x-position p)
			(y-position p)))



(defclass x-y-position (position) (x y))

(defmethod initialize-instance :after
	   ((pos x-y-position) &key x y &allow-other-keys)
  (setf (slot-value pos 'x) x
	(slot-value pos 'y) y))
    


(defclass rho-theta-position (position) (rho theta))

(defmethod initialize-instance :after
	   ((pos rho-theta-position) &key rho theta &allow-other-keys)
  (setf (slot-value pos 'rho) rho
	(slot-value pos 'theta) theta))

∂15-Jun-87  1920	Bobrow.pa@Xerox.COM 	Re: new new initialization protocol blues   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 15 Jun 87  19:20:30 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 JUN 87 15:06:21 PDT
Date: 15 Jun 87 15:06 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: new new initialization protocol blues
In-reply-to: Gregor.pa's message of 15 Jun 87 11:06 PDT
To: Gregor.pa@Xerox.COM
cc: Common-Lisp-Object-System@Sail.Stanford.edu, Bobrow.pa@Xerox.COM
Message-ID: <870615-150621-108@Xerox>


1) It is useful to be able to allocate storage for an instance without
having to evaluate all the initforms, for example, to build a
class-prototype without risking an error.  Either this must be a
function that is called by allocate-instance, or it can be the job of
allocate instance.  But in Gregor's message (and my earlier message) we
stated that
    The method for allocate-instance on standard-class is
    documented to allocate storage and evaluate and store all the
    initforms. 
A useful alternative may be to make the method for allocate-instance
only allocate storage for the instance.  Then the primary method on
object for initialize-instance would be documented to evaluate and store
all the initforms.


2) Gregor's method not only exposes the proposed implementation of
initargs as methods, but suggests that the user must program using this
verbose style.  Here is a useful macro, shown only in an example, that
would usually be used by users to specify how to handle inputs to
specify slot-values.  The name of the macro can obviously be improved. 


User-code:

(define-initialize-instance-after-method x-y-position (pos &key
start-the-engine)
     ((x :x number "a number")   ;; initialize x a slot, checking its
type as a number
      (y :second)                ;; initialize y as a slot, using
keyword :second
      z)                         ;;  initialize z as a slot, using z as
the keyword
  (when start-the-engine (fire-up pos)))  ;; other user init code


----
Translation:
(defmethod initialize-instance :after
           ((pos x-y-position) &key start-the-engine
                                    ((:x #:g1) nil #:g2)
                                    ((:y #:g3) nil #:g4)
                                    ((z #:g5) nil #:g6)
                               &allow-other-keys)
  
  (when #:g2
    (check-type #:g1 number "a number")
    (setf (slot-value pos 'x) #:g1))
  (when #:g4
    (setf (slot-value pos 'y) #:g3))
  (when #:g6
    (check-type #:g5 z-type)            ;; this here if :type specified
in the class
    (setf (slot-value pos 'z) #:g5))

  ;; Now comes the user-supplied body.
  (when start-the-engine (fire-up pos)))



 
  

∂23-Jun-87  2114	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object creation   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 23 Jun 87  21:13:04 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 180419; Wed 24-Jun-87 00:12:34 EDT
Date: Wed, 24 Jun 87 00:12 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object creation
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870624001226.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

I've been studying the huge piles of mail on this subject.  I'm not sure
that all of the ideas that were intended to be conveyed got through to
me, since there was so much mail and so many contradictions and minor
errors.  Hence I apologize if what follows misses the point.

I couldn't find anything that directly addressed the issues I raised in
my message of 29 May; the one dividing things up into eight parts, of
which only three are actually needed if we want to keep things simple. 
Did it get lost in the network?

My hardcopy of Dick's message of 31 May has "agreed" written all over
it.  The conclusion I drew was that we aren't doing automatic
programming here and the generic-function-dispatch mechanism is pretty
limited in what programming tasks it can do automatically for us. 
Still, it would be nice if we could come up with a general paradigm for the
procedural description of inheritance and use it uniformly for classes,
methods, slots, and initializations, and also make it available to users
with their own things-that-inherit; I don't have any specific
suggestions on this yet.  One thing that I think we have learned is that
it seems to be a mistake to try to abstract away the caching that
happens in every real implementation of inheritance; we need to separate
the generic functions that gather and combine information from the
superclasses, from the generic functions that are called when an object
is created; the cache that sits between them needs to be made explicit.

I do have some thoughts to offer on the various schemes that have been
discussed for object creation at the meta-object level.  It seems that
there are three rather different things that this could be for:
(1) The language used by ordinary, rank-and-file programmers to write
their programs.
(2) A procedural explanation of the semantics, so that there is no
magic and everything is explained in terms of something else.  This
seems to be where Patrick's suggested generic, high-level tools fit in.
(3) A way to modify very basic aspects of the system's behavior,
for instance changing the way initargs inherit.

Taking these in order:

(1) I feel that a successful standard will provide simple ways to do
simple things.  A good argument that controlling object creation only at
the meta-object level is too difficult is contained in Gregor's message
of 15 June.  In the x-y-rho-theta example, the compute-initargs method
for position looks impressive, but if you study it carefully you will
realize that it is actually a complicated no-op!  Regardless of whether
this method or the default method is called, the result will be the
same:  a list containing the supplied initargs plus all of the
unsupplied ones with their default values from class-default-initargs. 
I suspect that what happened here is that Gregor got so bogged down in
the complexity of describing the x/y/rho/theta class in these very
low-level procedural terms, that he forgot what the original point was. 
Gregor is a smart guy, so I think what this shows is that an
object-oriented system that works this way is too difficult for anyone
to use without making mistakes.

Actually, this is probably a non-issue.  Correct me if I am wrong, but
I think we have already agreed that we want a simple, high-level way to
do simple object-creation, with the procedural level behind the scenes
where it belongs.

(2) I think having a procedural explanation of the semantics is a good
idea.  If I earlier gave the impression that I was opposed to that, it
was a misimpression.  I do have some reservations, which I think fall
into two categories:

(a) This level of the standard involves a lot more detail than the
simple programmer interface, and there is correspondingly more
possibility for errors.  Two examples that I noticed were failure to
carry along a lexical environment with forms, so that they can be
evaluated in the lexical environment in which they were written; and
confusion between method selection by the class of the instance versus
by the class of the class.  These are small errors and fairly easy to
fix.  For example, the first could be fixed by using functions instead
of forms and the second could be fixed by being consistent.  The point
is simply that there are more things to go wrong and it will take longer
to get them right, because we are standardizing an implementation (at
some level of abstraction) rather than standardizing only a description
of how any implementation must behave.

(b) There is the danger of ripping too many holes in the veil of
abstraction between the user and the implementation, eliminating the
freedom to choose an implementation optimized for particular
circumstances.  We have often made this mistake in the Lisp Machine
world in the past, and paid for it later.  One example of this problem
is that I haven't been able to figure out whether some of the proposals
that have been discussed require the methods for class-default-initargs
to be called every time make-instance is called, thus ruling out
precomputation and caching of this information.  Similarly I wasn't able
to figure out whether initializing many of the slots by copying a
template containing the values of constant initforms would be a valid
implementation, or whether the initforms actually have to be evaluated
at the time we say they are evaluated.  A more serious problem is that
if the two operations, collection of the inherited default value forms
and evaluation of these forms, are combined into one generic function,
such as compute-initargs, it becomes impossible to collect these forms
without evaluating them and compile them into a function.  This is
really the same point I made earlier, that trying to hide the existence
of caches isn't working.  A third problem, which I mention because it's
of a completely different nature, is that if the standard mandates that
each little aspect of a class must be expressed as a method, and we
actually have to create method objects, compiled-function objects, and
generic-function dispatch table entries for each of those methods, it's
going to tie up a large amount of space.  In a large system like Genera,
a rough, no doubt inaccurate estimate I made came out to 3/4 megabyte.

The point of these reservations is that if we're going to include this
level of detail in the standard, we have to be very careful what we say
and be sure we know what it implies.

(3) I'm not very happy about the idea of the user being able to redefine
very basic aspects of the behavior of the system, such as the way the
supplied initargs are combined with the default initargs.  It seems like
this would weaken the idea of a standard, because there would be no
contract that the system could safely be assumed to obey.  Actually what
bothers me here is not the idea that it is possible to redefine these
things, because I'm an open-system kind of guy and if people want to yank
the foundations out from under themselves that's okay with me.  What really
bothers me is the idea that redefining this stuff will be part of ordinary
day to day programming, rather than just something that you do when you're
experimenting with new kinds of object systems; changing the rules should
be intentional, not accidental.

Where do we go from here?  I think we should go back to figuring out
what the language used daily by rank-and-file programmers is.  Once we
think we agree on that, we should verify that it makes sense by agreeing
on the procedural description of it; there will be some iteration of
these two steps (there has already been some).  The biggest issue seems
to be what suite of features we want in that language, for example, is
the extra complexity of allowing initargs to be defaulted worthwhile?

∂24-Jun-87  1045	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Object Creation   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jun 87  10:45:11 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 180885; Wed 24-Jun-87 12:59:08 EDT
Date: Wed, 24 Jun 87 12:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Object Creation
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870624125852.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

Here's how I would do the x/y/rho/theta example:

;;; Abstract class that can be specialized to use either
;;; polar or cartesian representation

(defclass position () ())

(defmethod initialize-instance :before
	   ((self position) &key x y rho theta)
  (when (or x y)
    (set-cartesian-position self (or x 0) (or y 0)))
  (when (or rho theta)
    (set-polar-position self (or rho 0) (or theta 0))))

;;; Default methods.  One pair or the other must be shadowed.

(defmethod cartesian-position ((self position))
  (multiple-value-call #'polar-to-cartesian (polar-position self)))

(defmethod set-cartesian-position ((self position) x y)
  (multiple-value-call #'set-polar-position
		       self (cartesian-to-polar x y)))

(defmethod polar-position ((self position))
  (multiple-value-call #'cartesian-to-polar (cartesian-position self)))

(defmethod set-polar-position ((self position) rho theta)
  (multiple-value-call #'set-cartesian-position
		       self (polar-to-cartesian rho theta)))

;;; Internal subroutines for coordinate transformation

(defun polar-to-cartesian (rho theta)
  (values (* rho (cos theta))
	  (* rho (sin theta))))

(defun cartesian-to-polar (x y)  
  (if (and (zerop x) (zerop y))
      (values 0 0)
      (values (sqrt (+ (* x x) (* y y)))
	      (atan y x))))

;;; Useful macro

(defmacro with-direct-slots ((instance) &body body)
  `(with-slots ((,instance :use-accessors nil))
     ,@body))

;;; Instantiable class that uses cartesian representation

(defclass cartesian-position (position) (x y))

(defmethod cartesian-position ((self cartesian-position))
  (with-direct-slots (self)
    (values x y)))

(defmethod set-cartesian-position ((self cartesian-position)
				   new-x new-y)
  (with-direct-slots (self)
    (setq x new-x y new-y)))

;;; Instantiable class that uses polar representation

(defclass polar-position (position) (rho theta))

(defmethod polar-position ((self polar-position))
  (with-direct-slots (self)
    (values rho theta)))

(defmethod set-polar-position ((self polar-position)
			       new-rho new-theta)
  (with-direct-slots (self)
    (setq rho new-rho theta new-theta)))

∂24-Jun-87  1155	RPG  	Request to Moon for Thursday's Discussion   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    
Dave, could you possibly gather some information about the
current uses of initialization in Genera? It would be useful to
know what the most complex requirements are, what the typical
requirements are, etc, in a real system. For example, how often would
the CLOS :initform protocol serve?
			-rpg-

∂25-Jun-87  0901	RPG  	Random Thoughts Concerning Initialization   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

Reading over Gregor's latest proposal I am struck by the choices
we have:

1. In Moon's proposal, we introduce a new programming language within
the DEFCLASS syntax. This language solves the initialization problem
efficiently with minimal syntax. Other problems reducable to initialization
might also be so reduced by users, leading to confusing programming 
methodologies.

2. In Gabriel's proposal, we introduce some additional lambda-list syntax
and semantics to effect the distribution of arguments to methods. This
also requires complex initialization protocol to be written in a verbose
manner, and it complicates lambda-lists in an unpleasant manner.

3. In Gregor's proposal, we solve the initialization problem by reducing
it to a problem of manipulating argument lists. The code (sans macros) is
verbose and complicated. In addition, we end up treating passed arguments
as lists, which I find to be an unpleasant exposure of representation.

If we approach the initialization question along the lines Gregor
suggests, and if we look at the nature of generic functions (dispatching
to code based on examination of passed arguments), it seems there is some
tendency towards introducing into the language a means of operating on
passed arguments. One reason we had trouble with generic functions that
discriminated on more than the required arguments is that we had a hard
time manipulating the passed arguments.

If we choose a solution to initialization that involves manipulating
passed arguments, we possibly ought to provide an abstraction for passed
arguments - a set of passed arguments along with a set of operators that
take them apart, put them together, and invoke functions on them?  I
believe Seus [Talcott] went some distance in this direction.

∂02-Jul-87  0911	kempf%hplabsc@hplabs.HP.COM 	ECOOP Reaction to CLOS    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 2 Jul 87  09:11:09 PDT
Received: from hplabsc by hplabs.HP.COM with TCP ; Thu, 2 Jul 87 09:10:20 pdt
Received: by hplabsc ; Thu, 2 Jul 87 08:35:59 pdt
Date: Thu, 2 Jul 87 08:35:59 pdt
From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>
Message-Id: <8707021535.AA22501@hplabsc>
To: common-lisp-object-system@sail.stanford.edu
Subject: ECOOP Reaction to CLOS


My impression from talking to people at ECOOP was that most people
were fairly positive about Dick's talk.

He did get some flak about the inheritance algorithm, but I think this
was due to the presentation. If you tell someone that something is
too complicated to understand, the likely response is that you should
make the design simpler so they can understand it. In my opinion, it
is simply unacceptable to go around saying this. The algorithm isn't
any more complicated than the one used for LR parser generation
(to which Aho, Sethi, and Ullman devote 37 pages in the new Dragon
book) or normalization of a relational database schema (to which
Date devotes 23 pages). 

The fact that the algorithm is the right one is bostered by a paper
by Ducournau and Habib at ECOOP, which examined a class of graph
linerization algorithms having desirable qualitative properties,
of which the CLOS algorithm is a member.

Therefore, I hope someone can stand up at OOPSLA and do a better
job of explaining it. It may take some time, and will probably
require some more examples, particularly of how things can go
wrong, but I think it will, in the end, gain more support for
CLOS and increase programmer understanding. People should feel
good about using it, not just because its the standard, but also
because it does what they want and they understand that.

I hope someone will post the results of the Boston meeting, particularly
any decisions on initialization.

		Jim Kempf	kempf@hplabs.hp.com

∂03-Jul-87  0843	Moon@STONY-BROOK.SCRC.Symbolics.COM 	ECOOP Reaction to CLOS 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Jul 87  08:43:36 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 187240; Thu 2-Jul-87 16:58:59 EDT
Date: Thu, 2 Jul 87 16:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: ECOOP Reaction to CLOS
To: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8707021535.AA22501@hplabsc>
Message-ID: <870702165857.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 2 Jul 87 08:35:59 pdt
    From: Jim Kempf <kempf%hplabsc@hplabs.HP.COM>

    I hope someone will post the results of the Boston meeting, particularly
    any decisions on initialization.

Definitely.  Because of the long weekend, and because Gregor will be off
work Monday and Tuesday, you can expect to see this around the second half
of next week.  I wouldn't say we made any hard and fast decisions, but we
certainly made a lot of progress and we should be able to finish that up
and make actual decisions through the mail.  We talked about having another
meeting and the scheduling for that will have to be discussed through the
mail.

∂06-Jul-87  1130	RPG  	ECOOP Reaction
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

As Kempf points out, there was some negative reaction to CLOS at my
presentation, but most of it was directed at the lack of encapsulation and
protection, multiple inheritance, and the use of CLOS as a knowledge
representation system.  I might point out that most of the people who
raised objections during the presentation came up to me afterwards to get
a hold of the spec, the code, etc.

I want to make clear what it is I said about the CPL computation: I stated
that the effect of the CPL algorithm was difficult to understand, not that
the algorithm is difficult to understand. The difference between the two
is that an algorithm can be easy to grasp while a characterization of it
suitable for a programmer to understand is not available.  In contrast,
the algorithm for computing the strongly connected components of a graph
is easy to understand as an algorithm, and it is easy to understand what
it does because the definition of a strongly connected component is easy
to understand.  The CPL is understood to be a total ordering on a class
and its superclasses, but the only characteriztion of it that I know of is
that the CPL is the total ordering computed by the algorithm.  That
algorithm is understandable at the operational level, but there is no easy
characterization of it.

What would constitute an understandable characterization of the CPL?
Here are some examples of approaches:

1.  We could have a set of constraints on the classes such that the CPL
is the unique total ordering satisfying those constraints.

2.  We could have a set of inheritance situations such that when two
graphs of classes were inherited in particular ways, the new CPL was
predictable. For example, suppose we have 2 graphs, G1 and G2, with no common
classes except for the class named T and suppose that C1 and C2 are the
bottom-most classes of G1 and G2, respectively; then if a class C is
a subclass of C1 and C2 in that order, the classes in G1 precede the classes
in G2, and the classes in G1 are in the same order as they are in the CPL
for C1 and similarly for G2; T comes last.

But we do not have such a characterization; Moon's constraints are close
to it, but not good enough. Possibly we can search for the
characterization.  Remember that at the Palo Alto meeting in March, smart
people like Scherlis could not understand the effect of the algorithm,
although they (and he) thought the algorithm was simple.

Intellectual honesty compels me to point out things like this when
I address an audience. I suppose it annoys people when I do that,
but maybe we should give some thought to designing a language such that
there are few oppurtunities for ``Gabriel's inevitable critique.''

			-rpg-

∂08-Jul-87  0928	RPG  	First Try at Terminology
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

At the Symbolics meeting we decided to introduce some terminology
about erroneous situations for use in the final document. Here is
a first attempt at that terminology - Sit is a situation and Syn is
syntax:

The terminology defined in 1 - 4 refers to situations that might occur,
while the terminology defined in 5 refers to syntax.  

A ``situation'' is one of the following:

	1. an expression in which the first form is given or specified and
	   the remaining subexpressions are either given, specified, or
	   evaluate to objects satisfying certain constraints;

	2. a state of affairs within a running CLOS system.

Examples: When the function + is given a non-number as an argument, that
is a situation under definition 1; when a numeric operation causes an
arithmetic overflow, that is a situation under definition 2.

``Syntax'' refers to the nature of the lambda-list of a function,
the nature of the defmacro lambda-list of a macro, and the number and
nature of the subexpressions in a special form.

In the specification of CLOS, the behavior of programs in all situations
is described, and the options available to the implementor are defined; no
implementation is allowed to extend the syntax or semantics of CLOS except
as explicitly defined in the CLOS specification. In particular, no
implementation is allowed to extend the syntax of CLOS in such a way that
ambiguity between the specified syntax of CLOS and those extensions is
possible.

The following are descriptive phrases and their meanings:

1. ``When Sit occurs an error is signaled.''

The meaning of this terminology is:

	a. If this situation occurs, an error will be signaled in code
	   compiled under all compiler safety optimization levels and in
	   the interpreter.

	b. Valid CLOS programs may rely on the fact that an error will be
	   signaled in code compiled under all compiler safety
	   optimization levels and in the interpreter.

	c. Every CLOS implementation is required to detect such an error
	   in code compiled under all compiler safety optimization levels
	   and in the interpreter.

2. ``When Sit occurs an error should be signaled.''

The meaning of this terminology is:

	a. If this situation occurs, an error will be signaled at least in
	   code compiled under one compiler safety optimization level and
	   in the interpreter.

	b. Valid CLOS programs may not rely on the fact that an error will be
	   signaled.

	c. Every CLOS implementation is required to detect such an error
	   at least in code compiled under one compiler safety
	   optimization level and in the interpreter.

	d. When an error is not signaled, the results are undefined (see
	   below).

3. ``When Sit occurs the results are undefined.''

The meaning of this terminology is:

	a. If this situation occurs, the results are unpredictable.  The
	   results may range from harmless to fatal to the running CLOS
	   system.

	b. No valid CLOS programs should cause this situation to happen.

	c. CLOS implementations are allowed to detect this situation and
	   signal an error, but no CLOS implementation is required to
	   detect the situation.

	d. No implementation is allowed to extend the semantics of CLOS to
	   this situation; the effects of the situation may be harmless,
	   but they must remain undefined.

4. ``CLOS may be extended to cover Sit.''

The meaning of this terminology is that an implementation is free to treat
Sit in one of four ways:

	a. When Sit occurs, an error is signaled;

	b. When Sit occurs, an error is signaled at least in code compiled
	   under one compiler safety optimization level and in the
	   interpreter.

	c. When Sit occurs, the results are undefined; or

	d. When Sit occurs, the results are defined and specified.

In addition, this terminology means that:

	e. No portable CLOS program can depend on the effects of this
	   situation, and all portable CLOS programs are required to treat
	   the situation as undefined.

5. ``Implementations are free to extend the syntax Syn.''

The meaning of this terminology is:

	a. Implementations are allowed to define unambiguous extensions to
	   that syntax.

The CLOS specification may disallow certain extensions while allowing others.

*****************************************************************************

The following is a discussion of the motivation behind these terms. Of course,
there is no commitment yet to these terms: This is simply the first proposal.

The definition of a situation is designed to cover function invocations,
macro calls, and instances of the use of special forms as well as
conditions that might arise within a running CLOS system. A situation is
not a purely syntactic state of affairs, because the preconditions for an
error usually requires that something about the nature of the arguments
to a function, for example, be known. The wording of these definitions will
need further work.

On syntax, I believe we want the default to be that no extensions are
allowed - that is, any extensions must be explicitly allowed. I
particularly wish to disallow syntactic extensions that extend the number
of arguments to a function or a macro or the number of subexpressions in a
special form.

These terms are a reaction to current CLtL terminology and the various
interpretations of it. The entire gamut of interpretations of CLtL terms
is valid, but there are more interpretations than terms. This proposal is
intended to identify the reasonable interpretations of CLtL terminology
and provide terms for those intepretations, so that, I hope, the terms and
interpretations are one-to-one.

1. ``When Sit occurs an error is signaled.''

This term is borrowed from CLtL. I think we need a more precise definition
that talks about errors being signaled in code compiled under all compiler
optimization levels.  Current practice in Common Lisp includes only
signaling errors in code that was compiled under high compiler safety
optimization levels. Because there is a constant desire to elide such
checks in compiled code on stock hadware, we should separate out cases in
which we want errors signaled in code compiled under all compiler
optimization levels from those in which we allow implementations to
provide a high-speed, unsafe operations - my recollection is that CLtL
``is an error'' was intended to accomplish that separation, but that is
not the current prevailing interpretation.  Hence the term:

2. ``When Sit occurs an error should be signaled.''

Some people who interpret CLtL maintain that, under a strict reading of
CLtL, CLOS ``signals an error'' corresponds to CLtL ``signals an error''
and CLOS ``an error should be signaled'' corresponds to CLtL ``is an
error.'' This does not correspond to current practice, in which CLtL
``signals an error'' generally corresponds to CLOS ``signals an error''
or ``should signal an error,'' while CLtL ``is an error'' generally
corresponds to CLOS ``is undefined'' or ``is extendable.''

3. ``When Sit occurs the results are undefined.''

The intention of this is to allow implementations to not worry about what
happens in Sit, because CLOS does not permit programs to be written that
fall into Sit, and no implementation is allowed to extend the semantics of
CLOS to provide useful behavior in Sit. Some people have claimed that CLtL
``is an error'' corresponds to CLOS ``is undefined.''

I might expect that we would add wording to this to the effect that an
implementation may include documentation about a situation of this sort
that states that the results are harmless, but no implementation is
allowed to state what actually happens.

4. ``CLOS may be extended to cover Sit.''

This term in intended to cover yet another reading of CLtL ``is an
error,'' namely that an implementation is allowed to extend the language
to cover an otherwise erroneous situation.

5. ``Implementations are free to extend the syntax Syn.''

I believe we wish to control where extensions to CLOS are allowed to occur.
The first four terms are designed to control semantic extensions while the 
fifth is designed to control syntactic extensions, which are somewhat
different.

I believe we want to define precise terms such as these and use them
exactly in the CLOS specification so that, rather than the CLOS
specification being a pseudo-user's-guide as CLtL is, it can be a
specification suitable for an implementor.

			-rpg-

∂08-Jul-87  0938	RPG  	Category Errors    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

One minor point that came up at the Symbolics meeting last Thursday
was category errors and whether we should try to outlaw them somehow.
Here is an example of a category error:

Suppose that MAKE-INSTANCE is a generic function. Its definition
might look like this:

	(defmethod make-instance ((class standard-class) &rest args)...)

Notice that the class of the argument CLASS is STANDARD-CLASS, which
indicates that the operation of MAKE-INSTANCE is controlled at the
meta-object level. Suppose someone were to write:

	(defmethod make-instance ((class apple-pie) &rest args)...)

	(make-instance (class-prototype (class-named 'apple-pie)) ...)

Here someone would be making a category error by defining a method on
MAKE-INSTANCE at the wrong level - the class level. What makes this easy
for a programmer to do this is the availability of CLASS-PROTOTYPE.
However, it is never hard to do because the programmer can write:

	(defvar *apple-pie-prototype* (make-instance 'apple-pie))

to get his class prototype. 

We have two alternatives:

	1. Let sea of classes/metaclasses remain a miasma and inform
	   programmer that he ought not mix things up.

	2. Define a notion of class category or classs level and have a
	   category of generic function for each class category.

			-rpg-

∂08-Jul-87  1643	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Class redefinition and class-changed. 
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 8 Jul 87  16:43:20 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa01894; 8 Jul 87 19:38 EDT
Received: from ti-csl by RELAY.CS.NET id aa05802; 8 Jul 87 19:31 EDT
Received: from Jenner by tilde id AA05525; Wed, 8 Jul 87 16:05:23 CDT
Message-Id: <2761765326-16486571@Jenner>
Date: Wed, 8 Jul 87  16:02:06 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Class redefinition and class-changed.

Redefining a class will provoke instances of this class to be changed to the new
class using the change-class protocol.  However there is no specified way to
take advantage of the class-changed generic function.

Goals:

 - There should be a way to define a method for class-changed on the obsolete
class and the class.

 - This method needs to be defined before any the instances is changed,
otherwise it wouldn't get invoked on all the instances of the class.

Proposal:

Before committing the class to redefinition, we specify a way to get the
obsolete class objects and thus, define methods for class-changed.  Since a
class redefinition will propagate down, it will be useful to get the closure of
all the redefintions.

GET-OBSOLETE-CLASSES-FOR-REDEFINITION will return an alist whose keys are the
classes implicated in the class-redefinition of CLASS and whose contents are the
obsolete classes.

Syntax:
GET-OBSOLETE-CLASSES-FOR-REDEFINITION CLASS &optional (REDEFINITION-CLOSURE-P t)

GET-OBSOLETE-CLASSES-FOR-REDEFINITION is a generic function.

CLASS is a class object 

if REDEFINITION-CLOSURE-P not provided or non nil, all the classes implicated in
the class redefinition of CLASS are returned as keys of the resulting alist.  If
REDEFINITION-CLOSURE-P is nil, then the alist returned contains only one entry
for CLASS.

Besides obsolete class creation, get-obsolete-classes-for-redefinition does not
side effect.  In other words, it it OK to call it more than once and the returned
obsolete classes are EQ from one call to the other.

Once the methods are defined, the class redefinition can be executed.

Patrick.

∂09-Jul-87  1207	Bobrow.pa@Xerox.COM 	Re: Class redefinition and class-changed.   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  12:07:25 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUL 87 11:54:12 PDT
Date: 9 Jul 87 11:51 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Class redefinition and class-changed.
In-reply-to: Patrick H Dussud <DUSSUD%Jenner@ti-csl.CSNET>'s message of
 Wed, 8 Jul 87 16:02:06 CDT
To: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870709-115412-4166@Xerox>

    Goals:

     - There should be a way to define a method for class-changed
    on the obsolete class and the class.

     - This method needs to be defined before any the instances is
    changed, otherwise it wouldn't get invoked on all the instances of
    the class.

Agreed.

The necessary and sufficient condition for this is to be able to get
hold of an obsolete version of a class.  

Proposal:

Changing a class updates a database to allow the following generic
functions to work.

GET-OBSOLETE-VERSION class
 returns the preceding obsolete version of this class, or NIL if none.
This allows users to define methods at any time on the obsolete class.
Obsolete classes themselves may also have an obsolete-version.  Obsolete
classes also respond to

GET-UPDATED-VERSION obsolete-class
 with the next class or NIL
This allows following the chain in the opposite direction

Providing this chain allows defining pair-wise updaters from an obsolete
to its updated version, a general updating protocal that will follow the
chain from any old version to the current version, and accelerators
between any old-version and any later version on the chain.

  

∂09-Jul-87  1326	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  13:26:09 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:24:30 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:23:58 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Thu, 9 Jul 87 13:24:38 pdt
Date: Thu, 9 Jul 87 13:24:38 pdt
From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>
Message-Id: <8707092024.AA22131@hplabsz.hpl.hp.com>
To: rpg@sail.stanford.edu
Subject: Re: ECOOP Reaction to CLOS
Cc: common-lisp-object-system@sail.stanford.edu

>I want to make clear what it is I said about the CPL computation: I stated
>that the effect of the CPL algorithm was difficult to understand, not that
>the algorithm is difficult to understand. The difference between the two
>is that an algorithm can be easy to grasp while a characterization of it
>suitable for a programmer to understand is not available.  In contrast,
>the algorithm for computing the strongly connected components of a graph
>is easy to understand as an algorithm, and it is easy to understand what
>it does because the definition of a strongly connected component is easy
>to understand.  The CPL is understood to be a total ordering on a class
>and its superclasses, but the only characteriztion of it that I know of is
>that the CPL is the total ordering computed by the algorithm.  That
>algorithm is understandable at the operational level, but there is no easy
>characterization of it.

I think what most programmers want is a two sentence explanation of how
inheritance works in CLOS. The equivalent for Smalltalk is:

	Child classes get all the methods and all the slots of
        their parents. Any methods defined with the same name
        as the parent defined in the child override the parent's
        method.

I propose this for CLOS:

	The inheritance graph is searched depth first, left to
        right, up to joins. Superclasses at joins are placed
        in the class precedence list at the last occurance,
        rather than the first, since such superclasses are
        usually more general than their subclasses, and classes
        at the end of the class precedence list should be more
        general than those at the beginning. The qualitative
        effect is to achieve a linearization of the inheritance
        graph, with more specialized classes at the head of
        the class precedence list and more general classes at
        the tail, keeping together groups of classes which occur
	together in the inheritance graph.

Well, that's three sentences, but I think most people won't mind.

A more detailed explantion should go into what can go wrong. The
Ducournau and Habib paper discusses this in a more formal way.
The essense is that if two or more subclasses share two
or more join superclasses, then the algorithm can fail. 
In such cases, the two join superclasses are two alternative end 
elements for the sublist CPL containing the subclasses, so there
is no unique linearization. Scherlis's comments about programmer
hooks at the Palo Alto meeting might be appropriate here, since
the programmer could choose which join superclass is more
general, but I think the appropriate place to put in these hooks
is the metaobject protocol, and not something like prompting the
programmer.

>Intellectual honesty compels me to point out things like this when
>I address an audience. I suppose it annoys people when I do that,
>but maybe we should give some thought to designing a language such that
>there are few oppurtunities for ``Gabriel's inevitable critique.''

I have no problem with such critiques, however, I think at some point
we need to iterate to a design which we all feel comfortable with,
and which application developers can use. My impression of the 
inheritance algorithm is that it refines and solidifies current practice
which is *precisely* what a standard should do. Whether or not it
is the ultimate in linguistic software reuse mechanisms is another 
question. I don't think it is, but until I know the answer, have
tested it with a couple of applications, and have discussed it extensively
with other people, I'm sure not going to recommend that it be made a
standard.


		Jim Kempf	kempf@hplabs.hp.com



















∂09-Jul-87  1327	kempf%hplabsz@hplabs.HP.COM 	Re: Category Errors  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  13:26:44 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:25:13 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:24:51 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Thu, 9 Jul 87 13:25:28 pdt
Date: Thu, 9 Jul 87 13:25:28 pdt
From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>
Message-Id: <8707092025.AA22144@hplabsz.hpl.hp.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Category Errors

>
>	1. Let sea of classes/metaclasses remain a miasma and inform
>	   programmer that he ought not mix things up.
>
>	2. Define a notion of class category or classs level and have a
>	   category of generic function for each class category.

This is a difficult one, and relates to Patrick's goal of maintaining metaclass
protocol and class protocol orthogonally. Pros are that it can avoid having
programmers make mistakes like defining MAKE-INSTANCE on a class, as cited
in the base note, cons are that a programmer might actually *want* to have
a particular class be instantiated slightly differently. Given Lisp's 
tendency to allow a programmer to do anything, as long as the name for
doing it can be found, I think 1) should be the choice, except the "sea
of classes/metaclasses" ought probably to be broken up into little bays
and gulfs via. the package system. With some method names (like MAKE-INSTANCE)
there is no hope, since they are firmly in the programmer interface.
With the rest of the metaobject protocol, the names should be exported
from a seperate package, so that only programmers who want to do metaclass
programming need be concerned with them. One can reasonably argue that
a programmer using CLOS should be familar enough with the programmer 
interface functions to be able to avoid an accidental redefinition of 
the methods there, but we should certainly not require CLOS programmers
to be familar with metaclass names unless they intend to do metaclass
programming.

			Jim Kempf	kempf@hplabs.hp.com


	

∂09-Jul-87  1329	kempf%hplabsz@hplabs.HP.COM 	Re: First Try at Terminology   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  13:29:00 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:27:28 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:27:01 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Thu, 9 Jul 87 13:27:41 pdt
Date: Thu, 9 Jul 87 13:27:41 pdt
From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>
Message-Id: <8707092027.AA22154@hplabsz.hpl.hp.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: First Try at Terminology

>The definition of a situation is designed to cover function invocations,
>macro calls, and instances of the use of special forms as well as
>conditions that might arise within a running CLOS system. A situation is
>not a purely syntactic state of affairs, because the preconditions for an
>error usually requires that something about the nature of the arguments
>to a function, for example, be known. The wording of these definitions will
>need further work.

Why not go one step further and use preconditions
and postconditions on the functions and macros, ala` Hoare logic?

Example from 87-002 spec (RET is the returned value, ARG the argument):

CLASS-OF

Pre: T
Post: RET is an element of C, the set of defined classes, if ARG is an
      instance of a class | error

The postconditions could contain error postconditions of three types:

1) errors at all optimization levels (1 in the original message)
2) errors at the lowest only (2 in the orignal message) 
3) errors which implementations are permitted to extend CLOS to
   cover.

>I believe we wish to control where extensions to CLOS are allowed to occur.
>The first four terms are designed to control semantic extensions while the 
>fifth is designed to control syntactic extensions, which are somewhat
>different.

Yes, this is a laudable goal, but I fear that any attempt to do this
in English may remain open to ambiguous interpretation. 

>I believe we want to define precise terms such as these and use them
>exactly in the CLOS specification so that, rather than the CLOS
>specification being a pseudo-user's-guide as CLtL is, it can be a
>specification suitable for an implementor.

100% agreement. Barring any agreement on more rigorous formalism, I
can live with the terminology in the base note. It's a whole lot better
than CLtL.

			Jim Kempf	kempf@hplabs.hp.com


      

∂09-Jul-87  1333	kempf%hplabsz@hplabs.HP.COM 	Re: Metaclass Protocol Goals   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  13:32:33 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 13:30:54 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 13:30:20 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Thu, 9 Jul 87 13:30:59 pdt
Date: Thu, 9 Jul 87 13:30:59 pdt
From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>
Message-Id: <8707092030.AA22198@hplabsz.hpl.hp.com>
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Metaclass Protocol Goals

Patrick's design rationale looks like a good beginning, and would be a good
addition to the beginning of 87-003, as motivation for the metaclass
protocol. I had a couple of comments and questions:

>Class behavior and instance behavior are othorgonal in CLOS.  The
>metaclass protocol must preserve this orthoganality.  

I'm not quite sure I understand what you mean by class and instance
behavior being orthogoal. Since class objects are instances of
the metaclass, this statement would seem not to be true for classes
when considered as instances.

>- The side effects on CLOS objects (Classes, generic-functions, methods)
>that spead across object links should be exposed.
>Compute-class-precedence-list is a good example.

I'm not sure I understand what you mean by "be exposed". What I
think you mean by "side effects on CLOS objects that spread across
object links" is protocols which affect objects whose structure acts
as templates for other objects (is that so?). As an example, the
structure of a class object acts as a template for instances. If
you mean that methods affecting the structure of such "template
objects" should be included in the public metaobject protocol, then
I agree.

>- It should be possible to access some exposed slots of a CLOS object
>without side-effect. 

I agree with this, but I think it might be difficult to achieve in
practice. With method combination, it should be possible for the designer
of a metaclass to define a daemon method on any method in the protocol
which cause side effects to occur. I can think of a couple solutions to
this off the top of my head. One is to suggest that metaclass programmers
follow a convention of not defining daemon methods which cause side
effects, another is to specifically forbid defining daemon methods on 
metaclass methods, possibly through a declaration mechanism (as I
suggested in an earlier note this spring). Probably the former is better,
since daemon methods for doing things like updating browsers when 
classes are defined might be useful.

>- We probably need to care about the compile environment.  We don't have
>to specify what it is but where, in our protocol it should be looked up
>or side effected.  At least we must make sure that we don't go against
>the following statements:
>1)Compile-file does not side effect the running environment.
>2)It is possible to implement a cross loader (Something that loads files
>in order to make some class definitions, etc  that will affect 
>the compilation but not the running environment).

Given the design of the Common Lisp, this might be very 
difficult to achieve. Using the PCLOS implementation from Gregor,
I tried a quick and dirty implementation of a seperate compile time
namespace for CommonObjects on CLOS and ran into some serious problems.
Basically, for languages such as CommonObjects which compute alot of
their inheritance information at compile time, the only alternative
to side effecting the compile time environment is to somehow maintain
the information and update global structures only when its safe. This
approach is used in our native code CommonObjects implementation, and
it is expensive. The CommonObjects on CLOS compiles about twice as
fast because it just side effects the compile time environment. In the
CLOS language, if attention is not paid to side effects, then classes
need to be defined in the compile time environment so that method
definintions being defined in the same file (a logical way to organize
a body of software) can be compiled.

Aside from problems with bootstrapping CLOS itself (which Gregor
seems to pretty well have under control in the portable implementation),
much of the reason for not side effecting the compile time environment
goes away with multiple virtual address spaces. A "spoiled" compile
time environment can just be thrown away. Of course, this doesn't
solve the problem for machines where multiple virtual address spaces
are not an option.

			Jim Kempf	kempf@hplabs.hp.com


∂09-Jul-87  1355	Kahn.pa@Xerox.COM 	Re: Category Errors  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  13:55:05 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 JUL 87 13:49:06 PDT
Date: Thu, 9 Jul 87 13:48:39 PDT
From: Ken Kahn <Kahn.pa@Xerox.COM>
Subject: Re: Category Errors
In-Reply-To: <8707092025.AA22144@hplabsz.hpl.hp.com>
To: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870709-134906-4431@Xerox>

I think it would be a mistake to build barriers between class and
metaclass protocols.  One of the strong appeals of CLOS is that one can
experiment within its framework.  We once worked out how Object Lisp's
view that classes and instances are pretty much the same could be
implemented in PCL.  A good fraction of the OOP community believes in
these "prototypes" which unify classes and instances.  We should be
careful not to prohibit CLOS from evolving in that direction if people
come to believe its a win.

References
	kempf%hplabsz@hplabs.HP.COM's message of Thu, 9 Jul 87 13:25:28 PDT --
Re: Category Errors

∂09-Jul-87  1431	kempf%hplabsz@hplabs.HP.COM 	Re: Category Errors  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  14:31:26 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Thu, 9 Jul 87 14:28:00 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Thu, 9 Jul 87 14:27:40 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Thu, 9 Jul 87 14:28:20 pdt
Date: Thu, 9 Jul 87 14:28:20 pdt
From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>
Message-Id: <8707092128.AA22639@hplabsz.hpl.hp.com>
To: Kahn.pa@Xerox.COM, kempf%hplabsz@hplabs.HP.COM
Subject: Re: Category Errors
Cc: common-lisp-object-system@sail.stanford.edu

>I think it would be a mistake to build barriers between class and
>metaclass protocols.  One of the strong appeals of CLOS is that one can
>experiment within its framework.  We once worked out how Object Lisp's
>view that classes and instances are pretty much the same could be
>implemented in PCL.  A good fraction of the OOP community believes in
>these "prototypes" which unify classes and instances.  We should be
>careful not to prohibit CLOS from evolving in that direction if people
>come to believe its a win.
>

I agree with this viewpoint in principle, which is why I wouldn't want
to see any stronger barriers be erected than packageization. That seems
to me to be the minimum to keep people happy who want to maintain some
distance and are already uncomfortable with the metaclass protocol,
and those who believe that no barriers are appropriate. Someone wanting
to implement Object Lisp need only use both the user interface and
metaclass symbols.

∂09-Jul-87  1933	Bobrow.pa@Xerox.COM 	Re: Metaclass Protocol Goals 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Jul 87  19:32:59 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 JUL 87 19:03:04 PDT
Date: 9 Jul 87 19:03 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Metaclass Protocol Goals
In-reply-to: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>'s message of Thu, 9
 Jul 87 13:30:59 pdt
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870709-190304-4903@Xerox>

    Patrick>- It should be possible to access some exposed slots of a
CLOS
    object >without side-effect. 

    Jim> I agree with this, but I think it might be difficult to achieve
    ...

It is not difficult to document for CLOS.  If a package adds behavior to
CLOS, then a user of that package should document its behavior.  This is
not a matter for program control -- just for social control.

∂10-Jul-87  1026	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 10 Jul 87  10:25:57 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae21575; 10 Jul 87 11:54 EDT
Received: from ti-csl by RELAY.CS.NET id ag17093; 10 Jul 87 11:47 EDT
Received: from Jenner by tilde id AA26237; Fri, 10 Jul 87 10:04:49 CDT
Message-Id: <2761916421-9049515@Jenner>
Date: Fri, 10 Jul 87  10:00:21 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Danny Bobrow <Bobrow.pa@XEROX.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class redefinition and class-changed.
In-Reply-To: Msg of 9 Jul 87 11:51 PDT from Danny Bobrow <Bobrow.pa@xerox.com>

     Date: 9 Jul 87 11:51 PDT
     From: Danny Bobrow <Bobrow.pa@xerox.com>
     Subject: Re: Class redefinition and class-changed.
     
         Goals:
     
          - There should be a way to define a method for class-changed
         on the obsolete class and the class.
     
          - This method needs to be defined before any the instances is
         changed, otherwise it wouldn't get invoked on all the instances of
         the class.
     
     Agreed.
     
     The necessary and sufficient condition for this is to be able to get
     hold of an obsolete version of a class.  

I don't agree.  We said in chapter 1 that the updating of the instances is done
at an implementation-dependent time.  It means that unless you prepare your
methods in advance (before the class is actually redefined) you are going to let
some instances be updated without proper class-changed method invokation.  The
worst part is you may not find out about it.  A necessary condition is to be
able to get hold of an obsolete version of a class before the class is changed.
     
     Proposal:
     
     Changing a class updates a database to allow the following generic
     functions to work.
     
     GET-OBSOLETE-VERSION class
      returns the preceding obsolete version of this class, or NIL if none.
     This allows users to define methods at any time on the obsolete class.
     Obsolete classes themselves may also have an obsolete-version.  Obsolete
     classes also respond to
     
     GET-UPDATED-VERSION obsolete-class
      with the next class or NIL
     This allows following the chain in the opposite direction
     
I don't have much objection to this.  However, I don't see it as sufficient to
implement the goals you agreed upon.  I see your proposal as a complement to
mine.

 (let ((obsolete-class
	 (cdr (assoc class (GET-OBSOLETE-CLASSES-FOR-REDEFINITION class )))))
   Add method on class-changes....
   redefine the class class ...
   (eq obsolete-class (GET-OBSOLETE-VERSION class)))
 
   => T

Patrick.

∂13-Jul-87  1039	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Metaclass Protocol Goals
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 13 Jul 87  10:39:10 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad17106; 13 Jul 87 13:12 EDT
Received: from ti-csl by RELAY.CS.NET id an13899; 13 Jul 87 13:05 EDT
Received: from Jenner by tilde id AA06513; Fri, 10 Jul 87 16:44:10 CDT
Message-Id: <2761940409-10490738@Jenner>
Date: Fri, 10 Jul 87  16:40:09 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Jim Kempf <kempf%hplabsz@hplabs.hp.com>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Metaclass Protocol Goals
In-Reply-To: Msg of Thu, 9 Jul 87 13:30:59 pdt from Jim Kempf <kempf%hplabsz@hplabs.hp.com>

     Patrick's design rationale looks like a good beginning, and would be a good
     addition to the beginning of 87-003, as motivation for the metaclass
     protocol. I had a couple of comments and questions:

Thank you for your comments.
     
     >Class behavior and instance behavior are othorgonal in CLOS.  The
     >metaclass protocol must preserve this orthoganality. 

     I'm not quite sure I understand what you mean by class and instance
     behavior being orthogoal. Since class objects are instances of
     the metaclass, this statement would seem not to be true for classes
     when considered as instances.

What I meant is that the metaclass does affect the way classes parse their
defclass, compute class precedence list, gather their slots... all these things
are class business. On the other hand, it affects how instances are allocated,
laid out, accessed. That's instance business. These two sorts of businesses are
independent. I may want to keep a CLOS Syntax, CPL, etc, but have my instances
represented differently. I may want to define a FLAVOR metaclass and
represent its instances the way the default CLOS metaclass represents them.

					
     >- The side effects on CLOS objects (Classes, generic-functions, methods)
     >that spread across object links should be exposed.
     >Compute-class-precedence-list is a good example.

     
     I'm not sure I understand what you mean by "be exposed". What I
     think you mean by "side effects on CLOS objects that spread across
     object links" is protocols which affect objects whose structure acts
     as templates for other objects (is that so?). As an example, the
     structure of a class object acts as a template for instances. If
     you mean that methods affecting the structure of such "template
     objects" should be included in the public metaobject protocol, then
     I agree.

Exposed means documented (what it is), with a protocol that goes with it (what
you can do, how you do it).

"Side effects on CLOS objects that spread across object links" means the side
effects that affect some other objects, not just the one you intended to
side-effect.  For example, if you redefine a class, you are likely to affect
other classes besides the one you are redefining.  These side effects are
particularly important to specify because they can spread across metaclasses.
If metaclass A handles class redefinition one way and metaclass B handles it in
a different way, then clearly we have a problem if we can mix classes of A with
classes of B.
     
     >- It should be possible to access some exposed slots of a CLOS object
     >without side-effect. 
     
     I agree with this, but I think it might be difficult to achieve in
     practice. With method combination, it should be possible for the designer
     of a metaclass to define a daemon method on any method in the protocol
     which cause side effects to occur. I can think of a couple solutions to
     this off the top of my head. One is to suggest that metaclass programmers
     follow a convention of not defining daemon methods which cause side
     effects, another is to specifically forbid defining daemon methods on 
     metaclass methods, possibly through a declaration mechanism (as I
     suggested in an earlier note this spring). Probably the former is better,
     since daemon methods for doing things like updating browsers when 
     classes are defined might be useful.

We define a protocol, not a language.  A protocol is a set of rules that someone
must observe in order to preserve the integrity of the system.  If we say "This
should be side effect free", it means that someone writing a new metaclass must
satisfy this constraint if he expect CLOS to continue working right.  We
certainly don't want to do anything complicated to enforce it.
     
     >- We probably need to care about the compile environment.  We don't have
     >to specify what it is but where, in our protocol it should be looked up
     >or side effected.  At least we must make sure that we don't go against
     >the following statements:
     >1)Compile-file does not side effect the running environment.
     >2)It is possible to implement a cross loader (Something that loads files
     >in order to make some class definitions, etc  that will affect 
     >the compilation but not the running environment).

What I was trying to say here is we must define provision for implementations to
do a good job of defining a compilation environment, not to require it.

     
      Using the PCLOS implementation from Gregor,
     I tried a quick and dirty implementation of a seperate compile time
     namespace for CommonObjects on CLOS and ran into some serious problems.

Running into problems because the implementation does not allow you to do it is
one thing, running into problems because the metaclass protocol makes it
impossible is another thing.

Patrick.

∂15-Jul-87  1000	kempf%hplabsz@hplabs.HP.COM 	Re: Class redefinition and class-changed.
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 15 Jul 87  10:00:19 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Wed, 15 Jul 87 09:58:27 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Wed, 15 Jul 87 09:58:07 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Wed, 15 Jul 87 10:58:34 pdt
Message-Id: <8707151658.AA08774@hplabsz.hpl.hp.com>
To: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
Cc: Danny Bobrow <Bobrow.pa@XEROX.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class redefinition and class-changed.
In-Reply-To: Your message of Fri, 10 Jul 87  10:00:21 CDT.
             <2761916421-9049515@Jenner>
Date: Wed, 15 Jul 87 10:58:31 -0700
From: kempf%hplabsz@hplabs.HP.COM

>     GET-OBSOLETE-VERSION class
>      returns the preceding obsolete version of this class, or NIL if none.
>     This allows users to define methods at any time on the obsolete class.
>     Obsolete classes themselves may also have an obsolete-version.  Obsolete
>     classes also respond to

Is this meant to imply that there can be multiple versions of classes
floating about? If so, then perhaps class versioning needs to be
investigated more closely.

			Jim Kempf	kempf@hplabs.hp.com


∂16-Jul-87  0752	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 16 Jul 87  07:52:13 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab01711; 16 Jul 87 10:24 EDT
Received: from ti-csl by RELAY.CS.NET id ac00916; 16 Jul 87 10:17 EDT
Received: from Jenner by tilde id AA07022; Thu, 16 Jul 87 08:00:48 CDT
Message-Id: <2762427556-15862063@Jenner>
Date: Thu, 16 Jul 87  07:59:16 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class redefinition and class-changed.
In-Reply-To: Msg of Wed, 15 Jul 87 10:58:31 -0700 from kempf%hplabsz@hplabs.hp.com

     
     >     GET-OBSOLETE-VERSION class
     >      returns the preceding obsolete version of this class, or NIL if none.
     >     This allows users to define methods at any time on the obsolete class.
     >     Obsolete classes themselves may also have an obsolete-version.  Obsolete
     >     classes also respond to
     
     Is this meant to imply that there can be multiple versions of classes
     floating about? If so, then perhaps class versioning needs to be
     investigated more closely.
     
I am not sure I agree with the term VERSION.  An obsolete class object
is not a version of the class because it is here just to support the
class-changed protocol.  It is not meant to have permanent instances.
Surrogate might be more appropriate.  In the sense there can only be
instances of "current class" outside of the execution of CLASS-CHANGED,
I don't think we need to worry about class versioning.

Patrick.

∂22-Jul-87  0639	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Category Errors    
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 22 Jul 87  06:39:08 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa18126; 22 Jul 87 9:35 EDT
Received: from ti-csl by RELAY.CS.NET id ab14379; 22 Jul 87 9:31 EDT
Received: from Jenner by tilde id AA23150; Wed, 22 Jul 87 07:33:54 CDT
Message-Id: <2762944528-5369042@Jenner>
Date: Wed, 22 Jul 87  07:35:28 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Category Errors    
In-Reply-To: Msg of 08 Jul 87  0938 PDT from Dick Gabriel <RPG@sail.stanford.edu>

From Gabriel:
     
     One minor point that came up at the Symbolics meeting last Thursday
     was category errors and whether we should try to outlaw them somehow.
     Here is an example of a category error:
     
     Suppose that MAKE-INSTANCE is a generic function. Its definition
     might look like this:
     
     	(defmethod make-instance ((class standard-class) &rest args)...)
     
     Notice that the class of the argument CLASS is STANDARD-CLASS, which
     indicates that the operation of MAKE-INSTANCE is controlled at the
     meta-object level. Suppose someone were to write:
     
     	(defmethod make-instance ((class apple-pie) &rest args)...)
     
     	(make-instance (class-prototype (class-named 'apple-pie)) ...)
     
     Here someone would be making a category error by defining a method on
     MAKE-INSTANCE at the wrong level - the class level. What makes this easy
     for a programmer to do this is the availability of CLASS-PROTOTYPE.
     However, it is never hard to do because the programmer can write:
     
     	(defvar *apple-pie-prototype* (make-instance 'apple-pie))
     
     to get his class prototype. 
     
     We have two alternatives:
     
     	1. Let sea of classes/metaclasses remain a miasma and inform
     	   programmer that he ought not mix things up.
     
     	2. Define a notion of class category or classs level and have a
     	   category of generic function for each class category.
     

From Ken Kahn:

      I think it would be a mistake to build barriers between class and
      metaclass protocols.  One of the strong appeals of CLOS is that one can
      experiment within its framework.  We once worked out how Object Lisp's
      view that classes and instances are pretty much the same could be
      implemented in PCL.  A good fraction of the OOP community believes in
      these "prototypes" which unify classes and instances.  We should be
      careful not to prohibit CLOS from evolving in that direction if people
      come to believe its a win.

I kind of agree with both Dick's and ken's concerns.  The user should be
able to do metaclass programming if he wants to but this should be an
intent, not an accident.  CLASS-PROTOTYPE working for standard-classes
is a good example of something intended to be used for metaclass
programming but works also for non metaclass classes.

I propose the following in order to categorize metaclass programming and
class programming:


                      CLASS

                        |

                  STANDARD-CLASS

                        |

                  METACLASS-CLASS


Now, all metaclass objects are instances of METACLASS-CLASS instead of
STANDARD-CLASS. This is to say that standard-class can be defined like:

(defclass STANDARD-CLASS (CLASS) 
   <slots>
   (:metaclass METACLASS-CLASS))

STANDARD-CLASS does not support metclass specific methods like 
CLASS-PROTOTYPE, METACLASS-CLASS does.

Somebody defining a new metaclass (or wanting to do metaclass
programming with his objects) will use METACLASS-CLASS as metaclass. It
will be a conscious decision.

The make-instance problem still exists but will not arise by accident,
somebody will have to do a trick like:
(defvar *apple-pie-prototype* (make-instance 'apple-pie))
and will probably get what he deserves. 

Patrick.

∂22-Jul-87  1014	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Category Errors        
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Jul 87  10:13:59 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 196114; Tue 21-Jul-87 12:35:38 EDT
Date: Tue, 21 Jul 87 12:35 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Category Errors    
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 8 Jul 87 12:38 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870721123511.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 08 Jul 87  0938 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Suppose that MAKE-INSTANCE is a generic function. Its definition
    might look like this:

	    (defmethod make-instance ((class standard-class) &rest args)...)

    Notice that the class of the argument CLASS is STANDARD-CLASS, which
    indicates that the operation of MAKE-INSTANCE is controlled at the
    meta-object level. Suppose someone were to write:

	    (defmethod make-instance ((class apple-pie) &rest args)...)

I don't think this is fundamentally different from someone defining
a method on spaceships for a generic function that is only supposed to
be used with windows.  The only reason I can see that confusion between
classes and metaclasses seems worse than confusion between spaceships
and windows is that metaclasses are less familiar.

If we didn't want to follow the usual Lisp philosophy of giving the
user enough rope to hang himself, we could add a feature such as the
following

  (defgeneric-options make-instance (class &rest initargs)
    (:parameter-specializer-restriction class (or class symbol)))

which says methods can't be defined with a parameter specializer for
the first parameter (named class) that isn't a subtype of (or class symbol).
Using the type system to express the restriction, rather than inventing
a new concept of levels, seems both more general and easier to understand.
However, I don't really think we want to add this kind of restriction, at
least, it wouldn't be consistent with the minimalist design criterion
we have used elsewhere in CLOS.

∂23-Jul-87  1812	Gregor.pa@Xerox.COM 	initialization meeting notes 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jul 87  18:12:34 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 23 JUL 87 18:11:32 PDT
Date: Thu, 23 Jul 87 18:09 PDT
From: Gregor.pa@Xerox.COM
Subject: initialization meeting notes
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870723180901.2.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no


In this message I try to summarize what we agreed at the meeting in
Boston.  The basis for this message is the 4 pages of notes which Sonya
took and which Sonya, Dave and I went over just before the meeting
ended.  I have tried to include in this message only what we actually
agreed on.  I will send out my comments and suggestions in a separate
message.


First, a brief summary of what we agreed:

 -  there will be a :initarg slot option

 -  will will support remote initarg defaulting by having an
    defclass option like :default-initargs.

 -  there will be a procedural model of how the whole thing
    works.  Extensions to initialization behavior other than
    simple-slot-filling-initargs and initarg-remote-defaulting
    will be done by defining a method on the appropriate generic
    function.


Another important thing which we agreed is that we are going to have to
go back and re-examine our rules for argument list congruence.  The
existing rules clearly get in our way for doing initialization.  In a
separate message I will try to summarize those problems.


In the meeting, we put up some code for make-instance and
initialize-instance.  I am including that here:

(defmethod make-instance ((class-name 'symbol) &rest initargs)
  (apply #'make-instance (class-named class-name) initargs))

(defmethod make-instance ((class standard-class) &rest initargs)
  (let* ((proto (class-prototype class))
	 (defaulted-initargs (default-initargs proto initargs)))
    (check-initargs class defaulted-initargs)
    (let ((instance (apply #'allocate-instance class defaulted-initargs)))
      (apply #'initialize-instance instance defaulted-initargs)
      instance)))


(defmethod initialize-instance ((obj object) &rest initargs)
  ;; The default initialize-instance method deals with setting the
  ;; values of slots from slot-filling-initargs and from initforms.
  ;;
  ;; The rules are that the leftmost initarg which is declared
  ;; as setting a slot (with the :initarg slot option) actually
  ;; does set it (or is it the rightmost?); and that slots which
  ;; are not set by an initarg have their :initform evaluated and
  ;; used to set them.
  )

An effect of putting the slot setting stuff in the default method on
initialize-instance is that most programmers will want to define their
initialize-instance methods as :after methods.  This means an instance
will get initialized in order from most general to least general.


The default method for default-initargs implements the initarg remote
defaulting behavior using the :default-initargs class option.

The default method for check-initargs checks the validity of the
initargs by checking two sources:
  1. an initarg is valid if it is specified as a slot-filling initarg.

  2. an initarg is valid if it is specified as a &key argument in
     one of the applicable methods on initialize-instance.


Here is an example of a use of this protocol:

(defclass ship ()
    ((x :initarg :x)
     (y :initarg :y)))

(defmethod initialize-instance :after ((s ship) &key startp)
  (when startp (start s)))

(defmethod start ((s ship))
  (with-slots ((s :use-accesors nil))
    (if (and x y)
        <start it up>
        (error "Have to set X and Y before starting a ship."))))


(defclass homing-ship (ship)
    ()
  (:default-initargs 
     :x 0
     :y 0))

(defmethod home ((s homing-ship))
  (with-slots ((s :use-accessors nil))
     (setq x 0 y 0)))



We also agreed that there would be documented functions for finding out
about the initargs that set slots for a class and also finding out about
the default initargs for a class.   This doesn't seem to be too hard;
the only serious problem has to do with arranging for a the default
initarg value forms to be evaluated in the lexical environment of the
defclass. (Of course if environments were first class objects this would
be trivial...)
-------

∂23-Jul-87  1917	Bobrow.pa@Xerox.COM 	Re: Category Errors     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jul 87  19:16:29 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 JUL 87 19:16:02 PDT
Date: 23 Jul 87 19:15 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Category Errors    
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 21 Jul 87 12:35 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870723-191602-1486@Xerox>

    I don't think this is fundamentally different from someone
    defining a method on spaceships for a generic function that is only
    supposed to be used with windows.  The only reason I can see that
    confusion between classes and metaclasses seems worse than
    confusion between spaceships and windows is that metaclasses are
    less familiar.

I think this is exactly right.
    If we didn't want to follow the usual Lisp philosophy of giving
    the user enough rope to hang himself,

Leave the rope.  We don't put strong typing in Lisp either.
  danny

∂23-Jul-87  1941	Bobrow.pa@Xerox.COM 	Re: Class redefinition and class-changed.   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 23 Jul 87  19:41:29 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 23 JUL 87 19:41:10 PDT
Date: 23 Jul 87 19:41 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Class redefinition and class-changed.
In-reply-to: Patrick H Dussud <DUSSUD%Jenner@ti-csl.CSNET>'s message of
 Fri, 10 Jul 87 10:00:21 CDT
To: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net
cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870723-194110-1523@Xerox>

         The necessary and sufficient condition for this is to
         be able to get hold of an obsolete version of a class.  

    I don't agree.  We said in chapter 1 that the updating of the
    instances is done at an implementation-dependent time.  

I agree that your arguments imply your conclusion.  I think however,
that it would be better to say that "updating of the
instances is done at an implementation-dependent time sometime after the
class is redefined."   Since this is really an environment support
feature, I think we should specify that it will not occur before the
first method on an obsolete instance is called.  
  danny

∂24-Jul-87  0623	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Jul 87  06:23:14 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa05351; 24 Jul 87 9:23 EDT
Received: from ti-csl by RELAY.CS.NET id aa06359; 24 Jul 87 9:16 EDT
Received: from Jenner by tilde id AA01610; Fri, 24 Jul 87 07:33:49 CDT
Message-Id: <2763117294-15749125@Jenner>
Date: Fri, 24 Jul 87  07:34:54 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Danny Bobrow <Bobrow.pa@XEROX.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class redefinition and class-changed.
In-Reply-To: Msg of 23 Jul 87 19:41 PDT from Danny Bobrow <Bobrow.pa@xerox.com>

     
     I agree that your arguments imply your conclusion.  I think however,
     that it would be better to say that "updating of the
     instances is done at an implementation-dependent time sometime after the
     class is redefined."   Since this is really an environment support
     feature, I think we should specify that it will not occur before the
     first method on an obsolete instance is called. 

I see two problems with this approach:

- How would the environment guess that a class-changed method will (or will not)
be defined?

- Even if you see it as an environment support, we need to specify this support
at the metaclass level since class redefinition will be specified. I don't think
we can afford to leave holes like that in the metaclass protocol.

Patrick.

∂24-Jul-87  0854	Bobrow.pa@Xerox.COM 	Re: Class redefinition and class-changed.   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 24 Jul 87  08:54:27 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUL 87 08:51:47 PDT
Date: 24 Jul 87 08:48 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Class redefinition and class-changed.
In-reply-to: Patrick H Dussud <DUSSUD%Jenner@ti-csl.CSNET>'s message of
 Fri, 24 Jul 87 07:34:54 CDT
To: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net
cc: Bobrow.pa@Xerox.COM, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870724-085147-2517@Xerox>

         I think we should specify that instance updating will
         not occur before the first method on an obsolete instance is
         called. 

    I see two problems with this approach:

    - How would the environment guess that a class-changed method
    will (or will not) be defined?

It doesn't have to guess.  If the class changed method is defined before
any any method is called on an obsolete instance, it will be used.
Otherwise not.  Hence users should define such class-changed methods
immediately (soon) after redefining the class. 

    - Even if you see it as an environment support, we need to
    specify this support at the metaclass level since class
    redefinition will be specified. I don't think we can afford to
    leave holes like that in the metaclass protocol.

The meta-object support necessary is to provide a mechanism to obtain
the obsolete class so that class-changed methods can be defined, and to
specify when these methods can be defined in order to effect all
instances that need to be updated.  
  danny

∂24-Jul-87  1133	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Category Errors    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jul 87  11:33:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198616; Fri 24-Jul-87 14:34:24 EDT
Date: Fri, 24 Jul 87 14:33 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Category Errors    
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <2762944528-5369042@Jenner>
Message-ID: <870724143345.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 22 Jul 87  07:35:28 CDT
    From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>

    ....
    I propose the following in order to categorize metaclass programming and
    class programming:


			  CLASS

			    |

		      STANDARD-CLASS

			    |

		      METACLASS-CLASS


    Now, all metaclass objects are instances of METACLASS-CLASS instead of
    STANDARD-CLASS. This is to say that standard-class can be defined like:

    (defclass STANDARD-CLASS (CLASS) 
       <slots>
       (:metaclass METACLASS-CLASS))

I believe this is a good suggestion.  That is, it appeals to my aesthetic
sense, although I have not been able to come up with any specific programming
activities that require it.

    STANDARD-CLASS does not support metaclass specific methods like 
    CLASS-PROTOTYPE, METACLASS-CLASS does.

This part, however, won't work.  As I understand it, CLASS-PROTOTYPE has
to work on all classes, because of the way the generic function dispatching
in the initialization protocol is going to work.  We still haven't nailed
down the initialization protocol, but I think the part of it we all seem
to agree on already requires all classes to have a prototype.

Similarly, functions like CLASS-DIRECT-SUPERCLASSES are part of metaclass
programming, but that doesn't mean they are only applicable to metaclasses.
They are applicable to all classes.

∂24-Jul-87  1136	RPG  	Category Errors    
To:   Common-lisp-object-system@SAIL.STANFORD.EDU    

Moon writes:

``I don't think this is fundamentally different from someone defining a
method on spaceships for a generic function that is only supposed to be
used with windows.''

Danny replies:

``I think this is exactly right.''

As I mentioned in my note, I don't care that this blemish appears in CLOS,
but I do insist that we understand that reasonable people will consider it
to be a blemish. The reason for this is also the reason that Danny's reply
is incorrect. The differences between someone writing a method on
spaceships for a generic function that is only supposed to be used with
windows and someone writing a method on a base-level class for the generic
function MAKE-INSTANCE are these:

	1. MAKE-INSTANCE is a generic function defined in CLOS, and we
	   have the ability to enforce the user not making this sort of
	   error.  We've carefully laid out, in most cases, the range of
	   legal arguments to functions and generic functions in CLOS; we
	   could easily do that here, whereas it's difficult to control a
	   user who wants to act irrationally with code all of his own
	   invention.

	2. Mistakenly writing methods for some class not intended to be
	   the subject of the generic function by the author of that
	   generic function is most likely a user-level semantic error,
	   while defining a method on a class where the person defining
	   the generic function intends methods to be on meta-classes is a
	   category error - that's why I called it a ``category error''
	   rather than a ``source of potential user bugs.'' The error lies
	   in confusing two levels of classes defined in CLOS rather than
	   in confusing two classes defined by a user.

My point was that one could rationally design CLOS to be able to
distinguish between classes and meta-classes, and hence we would be
justified in trying to prevent category errors. Or we could choose not to
do that. I think that to dismiss the point as some fluke in thought
process before understanding the issues does ill justice to the
specification process, even though I believe we will allow the blemish.

			-rpg-

∂24-Jul-87  1420	Bobrow.pa@Xerox.COM 	Re: Category Errors     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 24 Jul 87  14:20:00 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUL 87 14:19:44 PDT
Date: 24 Jul 87 14:19 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Category Errors    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 24 Jul 87
 11:36 PDT
To: RPG@SAIL.STANFORD.EDU
cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870724-141944-3247@Xerox>

    My point was that one could rationally design CLOS to be able
    to distinguish between classes and meta-classes, and hence we would
    be justified in trying to prevent category errors.

If it were clear that one could be sure that a definition were in error,
then perhaps we could consider enforcing some restrictions.  However, it
is a rational thing to experiment with various new types of object
system, defining methods for all the protocol of interest, and not use
any preexisting class as a super-class (this is particularly a good idea
if one wants to make sure that the new implementation is complete).  To
force a user to use a particular (perhaps empty) metaclass just for a
declaration surely violates the spirit of Lisp.

	   We've carefully laid out, in most cases, the range of
	   legal arguments to functions and generic functions in CLOS; we
	   could easily do that here, whereas it's difficult to control a
	   user who wants to act irrationally with code all of his own
	   invention.
We have NOT laid out the range of legal arguments for generic functions.
We have specified how they behave for arguments of particular classes;
tha is, we have described some method(s) on generic functions, and their
contract.  A major point of object oriented programming is to allow
users to add their own methods to generic functions.  To talk about THE
AUTHOR OF A GENERIC FUNCTION is to make the same mistake.  Generic
functions have certain contracts, but not ones that restrict them to
certain classes of arguments.
  
    I think that to dismiss the point as some fluke in thought
    process before understanding the issues does ill justice to the
    specification process, even though I believe we will allow the
    blemish.

I think understanding the issue is important.  So we agree on that
point.  But I feel that the "blemish" is really a beauty mark.

danny

∂24-Jul-87  1421	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Jul 87  14:21:16 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa10495; 24 Jul 87 17:10 EDT
Received: from ti-csl by RELAY.CS.NET id al08816; 24 Jul 87 17:04 EDT
Received: from Jenner by tilde id AA14079; Fri, 24 Jul 87 15:14:43 CDT
Message-Id: <2763144693-1137879@Jenner>
Date: Fri, 24 Jul 87  15:11:33 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Danny Bobrow <Bobrow.pa@XEROX.COM>
Cc: DUSSUD%Jenner%ti-csl.CSNet@RELAY.CS.NET, 
    common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class redefinition and class-changed.
In-Reply-To: Msg of 24 Jul 87 08:48 PDT from Danny Bobrow <Bobrow.pa@xerox.com>

     Date: 24 Jul 87 08:48 PDT
     From: Danny Bobrow <Bobrow.pa@xerox.com>
     Subject: Re: Class redefinition and class-changed.
     
     It doesn't have to guess.  If the class changed method is defined before
     any any method is called on an obsolete instance, it will be used.
     Otherwise not.  Hence users should define such class-changed methods
     immediately (soon) after redefining the class. 
     
In multiprocessing or interruptible environment, immediately is a weak
concept at best.  You might get in a race condition with another
computation unit that touches instances.  Furthermore, you can't prove
that some instances haven't been updated before you define the
changed-class method. How do you propose to solve this?

Patrick.

∂24-Jul-87  1427	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Category Errors    
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Jul 87  14:22:08 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ah10487; 24 Jul 87 17:10 EDT
Received: from ti-csl by RELAY.CS.NET id am08816; 24 Jul 87 17:04 EDT
Received: from Jenner by tilde id AA14334; Fri, 24 Jul 87 15:24:33 CDT
Message-Id: <2763145381-1179246@Jenner>
Date: Fri, 24 Jul 87  15:23:01 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Category Errors    
In-Reply-To: Msg of Fri, 24 Jul 87 14:33 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

         STANDARD-CLASS does not support metaclass specific methods like 
         CLASS-PROTOTYPE, METACLASS-CLASS does.
     
     This part, however, won't work.  As I understand it, CLASS-PROTOTYPE has
     to work on all classes, because of the way the generic function dispatching
     in the initialization protocol is going to work.  We still haven't nailed
     down the initialization protocol, but I think the part of it we all seem
     to agree on already requires all classes to have a prototype.
     
This is true, I forgot about it when I wrote this part.

Patrick.

∂24-Jul-87  1436	Moon@STONY-BROOK.SCRC.Symbolics.COM 	initialization meeting notes
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jul 87  14:36:38 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198754; Fri 24-Jul-87 16:44:25 EDT
Date: Fri, 24 Jul 87 16:43 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: initialization meeting notes
To: Gregor.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870723180901.2.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <870724164346.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

There's a bunch of other stuff in the notes that didn't make it into
your message.  Perhaps I'll send a summary of that in a later message,
but the most important thing right now from my point of view was a
statement (page 4) about open-coding which I think means that the
procedural model is to be done in such a way that it does not decrease
achievable performance of creating instances; in particular, the system
is allowed to recognize that the standard methods are being called for
make-instance of a particular class and use a different implementation
that produces equivalent results.  This will have to be defined in more
precise language in the final specification, so that it is quite clear
what users can and cannot depend on.

∂24-Jul-87  1437	Moon@STONY-BROOK.SCRC.Symbolics.COM 	First Try at Terminology    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 24 Jul 87  14:36:59 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198777; Fri 24-Jul-87 17:02:52 EDT
Date: Fri, 24 Jul 87 17:02 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: First Try at Terminology
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 8 Jul 87 12:28 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870724170213.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

I might quibble with one or two details, in particular the idea that it
is possible to prevent programmers from discovering and depending upon
what a particular implementation does in a particular undefined
situation, however on the whole this seems pretty good.  I'd like to
see the terminology for erroneous situations tightened up for all of
Common Lisp, not just CLOS.

I don't think that it's the business of the CLOS subcommittee to do this.
In other words, I'm uncomfortable with the idea that "the CLOS
subcommittee of X3J13 is the only subcommittee that ever does anything"
(incidentally this is not quite true) implies that "the CLOS
subcommittee should do everything."

We can use a working terminology in our deliberations, but we should
be prepared to convert to whatever standard terminology is defined for
Common Lisp as a whole, when that happens.  This suggests that we should
do something fairly simple and not develop an elaborate formalism.
Simply separating the cases of "an error is always signalled", "an error
is signalled unless you tell the compiler not to check for it", "the
effect is undefined", and "the effect is implementation-dependent"
seems sufficient to me.

∂24-Jul-87  1459	RPG  	Category Errors    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

Danny says:

``We have NOT laid out the range of legal arguments for generic functions.''

My comment was:

``We've carefully laid out, in most cases, the range of legal arguments to
functions and generic functions in CLOS....''

I guess I shouldn't rely on subtle wording to get across a subtle point.
Here is a generic function ``in CLOS'':

	Add-method generic-function method

And here is how we have ``carefully laid out ... the range of legal
arguments'' to it:

	Arguments:

	The generic-function argument is a generic function
	object.

	The method argument is a method object.  The
	lambda-list of the method function must be
	congruent with the lambda-lists of any other
	methods associated with the generic function and
	with the lambda-list of the generic function.

		(page 2-5, FUNCTIONS)

The thing in CLOS that is already the same sort of ``blemish'' as this
category error is discrimination on individuals. Blemish, beauty mark:
At least we can agree that in both cases an observer is justified in
thinking ``what's that thing?''

			-rpg-

∂24-Jul-87  1645	RPG  	Class Redefinition 
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

The problem with class redefinition is that the updating of instances can
be caused by arbitrary events, as far as the user is concerned. If none of
DEFCLASS, ADD-METHOD, MAKE-METHOD, CLASS-NAMED, the evaluation of the
special form FUNCTION, and garbage collection can update instances, then
if a CLOS implementation does not have multitasking, the following will
work (or something like it):

	(let ((obsolete-class (class-named 'heh-heh)))
         (defclass heh-heh ...)
         (add-method 
          #'class-changed
	  (make-method	;later, make-instance
           ()
           `(,obsolete-class ,(class-named 'heh-heh))
	   #'...)))

If there is a CLOS implementation with all of the properties named
above except it does have multitasking (including incremental GC),
then some form or macro like ATOMICALLY wrapped around the above
will work.

Something like this should work:

(let
 ((obsolete-class (class-named 'heh-heh))
  (new-class (make-instance 'standard-class ...))) ;make an anonymous class
                                                   ;that is the new HEH-HEH
 (add-method 
  #'class-changed
  (make-method	;later, make-instance
   ()
   `(,obsolete-class ,new-class)
   #'...))
 (name-that-class new-class 'heh-heh))             ;Hm, what is this function?

I think, though, that it probably makes sense to have Danny's version
of GET-OBSOLETE-CLASS for the same reason that I don't like UNIX - it's
too easy to do a DEFCLASS of an existing class and then wish you
had a handle on the old one. I think we need to decide whether Patrick's
versions of getting obsolete classes are worth having around to simplify
life.

I think we forgot to define NAME-THAT-CLASS. It should be the thing such
that MAKE-INSTANCE + (<the thing> <name>) = (DEFCLASS NAME ...).

			-rpg-

∂25-Jul-87  0719	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Category Errors        
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 25 Jul 87  07:19:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198981; Fri 24-Jul-87 22:34:00 EDT
Date: Fri, 24 Jul 87 22:33 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Category Errors    
To: Common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 24 Jul 87 14:36 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870724223320.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

As a believer in open systems who doesn't think there should be distinctions
between system and user programs, I believe that Dick's arguments for defense
against defining bogus methods for MAKE-INSTANCE are equally as good
arguments for defense against defining bogus methods for any user-defined
generic function.  Remember that not all user-written programs are used only
by their author.

Dick, would you agree that if CLOS removes this blemish, it should be done
with a mechanism that is easily accessible to the programmer-in-the-street?

My second point was that although I favor removing this blemish, CLOS currently
contains several other similar blemishes added in the name of simplicity
(example, no equivalent to Flavors' :required-methods defflavor option), so
I predict that we will end up leaving this blemish in.  That's not an argument,
just an observation.

∂25-Jul-87  0720	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Class redefinition and class-changed. 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 25 Jul 87  07:20:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198991; Sat 25-Jul-87 01:27:15 EDT
Date: Sat, 25 Jul 87 01:26 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Class redefinition and class-changed.
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <2761765326-16486571@Jenner>,
             <870709-115412-4166@Xerox>,
             <2761916421-9049515@Jenner>,
             <8707151658.AA08774@hplabsz.hpl.hp.com>,
             <2762427556-15862063@Jenner>,
             <870723-194110-1523@Xerox>,
             <2763117294-15749125@Jenner>,
             <870724-085147-2517@Xerox>,
             <2763144693-1137879@Jenner>
Message-ID: <870725012629.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

I have several comments to offer on this conversation.  I haven't managed
to organize the separate comments into as coherent a whole as I would like.

I believe Patrick's argument that it is necessary to define the
CLASS-CHANGED method -before- redefining the class.  Symbolics has a lot of
experience with doing it the other way and it's unpleasant.  I hope the
reasoning for this has been established now and doesn't need additional
argument (Danny, please speak up if you don't believe it yet).

I don't like Patrick's particular proposal, though.
GET-OBSOLETE-CLASSES-FOR-REDEFINITION is too complicated, because it
returns a whole alist rather than being just the primitive.  In addition, I
don't think the set of "classes implicated in the class-redefinition of
CLASS" is computable until the details of the redefinition are known.
Suppose
  (defclass one () (a b))
  (defclass two (one) (c))
  (defclass three (one) (d))
Now suppose we redefine one as follows:
  (defclass one () (a b d))
Referring to the third paragraph on page 1-11 of 87-002, one and two are
"implicated", but three is not, or at least, whether three is implicated is
implementation-dependent.  But if the new slot had been named e, both two
and three would have been implicated.  I don't think the information in
Patrick's alist is needed anyway; when defining a method, one only defines
it for the obsolete class corresponding to one class.  If a different
method needs to be defined for an obsolete subclass, the function can be
called again.

Thus I would replace Patrick's proposal with GET-OBSOLETE-CLASS-FOR-REDEFINITION
which takes one argument, a class, and returns one value, the obsolete class
that is a copy of the current definition of the class and will be used the next 
time the class is redefined; this is created the first time you ask for it.
Perhaps GET-OBSOLETE-CLASS-FOR-NEXT-REDEFINITION would be a better name.

As Danny proposed, a primitive to get the obsolete classes corresponding to
redefinitions that have already taken place is useful, for instance in case
you didn't realize ahead of time that you would need a CLASS-CHANGED method
and now want to patch up the program.  I would suggest a function
GET-OBSOLETE-CLASSES-FOR-PAST-REDEFINITIONS which takes one argument, a
class, and returns one value, a list of obsolete classes, newest first.

There seems to be some confusion about how class redefinition works in CLOS
and what an "obsolete class" is.  Let me restate what the 87-002 document
says in simpler language:  Redefining a class never creates a new class
object to replace the existing class object; it always modifies the
existing class object.  Thus there are no objects that exactly represent
"versions" of a class.  There is also the concept of "obsolete instances",
which have dynamic extent and are created solely to pass as the first
argument to CLASS-CHANGED.  When CLASS-CHANGED is called as a result of the
user calling CHANGE-CLASS, the obsolete instance is simply an instance of
the old class.  When CLASS-CHANGED is called as a result of updating an
instance to reflect the latest definition of its class, the obsolete
instance contains the slot values of the un-updated instance and therefore
needs to have a class that has those slots: this is an "obsolete class".
An obsolete class is a copy of a class remembering the slots, methods, and
superclasses it had before it was redefined.  Redefining a class only
creates an obsolete class when certain kinds of changes are made to the
class (see the third paragraph on page 1-11 of 87-002).  For each past
version of a class that is sufficiently different from the current version,
there is an obsolete class object.  Note that these are all obsolete versions
of the original class, they are not obsolete versions of each other.

Redefining a class also redefines subclasses of the class, so several
obsolete classes could be created.  87-002 doesn't say so, but I believe
the obsolete subclasses should be subclasses of the obsolete class and not
of the original class.

The second paragraph on page 1-12 of 87-002 could be interpreted as saying
that the only methods that are applicable to an obsolete instance I-sub-O
are the methods M-sub-C that were deleted from the class when it was
redefined.  I do not believe this is what was intended--I believe we
intended to say that all methods that were applicable to instances of the
class before it was redefined are applicable to I-sub-O (unless additional
redefinitions have been done, for instance deleting those methods
entirely).  If we really intended only deleted methods to be applicable, it
would be remarkably useless: for instance, deleted slots could be accessed
by normal means, but non-deleted slots could not be accessed except by
SLOT-VALUE, except in the case where the :ACCESSOR slot-option had been
removed.  Again, in the x-y-rho-theta example, if methods for accessing
values that are conceptually slots but are not physically represented as
slots were not applicable, it would be necessary to violate modularity and
duplicate the functionality of those methods within the CLASS-CHANGED
method.

We have our choice of three ways to define what happens when a class is
redefined:
(1) A new class object is created, the name-to-class-object mapping is
changed, defclass-defined methods implied by the new definition are put on
the new class object, all methods other than defclass-defined methods that
apply to the old class are made to apply also to the new class, subclasses
of the old class are made to be subclasses of the new class instead, and
superclasses of the old class are made to be also superclasses of the new
class.  If we had done this, there would have been an explicit
representation of versions of a class, and there would not have been any
concept of "obsolete classes."
(2) The old class object is modified, defclass-created methods that aren't
created by the new defclass are removed, new defclass-created methods are
added, an anonymous obsolete class object is created, the modification is
propagated to subclasses which may create obsolete class objects for them
that are subclasses of the first obsolete class created, superclasses of
the original class are to be also superclasses of the obsolete class, and
all methods that applied to the original class are made to apply also to
the new class.  (2) is what we did in 87-002.  (2) is not simpler than (1),
but it has the advantage that classes maintain their identity as objects.
(3) There is a third way, which I will describe later in this message.

Referring again to the third paragraph on page 1-11 of 87-002, there is
another use for a primitive to get the obsolete class before redefining the
class.  Not all redefinitions of a class call CHANGE-CLASS and
CLASS-CHANGED.  Suppose someone changes a class in such a way that they
need to call a function to update each instance, but they have not actually
add, removed, or renamed slots.  87-002 does not provide any mechanism for
this.  The programmer would probably resort to adding a dummy slot to force
instance updating.  I think a better approach would be to specify that
calling GET-OBSOLETE-CLASS-FOR-NEXT-REDEFINITION forces the next
redefinition of this class (directly or by redefining a superclass) to
update instances, even if it would not otherwise need to.

There are basically three approaches to the problem of writing a
CLASS-CHANGED method that updates an instance to reflect one particular
edit of the class's definition:
(1) Use the classes of the two arguments to CLASS-CHANGED to encode this
information.  This is what the 87-002 document says, however it doesn't work.
(2) Use a third argument to CLASS-CHANGED to encode the information, such as
a sequence number saying how many times the class had been redefined.  This
seems kludgey and was rejected in the past.
(3) Don't allow such precise control over instance updating in CLOS, instead
only allow CLASS-CHANGED methods that work for updates from -any- version of
the class to the current version.  This is copping out, however it's practical,
since it's what Flavors does.

There are two reasons (1) doesn't work.  First, 87-002 doesn't provide a way
to get the obsolete class for a particular edit, which you need in order to
define a method that applies specifically to that edit.  This is what Patrick's
proposal addresses.  Second, there is a problem when the class is redefined
multiple times.  Suppose we do
  (defclass foo () (a))
  (defclass foo () (a b))
  (defclass foo () (a b c))
  (defclass foo () (a b c d))
and in connection with the third definition we need a CLASS-CHANGED method
to initialize the slot C.  We don't want this method to be called for
instances that already have a slot C and are getting a slot D added, so we
want the method to specialize its first parameter as well as its second.
The problem is that CLOS has no way to define one method that applies to the
first and second obsolete classes, but not to the third obsolete class.  In
order to define this method, we have to know the exact editing history of
the class FOO, which seems unreasonable.  We can't fix this by making the
second obsolete class a subclass of the first obsolete class, because if
the user removes a slot we would have a class that has fewer slots than its
superclass, which CLOS does not allow.  We could call
GET-OBSOLETE-CLASSES-FOR-PAST-REDEFINITIONS to get the entire list of
obsolete classes for the class FOO, and then we could iterate over that
list seeing which obsolete classes had a slot C and which didn't, and
define CLASS-CHANGED methods accordingly, but this starts to look like an
elaborate rigamarole for something that should have been simple.

The above assumes that we believe what page 1-12 of 87-002 implies, namely
that instances are updated directly to the latest version of the class
("the second argument is an instance of the class C").  Alternatively, we
could specify that "ontogeny recapitulates phylogeny" and the instance is
repeatedly updated one step at a time, until it reaches the current
definition of its class.  In the FOO example above, we would define the
CLASS-CHANGED method that initializes C to specialize its first parameter
to the second obsolete class, with confidence that instances of the
original FOO would first get a slot B, then would get a slot C, then would
get a slot D, and in the second of the three steps, our method would be
called.

This means that -both- arguments to CLASS-CHANGED could be instances of
obsolete classes.  It also means that our CLASS-CHANGED method can't
specialize its second parameter, because at first that will be the class
FOO, but after FOO is redefined again, it will be an obsolete class.  If we
don't specialize the second parameter, it seems we could be confused by
CLASS-CHANGED being called when CHANGE-CLASS was used to change an instance
of FOO into an instance of BAR.  This is not a problem if CHANGE-CLASS,
like all other generic functions, first updates its argument to the latest
definition of its class, before changing it to the new class; then a method
specialized to an obsolete class in its first parameter can never be called
with the second parameter an instance of anything other than the next newer
version of the same class.  This all seems slightly kludgey, but does seem
like it should work.

Is there any chance of garbage collecting all these obsolete classes when
there are no longer any instances that haven't been updated yet?  We'd also
like to garbage collect the data structures required to make methods
applicable to the original class also applicable to the obsolete class.
I doubt it's possible to GC this stuff, the whole data structure seems too
interconnected.

The third way to define what happens when a class is redefined, mentioned
earlier, is as follows:  Don't try to use CLASS-CHANGED for both changing
the class of an instance and updating an instance to a new version of its
class.  Invent a new generic function CLASS-REDEFINED, which is called when
an instance is updated to a new version of its class.  This avoids the
complicated concept of "obsolete classes", at the cost of conveying the
former state of the instance in a less object-oriented fashion.  Perhaps
CLASS-REDEFINED would receive three arguments: an instance of the class,
already updated to the latest definition of the class, a property list
associating slot names to slot values, with one entry for each slot that is
no longer present, and a list of slot names of slots that were newly added
to the instance.  Thus when a class is redefined:
(3) The old class object is modified, defclass-created methods that aren't
created by the new defclass are removed, new defclass-created methods are
added, and the modification is propagated to subclasses.  This is simpler
than (1) or (2).

The FOO example given above is implemented by defining a CLASS-REDEFINED
method that checks whether slot C is a new slot before initializing it.
The problem is that there can only be one CLASS-REDEFINED method, since
there is only one class object, so if the class is redefined multiple times
in ways that need CLASS-REDEFINED methods, this one method must contain
unmodular knowledge of all the redefinitions.  In addition, in the
x-y-rho-theta example, if there are methods for accessing values that are
conceptually slots but are not physically represented as slots, the
CLASS-REDEFINED method has to know about the underlying slots used by
these methods, in case those slots have been deleted.

This "third way" seems simpler than the other two, so I hope that someone
can debug the problems mentioned in the previous paragraph.  If not, we
need to make several changes mentioned here and there in this message in
order to make obsolete classes work.

∂27-Jul-87  0930	kempf%hplabsz@hplabs.HP.COM 	Re: Class Redefinition    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 27 Jul 87  09:29:49 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Mon, 27 Jul 87 09:28:47 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Mon, 27 Jul 87 09:28:24 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Mon, 27 Jul 87 09:26:23 pdt
Message-Id: <8707271526.AA11550@hplabsz.hpl.hp.com>
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class Redefinition 
In-Reply-To: Your message of 24 Jul 87 16:45:00 -0700.
Date: Mon, 27 Jul 87 09:26:20 -0700
From: kempf%hplabsz@hplabs.HP.COM

> 

>  (name-that-class new-class 'heh-heh))             ;Hm, what is this function
?


> I think we forgot to de> f> ine NAME-THAT-CLASS. It should be the thing such
> that MAKE-INSTANCE + (<the thing> <name>) = (DEFCLASS NAME ...).

Something like:

	(setf (class-name new-class) 'heh-heh)

should work. The name is not listed as a slot in STANDARD-CLASS in the
87-003 metaobject protocol, however.

			jak




------- End of Forwarded Message

∂27-Jul-87  0933	kempf%hplabsz@hplabs.HP.COM 	Technical corrections in 87-002
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 27 Jul 87  09:32:43 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Mon, 27 Jul 87 09:31:19 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Mon, 27 Jul 87 09:30:46 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Mon, 27 Jul 87 07:45:32 pdt
Message-Id: <8707271445.AA11199@hplabsz.hpl.hp.com>
To: rpg@SAIL.STANFORD.EDU
Cc: common-lisp-object-system@SAIL.STANFORD.EDU, olthoff@hplabsz.hpl.hp.com,
        kempf@hplabsz.hpl.hp.com
Subject: Technical corrections in 87-002
X-Mailer: mh6.5
Date: Mon, 27 Jul 87 07:45:28 -0800
From: kempf%hplabsz@hplabs.HP.COM


Dick:

	Apologies if this arrives more than once. Our mail system is
changing.
	
	The formal specification of method application and combination
is completed, and a couple of omissions, typos, and other 
technical errors were found. While I agree with Moon that it probably
isn't a good idea to inject a level of formalism into CLOS beyond that
customary for the Common Lisp community, I hope that the results of
work from those who are interested in such formalism can be fed back
into the design process, in the spirit of trying to make the CLOS
specification as precise as possible.

Here are the corrections:

1) The use of the term "partial order" on pg. 1-15, paragraph 1 implies
a relation on R which is reflexive, antisymmetric, and transitive. From the
text of the paragraph, this relation is presumably the "is a subclass of" 
relation. However, earlier in the document, reflexivity is explicitly
excluded from the "is a subclass of" relation (pg. 1-4, paragraph 3),
since a class is defined to be neither a superclass nor a subclass
of itself. Either the partial order needs to be replaced
with a different order not requiring reflexivity (semiorder, etc.)
or the "is a subclass of" relation needs to be redefined
so that it is reflexive. Note that the latter solution is used in more
technical treatments of typing systems (e.g. Cardelli and Wegner, Computing
Surveys, 17, 1985, pp. 471-522).

2) As noted in the followup to my posting of the preliminary formal 
specification for method applicaton and combination, the phrase "either 
method may precede the other" on p. 1-21, last paragraph is not technically 
correct, since the two methods are incomparable with regard to precedence. The 
algorithm is nevertheless sound, because it describes sorting of method
equivalence classes rather than methods, and precedence between equivalence
classes, so the ordering of elements in a specific equivalence class is
arbitrary.

3) With reference to my original posting, the case of both specializers
being quoted objects cited on pg. 1-22, paragraph 3 cannot occur at that
point in the algorithm. Either one or the other can be a quoted object,
but since , by that point in the algorithm: a) the two methods 
being compared must differ on the parameter specializer, and, b) in
order for a method to be applicable at all and the specializer to be
a quoted object, the specializer must be EQL to the parameter, this 
condition cannot occur. 

4) The formal description of class precedence list calculation on pg. 1-15,
paragraph 3 is lacking a condition. In the third line, it is not sufficient
just to require the existence of an index i, but also its minimality.
As a counterexample, consider R := {(c1,c2) (c2,c3) (c3 c5) (c2 c4) (c4 c6)}
The inheritance graph for this is;

		c5  c6
		|   |
		c3  c4
		|   |
		\   /
		 \ /
		  c2
		  |
		  c1

In the first step, cpl := [c1] and R := R\{(c1,c2)}, where A\B denotes
the set A with all elements of A INTERSECT B removed (quotient set). 
Next step: cpl := [c1 c2] and R := {(c2,c3) (c2,c4)}. Now the set of
classes without predecessors is {c3 c4}. Then, according to the
description of the algorithm on pg. 1-15 paragraph 3, j=2 is the
largest number such that "there exists i=3 with c3 being the direct
superclass of c2," but i=4 also holds with this property, so it
cannot be determined whether c3 or c4 should be added to the class
precedence list. Requiring the minimal i to be used will remove
the ambiguity, in the example, making c3 the next element of the cpl.

I hope these corrections can be added to the next draft of the
CLOS document.



	







	Jim Kempf	kempf@hplabs.hp.com

∂27-Jul-87  1001	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Name That Class   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87  10:01:19 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 199633; Mon 27-Jul-87 12:53:29 EDT
Date: Mon, 27 Jul 87 12:53 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Name That Class
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 24 Jul 87 19:45 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870727125306.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 24 Jul 87  1645 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    I think we forgot to define NAME-THAT-CLASS. It should be the thing such
    that MAKE-INSTANCE + (<the thing> <name>) = (DEFCLASS NAME ...).

I thought CLASS-NAMED was SETF'able, but 87-002 doesn't say so.  Should
we change that?

∂27-Jul-87  1001	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Class Redefinition     
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87  10:01:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 199639; Mon 27-Jul-87 12:58:38 EDT
Date: Mon, 27 Jul 87 12:58 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Class Redefinition 
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 24 Jul 87 19:45 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870727125813.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 24 Jul 87  1645 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
    ....
    Something like this should work:

    (let
     ((obsolete-class (class-named 'heh-heh))
      (new-class (make-instance 'standard-class ...))) ;make an anonymous class
						       ;that is the new HEH-HEH
     (add-method 
      #'class-changed
      (make-method	;later, make-instance
       ()
       `(,obsolete-class ,new-class)
       #'...))
     (name-that-class new-class 'heh-heh))             ;Hm, what is this function?

This doesn't conform to 87-002's specification that redefining a class
updates the existing class object, rather than replacing it with a new
class object.  Indeed, if we changed that, we wouldn't need the concept
of "obsolete classes", as I pointed out in my message of early Saturday
morning (sent after you wrote this message, but before I saw your message;
we've had a lot of network problems lately, first with window-caulkers
parking their scaffolding in the middle of the through-the-air segment
of our network for a week, then MIT air conditioning failure, and who
knows what else.)  However, because methods are classified by class
objects rather than class names, replacing the old class object with a
new one has its own complexities.

∂27-Jul-87  1046	Bobrow.pa@Xerox.COM 	Re: Name That Class
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Jul 87  10:46:17 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 27 JUL 87 10:46:00 PDT
Date: 27 Jul 87 10:45 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Name That Class
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 27 Jul 87 12:53 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <870727-104600-1451@Xerox>

    I thought CLASS-NAMED was SETF'able, but 87-002 doesn't say so.
     Should we change that?

Yes.  
  danny

∂27-Jul-87  1159	RPG  	Name That Class    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

(setf (class-named ...) ...) is good.

			-rpg-

∂27-Jul-87  1224	RPG  	Class Redefinition 
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

Moon says: <your code won't work>.

I know that the specification states that my code won't work, but
many folks (and not unsophisticated ones) will think it should.
It would be nice if different classes weren't EQ. Is there no way to
make this work? Isn't it true that the only place we need to have
a class and its redefined class be the same is within method selection,
and can't we use surrogates there?

			-rpg-

∂27-Jul-87  1700	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class Redefinition 
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 27 Jul 87  17:00:15 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad05828; 27 Jul 87 17:02 EDT
Received: from ti-csl by RELAY.CS.NET id aw25936; 27 Jul 87 16:51 EDT
Received: from Jenner by tilde id AA12921; Mon, 27 Jul 87 09:16:28 CDT
Message-Id: <2763382458-15423174@Jenner>
Date: Mon, 27 Jul 87  09:14:18 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class Redefinition 
In-Reply-To: Msg of 24 Jul 87  1645 PDT from Dick Gabriel <RPG@sail.stanford.edu>


     Date: 24 Jul 87  1645 PDT
     From: Dick Gabriel <RPG@sail.stanford.edu>
     Subject: Class Redefinition 
     
     
     The problem with class redefinition is that the updating of instances can
     be caused by arbitrary events, as far as the user is concerned. If none of
     DEFCLASS, ADD-METHOD, MAKE-METHOD, CLASS-NAMED, the evaluation of the
     special form FUNCTION, and garbage collection can update instances, then
     if a CLOS implementation does not have multitasking, the following will
     work (or something like it):
     
     	(let ((obsolete-class (class-named 'heh-heh)))
              (defclass heh-heh ...)
              (add-method 
               #'class-changed
     	  (make-method	;later, make-instance
                ()
                `(,obsolete-class ,(class-named 'heh-heh))
     	   #'...)))

This code is not quite right, the new class object (produce by defclass
heh-heh is the same as the old one (the one you bound to
obsolete-class). [pg 1-11]
The following will work.
(let ((current-class (class-named 'heh-heh)))
   (defclass heh-heh ...)
   (add-method 
      #'class-changed
     (make-method	;later, make-instance
         ()
         `(,(get-obsolete-version current-class) ,current-class)
     	 #'...)))
     
     If there is a CLOS implementation with all of the properties named
     above except it does have multitasking (including incremental GC),
     then some form or macro like ATOMICALLY wrapped around the above
     will work.
Right. However, the CPU time spent in ATOMICALLY can be quite
large, realistically some implementation will not be able to give an
upper bound for its elapsed time from start to completion. If a CLOS
implementation has to make sure that this time is kept short, it will
have to bear yet another constraint that could be avoided.
     
     Something like this should work:
     
     (let
      ((obsolete-class (class-named 'heh-heh))
       (new-class (make-instance 'standard-class ...))) ;make an anonymous class
                                                        ;that is the new HEH-HEH
      (add-method 
       #'class-changed
       (make-method	;later, make-instance
        ()
        `(,obsolete-class ,new-class)
        #'...))
      (name-that-class new-class 'heh-heh))             ;Hm, what is this function?
     
This does not work for the same reason the first example did not work.
However I don't see how to fix this one without resorting to my
proposal. It would go like this:

(let*
     ((current-class (class-named 'heh-heh))
      (obsolete-class (assoc current-class
                             (GET-OBSOLETE-CLASSES-FOR-REDEFINITION
                                 current-class))))
  (add-method 
       #'class-changed
       (make-method	;later, make-instance
        ()
        `(,obsolete-class ,current-class)
        #'...))
  (defclass heh-heh ...))    ;(name-that-class new-class 'heh-heh))

     I think, though, that it probably makes sense to have Danny's version
     of GET-OBSOLETE-CLASS for the same reason that I don't like UNIX - it's
     too easy to do a DEFCLASS of an existing class and then wish you
     had a handle on the old one. I think we need to decide whether Patrick's
     versions of getting obsolete classes are worth having around to simplify
     life.

If you can find another solution to your second example (ie without
using ATOMICALLY), I would be inclined to live with Danny's
proposal.
     
     I think we forgot to define NAME-THAT-CLASS. It should be the thing such
     that MAKE-INSTANCE + (<the thing> <name>) = (DEFCLASS NAME ...).
This thing will be in the metaclass protocol

Patrick.

∂27-Jul-87  1905	Moon@STONY-BROOK.SCRC.Symbolics.COM 	initialization meeting notes
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87  19:05:41 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 200139; Mon 27-Jul-87 22:06:01 EDT
Date: Mon, 27 Jul 87 22:05 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: initialization meeting notes
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870723180901.2.GREGOR@SPIFF.isl.parc.xerox.com>
Message-ID: <870727220545.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 23 Jul 87 18:09 PDT
    From: Gregor.pa@Xerox.COM

    In this message I try to summarize what we agreed at the meeting in
    Boston.

Thanks for getting all this on-line.  I see only two things to disagree
with here, so we should start putting our heads down and agreeing on the
next level of detail.

    (defmethod initialize-instance ((obj object) &rest initargs)
      ;; The default initialize-instance method deals with setting the
      ;; values of slots from slot-filling-initargs and from initforms.
      ;;
      ;; The rules are that the leftmost initarg which is declared
      ;; as setting a slot (with the :initarg slot option) actually
      ;; does set it (or is it the rightmost?); and that slots which
      ;; are not set by an initarg have their :initform evaluated and
      ;; used to set them.
      )

It's leftmost, because that's the way duplicated &key arguments work
in all other Common Lisp functions.

Actually there are two issues here:

(1) If the same initarg appears more than once in the initargs list,
the leftmost occurrence is used and later occurrences are ignored.
This is just consistency with &key and there's really no choice.

(2) If more than one initarg is defined to fill a given slot, and more
than one of these initargs appears in the initargs list, what happens?
Flavors takes the rightmost, but that's a misfeature.  We should either
signal an error or take the leftmost.  It's a one-line change to make
Flavors take the leftmost (it will be a few microseconds slower, due to
doing MEMBER of a one-element list instead of EQ, not enough slowdown
to matter).  I like taking the leftmost better than signalling an error.

    (defclass ship ()
	((x :initarg :x)
	 (y :initarg :y)))

    (defmethod initialize-instance :after ((s ship) &key startp)
      (when startp (start s)))

    (defmethod start ((s ship))
      (with-slots ((s :use-accesors nil))
	(if (AND X Y)
	    <start it up>
	    (error "Have to set X and Y before starting a ship."))))

(One line of the above has been uppercased, the only ASCII way to
highlight it.)

I hope this is an erroneous example, and you're not really proposing that
otherwise-uninitialized slots should be initialized to NIL.

    the only serious problem has to do with arranging for the default
    initarg value forms to be evaluated in the lexical environment of the
    defclass. (Of course if environments were first class objects this would
    be trivial...)

I thought we agreed that defclass would translate the initforms into
functions and at the metaclass level they would appear as functions.  I
don't think we need a new way, besides lambda, for capturing lexical
environments.  (Of course implementations are not required to make new
functions in all cases; especially in the case of constant initforms,
they will probably make a closure of an existing function.)  This implies
that one cannot use metaclass protocol to recover the original forms
that appeared in the defclass.  Maybe we didn't agree on this, I couldn't
find anything about it in my notes from the meeting.  Can we converge
on this now?

∂27-Jul-87  2012	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 27 Jul 87  20:12:22 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 200153; Mon 27-Jul-87 22:46:48 EDT
Date: Mon, 27 Jul 87 22:46 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Miscellaneous decisions taken or to be taken
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870727224638.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

I have updated my file of miscellaneous decisions taken or to be taken,
based on my notes from the meeting we had in July.  The rest of this
message is it.


This page is things that I think we agreed that we had decided
after the March meeting and before the July meeting.

27 May 87 call-next-method is allowed to take arguments, however it is
  an error to give it arguments that would change the set of applicable
  methods.  I think we're saying this signals an error, and mentioning
  that in some simple cases the lack of need for an error check can be
  proved at compile time, but in general a run-time check is required.

10 June 87 There was no response when Sonya mailed out a writeup for how
the standard type classes are organized.  Does that mean we agreed on that?

!
This page is a list of issues on which we should make decisions,
brought up by Danny.  Where I saw responsive answers in the mail
(there were very few) I have edited them in.  I've removed comments
that were purely editorial comments on the document.

p1-12 Should defclass be allowed to change the metaclass of an existing
class? Under what conditions should a subclass of standard-class have
the same properties wrt instance updating as standard class?

  Kempf says you shouldn't be allowed to change the metaclass, I think
  because existing interfaces might not be transformable.

  Gregor says the metaclass protocol includes a predicate function
  that controls this.

p1-17 "It is currently under discussion whether to provide constructs
for giving generic functions local names."  Do we want to have this
discussion, or to punt on this syntax. I recall we did come up with some
reasonble semantics for a GFLET and GFLABELS. 

  In July we decided to defer this.

p1-18 It is not specified whether get-setf-generic-function is a
setf-able form.  I suggest that it be made so.  This would allow one to
trace setf-generic-function's without having to know their names.

  This set off a discussion of how TRACE should work that maybe doesn't
  bear directly on CLOS.

  Moon thinks this would be okay provided it is understood as setting the
  mapping from a name to a generic function, not side-effecting the
  generic function.

p1-19 "... Common Lisp be modified to include the following semantics
for quote in a type specifier:
 (deftype quote (object) '(member ,object)))"

Has any proposal for this been given to the cleanup committee? 

  Yes: ISSUE: TYPE-MEMBER-SINGLETON, Proposal TYPE-MEMBER-SINGLETON:QUOTE 
  It hasn't really gone through the mill yet, though.
  In July Moon volunteered to make sure this happens.

p1-24 Should we have a call-next-method? which calls such a next method
if it exists, else returns nil (rather than signalling an error?).  This
seems useful rather than having to define many base methods on object.

  Common Lisp reserves question mark for the user; this could be named
  CALL-NEXT-METHOD-OR-NIL, or something like that.

  In July we wondered whether there should be a way to get a list of
  the remaining methods.  I'm not sure what operations on that list,
  besides checking its length, would be permitted.

2-13(?) The generic function class-name is not written up.  It returns a
name for the class as argument.  I believe that (class-name class)
should be setf-able. Can a class have more than one name? Should
class-name then return a second argument -- the rest of the names this
class is known by.  

  Kempf thinks the class name should be changeable and only one name
  at a time should be allowed.  Moon agrees.
  We need to decide whether class-name of an anonymous class is nil.

p2-19 Values: I thought we agreed that all top level forms should return
the object.  It says here defclass "returns the name of the class"

p2-22 Same comment as 2-19, for defgeneric-options

2-24 ditto for defgeneric-options-setf

  Kempf agrees they should return the object.  Moon isn't sure, because
  defun, defvar, deftype, and defstruct return the name.  As far as I can
  tell every defxxx form in CLtL returns the name.  The problem is that
  we haven't admitted that defmethod has a name.

  In July we decided (for the previous three) to return the object for
  all CLOS defxxx functions (being inconsistent with Common Lisp).

p2-26  I believe that short form method combination ought to be a macro
in the standard library, and documented there, not in the basic
principles.  I think the standard combinations :append, :and, :or, ...
should also be put in the standard library too.
  
  Kempf agrees.  Moon can't have an opinion until he knows what this
  library is and whether it's going to be as much of a joke as the
  Common Lisp Yellow Pages.

p2-35 The argument order of the setf method ought to be documented here.
Gregor proposed that new-value be the first argument.  Any problem with
this?

  Kempf doesn't care but his users want it to be the second argument.
  Moon doesn't care but his users are used to it being the last argument.

  In July we suggested making the new-value argument a required argument that
  comes after all the other required arguments, and before the optional, rest,
  and keyword arguments.  Then we said we'd discuss it further in the mail.
  I think we agreed that the turning of two setf argument lists into one should
  depend only on the argument lists, and not on the generic function object.
  [My notes include an illegible comment, I think it means that I still hope
   we can keep things abstract enough that we don't have to document
   how the two setf argument lists are turned into one.]

p2-39 Arguments: "list of t's" should be replaced by "list of classes
named t" since get-method only takes specializers, not names of
specializers.

  Agreed.

p2-46 Last line:  If call-next method is extended ..."  I see no reason
for additional keyword arguments.  

  Moon doesn't remember the issue.  It may have been consistency; if call-next-method
  can specify the arguments, then so can make-method-call.  You need one keyword
  argument to specify the methods and another to specify funcall versus apply.
  It could also have been that call-next-method would be implemented in terms of
  make-method-call, and therefore would need to be able to specify the arguments.

p2-51 print-object should take a depth argument.

  Moon strongly disagrees and points to the fourth bullet.  I believe this issue
  was discussed to death on the Common Lisp mailing list a few months or a year ago.
  The point is that every single method for print-object should not have to deal
  with *print-level*; that's unmodular.

  Kempf raised a consistency argument (with defstruct?) but we decided
  not to change print-object.

p2-54 slot-missing should be documented

  It's a generic function of a class, an object, and a slot name.
  Gregor will propose the details.
!
This page is a list I made in March, keyed by page numbers in the
document, that hasn't been shown to anyone yet.  Issues mentioned
earlier, or that have since died, have been removed.  I've removed
comments that were purely editorial comments on the document.

2-6 call-next-method dynamic versus indefinite extent

  The document says it has dynamic extent; we need to be sure that we
  really mean that.  In July we said "implementation flexibility, not
  really a language thing", but I'm damned if I can figure out what
  that means.

2-9 semantic difficulties discussion was shortened for the document so much
that much of the point was lost.  At some point we need to decide how much
we want to standardize about this and where we want to say it; in the main
standard or in some kind of implementation guide.

2-13 class-named needs a new name for consistency.  get-class would be wrong
because the other get-xxx functions aren't name operations.  symbol-class
is the agreed name.  It needs an environment argument.  The errorp argument
gets in the way.  I think we agree that symbol-class should be setf'able,
but can it only be set once for a given symbol or is it allowed to change
the symbol-to-class-object mapping?

2-16 (slot-name form) should be allowed as an abbreviation
for (slot-name :initform form).  People have been assuming this,
but it never finds its way into the document.

  In July we rejected this.  Since people keep assuming it, we have
  to document explicitly that it is not allowed.

2-16 boa-arglist should support &key and &allow-other-keys.
2-18 default boa-arglist to be specified

2-18 (:accessor-prefix nil) is not a good way to say "use the slot names
as the accessor names".  We need to fix this.

  We could add another option, or remove the whole prefix feature, and
  require accessor names always to be listed explicitly.
  In July we agreed to discuss this in the mail.

2-19 uninitialized slots should be an error to reference, not be defined
to return an unstandardized value with no error.  I'm willing not to require
that it signals an error if people feel that would be an undue burden,
otherwise I prefer that reading an uninitialized slot signals an error.

  In July we decided that signalling an error here should depend on the
  declared safety level.  Dick has proposed terminology for this.

2-38 need a way to recover documentation of a method-combination type

  July: do this by adding a new value for the second argument to DOCUMENTATION.
  But the whole writeup on DOCUMENTATION is screwy, and we need a new proposal.
  When the CL-Cleanup subcommittee finishes cleaning up the concept of
  "definition" (I think it's waiting for Masinter to propose something)
  then DOCUMENTATION should follow.

2-40 get-setf-generic-function needs an errorp, but it and ensure-generic-function
should be subsumed by get-generic-function which would do all the right things.
We seem to have lost Gregor's proposal for get-generic-function.

  Gregor promised to mail out the proposal.

2-42 make-generic-function should be deleted, redocumented as a class
that can be given to make-instance

  July: Agreed

2-45 make-method should be deleted, redocumented as a class
that can be given to make-instance

  July: Agreed

2-57 with-slots :prefix package problem; This was discussed in the mail and
then the ball was dropped.  What's in the document is unworkable because it
depends on the dynamic value of *package* at macro-expansion time, but Common
Lisp doesn't guarantee anything about when macro-expansion occurs.  Moon would
prefer to flush the :prefix option.  An alternative that was discussed was to
use symbol-package of the prefix, both here and in defclass accessor construction,
as the package, relying on the likelyhood of prefixes always ending in delimiter
characters and exported symbols never ending in delimiter characters.

  July: We agreed to resolve this in the mail.

2-57 What does with-slots do for slots that exist in the class but don't
have accessors, when :use-accessors t is specified (or defaulted)?

  July: it shadows any outer bindings of the slot name, and if you
  actually access that pseudo-variable, it signals an error.

!
Documented holes in chapters 1 and 2 of 87-002.  We publicly promised
X3J13 that we would finish these and have a new draft of 87-003 by the
next meeting.

1-5, 2-44 The initialization protocol for make-instance is not yet
specified.

1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes
is still under discussion.

2-7, 2-46 [The proposed extension to call-next-method has been accepted.]

2-41, 2-48 [Perhaps we can adopt the condition signalling system now.]
!
Other issues:

What can be done with method objects, e.g. can one method be added
to more than one generic function?

Ida: make-specializable seems to be missing

  Gregor's proposal for get-generic-function will subsume this.

Moon: method arglist congruence still doesn't satisfy me.  I have some
ideas about this but unfortunately have not managed to pull them together.

Should we just flush multiple-value-prog2, as leading to more discussion
than is warranted by its simplification of the presentation of
define-method-combination?

Which symbols defined by the standard go in what package?

  July: I think we said some will go in LISP: and some will go in CLOS: and
  we don't know yet where to draw the line.

Should we flush defmethod-setf and friends in favor of function specs?
It probably turns out they could be just in the macros and not in the
underlying Lisp.  The big issue is standardizing where the "new-value"
argument goes; but we may do that anyway (mentioned earlier in this file).
What about the setf of values extension that Common Lisp provides syntactic
space for but does not currently prescribe?

Should we adopt the :component-order class-option from Flavors, as a
simple way for the user to have control of the CPL without making him
write his own algorithm?

  Gregor doesn't like the ability to specify constraints on the ordering
  of classes that only apply conditionally, i.e. if those classes are
  actually present among the superclasses.  He considers this bad style.
  Moon volunteered to write a proposal with some examples, and we agreed
  to resolve this over the mail.

The fact that symbol-function (the user callable primitive) needs to
be split from the subprimitive for implementators that gets and sets
the "real" function definition of a symbol.  This is so when a symbol's
function definition is a generic function object, the "real" definition
can be something that is easier for the implementation to call.

  July: We need to say explicitly somewhere that calling symbol-function
  of the name of a generic function is required to return the generic
  function object, not the "real" definition.

I'm not sure if we said anywhere what happens when you call a generic
function and there is no applicable method; I think it ought to signal
an error.

  Gergor volunteered to send some mail about this.

Clarify that because class names and classes are type-specifiers, they can be
validly be used in THE special forms and in TYPE declarations.  We forgot this
when we clarified that class objects can be used with TYPEP and SUBTYPEP.

  July: agreed

funcallable-standard-class should be documented.  It is a metaclass.
This is what makes generic function objects funcallable.  There is a slot
that is the actual function that gets called.

  I think Gregor volunteered to propose details.

Need to be able to get at the obsolete classes associated with a class,
to put methods on them.

  Patrick has proposed.
  Need discussion of how instances are transformed one step at a time
  when a class has been redefined multiple times.

∂28-Jul-87  1447	Bobrow.pa@Xerox.COM 	Re: Category Errors     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87  14:46:58 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 14:46:54 PDT
Date: 28 Jul 87 14:46 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Category Errors    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 24 Jul 87
 14:59 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870728-144654-2241@Xerox>

    Here is a generic function ``in CLOS'':

    	Add-method generic-function method

    And here is how we have ``carefully laid out ... the range of
    legal arguments'' to it:

    	Arguments:

    	The generic-function argument is a generic function 	object.

    	The method argument is a method object.  The 	lambda-list of
    the method function must be congruent with the lambda-lists of any
    other 	methods associated with the generic function and 	with the
    lambda-list of the generic function.

    		(page 2-5, FUNCTIONS)

We should have been more careful about our wording perhaps.  Because we
have not yet formalized the notion of protocol, we have had to say the
the first argument is a generic-function.  But it could of course be any
object that satisfied the same protocol (could act as the argument to
some set of generic-functions).   It is the ability to specialize (make
"is a generic-function object" mean "be an instance of a subclass of
generic-function object") and the ability to create alternative
implementations that is one of the important improvements that object
oriented programming adds to Lisp --  Hence a MAJOR feature.  Users who
ask "what's that thing?" have not understood object oriented
programming, and it is up to us to help explain it -- not apologize for
it.   

∂28-Jul-87  1527	Bobrow.pa@Xerox.COM 	Re: Class Redefinition  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87  15:26:54 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 15:26:43 PDT
Date: 28 Jul 87 15:26 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Class Redefinition 
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 27 Jul 87
 12:24 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870728-152643-2322@Xerox>

rpg says
    It would be nice if different classes weren't EQ. Is there no
    way to make this work?
The problem is what is a different class.  People build networks of
objects, including classes.  The point of the spec is that these
networks (including the one in the class lattice) should have to change
when a class is changed.   People do not always refer to classes by
names.

Response to Moon:
  
Although I have not thought about it a lot, I think Moon's refinements
GET-CLASS-FOR-NEXT-REDEFINITION
and
GET-OBSOLETE-CLASSES
  seems fine.  I don't understand the experience of why one gets into
trouble making CLASS-CHANGED methods after redefinition as Moon says,
but perhaps it is because I am not working in a true multi-process
system.  

I think we have only two choices with respect to methods applicable to
obsolete instances--
1) All methods applicable to the class itself i.e. the obsolete-class is
a subclass of the new class
2) Only slot-value-using class.

A problem with the first is what happens if a method is removed from a
class before an obsolete instance is converted to a real instance.  For
example, in the famous rho-theta example, suppose we have x-y points
(ones with x and y as slots), and decide to change class to store only
rho and theta.  Then after redefining the class, a naive user might 

1) build a class-changed method that used the methods for rho and theta
for conversion
2) believe that these rho and theta methods could be removed from the
rho-theta-point class.

In this description I have made it obvious why this is wrong.  But
suppose this were a case where both of generic functions for rho and
theta used another routine that was no longer needed.  The user might
easily delete that one. 

I think that it might be better to go to 2, though clearly it makes
class-changed have a lot less easily accessible power.

∂28-Jul-87  1550	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Class redefinition and class-changed.  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 28 Jul 87  15:49:56 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa18740; 28 Jul 87 18:40 EDT
Received: from ti-csl by RELAY.CS.NET id aa01279; 28 Jul 87 18:30 EDT
Received: from Jenner by tilde id AA20926; Tue, 28 Jul 87 15:53:07 CDT
Message-Id: <2763492729-5527834@Jenner>
Date: Tue, 28 Jul 87  15:52:09 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Class redefinition and class-changed.
In-Reply-To: Msg of Sat, 25 Jul 87 01:26 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

     
     I don't like Patrick's particular proposal, though.
     GET-OBSOLETE-CLASSES-FOR-REDEFINITION is too complicated, because it
     returns a whole alist rather than being just the primitive.  In addition, I
     don't think the set of "classes implicated in the class-redefinition of
     CLASS" is computable until the details of the redefinition are known.
     Suppose
       (defclass one () (a b))
       (defclass two (one) (c))
       (defclass three (one) (d))
     Now suppose we redefine one as follows:
       (defclass one () (a b d))
     Referring to the third paragraph on page 1-11 of 87-002, one and two are
     "implicated", but three is not, or at least, whether three is implicated is
     implementation-dependent.  But if the new slot had been named e, both two
     and three would have been implicated.  I don't think the information in
     Patrick's alist is needed anyway; when defining a method, one only defines
     it for the obsolete class corresponding to one class.  If a different
     method needs to be defined for an obsolete subclass, the function can be
     called again.

I see.  I don't care that much about the alist as long as we can get the
obsolete class of "one".

     
     Thus I would replace Patrick's proposal with GET-OBSOLETE-CLASS-FOR-REDEFINITION
     which takes one argument, a class, and returns one value, the obsolete class
     that is a copy of the current definition of the class and will be used the next 
     time the class is redefined; this is created the first time you ask for it.
     Perhaps GET-OBSOLETE-CLASS-FOR-NEXT-REDEFINITION would be a better name.

     As Danny proposed, a primitive to get the obsolete classes corresponding to
     redefinitions that have already taken place is useful, for instance in case
     you didn't realize ahead of time that you would need a CLASS-CHANGED method
     and now want to patch up the program.  I would suggest a function
     GET-OBSOLETE-CLASSES-FOR-PAST-REDEFINITIONS which takes one argument, a
     class, and returns one value, a list of obsolete classes, newest first.
Sounds OK.

I'll have to think some more about the rest of the message. Our
connection with Arpanet was broken and we got it back just one
hour ago.     

Patrick.

∂28-Jul-87  1642	Gregor.pa@Xerox.COM 	Re: Class Redefinition  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87  16:42:35 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 16:42:34 PDT
Date: 28 Jul 87 16:42 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Class Redefinition 
In-reply-to: Danny Bobrow <Bobrow.pa>'s message of 28 Jul 87 15:26 PDT
To: Bobrow.pa@Xerox.COM
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870728-164234-1120@Xerox>

The need for get-class-for-next-redefinition doesn't really have
anything to do with multi-processing as far as I can see.  Suppose that
(the class of) one of the objects actually involved in defining a method
on class-changed was going to be rendered obsolete by a certain defclass
form.  In that case, you would need to define the method before you
actually change the class definition.

∂28-Jul-87  1648	Gregor.pa@Xerox.COM 	Re: Class Redefinition  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87  16:48:48 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 16:48:45 PDT
Date: 28 Jul 87 16:48 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Class Redefinition 
In-reply-to: Danny Bobrow <Bobrow.pa>'s message of 28 Jul 87 15:26 PDT
To: Bobrow.pa@Xerox.COM
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870728-164845-1137@Xerox>

As far as "it would be nice if different classes weren't EQ" goes.

Stop thinking about names and naming!  If you do, I think it becomes
easier to see why the obsolete class should be a new object and the old
class object should be updated to have the new definition.

defclass just associates a class with a name for convenience.  Many
programs will use anonymous classes.  In these programs, changes in an
anymous or a named class might cause anymous or named classes to become
obsolete.  The obsolete class mechanism needs to support both anonymous
and named classes.  In order to do that, the 'redirection' needs to be
at the level of the class object not at the level of the class name.

∂28-Jul-87  1751	Bobrow.pa@Xerox.COM 	Re: initialization meeting notes  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87  17:51:25 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 17:51:21 PDT
Date: 28 Jul 87 17:51 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: initialization meeting notes
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 27 Jul 87 22:05 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870728-175121-1220@Xerox>

    This implies that one cannot use metaclass protocol to recover
    the original forms that appeared in the defclass.

This seems an unecssary mistake (we could have redundant information at
the very least).  I agree that we need not have any "new way, besides
lambda, for capturing lexical
environments."

∂28-Jul-87  1907	Gregor.pa@Xerox.COM 	Re: initialization meeting notes  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87  19:07:26 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 19:04:56 PDT
Date: 28 Jul 87 19:04 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: initialization meeting notes
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 27 Jul 87 22:05 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870728-190456-1292@Xerox>

    From: Moon

    (One line of the above has been uppercased, the only ASCII way
    to highlight it.)

    I hope this is an erroneous example, and you're not really
    proposing that otherwise-uninitialized slots should be initialized
    to NIL.

Yes, this example is erroneous.  What I was trying to capture was that
an :after initialize-instance method would be able to tell if a slot had
been set.

    I thought we agreed that defclass would translate the initforms
    into functions and at the metaclass level they would appear as
    functions.  I don't think we need a new way, besides lambda, for
    capturing lexical environments.  (Of course implementations are not
    required to make new functions in all cases; especially in the case
    of constant initforms, they will probably make a closure of an
    existing function.)  This implies that one cannot use metaclass
    protocol to recover the original forms that appeared in the
    defclass.  Maybe we didn't agree on this, I couldn't find anything
    about it in my notes from the meeting.  Can we converge on this now?

I remember now that we had agreed that both initforms and default
initargs would be translated into functions by defclass.  Note that this
does not necessarily mean that its impossible to reconstruct the
defclass form for a class.  We could say that at the metaclass level,
there is a separate mechanism for communicating the form that was in the
defclass.

But I would just as soon agree that there is no such mechanism at the
metaclass level.  Actually, I think the fact that Common Lisp doesn't
have first class lexical environments means that its impossible to
construct an 'equivalent' defclass form which an editor might put up for
the user to edit a little and then re-evaluate.  Only specific
implementations, in an implementation specific way will be able to do
this.

On the other hand, if Common Lisp had first class lexical environments,
this would be easy.  An unemployment would be lower.  And the national
debt would be under control, and glphh... uh...

∂28-Jul-87  1922	Gregor.pa@Xerox.COM 	Re: Name That Class     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Jul 87  19:22:30 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 87 19:21:57 PDT
Date: 28 Jul 87 19:21 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Name That Class    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 27 Jul 87
 11:59 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870728-192157-1316@Xerox>


It seems to me that there are ways for class-named and setf of such to
work.  I think only two of these are reasonable, but I will include the
third for completeness.  Note that this same analysis applies to
generic-function-name and setf of symbol-function and
get-setf-generic-function.  I will do class names first.

A class C 'is bound to' a given name Ni iff (class-named Ni) returns C.

In all this solutions, we document class-named and setf of class-named.
We say that class-named returns the class is bound to a particular name.
We say that setf of class-named can be used to set the binding of a
class to a name.


Solution 1:
  Only document class-named and setf of class-named.  Most
implementations will have some magic for printing out a class's name
when it has one.

Solution 2:
  Document class-named and setf of class-named.  Also document
class-name, but say that the the class may or may not 'bound' to that
name.

Solution 3:
  Document class-named and class-names and setf of class-named.  Say
that setf of class-named can be used to bind a clas to a name.  Say that
class-names returns the list of all names that a class is bound to.  For
example:

(setq foo (make-instance 'standard-class))
#<Standard-Class NIL 1>

(setf (class-named 'n1) foo)
#<Standard-Class N1 1>

(setf (class-named 'n2) foo)
#<Standard-Class N2 1>

(class-names foo)
(N1 N2)

(setf (class-named 'n1) nil)
#<Standard-Class N2 1>

(setf (class-named 'n2) nil)
#<Standard-Class NIL 1>

(class-names foo)
()

It seems to me that solution 1 and solution 3 are the only reasonable
ones.  My general dislike of names makes me prefer solution 1, but I
think that solution 3 actually provides users some important
functionality.



I think its easy to see how this whole thing would work for
generic-function-name, symbol-function, setf of symbol-function,
get-setf-generic-function and setf of get-setf-generic-function.

∂28-Jul-87  2126	RPG  	Partial Orderings  
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

You can define a partial ordering based on irreflexive relations
by using the `antirelation' and NOT. For example, instead of less than
or equal, you can use greater than and NOT. If you don't believe me,
believe Knuth Volume 1.

			-rpg-

∂29-Jul-87  1025	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Miscellaneous decisions taken or to be taken
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 29 Jul 87  10:25:11 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac27103; 29 Jul 87 13:10 EDT
Received: from ti-csl by RELAY.CS.NET id af06356; 29 Jul 87 13:02 EDT
Received: from Jenner by tilde id AA12158; Wed, 29 Jul 87 11:22:06 CDT
Message-Id: <2763562862-9741514@Jenner>
Date: Wed, 29 Jul 87  11:21:02 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Miscellaneous decisions taken or to be taken
In-Reply-To: Msg of Mon, 27 Jul 87 22:46 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

     10 June 87 There was no response when Sonya mailed out a writeup for how
     the standard type classes are organized.  Does that mean we agreed on that?
I agree with it.

     p1-12 Should defclass be allowed to change the metaclass of an existing
     class? Under what conditions should a subclass of standard-class have
     the same properties wrt instance updating as standard class?
     
       Kempf says you shouldn't be allowed to change the metaclass, I think
       because existing interfaces might not be transformable.
     
       Gregor says the metaclass protocol includes a predicate function
       that controls this.

I agree with Gregor.
     



∂29-Jul-87  1034	skeene@STONY-BROOK.SCRC.Symbolics.COM 	updated documentation
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 29 Jul 87  10:34:40 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 201218; Wed 29-Jul-87 13:27:29 EDT
Date: Wed, 29 Jul 87 13:26 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: updated documentation
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870729132641.0.SKEENE@JUNCO.SCRC.Symbolics.COM>


I wrote new versions of the functions, concepts, and design chapters.
The documentation now includes the write-up about Standard Type Classes
which I sent to this list several months ago.   I didn't receive any
comments about it, probably because the text was cluttered up with tex
formatting directives.   When we format the document again it will be
easier for people to read this section and make their comments then.  

I changed the documentation to state that the def-XXX macros return 
objects, not names.   We agreed on this change at our Cambridge meeting
a couple weeks ago.

The only problem with this is some awkwardness about the value of
define-method-combination.    There is no CLOS object for representing a
method combination type.   define-method-combination expands into a
defmethod, so its result is a method object.    




∂29-Jul-87  1415	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Class redefinition and class-changed. 
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 29 Jul 87  14:15:18 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae29814; 29 Jul 87 17:07 EDT
Received: from ti-csl by RELAY.CS.NET id ae07913; 29 Jul 87 17:02 EDT
Received: from dsg by tilde id AA02476; Wed, 29 Jul 87 15:11:11 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Wed, 29 Jul 87  15:00:19 CDT
Message-Id: <2763575892-10524347@Jenner>
Date: Wed, 29 Jul 87  14:58:12 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Class redefinition and class-changed.
In-Reply-To: Msg of Sat, 25 Jul 87 01:26 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

     
     We have our choice of three ways to define what happens when a class is
     redefined:
     (1) A new class object is created, the name-to-class-object mapping is
     changed, defclass-defined methods implied by the new definition are put on
     the new class object, all methods other than defclass-defined methods that
     apply to the old class are made to apply also to the new class, subclasses
     of the old class are made to be subclasses of the new class instead, and
     superclasses of the old class are made to be also superclasses of the new
     class.  If we had done this, there would have been an explicit
     representation of versions of a class, and there would not have been any
     concept of "obsolete classes."

I don't like this one for the reasons Gregor and Danny gave.

     
     This means that -both- arguments to CLASS-CHANGED could be instances of
     obsolete classes.  It also means that our CLASS-CHANGED method can't
     specialize its second parameter, because at first that will be the class
     FOO, but after FOO is redefined again, it will be an obsolete class.  If we
     don't specialize the second parameter, it seems we could be confused by
     CLASS-CHANGED being called when CHANGE-CLASS was used to change an instance
     of FOO into an instance of BAR.  This is not a problem if CHANGE-CLASS,
     like all other generic functions, first updates its argument to the latest
     definition of its class, before changing it to the new class; then a method
     specialized to an obsolete class in its first parameter can never be called
     with the second parameter an instance of anything other than the next newer
     version of the same class.  This all seems slightly kludgey, but does seem
     like it should work.

I like this approach the best because it is more object oriented than
the third one and seems more modular.  However it has the problem Danny
mentioned about applicable methods: 
[Bobrow]:
     I think we have only two choices with respect to methods applicable to
     obsolete instances--
     1) All methods applicable to the class itself i.e. the obsolete-class is
     a subclass of the new class
     2) Only slot-value-using class.
     
     A problem with the first is what happens if a method is removed from a
     class before an obsolete instance is converted to a real instance.  For
     example, in the famous rho-theta example, suppose we have x-y points
     (ones with x and y as slots), and decide to change class to store only
     rho and theta.  Then after redefining the class, a naive user might 
     
     1) build a class-changed method that used the methods for rho and theta
     for conversion
     2) believe that these rho and theta methods could be removed from the
     rho-theta-point class.
     
     In this description I have made it obvious why this is wrong.  But
     suppose this were a case where both of generic functions for rho and
     theta used another routine that was no longer needed.  The user might
     easily delete that one. 
     
     I think that it might be better to go to 2, though clearly it makes
     class-changed have a lot less easily accessible power.

I don't like danny's 1) because as he shows, it does not work. I don't
like 2) because it breaks modularity. You have to know if an accessor
is implemented as a physical slot access and if not, you have to know
what the accessor was doing. This knowledge is contained in your class
and its superclasses.
How about this one?
 1b)All methods applicable to the class itself at the time of the
redefinition.
It would be up to the implementation to choose the best way of doing
it.
     
     The third way to define what happens when a class is redefined, mentioned
     earlier, is as follows:  Don't try to use CLASS-CHANGED for both changing
     the class of an instance and updating an instance to a new version of its
     class.  Invent a new generic function CLASS-REDEFINED, which is called when
     an instance is updated to a new version of its class.  This avoids the
     complicated concept of "obsolete classes", at the cost of conveying the
     former state of the instance in a less object-oriented fashion.  Perhaps
     CLASS-REDEFINED would receive three arguments: an instance of the class,
     already updated to the latest definition of the class, a property list
     associating slot names to slot values, with one entry for each slot that is
     no longer present, and a list of slot names of slots that were newly added
     to the instance.  Thus when a class is redefined:
     (3) The old class object is modified, defclass-created methods that aren't
     created by the new defclass are removed, new defclass-created methods are
     added, and the modification is propagated to subclasses.  This is simpler
     than (1) or (2).

The third way is simpler indeed. My main objection to this is that
CLASS-REDEFINED methods have to know all about the implementation of the
class and superclasses (physical slots and methods) AND the whole story
about the successive redefinitions.
     
Patrick.

∂30-Jul-87  0021	kempf%hplabsz@hplabs.HP.COM 	Re: Miscellaneous decisions taken or to be taken   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 30 Jul 87  00:20:49 PDT
Received: from hplms1 by hplabs.HP.COM with TCP ; Wed, 29 Jul 87 15:26:18 pdt
Received: from hplabsz.hpl.hp.com by hplms1; Wed, 29 Jul 87 15:24:58 pdt
Return-Path: <kempf@hplabsz.hpl.hp.com>
Received: by hplabsz; Wed, 29 Jul 87 16:25:29 pdt
Message-Id: <8707292225.AA09896@hplabsz.hpl.hp.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU, kempf@hplabsz.hpl.hp.com
Subject: Re: Miscellaneous decisions taken or to be taken 
In-Reply-To: Your message of Mon, 27 Jul 87 22:46:00 -0400.
             <870727224638.5.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Wed, 29 Jul 87 16:25:25 -0700
From: kempf%hplabsz@hplabs.HP.COM


On anything not noted, I've got no opinion.

There was no mention made of compile time optimization, which I believe
I made some initial proposals on in late April or early May. I've been
meaning to revist them, will try to get to that in the next week or
so. If anybody thinks this isn't important and should be dropped, let
me know. Our applications developers are asking for it, however.

On initialization:

> 1-5, 2-44 The initialization protocol for make-instance is not yet
> specified.

I take it there was no agreement at the July meeting to a full specification? 
If so, then can someone write up the specification and post it?

PART I:

> 27 May 87 call-next-method is allowed to take arguments, however it is
>   an error to give it arguments that would change the set of applicable
>   methods.  I think we're saying this signals an error, and mentioning
>   that in some simple cases the lack of need for an error check can be
>   proved at compile time, but in general a run-time check is required.

This is fine. Do we need to further clarify the error based on Dick's
note about error signaling?

> 10 June 87 There was no response when Sonya mailed out a writeup for how
> the standard type classes are organized.  Does that mean we agreed on that?

Yes, modulo consideration of Patrick's suggested change in 
<2762944528-5369042@Jenner> for purposes of minimizing category errors. 
But I assume from the note he posted today, that he is satisfied with
Sonya's note.

> p1-12 Should defclass be allowed to change the metaclass of an existing
> class? Under what conditions should a subclass of standard-class have
> the same properties wrt instance updating as standard class?

>   Kempf says you shouldn't be allowed to change the metaclass, I think
>   because existing interfaces might not be transformable.

>   Gregor says the metaclass protocol includes a predicate function
>   that controls this.

The reason was because the representations might differ. Consider a
metaclass where the types of the slots were restricted. Instances of
classes of a metaclass which did not have those restrictions might be
difficult to update automatically. However, I think Gregor's solution of
a metaclass protocol predicate (generic) function to control this would
be sufficient.

This doesn't answer the second question, however, I'll abstain on that
one. I don't believe instance updating belongs in the language in the
first place, but rather in the environment. 

PART II:

> p1-17 "It is currently under discussion whether to provide constructs
> for giving generic functions local names."  Do we want to have this
> discussion, or to punt on this syntax. I recall we did come up with some
> reasonble semantics for a GFLET and GFLABELS. 
>
>   In July we decided to defer this.

Let's forget it for now. I've got some ideas, but I won't rehash them.

> p1-18 It is not specified whether get-setf-generic-function is a
> setf-able form.  I suggest that it be made so.  This would allow one to
> trace setf-generic-function's without having to know their names.

>   This set off a discussion of how TRACE should work that maybe doesn't
>   bear directly on CLOS.

>   Moon thinks this would be okay provided it is understood as setting the
>   mapping from a name to a generic function, not side-effecting the
>   generic function.

I've been thinking about modifications to TRACE to support tracing of
generic functions, which combines aspects of Danny's idea of making
TRACE a generic function and Moon's function specs. I'll try to get
it written up and posted by the end of the week. I think it's important
that this be addressed, since our applications developers are beginning
to express the need for the ability to trace individual methods, as
well as invocation of the generic function.

> p1-24 Should we have a call-next-method? which calls such a next method
> if it exists, else returns nil (rather than signalling an error?).  This
> seems useful rather than having to define many base methods on object.

CommonObjects had two messaging forms for this, but my general inclination
is to conform with what happens when an attempt to invoke a generic
function is made with an argument set for which there is no matching
method. Currently, an error is signalled, and I think that it should
also be for CALL-NEXT-METHOD.

>   We need to decide whether class-name of an anonymous class is nil.

Two choices are 1) NIL 2) CLASS-NAME signals an error. I vote for the
second. An anonymous class should be a class with NO name. 

> p2-19 Values: I thought we agreed that all top level forms should return
> the object.  It says here defclass "returns the name of the class"

> p2-22 Same comment as 2-19, for defgeneric-options

> 2-24 ditto for defgeneric-options-setf

>   Kempf agrees they should return the object.  Moon isn't sure, because
>   defun, defvar, deftype, and defstruct return the name.  As far as I can
>   tell every defxxx form in CLtL returns the name.  The problem is that
>   we haven't admitted that defmethod has a name.

>   In July we decided (for the previous three) to return the object for
>   all CLOS defxxx functions (being inconsistent with Common Lisp).

Additionally, it would be nice if
top level forms would also print out something at compile time. Our
applications developers are asking for some feedback about what gets
done at compile time. Maybe that's an implementation issue, though.

> p2-35 The argument order of the setf method ought to be documented here.
> Gregor proposed that new-value be the first argument.  Any problem with
> this?

>   Kempf doesn't care but his users want it to be the second argument.
>   Moon doesn't care but his users are used to it being the last argument.

>   In July we suggested making the new-value argument a required argument that
>   comes after all the other required arguments, and before the optional, rest
>   and keyword arguments.  Then we said we'd discuss it further in the mail.
>   I think we agreed that the turning of two setf argument lists into one 
>   should
>   depend only on the argument lists, and not on the gen eric function object.
>   [My notes include an illegible comment, I think it means that I still hope
>    we can keep things abstract enough that we don't have to document
>    how the two setf argument lists are turned into one.]

This sounds good to me. 

> p2-39 Arguments: "list of t's" should be replaced by "list of classes
> named t" since get-method only takes specializers, not names of
> specializers.

Yes, except I'd phrase it as "a list whose elements are the class object
for the the class named T". As I understand it, there is only one class T.

> p2-51 print-object should take a depth argument.

>   Moon strongly disagrees and points to the fourth bullet.  I believe this 
>   issue was discussed to death on the Common Lisp mailing list a few months 
>   or a year ago.
>   The point is that every single method for print-object should not have to 
>   deal with *print-level*; that's unmodular.

>   Kempf raised a consistency argument (with defstruct?) but we decided
>   not to change print-object.

I agree with Moon. Some implementors may scream (as I did), 
but it's probably not too late to correct this blemish.

PART III:

> 2-6 call-next-method dynamic versus indefinite extent

>   The document says it has dynamic extent; we need to be sure that we
>   really mean that.  In July we said "implementation flexibility, not
>   really a language thing", but I'm damned if I can figure out what
>   that means.

Yes, this needs to be resolved. See my comments below about adding
methods to more than one generic function. Although I wasn't there,
I think the "implementation flexibility" comment had something to
do with optimizing calculation of the effective method. Indefinite
extent would favor this, but dynamic extent would give more flexibility
with regard to what could be done with method objects. Indefinite
extent sounds good to me, but I'm not particularly choosy, however,
I think it should be pinned down.

> 2-9 semantic difficulties discussion was shortened for the document so much
> that much of the point was lost.  At some point we need to decide how much
> we want to standardize about this and where we want to say it; in the main
> standard or in some kind of implementation guide.

I think these semantic difficulties point out a fundamental problem with
CHANGE-CLASS. It is neither a full versioned class capability nor an
environmental undo capability, but rather a hack somewhere in between. Having
said my peace (and above, about instance changing), I'll forgoe any
further comments.

> 2-13 class-named needs a new name for consistency.  get-class would be wrong
> because the other get-xxx functions aren't name operations.  symbol-class
> is the agreed name.  It needs an environment argument.  The errorp argument
> gets in the way.  I think we agree that symbol-class should be setf'able,
> but can it only be set once for a given symbol or is it allowed to change
> the symbol-to-class-object mapping?

Why an environment argument? Since we haven't agreed to lexically scoped
class names, this would seem unnecessary. Is it to deal with the ERRORP
argument? Why do people think it will get in the way? Why not just make
it a keyword argument? A user might want to not have it signal an error
especially in metaclass programming. If whether or not it signals an
error is dependent on a (second-class) environment argument, then it
will be more difficult for a user to arrange. I think the name SYMBOL-CLASS 
is OK, and that it should be allowed to change the 
symbol-to-class-object mapping.
The important thing in CLOS is the object, and the name to object mapping
should be changable.

> 2-16 (slot-name form) should be allowed as an abbreviation
> for (slot-name :initform form).  People have been assuming this,
> but it never finds its way into the document.

>   In July we rejected this.  Since people keep assuming it, we have
>   to document explicitly that it is not allowed.

Yes.

> 2-16 boa-arglist should support &key and &allow-other-keys.

Agreed.

> 2-19 uninitialized slots should be an error to reference, not be defined
> to return an unstandardized value with no error.  I'm willing not to require
> that it signals an error if people feel that would be an undue burden,
> otherwise I prefer that reading an uninitialized slot signals an error.

I agree that it should signal an error.

>   In July we decided that signalling an error here should depend on the
>   declared safety level.  Dick has proposed terminology for this.

Dick's terminology is good. We probably need to backpatch it into the
document (it should probably be backpatched into CLtL too, but that's
not for us to decide).

> 2-57 with-slots :prefix package problem; This was discussed in the mail and
> then the ball was dropped.  What's in the document is unworkable because it
> depends on the dynamic value of *package* at macro-expansion time, but Common
> Lisp doesn't guarantee anything about when macro-expansion occurs.  Moon would
> prefer to flush the :prefix option.  An alternative
> that was discussed was to
> use symbol-package of the prefix, both here and in defclass accessor construc-
tion,
> as the package, relying on the likelyhood of prefixes always ending in delimi-
ter
> characters and exported symbols never ending in delimiter characters.

>   July: We agreed to resolve this in the mail.

I agree with Moon.

> 2-57 What does with-slots do for slots that exist in the class but don't
> have accessors, when :use-accessors t is specified (or defaulted)?

>   July: it shadows any outer bindings of the slot name, and if you
>   actually access that pseudo-variable, it signals an error.

Agreed.

> Documented holes in chapters 1 and 2 of 87-002.  We publicly promised
> X3J13 that we would finish these and have a new draft of 87-003 by the
> next meeting.

See my note of 27 July to Dick about holes in Chapter 1. I'll be replying
to Danny's comments on it shortly.

> 1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes
> is still under discussion.

Has a Cleanup Committee proposal been submitted for the type system?

> What can be done with method objects, e.g. can one method be added
> to more than one generic function?

There may be a problem if the method invokes CALL-NEXT-METHOD. This
relates back to whether CALL-NEXT-METHOD is dynamic  or indefinite
in extent. If it is dynamic, then there should be no problem, since
the binding of CALL-NEXT-METHOD is done when the method begins executing,
at the latest, or during calculation of the effective method, at the
earliest. Thus the same method object on multiple generic functions
would be no problem, since that case could be detected and establishment
of CALL-NEXT-METHOD's binding deferred as late as possible. If the
extent is indefinite, then the binding could potentially remain outside
of a particular method invocation, and so adding the same method to
more than one generic function may cause a problem.

> Ida: make-specializable seems to be missing

>   Gregor's proposal for get-generic-function will subsume this.

Wasn't ENSURE-GENERIC-FUNCTION supposed to replace this?

> Should we just flush multiple-value-prog2, as leading to more discussion
> than is warranted by its simplification of the presentation of
> define-method-combination?

Yes.

> Which symbols defined by the standard go in what package?

>   July: I think we said some will go in LISP: and some will go in CLOS: and
>   we don't know yet where to draw the line.

I think they should all go into CLOS, except those which are already in
LISP (like DOCUMENTATION) or those which are designed to replace aspects
of LISP already existing (like PRINT-OBJECT). Very few are in these categories.

> Should we flush defmethod-setf and friends in favor of function specs?
> It probably turns out they could be just in the macros and not in the
> underlying Lisp.  The big issue is standardizing where the "new-value"
> argument goes; but we may do that anyway (mentioned earlier in this file).

I think we ought to keep DEFMETHOD-SETF, but use function specs (or
something like them) as the programmer interface to TRACE. See my
comments above about TRACE.

> Should we adopt the :component-order class-option from Flavors, as a
> simple way for the user to have control of the CPL without making him
> write his own algorithm?

>   Gregor doesn't like the ability to specify constraints on the ordering
>   of classes that only apply conditionally, i.e. if those classes are
>   actually present among the superclasses.  He considers this bad style.
>   Moon volunteered to write a proposal with some examples, and we agreed
>   to resolve this over the mail.

I agree with Gregor. I think that user specified changes in the CPL
should be controlled through COMPUTE-CLASS-PRECEDENCE-LIST, or, if
the default algorithm can't make a decision. 

> The fact that symbol-function (the user callable primitive) needs to
> be split from the subprimitive for implementators that gets and sets
> the "real" function definition of a symbol.  This is so when a symbol's
> function definition is a generic function object, the "real" definition
> can be something that is easier for the implementation to call.

I don't see splitting SYMBOL-FUNCTION as an issue for the standard,
though it may be for certain implementations. Currently, most of the
PCL-derived implementations have no trouble with this.

>   July: We need to say explicitly somewhere that calling symbol-function
>   of the name of a generic function is required to return the generic
>   function object, not the "real" definition.

Yes. 

> I'm not sure if we said anywhere what happens when you call a generic
> function and there is no applicable method; I think it ought to signal
> an error.

Yes, and CALL-NEXT-METHOD should do the same. Again, we need to clarify
in the context of Dick's proposed error naming scheme.

> Clarify that because class names and classes are type-specifiers, they can be
> validly be used in THE special forms and in TYPE declarations.  We forgot this
> when we clarified that class objects can be used with TYPEP and SUBTYPEP.

>   July: agreed

Yes. Again, as mentioned in the beginning, this relates back to compile
time optimization.

> funcallable-standard-class should be documented.  It is a metaclass.
> This is what makes generic function objects funcallable.  There is a slot
> that is the actual function that gets called.

Agreed.

∂30-Jul-87  0612	DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET 	Re: Miscellaneous decisions taken or to be taken 
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 30 Jul 87  06:12:35 PDT
Received: from [128.89.1.80] by RELAY.CS.NET id aa02415; 30 Jul 87 9:08 EDT
Received: from ti-csl by RELAY.CS.NET id ad12225; 30 Jul 87 9:02 EDT
Received: from Jenner by tilde id AA02135; Thu, 30 Jul 87 07:59:04 CDT
Message-Id: <2763637077-14200445@Jenner>
Date: Thu, 30 Jul 87  07:57:57 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: kempf%hplabsz@hplabs.hp.com
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Miscellaneous decisions taken or to be taken 
In-Reply-To: Msg of Wed, 29 Jul 87 16:25:25 -0700 from kempf%hplabsz@hplabs.hp.com

     >   We need to decide whether class-name of an anonymous class is nil.
     
     Two choices are 1) NIL 2) CLASS-NAME signals an error. I vote for the
     second. An anonymous class should be a class with NO name. 

If we signal an error on class-name, then we have to come up with a
predicate to test if the class is named or not. Is it worth the trouble?

     Additionally, it would be nice if
     top level forms would also print out something at compile time. Our
     applications developers are asking for some feedback about what gets
     done at compile time. Maybe that's an implementation issue, though.

You're right, it is an implementation issue, some compilers have a
verbose option.
     

     > 2-13 class-named needs a new name for consistency.  get-class would be wrong
     > because the other get-xxx functions aren't name operations.  symbol-class
     > is the agreed name.  It needs an environment argument.  The errorp argument
     > gets in the way.  I think we agree that symbol-class should be setf'able,
     > but can it only be set once for a given symbol or is it allowed to change
     > the symbol-to-class-object mapping?
     
     Why an environment argument? Since we haven't agreed to lexically scoped
     class names, this would seem unnecessary. Is it to deal with the ERRORP
     argument? Why do people think it will get in the way? Why not just make
     it a keyword argument? A user might want to not have it signal an error
     especially in metaclass programming. If whether or not it signals an
     error is dependent on a (second-class) environment argument, then it
     will be more difficult for a user to arrange. I think the name SYMBOL-CLASS 
     is OK, and that it should be allowed to change the 
     symbol-to-class-object mapping.
     The important thing in CLOS is the object, and the name to object mapping
     should be changable.

The environment argument will be necessary to address the compile
environment problem.  The term might be confusing, it is not necessary
an environment like the &environment argument in a macro definition.
     
     
     > What can be done with method objects, e.g. can one method be added
     > to more than one generic function?
     
     There may be a problem if the method invokes CALL-NEXT-METHOD. This
     relates back to whether CALL-NEXT-METHOD is dynamic  or indefinite
     in extent. If it is dynamic, then there should be no problem, since
     the binding of CALL-NEXT-METHOD is done when the method begins executing,
     at the latest, or during calculation of the effective method, at the
     earliest. Thus the same method object on multiple generic functions
     would be no problem, since that case could be detected and establishment
     of CALL-NEXT-METHOD's binding deferred as late as possible. If the
     extent is indefinite, then the binding could potentially remain outside
     of a particular method invocation, and so adding the same method to
     more than one generic function may cause a problem.
     
     > Which symbols defined by the standard go in what package?
     
     >   July: I think we said some will go in LISP: and some will go in CLOS: and
     >   we don't know yet where to draw the line.
     
     I think they should all go into CLOS, except those which are already in
     LISP (like DOCUMENTATION) or those which are designed to replace aspects
     of LISP already existing (like PRINT-OBJECT). Very few are in these categories.
     
We said that some of the symbols will go to LISP because CLOS is
supposed to be part of ANSI Common Lisp. The top level macros and
functions should be part of LISP.  The internal functions specified for
the sake of metaclass programming can reside in CLOS.

     >   Gregor doesn't like the ability to specify constraints on the ordering
     >   of classes that only apply conditionally, i.e. if those classes are
     >   actually present among the superclasses.  He considers this bad style.
     >   Moon volunteered to write a proposal with some examples, and we agreed
     >   to resolve this over the mail.
     
     I agree with Gregor. I think that user specified changes in the CPL
     should be controlled through COMPUTE-CLASS-PRECEDENCE-LIST, or, if
     the default algorithm can't make a decision. 

Let's see what Moon's proposal before discussing the issue.
     
     > I'm not sure if we said anywhere what happens when you call a generic
     > function and there is no applicable method; I think it ought to signal
     > an error.
     
     Yes, and CALL-NEXT-METHOD should do the same. Again, we need to clarify
     in the context of Dick's proposed error naming scheme.

If we can assume that the ANSI will standardize an error handler then I
am in favor of signalling an error and specifying the signal name.  If
we can't assume that, I would rather call a generic function like
NO-MATCHING-METHOD.






∂30-Jul-87  1306	Bobrow.pa@Xerox.COM 	Re: Name That Class     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 30 Jul 87  13:06:15 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 29 JUL 87 18:36:33 PDT
Date: 29 Jul 87 18:36 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Name That Class    
In-reply-to: Gregor.pa's message of 28 Jul 87 19:21 PDT
To: Gregor.pa@Xerox.COM
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870729-183633-103@Xerox>

I support proposal 3

(setf(class-named <symbol>) <class>)

and 
(class-names <class>)
for the reasons given
  danny

∂31-Jul-87  0939	kempf%hplabsz@hplabs.HP.COM 	Re: Miscellaneous decisions taken or to be taken   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 31 Jul 87  09:38:35 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 30 Jul 87 15:21:28 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 30 Jul 87 15:21:04 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 30 Jul 87 16:21:49 pdt
Message-Id: <8707302221.AA01264@hplabsz.hpl.hp.com>
To: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Miscellaneous decisions taken or to be taken 
In-Reply-To: Your message of Thu, 30 Jul 87 07:57:57 -0500.
             <2763637077-14200445@Jenner> 
Date: Thu, 30 Jul 87 16:21:46 MST
From: kempf%hplabsz@hplabs.HP.COM

>      >   We need to decide whether class-name of an anonymous class is nil.
>      
>      Two choices are 1) NIL 2) CLASS-NAME signals an error. I vote for the
>      second. An anonymous class should be a class with NO name. 

> If we signal an error on class-name, then we have to come up with a
> predicate to test if the class is named or not. Is it worth the trouble?

This is a problem. Also with unnamed generic function objects, and
methods. In the interest of simplicity, I'd be willing to forgo this.
I can't think of why anyone would want to name a class NIL anyway.

> The environment argument will be necessary to address the compile
> environment problem.  The term might be confusing, it is not necessary
> an environment like the &environment argument in a macro definition.
>      

We need some more discussion on this first. I agree that the the compile
environment problem needs solution (especially for single address space
implementations) but I'd rather see some concensus on a general solution
before bringing up specific functions. Even if it means having to revise
the parameter lists of some functions.

>      
>      I think they should all go into CLOS, except those which are already in
>      LISP (like DOCUMENTATION) or those which are designed to replace aspects
>      of LISP already existing (like PRINT-OBJECT). Very few are in these categories.
>      
> We said that some of the symbols will go to LISP because CLOS is
> supposed to be part of ANSI Common Lisp. The top level macros and
> functions should be part of LISP.  The internal functions specified for
> the sake of metaclass programming can reside in CLOS.

Does this mean that a decision was made at the July meeting on the point 
Pavel Curtis raised at the March meeting about what relationship CLOS 
should have with the full language standard? Unless implementors of
Common Lisp are required to implement CLOS in order to have "full
ANSI Standard Common Lisp", I think it would be better to allow some
flexibility in where the symbols go.

>      > I'm not sure if we said anywhere what happens when you call a generic
>      > function and there is no applicable method; I think it ought to signal
>      > an error.
>      
>      Yes, and CALL-NEXT-METHOD should do the same. Again, we need to clarify
>      in the context of Dick's proposed error naming scheme.

> If we can assume that the ANSI will standardize an error handler then I
> am in favor of signalling an error and specifying the signal name.  If
> we can't assume that, I would rather call a generic function like
> NO-MATCHING-METHOD.

I agree with your preferences here. The error message should also give some
information about the classes of the parameters, in addition, to help 
debugging.





∂31-Jul-87  1110	kempf%hplabsz@hplabs.HP.COM 	TRACE Proposal (Version 1)
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 31 Jul 87  11:09:44 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Fri, 31 Jul 87 11:07:37 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Fri, 31 Jul 87 11:07:05 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Fri, 31 Jul 87 12:07:43 pdt
Message-Id: <8707311807.AA10361@hplabsz.hpl.hp.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: TRACE Proposal (Version 1)
X-Mailer: mh6.5
Date: Fri, 31 Jul 87 12:07:37 MST
From: kempf%hplabsz@hplabs.HP.COM

As promised, here is an initial draft of a proposal for modifying the
TRACE macro (CLtL, pp. 440-441) to better support object-oriented
programming. The proposal is motivated by the expressed need of our
applications programmers. Sometimes, they would like to only trace
when a particular method is run, rather than tracing every method
when the generic function is invoked. Additionally, some constructs
in Common Lisp which are usually implemented as functions (macroexpansions,
SETF's) are currently not tracable through the TRACE function, but rather
require extra effort. There is obviously lots of room for implementation
dependency here, and some things which would be nice to do portably
(like tracing local function invocations) are difficult because Common
Lisp doesn't have the right constructs (like no first class environments).

The proposal is a combination of Moon's function spec idea, at the
programmer interface level, and Danny's generic function idea, at the
system level. I think most Common Lisp implementors probably include
some help for tracing methods already, if they implement an object-oriented
language.

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

TRACE &REST {function-spec}*  		[Macro]

Invoking TRACE with one or more function specifications causes the
functions specified to be traced. Henceforth whenever a specified
function is invoked, information about the call, the arguments passed,
and the returned values, if any, will be printed to the stream that is
the value of *TRACE-OUTPUT*.

A function-spec is either a symbol naming a function (i.e. a symbol
whose global function cell is bound to a function definition object)
or a list whose first element is a function specification type, and 
whose tail indicates which particular function of that type should 
be traced. The complete set of function specification types will 
necessarily be implementation specific, but all implementations 
are required to provide the following:

<symbol>-Invocation of the function named by <symbol> via. <symbol>'s
global function cell are traced.

(:SETF <place> )-If the generalized variable reference indicated by
<place> is tracable, then invocations of the function implementing
the SETF operation will be traced.

(:METHOD <generic-function-name> <parameter-specializer-name-list>)-
If the method whose parameter specializer list and generic function
are indicated in the specification is tracable, then invocations 
through the generic function name will be traced.

(:MACRO-FUNCTION <symbol>)-If <symbol> has a global function definition
that is a macro definition, then invocations of the macro function through
<symbol> will be traced.

>>>>others? Some which I can think of that might be useful are:

(:LOCAL <symbol> <environment>)-Invocations of the function named
<symbol> when the current environment is <environment> are traced.

Problems: Environments are second-class in Common Lisp. Something similar
would be:

(:LOCAL <global-function-symbol> <local-function-symbol>)-Same, except
would get at the environment via. a global function name. This won't take
care of FLETS inside FLETS, nor of FLETS at the top level, however.

This could also be potentially handled via. the macro's environment
parameter.

(:FUNDEF <function definition object>)-Invocations of the function
definition object are traced, regardless of whether they are through
a global or local name symbol.

Problems: Wrapping the function to trace invocation may require modifying the
function definition object, which may not be possible in all
implementations of Common Lisp.

Slot initialization functions, and lambdas are other items which need
consideration.

Note: Another useful enhancement would be to support a :BREAK flag, like
this:

	(:METHOD <spec>  :BREAK)

indicating that a break loop should be entered before and after the
function executes. Most implementations support this, but it is not
in CLtL. This may be an issue for the cleanup committee, however.

<<<<<<<<<<

TRACE-EXECUTION object &OPTIONAL env		[Generic Function]

TRACE-EXECUTION discriminates on object to select an implementation
specific method that arranges for the executable entity associated
with object to be traced. The optional env environment parameter is for 
those implementations which require environmental information to
arrange for tracing to occur. Implementations are required to provide
TRACE-EXECUTION as the system level entry point for implementing trace
functionality.

The exact nature and number of methods associated with TRACE-EXECUTION
will differ, depending on what function specifications are supported
by TRACE, but every implementation needs to support the following:

SYMBOL-The function indicated by the symbol will be traced when invoked
in the environment. If the function is a macro, then tracing will occur
when the macro function is invoked. If the function definition is bound to
the symbol's global function definition cell, then invocations of
the function via. its global name will be traced. If the function is a 
local function, then only invocations when the environment parameter is 
the current environment will be traced, provided the implementation can
arrange for it.

METHOD-The method function is traced when invoked.

GENERIC-FUNCTION-The generic function is traced when the discriminator
code is invoked.

FUNCALLABLE-STANDARD-CLASS-???? need more information about what
this is.

>>>>>>>>>others? Some which I can think of are:

FUNCTION-Invocation of the function is traced, regardless
of whether invocation is through a named symbol. This will obviously
depend on whether modifications in fundefs are allowed to support
tracing.










∂02-Aug-87  1725	RPG  	Miscellenia   
To:   Common-lisp-object-system@SAIL.STANFORD.EDU    

Moon writes:

``p1-17 "It is currently under discussion whether to provide constructs
for giving generic functions local names."  Do we want to have this
discussion, or to punt on this syntax. I recall we did come up with some
reasonble semantics for a GFLET and GFLABELS.''

I am willing to write up a proposal for this, basing it on our latest
thoughts from the mail, if people wish. I do not feel strongly about
this at the moment.

Moon writes:

``p2-19 Values: I thought we agreed that all top level forms should return
the object.  It says here defclass "returns the name of the class"''

I believe we originally tried to be consistent with all other DEF<mumble>s
in returning a name. I believe we decided it was ok to return an object
in CLOS DEF<mumble>s.

[Note: Hackers are proud of having invented the `mumble' convention. However,
there is rarely anything new under the sun. Here is a quote from the Saturday,
August 25, 1753 Adventurer by Samuel Johnson:

	   ``I remember,'' says he, ``it was on just such a morning as
	   this that I and my lord Mumble and the Duke of Tenterden were
	   out upon a ramble....''

``Tenterden'' is someone who tends a den.]

				-rpg-

∂03-Aug-87  1656	kempf%hplabsz@hplabs.HP.COM 	Re: Miscellenia 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 3 Aug 87  16:56:04 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 3 Aug 87 15:32:53 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 3 Aug 87 15:32:17 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 3 Aug 87 16:33:03 pdt
Message-Id: <8708032233.AA06651@hplabsz.hpl.hp.com>
To: Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Miscellenia 
In-Reply-To: Your message of 02 Aug 87 17:25:00 -0700.
Date: Mon, 03 Aug 87 16:32:57 MST
From: kempf%hplabsz@hplabs.HP.COM

> 
> ``p1-17 "It is currently under discussion whether to provide constructs
> for giving generic functions local names."  Do we want to have this
> discussion, or to punt on this syntax. I recall we did come up with some
> reasonble semantics for a GFLET and GFLABELS.''

> I am willing to write up a proposal for this, basing it on our latest
> thoughts from the mail, if people wish. I do not feel strongly about
> this at the moment.

I also don't feel strongly about it at the moment, but a proposal would be
good, if other people agree. Originally, there was some talk about a 
GFLAMBDA, but that didn't seem to make it into the document. If you're
open for suggestions, a useful primitive that might address all these
uses might be GFUNCTION, similar to the FUNCTION special form, except
it takes multiple lambda's as arguments.

> [Note: Hackers are proud of having invented the `mumble' convention. However,
> there is rarely anything new under the sun. Here is a quote from the Saturday
,
> August 25, 1753 Adventurer by Samuel Johnson:

> 	   ``I remember,'' says he, ``it was on just such a morning as
> 	   this that I and my lord Mumble and the Duke of Tenterden were
> 	   out upon a ramble....''

> ``Tenterden'' is someone who tends a den.]

Interesting. My English friends tend to use "doobrey" as an unbound in
similar circumstances, viz. DEF<doobrey>. Perhaps, in the 200 odd years
since we've been independent, the language has diverged, like the
pronounciation of "clerk".

I used to occasionally use "X" as an unbound, but, thanks to 
Bob Schieffler, that's out now.

			jak




∂04-Aug-87  2243	kempf%hplabsz@hplabs.HP.COM 	Re: Technical corrections in 87-002 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 4 Aug 87  22:43:16 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 4 Aug 87 14:52:14 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 4 Aug 87 14:51:51 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 4 Aug 87 15:52:31 pdt
Message-Id: <8708042152.AA10558@hplabsz.hpl.hp.com>
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU, olthoff%hplabsz@hplabs.HP.COM
Subject: Re: Technical corrections in 87-002 
X-Mailer: mh6.5
In-Reply-To: Your message of 28 Jul 87 15:02:00 -0700.
             <870728-150405-2277@Xerox> 
Date: Tue, 04 Aug 87 15:52:27 MST
From: kempf%hplabsz@hplabs.HP.COM


Sorry it's taken so long to answer this. 

JAK> As a counterexample, consider R := {(c1,c2) (c2,c3) (c3 c5) (c2 c4) (c4
JAK> c6)}

This is, in fact, incorrect, as Danny pointed out. It should be:

	R = { (c1,c2),(c2,c3),(c3,c4),(c3,c5),(c4,c6) }

by the algorithm at the top of pg. 1-14. But see below for more.

JAK> The inheritance graph for this is;

JAK> 		c5  c6
JAK> 		|   |
JAK> 		c3  c4
JAK> 		|   |
JAK> 		\   /
JAK> 		 \ /
JAK> 		  c2
JAK> 		  |
JAK> 		  c1


DB> This counterexample is wrong in that the inheritance graph must specify
DB> a local ordering of c3 and c4 (if vertical  means direct superclass and
DB> horizontal is an ordered list.

The intention was that the numbers would indicate the local precedence
ordering. Thus the CLOS definitions would look like:

(defclass c6 () ...)
(defclass c5 () ...)
(defclass c4 (c6) ...)
(defclass c3 (c5) ...)
(defclass c2 (c3 c4) ...)
(defclass c1 (c2) ...)

In fact, the counterexample is wrong, but the interesting fact is
WHY. The counterexample was generated by looking at the pie example
on pg. 1-15, where R is given as:

	R = { (pie,apple) (pie,cinnamon),(apple,cinnamon),(apple,fruit),
	      (cinnamon,spice),(fruit,food),(spice,food),(food,t)
	    }

However, this is incorrect. The correct value of R before the start
of CPL construction is:

	R = { (pie,apple),(apple,cinnamon),(apple,fruit),(cinammon,spice),
	      (fruit,food),(spice,food),(food,t)
	    }

This follows by merging the R(C) for each of the classes:

	R(pie) = { (pie,apple),(apple,cinnamon) }
	R(apple) = { (apple,fruit) }
	R(cinnamon) = { (cinnamon,spice) }
	R(fruit) = { (fruit,food) }
	R(spice) = { (spice,food) }
	R(food) = { (food,T) }

Thus the entry (pie,cinnamon) in R is incorrect, and leads to a lack
of the local precedence order being reflected in R.

The R in the counterexample was constructed directly from this example.

Perhaps someone has noted this before and corrected it. In any event,
I suspect that some of the confusion expressed by Sherlis and others
at the March meeting may have been a result of trying to understand
the algorithm via the example. We have had several people here run
into that problem.

DB> The partial order relationship that Dick defines is the one using the
DB> relation "is the same or is subclass of"  This one is reflexive, though
DB> we don't have a simple name for it.

This relationship should be sufficient, but I think it should be
made explicit on the top of pg. 1-14. We need not have a simple name,
as long as it is defined. Leaving it implict leaves room for confusion.

I hope whoever is the current custodian of 87-002 can make these corrections.

		jak


∂05-Aug-87  1751	Kelley.pa@Xerox.COM 	Re: ECOOP Reaction to CLOS   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 5 Aug 87  17:51:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 05 AUG 87 17:48:48 PDT
Date: 5 Aug 87 17:48 PDT
From: Kelley.pa@Xerox.COM
Subject: Re: ECOOP Reaction to CLOS
In-reply-to: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>'s message of Thu, 9
 Jul 87 13:24:38 pdt
To: kempf%hplabsz@hplabs.HP.COM
Cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870805-174848-5665@Xerox>


In dealing with the intractability of the effect of the proposed CLOS
mechanism for multiple inheritance, violation of the "implicit
inheritance - explicit override" rule should be factored out of the
complexity of the linearization algorithm.  Each contribute to the
complexity of the CLOS proposal, but hopefully by distinguishing them
and dealing with each seperately, the total complexity can be reduced.

The CLOS proposed standard explicitly claims in general to obey the
implicit inheritance - explicit override rule, but it does not for
multiple inheritance of slots and methods with the same name.  Instead,
it actually reverses the rule in this case.  Overriding is implicit and
one must explicitly inherit (via qualifiers).  

In as much as implicit inheritance is a sub-conscious assumption of
application programmers, standard CLOS behaves in a counter intuitive
manner.     

(defclass border (object) (width))
(defmethod close (b border) ...)

(defclass window (object) (width))
(defmethod close (w window) ...)

(defclass bordered-window (border window))
(setq b-window (make-instance 'bordered-window))

(close b-window)  ; with the current inheritance algorithm, only closes
the border.  Does not close the window.

The following explores what could happen if the implicit inheritance -
explicit override rule were followed in CLOS.  

(close b-window) would result in both the border and window close
methods getting called because it inherits them implicitly and has not
explicitly overridden them.  

With implicit inheritance a class may have in addition to multiple
methods with the same name that all get called by one call, multiple
occurrences of a slot with the same name that are manipulated in one
operation so b-window would contain two slots named width.

(setf (slot-value b-window width) 0)  

Would set both slots to 0.

A problem is what to do with the results of an operation on a slot name
that refers to two or more slots or on a call that refers to two or more
methods.  Operating on these slots or methods that have not been
overridden could be specified to return a "multiple-inheritance-result"
object containing the multiple results.  

Any code that depended on the results from instances of singly inherited
classes would not work correctly with instances of multiply inherited
classes. (In the example above, any code that depended on the value
returned by the "close" method on an instance of the window class would
not work on an instance of the bordered-window class.)  A blatant error
would usually be generated at run time.  A warning of potential such
behavior at definition time might be a desireable feature.

All the unqualified inherited methods with the same name would still
have to get executed in some order.  However, it would be possible to
simply specify that these operations are executed in a random order. 

 -- kirk

∂06-Aug-87  1249	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellenia       
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87  12:48:53 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208062; Thu 6-Aug-87 13:55:31 EDT
Date: Thu, 6 Aug 87 13:55 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Miscellenia   
To: Common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 2 Aug 87 20:25 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870806135534.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 02 Aug 87  1725 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Moon writes:

    ``p1-17 "It is currently under discussion whether to provide constructs
    for giving generic functions local names."  Do we want to have this
    discussion, or to punt on this syntax. I recall we did come up with some
    reasonble semantics for a GFLET and GFLABELS.''

    I am willing to write up a proposal for this, basing it on our latest
    thoughts from the mail, if people wish. I do not feel strongly about
    this at the moment.

Please do write the proposal.  But I wouldn't consider this high priority
at the moment, since you don't feel strongly about it and no one else has
said they feel strongly.

∂06-Aug-87  1249	Moon@STONY-BROOK.SCRC.Symbolics.COM 	TRACE Proposal (Version 1)  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87  12:49:12 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208071; Thu 6-Aug-87 14:09:57 EDT
Date: Thu, 6 Aug 87 14:10 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: TRACE Proposal (Version 1)
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU, Masinter.pa@XEROX.COM
In-Reply-To: <8707311807.AA10361@hplabsz.hpl.hp.com>
Message-ID: <870806141000.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Fri, 31 Jul 87 12:07:37 MST
    From: kempf%hplabsz@hplabs.HP.COM

    As promised, here is an initial draft of a proposal for modifying the
    TRACE macro (CLtL, pp. 440-441) to better support object-oriented
    programming....

This looks interesting.  I have a couple of comments to offer right now.

    A function-spec is either a symbol naming a function (i.e. a symbol
    whose global function cell is bound to a function definition object)
    or a list whose first element is a function specification type, and 
    whose tail indicates which particular function of that type should 
    be traced. 

The Cleanup subcommittee of X3J13 were discussing something similar
a while back, starting from a different point.  The DOCUMENTATION function
of Common Lisp introduces the concept of "definition types", and this
concept could be useful in other operations.  For instance, it would be
nice to be able to remove any definition (function, variable, type, setf)
through a uniform interface.  "Definition type" and "function spec type"
are not the same concept, however there seems to be enough overlap here
that some coordination is probably called for.

I don't remember for sure, but I think Larry Masinter volunteered to make
a proposal for "definition types" when he got time.

    ....
    Note: Another useful enhancement would be to support a :BREAK flag, like
    this:

	    (:METHOD <spec>  :BREAK)

    indicating that a break loop should be entered before and after the
    function executes.

Here you see a conflict between lists as function-specs and lists as
lists of options, in the arguments to TRACE.  Because of this your proposal
for TRACE is not compatible with what Symbolics currently does, but I don't
think that's too important for us.  We say that a list is a list of options,
and if you want to trace a function whose name is a list, you have to do
(TRACE (:function <function-spec> <options>...)).  But all this really
shows is that the syntax of TRACE is ridiculous.  I usually ignore the TRACE
function and trace things through a command interface.  Anyway, for your
proposal you have to decide between lists as function specs and lists as
options; I don't think you can mix them freely as you proposed.  Of course
it would be a lot easier if TRACE only traced one function at a time,
then the rest of the form could be used for options.  That would be a bit
incompatible with CLtL.

    TRACE-EXECUTION object &OPTIONAL env		[Generic Function]

I didn't completely understand this.  It looks like there is some
incoherence about whether TRACE is an operation on functions or on
places in which you can store a function definition.  In other words,
does tracing a function redefine the function or alter the object that
is the function's definition?  In other words, does
  (defun foo () ...)
  (setq f #'foo)
  (trace foo)
  (funcall f)
generate trace-output or not?  We have to decide one way or the other.
CLtL is obscure on this point.

∂06-Aug-87  1914	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Name That Class    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87  19:14:07 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208497; Thu 6-Aug-87 22:14:54 EDT
Date: Thu, 6 Aug 87 22:14 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Name That Class    
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <870728-192157-1316@Xerox>
Message-ID: <870806221457.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 28 Jul 87 19:21 PDT
    From: Gregor.pa@Xerox.COM

    It seems to me that there are ways for class-named and setf of such to
    work.  I think only two of these are reasonable, but I will include the
    third for completeness.  Note that this same analysis applies to
    generic-function-name and setf of symbol-function and
    get-setf-generic-function.  I will do class names first.

    A class C 'is bound to' a given name Ni iff (class-named Ni) returns C.

    In all this solutions, we document class-named and setf of class-named.
    We say that class-named returns the class is bound to a particular name.
    We say that setf of class-named can be used to set the binding of a
    class to a name.

All agreed, except I think we decided a month ago to rename class-named to
symbol-class, to be more consistent with the rest of Common-Lisp.

    Solution 1:
      Only document class-named and setf of class-named.  Most
    implementations will have some magic for printing out a class's name
    when it has one.

    Solution 2:
      Document class-named and setf of class-named.  Also document
    class-name, but say that the the class may or may not 'bound' to that
    name.

    Solution 3:
      Document class-named and class-names and setf of class-named.  Say
    that setf of class-named can be used to bind a clas to a name.  Say that
    class-names returns the list of all names that a class is bound to.

    It seems to me that solution 1 and solution 3 are the only reasonable
    ones.  My general dislike of names makes me prefer solution 1, but I
    think that solution 3 actually provides users some important
    functionality.

That's interesting, because I prefer solution 2, for the simple reason
that everything else I can think of that has a name works that way.  The
symbol->object mapping is the "real" one, and the object->symbol mapping
is only a helpful hint for printing things out, but isn't necessarily kept
consistent with the symbol->object (a programming environment might try
to keep it consistent).

As far as I am concerned, any of these three would work.  My objection
to solution 3 is primarily that it is more complicated.  My objection to
solution 1 is that it is the same as solution 2 as soon as the users
discover what the name of the class-name function is, and no useful
purpose is served by making this name implementation-dependent.

    ....
    (setf (class-named 'n1) nil)
    #<Standard-Class N2 1>

Is this really how we want to undo these bindings?  Nothing else in Common
Lisp I can think of works this way (storing nil).  Also, a minor nit, CL
requires that such a setf form return nil, not the former value.

    I think its easy to see how this whole thing would work for
    generic-function-name, symbol-function, setf of symbol-function,
    get-setf-generic-function and setf of get-setf-generic-function.

Agreed.  Note that (setf (symbol-function 'foo) nil) isn't how we do
(fmakunbound 'foo) in CL currently.

∂06-Aug-87  1929	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 6 Aug 87  19:29:18 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208512; Thu 6-Aug-87 22:29:57 EDT
Date: Thu, 6 Aug 87 22:30 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Miscellaneous decisions taken or to be taken
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870727224638.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <870806223002.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

I have updated my file of miscellaneous decisions taken or to be taken,
based on my notes from the meeting we had in July and on mail received
in response to the last time I mailed this out (about two weeks ago).
If anyone doesn't see their response included, or thinks their favorite
issue is missing, please let me know and I will apologize for my error
and add it.  I hope that we can use this file to help drive progress.
The major issues of object creation and class redefinition are not in
here, being handled individually.

The rest of this message is the file.  Page separator characters don't
seem to go through, so I have replaced each with 16 equal signs.

This page is things that I think we agreed that we had decided
after the March meeting and before the July meeting.

27 May 87 call-next-method is allowed to take arguments, however it is
  an error to give it arguments that would change the set of applicable
  methods.  I think we're saying this signals an error, and mentioning
  that in some simple cases the lack of need for an error check can be
  proved at compile time, but in general a run-time check is required.
  Specify precisely the type of error signalling.

10 June 87 There was no response when Sonya mailed out a writeup for how
the standard type classes are organized.  Does that mean we agreed on that?

  Patrick agrees 7/29/87.  It's in the document file now.

p2-19 Values: I thought we agreed that all top level forms should return
the object.  It says here defclass "returns the name of the class"
p2-22 Same comment as 2-19, for defgeneric-options
2-24 ditto for defgeneric-options-setf

  Kempf agrees they should return the object.  Moon isn't sure, because
  defun, defvar, deftype, and defstruct return the name.  As far as I can
  tell every defxxx form in CLtL returns the name.  The problem is that
  we haven't admitted that defmethod has a name.

  In July we decided (for the previous three) to return the object for
  all CLOS defxxx functions (being inconsistent with Common Lisp, but
  consistent within CLOS).  The document file has been updated.
================
This page is a list of issues on which we should make decisions,
brought up by Danny.  Where I saw responsive answers in the mail
(there were very few) I have edited them in.  I've removed comments
that were purely editorial comments on the document.

p1-12 Should defclass be allowed to change the metaclass of an existing
class? Under what conditions should a subclass of standard-class have
the same properties wrt instance updating as standard class?

  Kempf says you shouldn't be allowed to change the metaclass, because
  the representations might differ and existing instances might not
  be transformable.

  Gregor says the metaclass protocol includes a predicate function
  that controls this, and Patrick and Jim agree.

p1-17 "It is currently under discussion whether to provide constructs
for giving generic functions local names."  Do we want to have this
discussion, or to punt on this syntax. I recall we did come up with some
reasonble semantics for a GFLET and GFLABELS. 

  In July we decided to defer this.
  2 Aug 87 RPG offered to write a proposal.

p1-18 It is not specified whether get-setf-generic-function is a
setf-able form.  I suggest that it be made so.  This would allow one to
trace setf-generic-function's without having to know their names.

  This set off a discussion of how TRACE should work that maybe doesn't
  bear directly on CLOS.  Kempf is working on a proposal.

  Moon thinks this would be okay provided it is understood as setting the
  mapping from a name to a generic function, not side-effecting the
  generic function.  See class-name discussion below (2-13).

p1-19 "... Common Lisp be modified to include the following semantics
for quote in a type specifier:
 (deftype quote (object) '(member ,object)))"

Has any proposal for this been given to the cleanup committee? 

  Yes: ISSUE: TYPE-MEMBER-SINGLETON, Proposal TYPE-MEMBER-SINGLETON:QUOTE 
  It hasn't really gone through the mill yet, though.
  In July Moon volunteered to make sure this happens.

p1-24 Should we have a call-next-method? which calls such a next method
if it exists, else returns nil (rather than signalling an error?).  This
seems useful rather than having to define many base methods on object.

  Common Lisp reserves question mark for the user; this could be named
  CALL-NEXT-METHOD-OR-NIL, or something like that.
  Kempf: signalling an error is sufficient, this probably isn't needed.

  In July we wondered whether there should be a way to get a list of
  the remaining methods.  I'm not sure what operations on that list,
  besides checking its length, would be permitted.

2-13(?) The generic function class-name is not written up.  It returns a
name for the class as argument.  I believe that (class-name class)
should be setf-able. Can a class have more than one name? Should
class-name then return a second argument -- the rest of the names this
class is known by.  

  Kempf thinks the class name should be changeable and only one name
  at a time should be allowed.  Moon agrees.
  See additional discussion of class names below (2-13).

We need to decide whether class-name of an anonymous class is nil or
signals an error.

  The concensus seems to be to return nil.

p2-26  I believe that short form method combination ought to be a macro
in the standard library, and documented there, not in the basic
principles.  I think the standard combinations :append, :and, :or, ...
should also be put in the standard library too.
  
  Kempf agrees.  Moon can't have an opinion until he knows what this
  library is and whether it's going to be as much of a joke as the
  Common Lisp Yellow Pages.

p2-35 The argument order of the setf method ought to be documented here.
Gregor proposed that new-value be the first argument.  Any problem with
this?

  Kempf doesn't care but his users want it to be the second argument.
  Moon doesn't care but his users are used to it being the last argument.

  In July we suggested making the new-value argument a required argument that
  comes after all the other required arguments, and before the optional, rest,
  and keyword arguments.  Then we said we'd discuss it further in the mail.
  I think we agreed that the turning of two setf argument lists into one should
  depend only on the argument lists, and not on the generic function object.
  [My notes include an illegible comment, I think it means that I still hope
   we can keep things abstract enough that we don't have to document
   how the two setf argument lists are turned into one.  But maybe it means that
   we will document it, but still have defmethod-setf so that most users
   don't have to think about it (only users making setf methods "directly").]

p2-39 Arguments: "list of t's" should be replaced by "list whose elements are
the class named t" since get-method only takes specializers, not names of
specializers.

  Agreed.

p2-46 Last line:  If call-next method is extended ..."  I see no reason
for additional keyword arguments.  

  Moon doesn't remember the issue.  It may have been consistency; if call-next-method
  can specify the arguments, then so can make-method-call.  You need one keyword
  argument to specify the methods and another to specify funcall versus apply.
  It could also have been that call-next-method would be implemented in terms of
  make-method-call, and therefore would need to be able to specify the arguments.

p2-51 print-object should take a depth argument.

  Moon strongly disagrees and points to the fourth bullet.  I believe this issue
  was discussed to death on the Common Lisp mailing list a few months or a year ago.
  The point is that every single method for print-object should not have to deal
  with *print-level*; that's unmodular.

  Kempf raised a consistency argument (with defstruct?) but we decided
  not to change print-object.

p2-54 slot-missing should be documented

  It's a generic function of a class, an object, and a slot name.
  I suppose the default method signals a condition of the same name?
  Gregor will propose the details.
================
This page is a list I made in March, keyed by page numbers in the document. 
Issues mentioned earlier, or that have since died, have been removed.  I've
removed comments that were purely editorial comments on the document.

2-6 call-next-method dynamic versus indefinite extent

  The document says it has dynamic extent; we need to be sure that we
  really mean that.  In July we said "implementation flexibility, not
  really a language thing", but I'm damned if I can figure out what
  that means (optimizing calculation of the effective method?).

2-9 semantic difficulties discussion was shortened for the document so much
that much of the point was lost.  At some point we need to decide how much
we want to standardize about this and where we want to say it; in the main
standard or in some kind of implementation guide.

2-13 class-named needs a new name for consistency.  get-class would be wrong
because the other get-xxx functions aren't name operations.  symbol-class is
the agreed name.  It needs an environment argument to deal with the issue of
compile environment versus run-time environment.  The errorp argument gets in
the way, because it's an optional argument--we could get rid of it, or we
could make both arguments keywords.  I think we agree that symbol-class
should be setf'able, but can it only be set once for a given symbol or is it
allowed to change the symbol-to-class-object mapping?

  Kempf: Need consensus on a general solution of the compile environment
  issue before fixing individual functions such as symbol-class.
  The symbol-to-class-object mapping should be changeable.
  Bobrow: symbol-class should be setf'able.
  Gregor: setf'able.  Issue is consistency of symbol-class with class-name.
  1) No class-name. 2) No consistency. 3) class-names returns a list of
  names and setf of symbol-class maintains it.  2 is unreasonable.
  I like 1 but 3 is good too.
  (setf (class-named 'n1) nil) is how you undo the binding.
  Note that this same analysis applies to generic-function-name and
  setf of symbol-function and get-setf-generic-function.
  Bobrow: I like 3.
  Moon: class-names would need an environment argument too.
  I guess any of these is okay but 2 is how everything else works.
  I don't like undoing the binding by setting to NIL (CL Cleanup
  may propose a general mechanism for undoing named definitions).

2-16 (slot-name form) should be allowed as an abbreviation
for (slot-name :initform form).  People have been assuming this,
but it never finds its way into the document.

  In July we rejected this.  Since people keep assuming it, we have
  to document explicitly that it is not allowed.

2-16 boa-arglist should support &key and &allow-other-keys.
2-18 default boa-arglist to be specified

2-18 (:accessor-prefix nil) is not a good way to say "use the slot names
as the accessor names".  We need to fix this.

  We could add another option, or remove the whole prefix feature, and
  require accessor names always to be listed explicitly.
  In July we agreed to discuss this in the mail.

2-19 uninitialized slots should be an error to reference, not be defined
to return an unstandardized value with no error.  I'm willing not to require
that it signals an error if people feel that would be an undue burden,
otherwise I prefer that reading an uninitialized slot signals an error.

  In July we decided that signalling an error here should depend on the
  declared safety level.  Dick has proposed terminology for this.
  Kempf: it should signal an error.

2-38 need a way to recover documentation of a method-combination type

  July: do this by adding a new value for the second argument to DOCUMENTATION.
  But the whole writeup on DOCUMENTATION is screwy, and we need a new proposal.
  When the CL-Cleanup subcommittee finishes cleaning up the concept of
  "definition" (I think it's waiting for Masinter to propose something)
  then DOCUMENTATION should follow.

2-40 get-setf-generic-function needs an errorp, but it and ensure-generic-function
should be subsumed by get-generic-function which would do all the right things.
We seem to have lost Gregor's proposal for get-generic-function.
Or was it called ensure-generic-function?

  Gregor promised to mail out the proposal.

2-42 make-generic-function should be deleted, redocumented as a class
that can be given to make-instance

  July: Agreed

2-45 make-method should be deleted, redocumented as a class
that can be given to make-instance

  July: Agreed

2-57 with-slots :prefix package problem; This was discussed in the mail and
then the ball was dropped.  What's in the document is unworkable because it
depends on the dynamic value of *package* at macro-expansion time, but Common
Lisp doesn't guarantee anything about when macro-expansion occurs.  Moon would
prefer to flush the :prefix option.  An alternative that was discussed was to
use symbol-package of the prefix, both here and in defclass accessor construction,
as the package, relying on the likelyhood of prefixes always ending in delimiter
characters and exported symbols never ending in delimiter characters.

  July: We agreed to resolve this in the mail.
  Kempf, Moon: Flush :prefix.

2-57 What does with-slots do for slots that exist in the class but don't
have accessors, when :use-accessors t is specified (or defaulted)?

  July: it shadows any outer bindings of the slot name, and if you
  actually access that pseudo-variable, it signals an error.

================
Documented holes in chapters 1 and 2 of 87-002.  We publicly promised
X3J13 that we would finish these and have a new draft of 87-003 by the
next meeting.

1-5, 2-44 The initialization protocol for make-instance is not yet
specified.

1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes
is still under discussion.

  Document has been updated in draft.
  Need Cleanup Committee proposals for fixes to the type system.

2-7, 2-46 [The proposed extension to call-next-method has been accepted.]

  This may not have been put into the document yet.

2-41, 2-48 [Perhaps we can adopt the condition signalling system now.]
================
Other issues:

What can be done with method objects, e.g. can one method be added
to more than one generic function?

  Kempf: There may be a problem if the method invokes CALL-NEXT-METHOD.
  [I wasn't able to understand his description of the problem -- Moon]

Ida: make-specializable seems to be missing

  Gregor's proposal for ensure-generic-function will subsume this.

Moon: method arglist congruence still doesn't satisfy me.  I have some
ideas about this but unfortunately have not managed to pull them together.

  To be resolved as part of the initialization protocol discussion.

Should we just flush multiple-value-prog2, as leading to more discussion
than is warranted by its simplification of the presentation of
define-method-combination?

  Kempf: Yes.

Which symbols defined by the standard go in what package?

  July: I think we said some will go in LISP: and some will go in CLOS: and
  we don't know yet where to draw the line.
  The top level macros and functions should be part of LISP.
  The internal functions specified for the sake of metaclass programming
  can reside in CLOS.
  If CLOS is an optional part of CL, are the symbols in the LISP package
  even when the option is not present?  Probably.

Should we flush defmethod-setf and friends in favor of function specs?
It probably turns out they could be just in the macros and not in the
underlying Lisp.  The big issue is standardizing where the "new-value"
argument goes; but we may do that anyway (mentioned earlier in this file).
What about the setf of values extension that Common Lisp provides syntactic
space for but does not currently prescribe?

  Kempf: I think we ought to keep DEFMETHOD-SETF, but use function specs (or
  something like them) as the programmer interface to TRACE.

Should we adopt the :component-order class-option from Flavors, as a
simple way for the user to have control of the CPL without making him
write his own algorithm?

  Gregor doesn't like the ability to specify constraints on the ordering
  of classes that only apply conditionally, i.e. if those classes are
  actually present among the superclasses.  He considers this bad style.
  Moon volunteered to write a proposal with some examples, and we agreed
  to resolve this over the mail.

The fact that symbol-function (the user callable primitive) needs to
be split from the subprimitive for implementators that gets and sets
the "real" function definition of a symbol.  This is so when a symbol's
function definition is a generic function object, the "real" definition
can be something that is easier for the implementation to call.

  July: We need to say explicitly somewhere that calling symbol-function
  of the name of a generic function is required to return the generic
  function object, not the "real" definition.
  Kempf: I don't see splitting SYMBOL-FUNCTION as an issue for the standard,
  though it may be for certain implementations.
  Moon: Right, the only standardization issue is making sure
  SYMBOL-FUNCTION returns the generic function object, not something internal.
  See earlier discussion of class-names (2-13), which affects symbol-function.

I'm not sure if we said anywhere what happens when you call a generic
function and there is no applicable method; I think it ought to signal
an error.

  Gregor volunteered to send some mail about this.
  CALL-NEXT-METHOD with no more methods should do something similar,
  but not identical.
  We could call a generic function like NO-MATCHING-METHOD, but it would
  be better to signal a condition (assuming conditions are adopted into
  Common Lisp).  The error message should give some information about
  the classes of the parameters, to help debugging.

Clarify that because class names and classes are type-specifiers, they can be
validly be used in THE special forms and in TYPE declarations.  We forgot this
when we clarified that class objects can be used with TYPEP and SUBTYPEP.

  July: agreed

funcallable-standard-class should be documented.  It is a metaclass.
This is what makes generic function objects funcallable.  There is a slot
that is the actual function that gets called.

  I think Gregor volunteered to propose details.

Need to be able to get at the obsolete classes associated with a class,
to put methods on them.

  Patrick has proposed.
  Need discussion of how instances are transformed one step at a time
  when a class has been redefined multiple times.

Not all of the "corrections and amendments" handed out at the March 1987
X3J13 meeting in Palo Alto have been put into the document yet.  The
corrections are in but the amendments and the revised explanation of slot
inheritance are awaiting review by the group.

Kempf 29 Jul 87: There was no mention made of compile time optimization,
which I believe I made some initial proposals on in late April or early May.
I've been meaning to revisit them.

2-30: Note the third paragraph on p.2-30 of 87-002, speaking of signalling an
error when the arbitrary order of two methods affects the result.  I suggest
that this error be mandatory instead of optional.

∂09-Aug-87  1514	Gregor.pa@Xerox.COM 	Miscellaneous decisions taken or to be taken
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Aug 87  15:14:01 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 09 AUG 87 15:14:26 PDT
Date: Sun, 9 Aug 87 15:14 PDT
From: Gregor.pa@Xerox.COM
Subject: Miscellaneous decisions taken or to be taken
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870809151423.5.GREGOR@SPIFF.isl.parc.xerox.com>
Line-fold: no


    Date: Thu, 6 Aug 87 22:30 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
    
    I have updated my file of miscellaneous decisions taken or to be taken,
    based on my notes from the meeting we had in July and on mail received
    in response to the last time I mailed this out (about two weeks ago).   

In the usual way, I have included only parts of your message on which
I am making specific comments.  In several places I have sketched
proposal which were on my to do list.  I am about to go away for a
week and don't have time between now and then to flesh these
proposals out, but I think they are fairly clear from the sketches. 

    

    10 June 87 There was no response when Sonya mailed out a writeup for how
    the standard type classes are organized.  Does that mean we agreed on
    that?
    
      Patrick agrees 7/29/87.  It's in the document file now.

I have it on my list of things to do to come up with a picture of how
all the standard classes (including standard type classes) are
organized.  I have this on the whiteboard in my office now.  In a
separate message, I will send out the name of a press file which
contains a simple version of such a picture.  If people could FTP
that press file and try printing it, then I could now if its worth
trying to cast the whole picture in that format.


    
    p1-18 It is not specified whether get-setf-generic-function is a
    setf-able form.  I suggest that it be made so.  This would allow one to
    trace setf-generic-function's without having to know their names.
    
      This set off a discussion of how TRACE should work that maybe doesn't
      bear directly on CLOS.  Kempf is working on a proposal.
    
      Moon thinks this would be okay provided it is understood as setting the
      mapping from a name to a generic function, not side-effecting the
      generic function.  See class-name discussion below (2-13).

Yes, I believe get-setf-generic-function should be a setfable form
with the same provision as Moon mentions.  The way to think of
get-setf-generic-function is just like symbol-function and
symbol-class.  (This may mean that it would be appropriate to rename
it to symbol-setf-generic-function.)  Later in this message, I will
make some other comments which address this issue. 
    

    
    p1-24 Should we have a call-next-method? which calls such a next method
    if it exists, else returns nil (rather than signalling an error?).  This
    seems useful rather than having to define many base methods on object.
    
      Common Lisp reserves question mark for the user; this could be named
      CALL-NEXT-METHOD-OR-NIL, or something like that.
      Kempf: signalling an error is sufficient, this probably isn't needed.
    
      In July we wondered whether there should be a way to get a list of
      the remaining methods.  I'm not sure what operations on that list,
      besides checking its length, would be permitted.

I am not sure what you mean by this.  Surely other non-destructive
operations would be legal as well.  For example, one could implement
some sort of "tracing" :around method by having it get the list of
next methods, and calling each of their functions.  But clearly it
would not be legal to rplaca or rplacd that list. 
    


    2-13(?) The generic function class-name is not written up.  It returns a
    name for the class as argument.  I believe that (class-name class)
    should be setf-able. Can a class have more than one name? Should
    class-name then return a second argument -- the rest of the names this
    class is known by.  
    
      Kempf thinks the class name should be changeable and only one name
      at a time should be allowed.  Moon agrees.
      See additional discussion of class names below (2-13).

As I said in another message, I don't believe class-name should be
setfable.  symbol-class (nee class-named) should be setfable, it is
possible that it should update class-named as well, the details of
how that updating might work were the subject of my other message.

Even if we decide that class-name should return at most one name, I
think it is clear that a class can have more than one name.  That is,
it is legal to use setf of symbol-class to make the multiple symbols
point to the same class. 
    

    
    p2-35 The argument order of the setf method ought to be documented here.
    Gregor proposed that new-value be the first argument.  Any problem with
    this?
    
      Kempf doesn't care but his users want it to be the second argument.
      Moon doesn't care but his users are used to it being the last argument.
    
      In July we suggested making the new-value argument a required argument
      that comes after all the other required arguments, and before the
      optional, rest, and keyword arguments.  Then we said we'd discuss it
      further in the mail.

      I think we agreed that the turning of two setf argument lists into one
      should depend only on the argument lists, and not on the generic
      function object.
      [My notes include an illegible comment, I think it means that I still
      hope we can keep things abstract enough that we don't have to document
      how the two setf argument lists are turned into one.  But maybe it
      means that we will document it, but still have defmethod-setf so that
      most users don't have to think about it (only users making setf
      methods "directly").]

I have several coments.

First, I believe it is very important that this operation only be a
function of the two lambda lists.

Second, I would rather the rules of this operation be documented.
That is, I would not be as happy if we just provided a function
(make-setf-method-lambda-list) which did the work.  Providing that
function in addition to documenting its behavior might be a good idea
though.

Third, as we agreed, its fine with me to have it be the last required
argument.  But I think we need to be careful how we word this.
Because we have to make it clear what happens in implementations
which have non-standard lambda-list-keywords.



    p2-54 slot-missing should be documented
    
      It's a generic function of a class, an object, and a slot name.
      I suppose the default method signals a condition of the same name?
      Gregor will propose the details.

slot-missing is a generic function which takes three required
arguments and an optional fourth argument.  The three required
arguments are the class of the object, the object and the name of the
slot.  The fourth argument is the new value for the slot if
slot-missing is being called by setf of slot-value.  This set of
arguments allows people to define methods on the metaclass for
handling slot-missing.  For example, a low performance implementation
of dynamic slots could work this way.

(defmethod slot-missing ((class dynamic-class) obj slot
                         &optional (nv nvp))
  (if nvp
      (set-dynamic-slot obj slot nv)
      (get-dynamic-slot obj slot)))

The default method on slot-missing signals an error of the same name.


    
    2-6 call-next-method dynamic versus indefinite extent
    
      The document says it has dynamic extent; we need to be sure that we
      really mean that.  In July we said "implementation flexibility, not
      really a language thing", but I'm damned if I can figure out what
      that means (optimizing calculation of the effective method?).

I am pretty sure what we meant was we didn't want to have to worry
about the case where someone returns a closure that includes a call
to call-next-method, and then redefines the class or method structure
so that the closure would have to call different 'next methods'.

    
    2-13 class-named needs a new name for consistency.  get-class would be
    wrong because the other get-xxx functions aren't name operations.
    symbol-class is the agreed name.  It needs an environment argument to
    deal with the issue of compile environment versus run-time environment.
    The errorp argument gets in

    the way, because it's an optional argument--we could get rid of it, or we
    could make both arguments keywords.  I think we agree that symbol-class
    should be setf'able, but can it only be set once for a given symbol or
    is it allowed to change the symbol-to-class-object mapping?
    
      Kempf: Need consensus on a general solution of the compile environment
      issue before fixing individual functions such as symbol-class.
      The symbol-to-class-object mapping should be changeable.
      Bobrow: symbol-class should be setf'able.
      Gregor: setf'able.  Issue is consistency of symbol-class with class-name.
      1) No class-name. 2) No consistency. 3) class-names returns a list of
      names and setf of symbol-class maintains it.  2 is unreasonable.
      I like 1 but 3 is good too.
      (setf (class-named 'n1) nil) is how you undo the binding.
      Note that this same analysis applies to generic-function-name and
      setf of symbol-function and get-setf-generic-function.
      Bobrow: I like 3.
      Moon: class-names would need an environment argument too.
      I guess any of these is okay but 2 is how everything else works.
      I don't like undoing the binding by setting to NIL (CL Cleanup
      may propose a general mechanism for undoing named definitions).

If this whole mess isn't an argument for a lisp-1 I don't know what
is.  At this point I guess we need:

  symbol-class
  symbol-setf-generic-function
  (both of the above need to be setfable)
  (there needs to be a mechanism for making each unbound)
  (we need to decide how they interact with class-name and
   generic-function-name)

    

    2-16 boa-arglist should support &key and &allow-other-keys.
    2-18 default boa-arglist to be specified

The current initialization proposal doesn't have constructors?

    
    
    2-40 get-setf-generic-function needs an errorp, but it and
    ensure-generic-function should be subsumed by get-generic-function
    which would do all the right things.

    We seem to have lost Gregor's proposal for get-generic-function.
    Or was it called ensure-generic-function?
    
      Gregor promised to mail out the proposal.

I propose that we keep get-setf-generic-function, but that we rename it to
symbol-setf-generic-function.  In addition, I propose that we do the
following:

  ensure-generic-function, add-named-method and any other CLOS
  function that takes the name of a generic function as an argument
  can also take a list like (SETF <symbol>) which means the
  setf-generic function for that argument.

I propose that ensure-generic-function do basically what
defgeneric-options and defgeneric-options-setf used to do except that
ensure-generic-function would be a function (that is it would
evaluate its arguments).  This isn't a problem since
defgeneric-options didn't take any &body arguments anyways.  The real
thing that needs to be worked out here is what happens if the generic
function already exists, but is different in some ways than the
description in the arguments to ensure-generic-function.
    


    2-57 with-slots :prefix package problem; This was discussed in the mail
    and then the ball was dropped.  What's in the document is unworkable
    because it depends on the dynamic value of *package* at macro-expansion
    time, but Common Lisp doesn't guarantee anything about when
    macro-expansion occurs.  Moon would prefer to flush the :prefix option.
    An alternative that was discussed was to use symbol-package of the
    prefix, both here and in defclass accessor construction, as the package,
    relying on the likelyhood of prefixes always ending in delimiter
    characters and exported symbols never ending in delimiter characters.
    
      July: We agreed to resolve this in the mail.
      Kempf, Moon: Flush :prefix.

I like the prefix option, although I agree that this is a serious
problem.

    2-57 What does with-slots do for slots that exist in the class but don't
    have accessors, when :use-accessors t is specified (or defaulted)?
    
      July: it shadows any outer bindings of the slot name, and if you
      actually access that pseudo-variable, it signals an error.

What if by the time you actually run the body of the method, the slot
has an accessor.  That is to say, what if you do the following:

(defclass foo () (a b c))

(defmethod bar ((o foo))                ;Put this in a file,
  (with-slots (o) (list a b c)))        ;compile and load it.

(defclass foo ()
    (a b c)
  (:accessor-prefix foo-))

(bar (make-instance 'foo))

Does this signal an error?  It seems to me that the real problem with
this case is the same as the real problem with the above case.  It
all hinges on exactly when macro-expansion time is and that is not
specified. 
    



    Other issues:
    
    What can be done with method objects, e.g. can one method be added
    to more than one generic function?

I believe it should signal an error to attempt to put a method on
more than one generic function.  My model of this is that if you want
to do something like that, you can take one function, use it as the
method function of multiple methods, each of which would be on a
different generic function.




    I'm not sure if we said anywhere what happens when you call a generic
    function and there is no applicable method; I think it ought to signal
    an error.
    
      Gregor volunteered to send some mail about this.

This is a generic function like slot-missing.  There is a generic
function NO-MATCHING-METHOD which is called with the generic function
as the first argument and the arguments to the generic function as
the remaining arguments.  This allows people to defined method to
handle the no matching method case either on the class of the generic
function or on the individual generic function.  The default method
for no-matching-method signals an error of the same type.
-------

∂10-Aug-87  1122	kempf%hplabsz@hplabs.HP.COM 	Re: Name That Class  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Aug 87  11:21:44 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 10 Aug 87 11:14:59 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 10 Aug 87 11:14:33 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 10 Aug 87 12:15:19 pdt
Message-Id: <8708101815.AA15913@hplabsz.hpl.hp.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Name That Class 
In-Reply-To: Your message of Thu, 06 Aug 87 22:14:00 -0400.
             <870806221457.8.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Mon, 10 Aug 87 12:15:15 MST
From: kempf%hplabsz@hplabs.HP.COM


> As far as I am concerned, any of these three would work.  My objection
> to solution 3 is primarily that it is more complicated. 

In addition to this objection to solution 3, another is that while other things
(particularly functions) can be multiply named, there
is currently no portable way in CL to get the name (or names) of
a function given a function definition object. If we are going to model
class object naming similarly to function naming (as the name SYMBOL-CLASS
seems to indicate) then we should probably be consistent with the way
functions are done, or suggest that a FUNCTION-NAME or a FUNCTION-NAMES
function be introduced which provides similar functionality; otherwise,
people may become confused. But see below for further thoughts.

>     ....
>     (setf (class-named 'n1) nil)
>     #<Standard-Class N2 1>

> Is this really how we want to undo these bindings?  Nothing else in Common
> Lisp I can think of works this way (storing nil).  Also, a minor nit, CL
> requires that such a setf form return nil, not the former value.

>     I think its easy to see how this whole thing would work for
>     generic-function-name, symbol-function, setf of symbol-function,
>     get-setf-generic-function and setf of get-setf-generic-function.

> Agreed.  Note that (setf (symbol-function 'foo) nil) isn't how we do
> (fmakunbound 'foo) in CL currently.

Your observation about undoing bindings is correct, and, again, to maintain
consistency, CMAKUNBOUND would be the way do this if class name to
object binding is modelled on function name to object binding.

We seem to be slowly drifting towards using a name to object binding
for classes which is modelled on the way function name to object bindings
are handled.  I wonder how useful the function model is for modelling 
class name to object bindings. In particular, is this going to lead to 
the proposal of a "class cell" like the "function cell" for a symbol? 
Considering the controversy surrounding the latter, I certainly hope not. 

Somehow, I would prefer a more object-oriented approach to resolving this
problem. Two ways which I can think of offhand are:

1) Have the class name be a SETFable slot in the class object. SETFing
a class object's name slot to NIL would be equivalent to making the class 
anonymous, if we abide by the convention that asking for the name of
an anonymous class returns NIL (as was discussed in another note string).

2) Have the name to class object binding for an entire class be handled
by the metaclass protocol. 

Of the two, I prefer the second one, since it gives some flexibility
for users wanting to define new metaclasses, and also gives some potential
for resolving the compile time name to object mapping, since the metaclass
can potentially control this, but perhaps in an implementation dependent
manner.

I'm willing to write up a proposal on this, if there is any interest.
Though I prefer a more object-oriented approach, I think it is important 
that the name to object mapping issue be resolved in a way that is self 
consistent and consistent with the rest of Common Lisp.


			jak



∂10-Aug-87  1145	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Name That Class 
Received: from [128.81.41.223] by SAIL.STANFORD.EDU with TCP; 10 Aug 87  11:45:49 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 152618; Mon 10-Aug-87 14:42:59 EDT
Date: Mon, 10 Aug 87 14:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Name That Class 
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
In-Reply-To: <8708101815.AA15913@hplabsz.hpl.hp.com>
Message-ID: <870810144215.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Mon, 10 Aug 87 12:15:15 MST
    From: kempf%hplabsz@hplabs.HP.COM

    2) Have the name to class object binding for an entire class be handled
    by the metaclass protocol. 

    Of the two, I prefer the second one, since it gives some flexibility
    for users wanting to define new metaclasses, and also gives some potential
    for resolving the compile time name to object mapping, since the metaclass
    can potentially control this, but perhaps in an implementation dependent
    manner.

    I'm willing to write up a proposal on this, if there is any interest.

I don't understand how this could work.  If one is given a class name and
one wants to find the corresponding class object, how do you know what
metaclass is relevant before you have found the class object?

∂10-Aug-87  1419	kempf%hplabsz@hplabs.HP.COM 	Re: TRACE Proposal (Version 1) 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Aug 87  14:18:43 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 10 Aug 87 10:45:16 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 10 Aug 87 10:44:48 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 10 Aug 87 11:45:34 pdt
Message-Id: <8708101745.AA15689@hplabsz.hpl.hp.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU, masinter.pa@XEROX.COM
Subject: Re: TRACE Proposal (Version 1) 
In-Reply-To: Your message of Thu, 06 Aug 87 14:10:00 -0400.
             <870806141000.0.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Mon, 10 Aug 87 11:45:31 MST
From: kempf%hplabsz@hplabs.HP.COM


>     A function-spec is either a symbol naming a function (i.e. a symbol
>     whose global function cell is bound to a function definition object)
>     or a list whose first element is a function specification type, and 
>     whose tail indicates which particular function of that type should 
>     be traced. 

> The Cleanup subcommittee of X3J13 were discussing something similar
> a while back, starting from a different point.  The DOCUMENTATION function
> of Common Lisp introduces the concept of "definition types", and this
> concept could be useful in other operations.  For instance, it would be

A definition type would certainly be a nicer way of handling this. It
would unify how to indicate that a particular definition is wanted. 

>     Note: Another useful enhancement would be to support a :BREAK flag, like
>     this:

> 	    (:METHOD <spec>  :BREAK)

>     indicating that a break loop should be entered before and after the
>     function executes.

> Here you see a conflict between lists as function-specs and lists as
> lists of options, in the arguments to TRACE.  Because of this your proposal
> for TRACE is not compatible with what Symbolics currently does, but I don't
> think that's too important for us.  We say that a list is a list of options,
> and if you want to trace a function whose name is a list, you have to do
> (TRACE (:function <function-spec> <options>...)).  But all this really
> shows is that the syntax of TRACE is ridiculous.  I usually ignore the TRACE
> function and trace things through a command interface.  Anyway, for your
> proposal you have to decide between lists as function specs and lists as
> options; I don't think you can mix them freely as you proposed.  Of course
> it would be a lot > e> asier if TRACE only traced one function at a time,
> then the rest of the form could be used for options.  That would be a bit
> incompatible with CLtL.

An alternative would be to introduce a BREAK macro:

	BREAK &REST {function-spec or definition}*	[Macro]

having the obvious functionality. Such a "functional" interface would 
avoid having to try indicating everything through one operation. I
just suggested the :BREAK option because this similar to how we currently
do it.

>     TRACE-EXECUTION object &OPTIONAL env		[Generic Function]

> I didn't completely understand this.  It looks like there is some
> incoherence about whether TRACE is an operation on functions or on
> places in which you can store a function definition.  In other words,
> does tracing a function redefine the function or alter the object that
> is the function's definition?  In other words, does
>   (defun foo () ...)
>   (setq f #'foo)
>   (trace foo)
>   (funcall f)
> generate trace-output or not?  We have to decide one way or the other.
> CLtL is obscure on this point.

As is usual in CLOS, the idea here was to split trace functionality into
two pieces a) a programmer interface (TRACE) b) a system level or
metaclass protocol function (TRACE-EXECUTION). 

With reference to your example, certain implementations may support the 
ability to modify function definition objects directly to allow trace 
information to be inserted. Thus the FUNCALL in the example could be 
traceable. As the base note suggested, these implementations could then 
have a function spec (or definition type) for indicating that the function 
should be trace through the fundef object rather than through the symbol. 
Other implementations may only be able to trace though a wrapper on the 
function symbol. The function spec or definition type would be used for
indicating to TRACE what to do, a corresponding TRACE-EXECUTION method
would contain the implementation dependent code to do it.

As to why go to the trouble of having an extra layer, consider a user
who wants to write a method or generic function class for remote procedure
calls. This user would like some way of handling debugging, and a generic
function in the metaclass protocol seems like the right way to do it.
A generic function would provide the system level interface for other
kinds of debugging functionality.


				jak

∂11-Aug-87  1504	kempf%hplabsz@hplabs.HP.COM 	Re: Name That Class  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 11 Aug 87  15:03:36 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 11 Aug 87 15:01:11 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 11 Aug 87 15:00:34 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 11 Aug 87 16:01:15 pdt
Date: Tue, 11 Aug 87 16:01:13 pdt
From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>
Message-Id: <8708112201.AA26864@hplabsz.hpl.hp.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Name That Class 
In-Reply-To: Your message of Mon, 10 Aug 87 14:42:00 -0400.
             <870810144215.3.MOON@EUPHRATES.SCRC.Symbolics.COM> 

I said: 
Date: Tue, 11 Aug 87 16:01:12 MST
From: kempf@hplabsz

>> 2) Have the name to class object binding for an entire class be handled
>>    by the metaclass protocol. 

Moon replied:

> I don't understand how this could work.  If one is given a class name and
> one wants to find the corresponding class object, how do you know what
> metaclass is relevant before you have found the class object?

and Gregor said (somewhat earlier):

>Even if we decide that class-name should return at most one name, I
>think it is clear that a class can have more than one name.  That is,
>it is legal to use setf of symbol-class to make the multiple symbols
>point to the same class. 

and Patrick said (even earlier):

>The environment argument will be necessary to address the compile
>environment problem.  The term might be confusing, it is not necessary
>an environment like the &environment argument in a macro definition.

I've been rethinking this issue somewhat, and I think we need to consider
how class names will be used. I can see three ways in which
users may need to use class names:

1) In inheritance lists for indicating direct supers,
2) In parameter specializer lists for indicating that particular method
   parameters are specialized to particular classes (or their subclasses),
3) For instantiation,
4) For general queries (i.e. system building-"Is this class there?", etc).

There will be more reasons for using class names if metaclass programming
is taken into account. Let's just consider these for the moment and ask
what would happen if a many to one mapping of classes to names (and
vice versa) were allowed.

If multiple names were allowed to be "bound" to a single class object,
then the function CLASS-NAME(S) could potentially return a list.
The function SYMBOL-CLASS (or CLASS-NAMED) could also return a list,
since, for any particular name, there could be multiple class
objects having it. That is, if we have FOO1 and FOO2 bound to two different
class objects, and the following is legal:

	(setf (class-name foo1) 'baz)
	(setf (class-name foo2) 'baz)

then the following:

	(symbol-class 'baz)

should return a list with two elements, with the CAR EQ to FOO1 and the
CADR EQ to FOO2.

What would this mean for user code? For one thing, the following would be
ambiguous:

(defmethod doit ((x baz))
  ...
)

since there are now two possibilities for the class BAZ. One could argue
that this should mean that the method should be selected if X is
from either class, but that would be expanding the kind of parameter
specializer to boolean selection, and users may begin to demand something
like:

(defmethod doit ((x (or foo1-class foo2-class)))
  ...
)

which we may want to avoid. Of course, we could always demand that the
user put in the class object directly, to disambiguate, but names are
good for *something*, in this case, as a shorthand for not having to
say something like:

(defmethod doit ( (x (cadr (symbol-class 'baz))) )
 ....
)

The reason classes are different from functions is because function
definition objects don't have settable names. You can't say:

	(setf (function-name fundef1) 'foo)
        (setf (function-name fundef2) 'foo)

at least, not in portable Common Lisp (most implementations probably 
allow this sort of thing internally). In addition, the inverse mapping 
to SYMBOL-FUNCTION (from function definition objects to names, called 
FUNCTION-NAME in the above example) is not defined.
With classes, the inverse mapping needs to be defined and settable, and 
that is what is compilicating the issue. There are ways to hack around it,
designating one name the principle name, etc., but they all introduce more 
machinery that I think most users will want.

Metaclasses could be used to allow multiple names per class only if
the name to class binding were restricted to one to one within a metaclass.
Across metaclasses, multiple names per class could be allowed.
The various ways this would affect the programmer interface are as follows:

1) SYMBOL-CLASS would require an optional metaclass argument, which
would default to STANDARD-CLASS. SYMBOL-CLASS would be used for general 
queries, in addition.

2) Inheritance lists would be no problem, since supers must be of
the same metaclass anyway.

3) DEFMETHOD would require additional machinery to specify the metaclass
of the parameters. Possible choices are:

  a) A DEFMETHOD option specifying that the parameters must be
     from a particular metaclass. This will give problems with
     mixing specializers, for example, if specializers of 
     metaclass STANDARD-TYPE-CLASS are mixed with those of
     metaclass STANDARD-CLASS, as is likely.

  b) The syntax of specialized lambda lists be expanded to include
     some means of indicating that the class is of a particular
     metaclass. This is more flexible, but syntatically clumsier.
     Something like:

	(defmethod doit ((x foo nonstandard-class) y x)
            ...
        )

     is what I have in mind. Defaulting to STANDARD-CLASS may help.

  c) DEFMETHOD only works with parameter lists whose classes
     are from a restricted set of metaclasses. STANDARD-TYPE-CLASS,
     and STANDARD-CLASS are obvious candidates. A user wanting to 
     handle parameters of another metaclass would need to write
     their own parameter list parser, and their own top level macro.

4) Instantiation via. MAKE-INSTANCE would require either:

  a) An optional metaclass argument, 

  b) The argument would need to be the class object itself
     rather than a symbol, 

  c) A symbol argument could default to STANDARD-CLASS.

I honestly think that even this is more machinery than most applications
programmers are going to need. Most users are simply going to use the
default metaclass, and won't want to have more than one name per class
or more than one class per name.

But, as Patrick has pointed out, the issue is more complex. The name
to class (or name to generic function) binding has an additional component,
namely the environment. What I think we *really* want is a way to have
the name to object binding be dependent on the environment as well.
This issue is more important than the issue of user level multiple
names per class (even for metaclass programming) since it directly
affects implementations which can't use virtual memory to segment
processing steps, and could adversely affect bootstrapping in any event.
As I mentioned in a previous note, I think this issue should be resolved
by a comprehensive, well thought out statement about the processing model
for the Concepts chapter. Then, individual functions which require
interface modifications should be modified. As Patrick mentioned in his
note, the environment need not be a CLtL environment; in fact, given
the second class status of environments in Common Lisp, it is hard
to see how it *could* be without some beefing up of what you can do
with them.

I'll leave it at that for this note. Summarizing, my feeling is that
allowing a multiple name per class object binding has some serious problems
for user level code, since the names of class objects are and
probably should be settable. I don't feel offering the functionality
to users is particularly important at this time, but if people want
it, then I think restricting the name to object mapping to be one to
one on a metaclass by metaclass basis is probably the right way to go.
More important is a resolution of the name to object mapping in different
processing environments, and this should probably be done in a comprehensive
manner, including generic functions also.

	Jim Kempf 	kempf@hplabs.hp.com


∂13-Aug-87  0928	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Name That Class    
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 13 Aug 87  09:20:00 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ah09181; 13 Aug 87 11:56 EDT
Received: from ti-csl by RELAY.CS.NET id ag11477; 13 Aug 87 11:49 EDT
Received: from Jenner by tilde id AA15544; Thu, 13 Aug 87 10:22:32 CDT
Message-Id: <2764855505-13956774@Jenner>
Date: Thu, 13 Aug 87  10:25:05 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Jim Kempf <kempf%hplabsz@hplabs.hp.com>
Cc: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>, 
    common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Name That Class 
In-Reply-To: Msg of Tue, 11 Aug 87 16:01:13 pdt from Jim Kempf <kempf%hplabsz@hplabs.hp.com>

      
     
     2) Inheritance lists would be no problem, since supers must be of
     the same metaclass anyway.
That's not true, supers can be of other compatible metaclasses.
     
     
     But, as Patrick has pointed out, the issue is more complex. The name
     to class (or name to generic function) binding has an additional component,
     namely the environment. What I think we *really* want is a way to have
     the name to object binding be dependent on the environment as well.
     This issue is more important than the issue of user level multiple
     names per class (even for metaclass programming) since it directly
     affects implementations which can't use virtual memory to segment
     processing steps, and could adversely affect bootstrapping in any event.
     As I mentioned in a previous note, I think this issue should be resolved
     by a comprehensive, well thought out statement about the processing model
     for the Concepts chapter. Then, individual functions which require
     interface modifications should be modified. As Patrick mentioned in his
     note, the environment need not be a CLtL environment; in fact, given
     the second class status of environments in Common Lisp, it is hard
     to see how it *could* be without some beefing up of what you can do
     with them.

This is an entirely different issue from what you've been talking about.
Environments and metaclasses are orthogonal.
     
     I'll leave it at that for this note. Summarizing, my feeling is that
     allowing a multiple name per class object binding has some serious problems
     for user level code, since the names of class objects are and
     probably should be settable. I don't feel offering the functionality
     to users is particularly important at this time, but if people want
     it, then I think restricting the name to object mapping to be one to
     one on a metaclass by metaclass basis is probably the right way to go.

I don't see what can be gained by having one namespace per metaclass.  I think
it compromises modularity.  When you list your supers in DEFCLASS, you
don't/shouldn't have to care what metaclass they belong to as long as they are
compatible with your metaclass.

Patrick.     

∂17-Aug-87  2133	kempf%hplabsz@hplabs.HP.COM 	Environments, Naming, and CLOS (was Re: Name that Class)
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 17 Aug 87  21:32:55 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 17 Aug 87 21:31:02 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 17 Aug 87 17:02:14 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 17 Aug 87 18:02:53 pdt
Message-Id: <8708180002.AA10001@hplabsz.hpl.hp.com>
To: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Environments, Naming, and CLOS (was Re: Name that Class)
In-Reply-To: Your message of Thu, 13 Aug 87 10:25:05 -0500.
             <2764855505-13956774@Jenner> 
Date: Mon, 17 Aug 87 18:02:50 MST
From: kempf%hplabsz@hplabs.HP.COM

>      2) Inheritance lists would be no problem, since supers must be of
>      the same metaclass anyway.
> That's not true, supers can be of other compatible metaclasses.

	I stand corrected. In the event of a name clash, some means
	of disambiguating the name to class mapping would be needed.
	One possiblility would be to extend the definition of "compatible" 
	to include "not having classes with the same name". Provided,
	of course, that multiply named classes were seen to be such
	an important feature that they should be included (which I
	doubt).
>      
>      
>      But, as Patrick has pointed out, the issue is more complex. The name
>      to class (or name to generic function) binding has an additional component,
>      namely the environment. What I think we *really* want is a way to have
>      the name to object binding be dependent on the environment as well.

> This is an entirely different issue from what you've been talking about.
> Environments and metaclasses are orthogonal.

	To the extent that the metaclass protocol takes into account 
	the processing environment, it may be possible for a particular
	metaclass to do things differently in an environment from
	others. For example, a metaclass supporting a language which
	always resolves inheritance at compile time would need to
	deal with the environment in a different way from the default
	metaclass, where inheritance is resolved much later. 

>      I'll leave it at that for this note. Summarizing, my feeling is that
>      allowing a multiple name per class object binding has some serious problems
>      for user level code, since the names of class objects are and
>      probably should be settable. I don't feel offering the functionality
>      to users is particularly important at this time, but if people want
>      it, then I think restricting the name to object mapping to be one to
>      one on a metaclass by metaclass basis is probably the right way to go.

> I don't see what can be gained by having one namespace per metaclass.  I thin> k> 
> it compromises modularity.  When you list your supers in DEFCLASS, you
> don't/shouldn't have to care what metaclass they belong to as long as they are
> compatible with your metaclass.

	I agree. I can't see much use for allowing multiple names for
	classes in the first place, since it requires more syntatic
	machinery on the part of the programmer to indicate precisely
	which class is meant in user level code. The point of the
	metaclass proposal was that, if anywhere, that might be a
	place where people might want to have multiple classes with
	the same name. Suppose, for example, you want to have a 
	WINDOW class in CLOS and one in Smalltalk (or CommonObjects,
	or Flavors, etc.). But Common Lisp provides packages for 
	seperating namespaces, and I think that's probably enough, as
	long as you don't insist on exporting more than one WINDOW.
	So you could have a FLAVORS::WINDOW and a SMALLTALK::WINDOW.
	
	Personally, I think that this issue (multiple names for classes)
	is a bit of a red herring. I just presented the metclass proposal 
	as an example of how it might make sense, but, as was pointed
	out, additional machinery would be required at the syntatic
	level to support it. The package system, despite its faults,
	is the customary way of modularizing namespaces in Common Lisp,
	and I think we should stick with that for user level code.

	The issue of multiple names in different processing environments
	is somewhat different. Because the package system is read time
	only, and symbols map across compilation and loading into the
	same package, the package system cannot be used to allow a
	class of the same name to co-exist at compile time. Similarly
	for methods. In order for a class or a set of classes and
	their applicable methods to be compilable in the same file,
	the CLOS metaclass protocol must insert enough information
	into the compile time environment so that the methods can
	be defined. At the extreme, the classes being compiled 
	could be simply be completely defined at compile time, but 
	this will, of course trash any existing definitions. This is 
        not a problem for implementations which an easily get new 
	virtual address spaces (modulo lengthening the time required 
	for compilation of a system), since most bootstrapping problems 
	could be solved by simply throwing away the environment and
	getting a new one (there are probably some more subtle problems
	here which I'm missing).

	Is that a fair statement of the problem with environments
	and naming?

	As mentioned in previous notes, I think a section in Part I
	about what CLOS needs in terms of processing environment
	is important. I might add that the ANSI C standard has
	about 8 pages of material on the processing environment at
	the beginning. We are, of course, limited by what CLtL provides,
	but I think, within that limit, we can probably be more
	precise.

		


	 




∂18-Aug-87  0820	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Names to Objects and Compiler-environment  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 18 Aug 87  08:20:03 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa00914; 18 Aug 87 11:18 EDT
Received: from ti-csl by RELAY.CS.NET id af11433; 18 Aug 87 11:08 EDT
Received: from dsg by tilde id AA23644; Tue, 18 Aug 87 09:44:15 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Mon, 17 Aug 87  16:14:24 CDT
Message-Id: <2765222127-2953787@Jenner>
Date: Mon, 17 Aug 87  16:15:27 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Names to Objects and Compiler-environment

The name-to-object primitives we have in CLOS are:

Object                Function       Metaclass    Implementation
                                     dependent      dependent

Class                 CLASS-NAME      No               Yes

Generic-function   SYMBOL-FUNCTION    No               Yes

Method              GET-METHOD        Yes               *


Name-to-method mapping implementation should be left to the metaclass writer
since it is tied up to the strategy of finding the applicable methods for method
discrimination and method combination.  Besides name to object mapping, the
implementation provides some generic name services (source filename recording,
redefinition warnings...) that the metaclass wants/needs to use.  This answers
the * sign in the above table.  I believe that we need a portable interface to
those services.

Compile environment: 
In order to avoid side-effecting the running environment during COMPILE-FILE,
the environment stores definitions in another namespace (compile environment).
The management of the environment(s) should be left to the implementation.  All
our name-to-object functions are affected by this.  We could make the
environment implicit and say that those function will return the object from the
"right environment" (SYMBOL-FUNCTION might work like that on some
implementations), but then it becomes hard to write GET-METHOD portably.  I
propose that we make the environment explicit, passed as an argument to
CLASS-NAME, GET-METHOD, their SETF functions and related function such as
FIND-APPLICABLE-METHODS.  I believe that CLOS should not know a whole lot about
environments so we don't require all the implementations currently supporting
compile-environment to change.  Another issue is the dynamic extent of the
compile environment: The implementation control their lifetime.  Their should
be a way for the implementation to signal the fact that a CLOS object no longer
needed because COMPILE-FILE is over.

Proposal(This would be part of the metaclass protocol):

1- Environment:

The implementation should provide some objects called environments.  The
implementation controls their dynamic extent and their representation.
One can get an environment by the function GET-CURRENT-ENVIRONMENT.  If
an implementation supports compile-environment, then a call to
GET-CURRENT-ENVIRONMENT in the top level loop is not EQL to a call to
GET-CURRENT-ENVIRONMENT inside a macro expansion while compiling a file.

GET-NEXT-ENVIRONMENT ENVIRONMENT.  This function returns the next
environment to lookup if any or NIL.  This allows the implementation to
implement search lists.

The function (GET-RUNTIME-ENVIRONMENT) always
returns the runtime environment.

CLOS will use environment as a key into its data structures to mark an
object defined in a given environment (ie a method defined in a file
during COMPILE-FILE) or to look it up. 

2- CLOS functions that must have an environment argument:

CLASS-NAMED and its SETF form,
ADD-METHOD,
GET-METHOD,
REMOVE-METHOD,
FIND-APPLICABLE-METHODS,
ENSURE-GENERIC-FUNCTION.

Questions:
Do we need to add an environment slot to STANDARD-CLASS, STANDARD-METHOD
and STANDARD-GENERIC-FUNCTION to get the environment they were defined in?

How do we provide a portable interface to those generic "name" services provided
by the implementation?

How does the implementation signal an object that it has been deleted from the
compiler environment?
The following might work but I am not sure:

ADD-TO-ENVIRONMENT OBJECT ENVIRONMENT.  Tells the implementation that
the dynamic extent of OBJECT is the same as the dynamic extent of ENVIRONMENT.

DELETED-FROM-ENVIRONMENT OBJECT ENVIRONMENT this function is called by
the implementation on every object added to the environment by the call
to Add-to-environment before invalidating ENVIRONMENT.  typically, It is
done at the end of COMPILE-FILE.


∂18-Aug-87  1136	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS     
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 18 Aug 87  11:35:40 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 18 Aug 87 08:51:16 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 18 Aug 87 08:50:43 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 18 Aug 87 09:51:23 pdt
Message-Id: <8708181551.AA15800@hplabsz.hpl.hp.com>
To: Kelley.pa@Xerox.COM
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: ECOOP Reaction to CLOS 
In-Reply-To: Your message of 05 Aug 87 17:48:00 -0700.
             <870805-174848-5665@Xerox> 
Date: Tue, 18 Aug 87 09:51:20 MST
From: kempf%hplabsz@hplabs.HP.COM

Sorry it's taken so long to respond.

> 
> The CLOS proposed standard explicitly claims in general to obey the
> implicit inheritance - explicit override rule, but it does not for

I couldn't find a reference to "implicit inheritance - explicit override"
in Part 1 of the 87-002 spec. What page is it on?

> In as much as implicit inheritance is a sub-conscious assumption of
> application programmers, standard CLOS behaves in a counter intuitive
> manner.     

In my opinion, inheritance should *never* be a sub-concious assumption.
It should be an explict design decision, made after considering 
alternatives. If the supers are in a library to which the programmer
does not have source, then enough information should be given in the
library's documentation that the programmer can design accordingly.
Full analysis might not be required during a prototyping phase, but
nevertheless, the programmer should be familiar with the details of
the supers.

> (defclass border (object) (width))
> (defmethod close (b border) ...)

> (defclass window (object) (width))
> (defmethod close (w window) ...)

> (defclass bordered-window (border window))
> (setq b-window (make-instance 'bordered-window))

> (close b-window)  ; with the current inheritance algorithm, only closes
> the border.  Does not close the window.

> The following explores what could happen if the implicit inheritance -
> explicit override rule were followed in CLOS.  

> (close b-window) would result in both the border and window close
> methods getting called because it inherits them implicitly and has not
> explicitly overridden them.  

> With implicit inheritance a class may have in addition to multiple
> methods with the same name that all get called by one call, multiple
> occurrences of a slot with the same name that are manipulated in one
> operation so b-window would contain two slots named width.

> (setf (slot-value b-window width) 0)  

> Would set both slots to 0.

Consider what would happen with a join superclass. In your example 
OBJECT is a join superclass, since it is inherited through two supers
(WINDOW and BORDER) in BORDERED-WINDOW. For the supers above the join, 
the base class gets two copies of slots, one through each branch through
the join class. There are two alternatives about what to do with the
two sets of slots:

1) Keep a seperate set for each branch of the join,
2) Merge them in some manner.

If the first approach is taken, then the object essentially has duplicate
copies of logically the same state. This approach was used in
CommonObjects, and is one aspect of CommonObjects which seems to bother
programmers the most. If the second approach is taken, it is possible
for some methods to be invoked more than once on the same set of
slots, making the method semantics for singly inherited and multiply 
inherited cases different (see below for more discussion).

> A problem is what to do with the results of an operation on a slot name
> that refers to two or more slots or on a call that refers to two or more
> methods.  Operating on these slots or methods that have not been
> overridden could be specified to return a "multiple-inheritance-result"
> object containing the multiple results.  

This seems to me to be more complicated than most application programmers
will want. It would be hard to integrate with WITH-SLOTS, and would require
more syntatic machinery for setting or getting slots, pathnames to the
appropriate slot, or something similar. It seems inappropriate to
burden programmers with having to deal with such extra syntatic 
machinery when slot merging will do the job most of the time.

> Any code that depended on the results from instances of singly inherited
> classes would not work correctly with instances of multiply inherited
> classes. (In the example above, any code that depended on the value

This is a general problem with linearizing multiple inheritance, 
but most programmers who have used Flavors or CommonLoops are used to it,
and plan accordingly. It requires more knowledge about the supers 
than for singly inherited languages, however.

The problem here is that every algorithm for multiple inheritance loses
somehow. If linearizing multiple inheritance is used, then the problem
with changing method semantics occurs. If tree-structured multiple
inheritance is used (where the entire tree of supers
is maintained, duplicating branches above joins) then duplicated state
occurs above join classes. If graph structured multiple inheritance is
used (where the graph of supers is maintained without duplication), 
methods can be invoked multiple times on the same slot.
For a more detailed analysis, see Alan Snyder's paper in the last 
OOPSLA proceedings.

What CLOS has tried to do (I think) is to provide Lisp programmers with
what they are most used to (i.e. codify existing practice), and to
do so in a manner which produces expected behavior most of the time.
If a programmer requires something out of the ordinary, then more time
and effort needs to be invested in learning more details, and, with
the metaclass protocol, much flexibility for changing inheritance
behavior is available. Where the CLOS inheritance algorithm could be
faulted, is that it handles the inability to linearize an inheritance
graph as an error, rather than providing hooks for the programmer
to override the default.

Alternatives to multiple inheritance for achieving the same effect
(i.e. maximum code reuse) are the subject for another basenote and
mailing list.

		Jim Kempf		kempf@hplabs.hp.com



∂18-Aug-87  1146	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Agenda for September meeting
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87  11:45:56 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 215676; Tue 18-Aug-87 14:47:05 EDT
Date: Tue, 18 Aug 87 14:46 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Agenda for September meeting
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870818144639.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

Sonya and I have put together a proposed agenda for the meeting
in September.  Let's agree on what the agenda will be by the end
of this week.

Earlier I said that I wanted to leave by Friday noon, but in putting
together the agenda it became clear that 1 1/2 days wasn't enough time.
Hence we've written the agenda for two full days.  Is that okay with
everyone?



Agenda for CLOS Meeting Sep 17-18 at Lucid in Menlo Park  (first draft)

THURSDAY MORNING:

Discuss written proposals on major areas, circulated over the network
before the meeting and brought to the meeting in hardcopy.  Spend no
more than 45 minutes on each proposal, determining yes, no, or needs
further discussion.  Expected areas for proposals: object creation, new
draft of metaclass chapter, change-class, 1 or 2 others.

BREAK

Discuss a list of minor issues, to be circulated over the network before
the meeting and brought to the meeting in hardcopy.  Moon will provide a
list (based on one that has already been circulated, updated from recent
mail), others will probably add to the list.  Spend no more than 10
minutes on each issue, determining yes, no, or needs further discussion.
If yes, assign a volunteer to update the document accordingly.

LUNCH (let's keep this short)

Finish going through list of minor issues.

BREAK

Discuss proposals & issues that were determined to need further
discussion in the morning, in priority order.  Objective is to decide
what will be in the document for the October X3J13 meeting.  Things we
can't agree on here will be listed in the document as open issues.

END OF THURSDAY

Individuals may want to work on proposal drafts, writing tasks, etc.
during the evening.

FRIDAY MORNING:
 
Allocate remaining writing tasks and make sure we understand how we will
produce a document in time for the October X3J13 meeting, to be mailed
out around September 30.  The objective should be for the tasks remaining
after the meeting breaks up to be purely editorial.

Prepare first drafts of material to go into the document, for all issues
where group effort is required.  Each issue should have an individual
assigned as the leader for that issue, who writes the first draft which
is then criticized by others who are interested.

FRIDAY AFTERNOON:

Review what was written in the morning.

PREPARATION REQUIRED AHEAD OF TIME

Use network mail to finalize list of issues to be discussed and to get
everyone up to date on them.

Circulate proposals and issues list by the Friday before the meeting
(Sep 11).

Mail out hardcopies of the latest version of the 87-002 document
immediately (no further editing is planned, right?).

∂18-Aug-87  1522	Moon@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87  15:22:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 215969; Tue 18-Aug-87 18:22:49 EDT
Date: Tue, 18 Aug 87 18:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: short form of define-method-combination
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870818182230.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

I would like to propose a small simplification of the short form of
define-method-combination.

Recognizing both an unqualified method and a method whose qualifier is
the name of the method combination type as primary methods seems
unnecessary and confusing.  It muddles the issue of the identity of
a method (these are two separate methods with separate identities,
yet they do the same thing).

In addition, the qualifier is the name of the method combination type
but in the keyword package, so this is one more place where CLOS is
inventing symbols that don't appear in the source of the program, and
each time we do that it seems to cause trouble.

A possible drawback of this simplification is that it might make it
harder for users to understand the difference between "primary method"
and "unqualified method", since there won't be a counterexample to
the theory that the two terms are synonymous.

The specific document amendments are as follows, referring to 87-002:

2-27 Remove "A method with the keyword symbol with the same name as
{\it name\/} as its one qualifier is also defined to be a primary
method.  Attaching this qualifier to a primary method documents that
this method is intended for use with an unusual form of method
combination and can make programs easier to understand."

2-30 Remove ":and" after "defmethod func".
Remove "(:and)" after "primary ()".

2-31 Remove "(:and)" after "methods ()".
Remove "(:and)" after "primary ()" [two places].

A related point is that we forgot to say in the document that a primary
method is required when using a method combination type defined with
the short form of define-method-combination, just as when using standard
method combination.  We should say that explicitly.

∂18-Aug-87  1534	Kelley.pa@Xerox.COM 	Re: ECOOP Reaction to CLOS   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 18 Aug 87  15:34:39 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 18 AUG 87 15:33:17 PDT
Date: 18 Aug 87 15:31 PDT
From: Kelley.pa@Xerox.COM
Subject: Re: ECOOP Reaction to CLOS 
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Tue, 18 Aug 87
 09:51:20 MST
To: kempf%hplabsz@hplabs.HP.COM
cc: Kelley.pa@Xerox.COM, common-lisp-object-system@sail.stanford.edu
Message-ID: <870818-153317-1383@Xerox>

> The CLOS proposed standard explicitly claims in general to obey the
> implicit inheritance - explicit override rule, but it does not for

|I couldn't find a reference to "implicit inheritance - explicit
override"
|in Part 1 of the 87-002 spec. What page is it on?

I was refering primarily to page 1-7, the first paragraph both under
Inheritance of Methods and Inheritance of Slots and Slot Options.
Obeying implicit inheritance in general is claimed there (though
explicit override is implicit :-).  The implication that the rule was
quoted as such in 87-002 was unintentionally misleading -- one too many
explicits in my original statement.

| ... the object essentially has duplicate
|copies of logically the same state. This approach was used in
|CommonObjects, and is one aspect of CommonObjects which seems to bother
|programmers the most. ...

If inheritance of methods with the same name in CommonObjects signals an
error, that is inconsistent with its slot inheritance. 

|The problem here is that every algorithm for multiple inheritance loses
|somehow. ... If tree-structured multiple
|inheritance is used (where the entire tree of supers
|is maintained, duplicating branches above joins) then duplicated state
|occurs above join classes....

Based on the arguments in Snyder's OOPSLA 86 paper, I would claim this
problem is really a feature in disguise.

At any rate, presenting the effects of the proposed inheritance
algorithm for CLOS would be more understandable if in conjunction with
presenting the class ordering algorithm, violations of the "implicit
inheritance - explicit override" rule are clearly marked as such.

 -- kirk

∂18-Aug-87  1615	DLW@ALDERAAN.SCRC.Symbolics.COM 	short form of define-method-combination   
Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 18 Aug 87  16:15:06 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110793; Tue 18-Aug-87 19:09:52 EDT
Date: Tue, 18 Aug 87 19:06 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: short form of define-method-combination
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870818182230.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <870818190658.2.DLW@CHICOPEE.SCRC.Symbolics.COM>

I am not enthusiastic about this proposal.  I have always liked having
the qualifier in the defmethod form explicitly, because it enhances
readability.  I think it's hard to understand what a method is doing if
you don't know how that method is going to be combined.  Having the
qualifier there reminds you what kind of combination is going to be
used.

In order to eliminate the problem of having two separate methods that do
the same thing, I would rather make use of the qualifier be required
than forbidden.

I realize that this does not solve the problem of inventing symbols.
However, I think the benefit in readability outweighs this consideration.

∂18-Aug-87  1707	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: ECOOP Reaction to CLOS  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87  17:07:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216070; Tue 18-Aug-87 20:06:44 EDT
Date: Tue, 18 Aug 87 20:06 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: ECOOP Reaction to CLOS
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8707092024.AA22131@hplabsz.hpl.hp.com>,
             The message of 6 Jul 87 14:30 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870818200622.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

Some comments on characterizing the class precedence list algorithm.
In my comments I will refer to this set of classes (slots omitted):

(defclass a (b c w))            w   x  w   y w  x
(defclass aa (b c d w))          \ /    \ /   \/
(defclass b (w x))                b      c    d   w
(defclass c (w y))                 \     |   /   /
(defclass d (w x))                   \   | /   /
(defclass w ())                        \ |/  /
(defclass x ())                          aa
(defclass y ())

We've seen these classes before.  By the rules in 87-002,
the CPL of a is (a b c w y x) and of aa is (aa b c d w x y).

    Date: Thu, 9 Jul 87 13:24:38 pdt
    From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>

    The inheritance graph is searched depth first, left to
    right, up to joins. Superclasses at joins are placed
    in the class precedence list at the last occurance,
    rather than the first, since such superclasses are
    usually more general than their subclasses, and classes
    at the end of the class precedence list should be more
    general than those at the beginning. The qualitative
    effect is to achieve a linearization of the inheritance
    graph, with more specialized classes at the head of
    the class precedence list and more general classes at
    the tail, keeping together groups of classes which occur
    together in the inheritance graph.

    A more detailed explantion should go into what can go wrong. The
    Ducournau and Habib paper discusses this in a more formal way....

I like this informal way of explaining it, except that I never figured
out precisely what "up to joins" means, and depending on the
interpretation of that phrase, this explanation could be incorrect.
When the depth first walk of the graph for aa above encounters w above
c, that's a join.  If it goes on to y, I don't think y is a join,
nevertheless y is not next in the CPL, x is.

    Date: 06 Jul 87  1130 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    What would constitute an understandable characterization of the CPL?
    Here are some examples of approaches:

    1.  We could have a set of constraints on the classes such that the CPL
    is the unique total ordering satisfying those constraints.

If I understand the meaning of constraints as being additive, the
example above shows that it can't be done with constraints.  Taking a
and adding d to make aa reverses the order of x and y, thus whatever
constraint was controlling the order of x and y must have been removed
when d was added.  Perhaps this nonadditiveness is at the root of
people's difficulty in understanding the CPL computation.

    2.  We could have a set of inheritance situations such that when two
    graphs of classes were inherited in particular ways, the new CPL was
    predictable. For example, suppose we have 2 graphs, G1 and G2, with no common
    classes except for the class named T and suppose that C1 and C2 are the
    bottom-most classes of G1 and G2, respectively; then if a class C is
    a subclass of C1 and C2 in that order, the classes in G1 precede the classes
    in G2, and the classes in G1 are in the same order as they are in the CPL
    for C1 and similarly for G2; T comes last.

Characterization #2 is in fact true, and it's not too hard to see why.
Suppose G1A is the second class in C1's class precedence list.  After
topological sort has added C1 to C's cpl, the rule at the top of page
1-15 comes into play because either C2 or G1A could be next.  The rule
selects G1A.  By what amounts to induction, one can show that every
class in G1 will have a direct subclass to the right of C2's direct
subclass (C), and therefore every class in G1 will precede C2.  I believe
one can also show that the classes in G1 will appear in the same order in
C's cpl as in C1's cpl.  I don't think it's a coincidence that
characterization #2 is true, I think making it true was one of the
acceptance criteria for the CPL algorithm.

The problems occur just when G1 and G2 do have common classes (other
than T).

∂18-Aug-87  1728	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Names to Objects and Compiler-environment  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 18 Aug 87  17:28:19 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216083; Tue 18-Aug-87 20:29:21 EDT
Date: Tue, 18 Aug 87 20:29 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Names to Objects and Compiler-environment
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <2765222127-2953787@Jenner>
Message-ID: <870818202904.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Mon, 17 Aug 87  16:15:27 CDT
    From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>

I agree with the general thrust of what you're saying, but have some
nits to pick and a question to ask.  I might have more to say on this
topic later.

Question: I had thought that environments referred only to the mapping
from names (Lisp symbols) to objects, but in saying that ADD-METHOD,
GET-METHOD, REMOVE-METHOD, and FIND-APPLICABLE-METHODS (not documented)
need an environment argument, I think you're saying that environments
also affect the mapping from generic-function objects to lists of
method objects.  Is this correct?  And is there any other kind of
mapping that they affect?

An environment of NIL should be defined to be synonymous with the
run-time environment, for programmer convenience.

    One can get an environment by the function GET-CURRENT-ENVIRONMENT.  If
    an implementation supports compile-environment, then a call to
    GET-CURRENT-ENVIRONMENT in the top level loop is not EQL to a call to
    GET-CURRENT-ENVIRONMENT inside a macro expansion while compiling a file.

Does GET-CURRENT-ENVIRONMENT take no arguments?  I believe that the
&environment argument to a macro expander is the only viable way for
the macro expander to know whether the code it's going to return has
its meaning defined in terms of the compile-environment or the run-time
environment.  Thus I believe that the macro expander should pass its
&environment argument to GET-CURRENT-ENVIRONMENT.  To avoid confusion,
we should either declare that these two kinds of environments are
identical, eliminating the need for GET-CURRENT-ENVIRONMENT, or else
we should find a new name for the CLOS kind of environment.

If GET-CURRENT-ENVIRONMENT takes no arguments, then what you have is
some form of dynamic scoping, rather than lexical scoping, and you can
get scoping problems.  Symbolics' implementation, and I believe TI's as
well, currently works this way, using the special variable
SYS:UNDO-DECLARATIONS-FLAG to inform macro expanders on behalf of which
environment they are working.  The genesis of this is historical and
predates lexical scoping.  This causes a number of subtle problems.
CLOS should not make this mistake.

    GET-NEXT-ENVIRONMENT ENVIRONMENT.  This function returns the next
    environment to lookup if any or NIL.  This allows the implementation to
    implement search lists.

I don't understand how adding GET-NEXT-ENVIRONMENT to the documented
interface is related to the issue of search lists.  The implementation
can have those without anything special for them in the interface.

If there is searching, and I think there needs to be if only so the
compile environment can inherit from the run time environment, you need
a negative inheritance mechanism, so that the compile environment can say
such and such a method does not exist in the new version of this program
being compiled, even though it exists in the old version that is being
used to do the compilation.

    How does the implementation signal an object that it has been deleted from the
    compiler environment?

I would prefer that object deallocation be left to the garbage collector.
Are there any problems with that?

∂19-Aug-87  0632	skeene@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87  06:32:28 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216238; Wed 19-Aug-87 09:33:33 EDT
Date: Wed, 19 Aug 87 09:32 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: short form of define-method-combination
To: DLW@ALDERAAN.SCRC.Symbolics.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870818190658.2.DLW@CHICOPEE.SCRC.Symbolics.COM>
Message-ID: <870819093252.6.SKEENE@JUNCO.SCRC.Symbolics.COM>


Initially, I had the same opinion you state -- that having the qualifier
in the defmethod form enhances readability, and that it was preferable
to make that qualifier be required rather than forbidden.

The reason for including the qualifier in the defmethod form is to
document the method (how it will be combined with other methods).   But
we already provide a way to document a method, via the documentation
string.  So now I'm in favor of having the methods be unqualified 
instead of requiring that they be qualified.  

Either of the new suggestions would be better than the way it is now, 
where you can choose whether to include the qualifier or not.   


∂19-Aug-87  0745	DLW@ALDERAAN.SCRC.Symbolics.COM 	short form of define-method-combination   
Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 19 Aug 87  07:44:55 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 110961; Wed 19-Aug-87 10:27:55 EDT
Date: Wed, 19 Aug 87 10:25 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: short form of define-method-combination
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870819093252.6.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <870819102506.5.DLW@CHICOPEE.SCRC.Symbolics.COM>

I don't think the documentation string is adequate to produce the
results I'd like to see.  In practice, I just don't believe that
programmers will, in fact, invariably (or even usually) remember to note
the method combination type in the documentation string for every method
that uses non-default method combination.

∂19-Aug-87  1020	Moon@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87  10:20:10 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216470; Wed 19-Aug-87 13:21:20 EDT
Date: Wed, 19 Aug 87 13:20 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: short form of define-method-combination
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870818182230.3.MOON@EUPHRATES.SCRC.Symbolics.COM>,
             <870818190658.2.DLW@CHICOPEE.SCRC.Symbolics.COM>,
             <870819093252.6.SKEENE@JUNCO.SCRC.Symbolics.COM>,
             <870819102506.5.DLW@CHICOPEE.SCRC.Symbolics.COM>
Message-ID: <870819132057.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Tue, 18 Aug 87 19:06 EDT
    From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>

    I am not enthusiastic about this proposal.  I have always liked having
    the qualifier in the defmethod form explicitly, because it enhances
    readability.

Requiring the qualifier would satisfy my stated wants, provided that the
qualifier wasn't optional (so there was only one way to write a primary
method) and wasn't re-interned in the keyword package (so we aren't
inventing symbols).

However, I don't understand why you think the method-combination type of
a generic function needs to be repeated in the defmethod, while the rest
of the contract of the generic function does not need to be repeated.
It seems to me that the command provided by the programming environment
to remind one of the arguments expected, values returned, and documentation
of the generic function can also remind one of the method-combination type.
If you convince me that the method-combination type deserves special
treatment, then I'll change my proposal to make the qualifier mandatory
instead of prohibited.

∂19-Aug-87  1123	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Names to Objects and Compiler-environment
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87  11:23:15 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216533; Wed 19-Aug-87 14:23:16 EDT
Date: Wed, 19 Aug 87 14:22 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Names to Objects and Compiler-environment
To: DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET
cc: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <2765222127-2953787@Jenner>
Message-ID: <870819142229.0.SKEENE@JUNCO.SCRC.Symbolics.COM>

    Date: Mon, 17 Aug 87  16:15:27 CDT
    From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>

    The name-to-object primitives we have in CLOS are:

    Object                Function       Metaclass    Implementation
					 dependent      dependent

    Class                 CLASS-NAME      No               Yes

    Generic-function   SYMBOL-FUNCTION    No               Yes

    Method              GET-METHOD        Yes               *

There's also GET-SETF-GENERIC-FUNCTION.


∂19-Aug-87  1349	DLW@ALDERAAN.SCRC.Symbolics.COM 	short form of define-method-combination   
Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 19 Aug 87  13:49:28 PDT
Received: from CHICOPEE.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 111131; Wed 19-Aug-87 16:50:17 EDT
Date: Wed, 19 Aug 87 16:47 EDT
From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
Subject: short form of define-method-combination
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870819132057.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <870819164729.8.DLW@CHICOPEE.SCRC.Symbolics.COM>

    Date: Wed, 19 Aug 87 13:20 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    However, I don't understand why you think the method-combination type of
    a generic function needs to be repeated in the defmethod, while the rest
    of the contract of the generic function does not need to be repeated.

You seem to be setting up a hypothetical alternative, but I don't
understand what the alternative is.  We don't have a language for
contracts.

It just seems to me that it's very hard to understand what a method is
doing, and easy to misunderstand it or be confused, if you don't see
what kind of combination is being employed.  When you see a BEFORE
method, you know what that is.  When you see an unqualified method, you
naturally assume that it's a primary method, and that (for example) what
it returns will be the result of the generic function call.  But that's
not true if it's an AND-combined method, or worse yet a PROGN combined
method.

    It seems to me that the command provided by the programming environment
    to remind one of the arguments expected, values returned, and documentation
    of the generic function can also remind one of the method-combination type.
    If you convince me that the method-combination type deserves special
    treatment, then I'll change my proposal to make the qualifier mandatory
    instead of prohibited.

I doubt I can come up with something much more convincing.  It just
seems a lot clearer to me.  (DanG mentioned to me, two days ago, that he
feels the same way.)  In fact, I thought that the reason that qualifiers
for things like AND and OR were first (1980?) introduced was because we
felt they made the code clearer.

∂19-Aug-87  1455	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Names to Objects and Compiler-environment   
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 19 Aug 87  14:55:12 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ae09985; 19 Aug 87 17:46 EDT
Received: from ti-csl by RELAY.CS.NET id ac19836; 19 Aug 87 17:33 EDT
Received: from Jenner by tilde id AA03684; Wed, 19 Aug 87 15:19:37 CDT
Message-Id: <2765391661-13139657@Jenner>
Date: Wed, 19 Aug 87  15:21:01 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Names to Objects and Compiler-environment
In-Reply-To: Msg of Tue, 18 Aug 87 20:29 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>

     Date: Tue, 18 Aug 87 20:29 EDT
     From: "David A. Moon" <Moon@scrc-stony-brook.arpa>
     Subject: Names to Objects and Compiler-environment
     
         Date: Mon, 17 Aug 87  16:15:27 CDT
         From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
     
     I agree with the general thrust of what you're saying, but have some
     nits to pick and a question to ask.  I might have more to say on this
     topic later.
     
     Question: I had thought that environments referred only to the mapping
     from names (Lisp symbols) to objects, but in saying that ADD-METHOD,
     GET-METHOD, REMOVE-METHOD, and FIND-APPLICABLE-METHODS (not documented)
     need an environment argument, I think you're saying that environments
     also affect the mapping from generic-function objects to lists of
     method objects.  Is this correct? 

Yes, I want to do this primarily because It allows to be more efficient in terms
of structure copy.  My file contains:

(defmethod speed ((thing my-ship))
   .....)
;;some other things but no DEFCLASS for my-ship and 
;;no DEFGENERIC-OPTIONS for speed.

During COMPILE-FILE I think it is unnecessary to copy the generic-function
or/and the class, to hold the method definition.  What I had in mind was to add
the method to the runtime version of SPEED, in another namespace so a lookup for
this method in the runtime environment is not affected.  I realize that we can
avoid this by copying the generic-function object to the compile environment,
but then we will have to copy some other objects (those side effected by the
defmethod) and end up having to copy a large portion of the world.  Since we
tend to store first class object instead of names, we can't get enough leverage
off the name-to-object lookup.  I tried to address this problem.

     And is there any other kind of mapping that they affect?
I don't know, I can't think of any others but I might be ovelooking something.
     
     An environment of NIL should be defined to be synonymous with the
     run-time environment, for programmer convenience.
     
         One can get an environment by the function GET-CURRENT-ENVIRONMENT.  If
         an implementation supports compile-environment, then a call to
         GET-CURRENT-ENVIRONMENT in the top level loop is not EQL to a call to
         GET-CURRENT-ENVIRONMENT inside a macro expansion while compiling a file.
     
     Does GET-CURRENT-ENVIRONMENT take no arguments?  I believe that the
     &environment argument to a macro expander is the only viable way for
     the macro expander to know whether the code it's going to return has
     its meaning defined in terms of the compile-environment or the run-time
     environment.  Thus I believe that the macro expander should pass its
     &environment argument to GET-CURRENT-ENVIRONMENT.  To avoid confusion,
     we should either declare that these two kinds of environments are
     identical, eliminating the need for GET-CURRENT-ENVIRONMENT, or else
     we should find a new name for the CLOS kind of environment.
     
     If GET-CURRENT-ENVIRONMENT takes no arguments, then what you have is
     some form of dynamic scoping, rather than lexical scoping, and you can
     get scoping problems.  Symbolics' implementation, and I believe TI's as
     well, currently works this way, using the special variable
     SYS:UNDO-DECLARATIONS-FLAG to inform macro expanders on behalf of which
     environment they are working.  The genesis of this is historical and
     predates lexical scoping.  This causes a number of subtle problems.
     CLOS should not make this mistake.

I agree with you. Passing the &environment argument to get-current-environment
is the best. I feared that the existing implementation would have to change too
much. If we do that, the compiler must tie up their compile-environment to the
macroexpand environment (which, to me, is a good thing ) and therefore must
change. 
I don't think the two environments must be identical: a macroexpand
environment is free to change at each top level form, the compile environment
needs to be stay EQ for the extent of  COMPILE-FILE. I would propose NAMESPACE
instead of environment.??
     
         GET-NEXT-ENVIRONMENT ENVIRONMENT.  This function returns the next
         environment to lookup if any or NIL.  This allows the implementation to
         implement search lists.
     
     I don't understand how adding GET-NEXT-ENVIRONMENT to the documented
     interface is related to the issue of search lists.  The implementation
     can have those without anything special for them in the interface.

If we want a metaclass to be written portably, to use environments, and be able
to implement the searching by itself, GET-METHOD should be able to be coded
like: search the method, using the specified environment as a tag and then using
the next environment and so forth.  Does that make sense?  I guess it is tied to
this assumption: [From my original message: Name-to-method mapping
implementation should be left to the metaclass writer since it is tied up to the
strategy of finding the applicable methods for method discrimination and method
combination.].
     
     If there is searching, and I think there needs to be if only so the
     compile environment can inherit from the run time environment, you need
     a negative inheritance mechanism, so that the compile environment can say
     such and such a method does not exist in the new version of this program
     being compiled, even though it exists in the old version that is being
     used to do the compilation.

I agree. (REMOVE-METHOD gf .... ENV) for example has to store in the place where
the metaclass will search that the method is not to be found in the context of 
ENV. Does this negative inheritance need to be specified?
     
         How does the implementation signal an object that it has been deleted from the
         compiler environment?
     
     I would prefer that object deallocation be left to the garbage collector.
     Are there any problems with that?

The problem I see is that the objects are pointed to by more than the
environment: The direct-subclasses slot of a runtime class might point to a
compile-time class.  The environment itself can be hold on to: A metaclass
writer can store object on an Alist whose key is the environment.  I don't think
the garbage collector will be able to get rid of those objects.

Patrick.

∂19-Aug-87  1737	Gregor.pa@Xerox.COM 	meeting place 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 19 Aug 87  17:37:35 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 19 AUG 87 17:36:55 PDT
Date: 19 Aug 87 17:36 PDT
From: Gregor.pa@Xerox.COM
Subject: meeting place
To: Common-Lisp-Object-System@Sail.Stanford.edu
cc: Gregor.pa@Xerox.COM
Message-ID: <870819-173655-3259@Xerox>

I just got back and haven't had a chance to really look through the
mail.  The messages I thought I should try to answer right away were the
ones about meeting time and place.

Speaking for myself and Danny, we would rather have two entire days of
meetings.  

Also speaking for Danny and myself, we would rather meet at PARC this
time.  We met at Lucid last time, and parking and food are easier at
PARC.  We can get a nice conference room in a part of the building where
we won't be bothered.  I'll even try to get us one of those fancy
(Japanese) whiteboards that makes copies of what is written on it.

∂19-Aug-87  1830	Moon@STONY-BROOK.SCRC.Symbolics.COM 	meeting place
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Aug 87  18:30:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 216931; Wed 19-Aug-87 21:31:58 EDT
Date: Wed, 19 Aug 87 21:31 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: meeting place
To: Common-Lisp-Object-System@Sail.Stanford.edu
In-Reply-To: <870819-173655-3259@Xerox>
Message-ID: <870819213135.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

I don't care where we meet, but if it isn't Lucid someone should tell
Jan Zubkoff, since she has been making arrangements for a room.

∂20-Aug-87  0928	Moon@STONY-BROOK.SCRC.Symbolics.COM 	proposed syntactic cleanups in defmethod   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 20 Aug 87  09:28:29 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 217224; Thu 20-Aug-87 12:29:36 EDT
Date: Thu, 20 Aug 87 12:29 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: proposed syntactic cleanups in defmethod
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870820122915.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

We've noticed some problems with the CLOS syntax for defmethod,
especially when using methods on individuals, and in response I'd like
to propose three cleanups.  Note that all of these changes are purely
syntactic; that is, they only affect the readability of programs, they
don't add or remove capabilities of the language.  I hope this is a
minor issue that can be dealt with quickly.

The first problem has to do with the suggested compiler warnings
mentioned on CLtL p. 160 under the IGNORE declaration.  Methods often
don't use some of their parameters for anything other than making the
method applicable for certain arguments to the generic function.
Consider this example

  (defmethod additional-mail-headers ((host 'xerox.com))
    (declare (ignore host))
    '(:line-fold "No"))

One would prefer not to have to write the (declare (ignore host)).
This almost always happens with methods on individuals, but it can
also happen with methods on classes.  Consider

  (defmethod color ((e elephant))
    (declare (ignore e))
    'grey)

I propose that the DEFMETHOD macro be specified to "refer to" (in the
sense of CLtL p.160) each specialized parameter.  This means that a
compiler warning will not occur regardless of whether the body of the
method does or does not refer to the parameter, and the declare ignore
in the above examples must be removed.  This makes sense intuitively
if one regards the type check of the argument against the parameter
specializer as being part of the method; thus any specialized parameter
is referred to by the type check.

An interesting effect of this is that

  (defmethod part-color ((e elephant) part)
    'grey)

and 

  (defmethod part-color ((e elephant) (part t))
    'grey)

are no longer synonymous, since the first gives a compiler warning
and the second does not.  I think this is a feature, not a bug.

================

The second problem relates to the use of the single quote syntax (') for
methods on individuals.  There are actually two problems here.  One is
that that single character is easy to overlook.  One of the most common
mistakes of beginning Lisp programmers is omitting quote marks or putting
them in the wrong place.  Actually, it's not only beginning programmers
who do this.  I still do it myself sometimes, and I believe I have seen
Danny Bobrow do it.

I believe the programmer who intended to write

  (defmethod color ((e elephant))
    'grey)

but accidentally wrote

  (defmethod color ((e 'elephant))
    'grey)

instead is going to have a lot of trouble figuring out what happened.
It would be better to make the latter form a syntactic error, so that
we can give a clear error message.  We should use a different syntax for
methods on individuals.  The quote mark is a cute hack, but I think we
can afford to use something slightly more verbose.  Suggestion below.

The other problem with methods on individuals is that the current syntax
is awkward when the individual is anything other than a symbol or a
number, just because defmethod is using a special magic syntax instead
of a normal Lisp form.  Returning to my first example, suppose hosts are
to be represented by CLOS objects rather than symbols.  Instead of
writing

  (defmethod additional-mail-headers ((host 'xerox.com))
    '(:line-fold "No"))

I now have to write

  (defmethod additional-mail-headers ((host '(parse-host "xerox.com")))
    '(:line-fold "No"))

but this doesn't work, because the form (parse-host "xerox.com")
is not in a position to be evaluated.  I can write

  (eval `(defmethod additional-mail-headers ((host ',(parse-host "xerox.com")))
	   '(:line-fold "No")))

but that's grotesque.  I can also write

  (defmethod additional-mail-headers ((host '#.(parse-host "xerox.com")))
    '(:line-fold "No"))

which works for this case, but #. has scoping problems exposed by the
next example.  Suppose we're writing methods on individual numbers, but
rather than sprinkle numbers all over the code, we use defconstant, as
good style dictates.  This is boiled down from a remote-procedure-call
example.

  (defconstant begin-code 1)
  (defconstant end-code 2)
  (defconstant integer-code 3)
  (defconstant float-code 4)

  (defmethod decode (stream (opcode '#.begin-code))
    ... begin processing a message ...)

One problem with this occurs when using compile-file.  CLtL isn't very
clear on whether #. evaluates in an environment in which those
defconstants have been evaluated.  It's likely that the programmer has
to play some games with eval-when to make this work.  This could be
fixed by tightening up the semantics of compilation in Common Lisp, but
a worse problem is that #. does not and can not respect lexical scoping.
Suppose we had

  (let ((begin-code 1))
    (defmethod decode (stream (opcode '#.begin-code))
      ... begin processing a message ...))

There is no way the #. can see the environment created by the LET
which is still being read in at the time the #. is processed.

It seems that it would make a lot more sense to put a regular Lisp form
in the parameter-specializer-name, scoped completely normally, and let
the defmethod macro (rather than the programmer) take care of any
special mechanism needed to evaluate with respect to the proper
environment, including compile-time defconstants.  Common Lisp doesn't
currently standardize all the primitives needed to write that defmethod
portably, but I think that only strengthens the argument for making
defmethod worry about those issues, instead of making every programmer
worry about them.

So I'd like to see the syntax of an individual
parameter-specializer-name changed to use a different word instead of
QUOTE, and to use a form that evaluates to the object, instead of the
object itself.  The form is evaluated at the time the method is defined;
it is not evaluated each time the generic function is called.  I have
two suggestions for what word to use, one based on what test is being
performed and the second based on the Common Lisp type system:

  (defmethod additional-mail-headers
	     ((host (eql (parse-host "xerox.com"))))
    '(:line-fold "No"))

  (defmethod additional-mail-headers
	     ((host (member (parse-host "xerox.com"))))
    '(:line-fold "No"))

I mildly prefer EQL over MEMBER, but I thought I'd open up both
suggestions for discussion.  Each of these suggests an obvious
generalization, EQL to other predicates and MEMBER to multiple
individuals, and the choice might be based on which generalization we
want people to think about, even if we don't propose to implement the
generalization.

================

The final issue has to do with parameter-specializers rather than
parameter-specializer-names, using the terminology of 87-002 page 1-18.
I think that adding QUOTE as a type-specifier to Common Lisp is both
unnecessary and confusing.  (Yes, I know I suggested it.  I was wrong.)
Instead, the parameter-specializer for a method on an individual should
be (MEMBER object), the type-specifier that Common Lisp already defines
for this purpose.  Note that there is no particular reason why the
parameter-specializer should be the same as the parameter-specializer-name;
they're already not the same for methods on classes.

∂20-Aug-87  1010	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 20 Aug 87  10:09:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 217266; Thu 20-Aug-87 13:10:51 EDT
Date: Thu, 20 Aug 87 13:10 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Miscellaneous decisions taken or to be taken
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870820131023.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

I have updated my file of miscellaneous decisions taken or to be taken,
based on mail received in response to the last time I mailed this out
(two weeks ago).  If anyone doesn't see their response included, or
thinks their favorite issue is missing, please let me know and I will
apologize for my error and add it.  I hope that we can use this file as
part of the agenda for the September meeting.  Let's try to resolve any
of these issues that can be resolved through the mail before that meeting.
Also, if I've marked an issue as agreed but you disagree, please speak up
now.

The rest of this message is the file.  Page separator characters don't
seem to go through, so I have replaced each with 16 equal signs.

This file reflects Moon's understanding of the status of various CLOS issues,
concentrating on the more minor issues.  The goal is to make sure that nothing
is overlooked, and especially to make sure that issues that have been brought up
and resolved are not forgotten before they get into the document.  I've removed
most comments that were purely editorial comments on the document.  I also
haven't tried to keep track of all the purely meta-object issues.  I've edited
things to be as brief as possible.

All page references are to the 87-002 version of the CLOS document.



The file is divided into pages as follows:

0. This page of general outline

1. Documented holes in chapters 1 and 2 of 87-002

2. Things that have been already decided (but may not be in the document yet)

3. Issues with no apparent remaining disagreement

4. Small issues needing discussion

5. Issues whose status is unclear, maybe to be tabled

6. Big issues needing discussion, each on its own page
================
DOCUMENTED HOLES IN CHAPTERS 1 AND 2 OF 87-002

We publicly promised X3J13 that we would finish these holes and also have a new
draft of 87-003 by the next meeting (October).

1-5, 2-44 The initialization protocol for make-instance is not yet
specified.


1-13, 1-26, 2-14 Which Common Lisp types will have corresponding classes
is still under discussion.

  Document has been updated in draft.
  Need Cleanup Committee proposals for fixes to the type system.


2-7, 2-46 [The proposed extension to call-next-method has been accepted.]

  This may not have been put into the document yet.


2-41, 2-48 [Perhaps we can adopt the condition signalling system now.]
================
THINGS THAT HAVE BEEN ALREADY DECIDED (BUT MAY NOT BE IN THE DOCUMENT YET)

27 May 87 call-next-method is allowed to take arguments, however it is an error
to give it arguments that would change the set of applicable methods.  I think
we're saying this signals an error, and mentioning that in some simple cases the
lack of need for an error check can be proved at compile time, but in general a
run-time check is required.  Specify precisely the type of error signalling.


10 June 87 The document has been updated with a discussion of how the standard
type classes are organized.

  8/9/87 Gregor promised to draw a picture.


2-16 (slot-name form) is not allowed as an abbreviation
for (slot-name :initform form).  People have been assuming this,
we have to document explicitly that it is not allowed.

  The decision to reject (slot-name form) was made at the July meeting.


2-19 uninitialized slots should be an error to reference, not be defined
to return an unstandardized value with no error.  I'm willing not to require
that it signals an error if people feel that would be an undue burden,
otherwise I prefer that reading an uninitialized slot signals an error.

  In July we decided that signalling an error here should depend on the
  declared safety level.  Dick has proposed terminology for this.


p2-19 Values: I thought we agreed that all top level forms should return
the object.  It says here defclass "returns the name of the class"
p2-22 Same comment as 2-19, for defgeneric-options
2-24 ditto for defgeneric-options-setf

  In July we decided to return the object for all CLOS defxxx functions (being
  inconsistent with Common Lisp, but consistent within CLOS).  The document file
  has been updated.


p2-39 Arguments: "list of t's" should be replaced by "list whose elements are
the class named t" since get-method only takes specializers, not names of
specializers.

  Agreed.


2-42 make-generic-function should be deleted, redocumented as a class
that can be given to make-instance

  July: Agreed


2-45 make-method should be deleted, redocumented as a class
that can be given to make-instance

  July: Agreed


2-54 in the Amendments:  Clarify that because class names and classes are
type-specifiers, they can be validly be used in THE special forms and in TYPE
declarations.  We forgot this when we clarified that class objects can be used
with TYPEP and SUBTYPEP.

  July: agreed
================
ISSUES WITH NO APPARENT REMAINING DISAGREEMENT

1-12 Should defclass be allowed to change the metaclass of an existing
class? Under what conditions should a subclass of standard-class have
the same properties wrt instance updating as standard class?

  Gregor says the metaclass protocol includes a predicate function that controls
  whether the metaclass can be changed, which depends on whether the
  representations differ and existing instances might not be transformable.
  Some cross-reference to this should be added to the documentation of DEFCLASS.


1-15 to 1-22 Several errors in the formal description of class precedence and
method combination, pointed out by Jim Kempf on 4 August and 27 July, need to be
corrected.  These are editorial changes only, that is, they make what the
document says conform to what I believe our intent to have been.


2-35 The argument order of the setf method ought to be documented here.

  In July we suggested making the new-value argument a required argument that
  comes after all the other required arguments, and before the optional, rest,
  and keyword arguments.  It's important that this depends only on the two
  lambda-lists, and not on any context such as the generic function object.

  We still have defmethod-setf so that most users don't have to think about it
  (only users making setf methods "directly").

  The rule, carefully worded so as to work in the face of implementations with
  non-standard lambda-list-keywords, is that the setf-lambda-list is inserted
  into the normal lambda-list immediately after the last parameter-specifier
  that precedes &optional, &rest, &key, or &aux.  This is implemented by the
  following function (should it be standardized as part of CLOS?):

   (defun combine-setf-lambda-lists (lambda-list setf-lambda-list)
     (do ((ll lambda-list (cdr ll))
	  (tail lambda-list))
	 ((or (null ll) (member (car ll) '(&optional &rest &key &aux)))
	  (when (null ll)
	    (setq tail nil))
	  (append (ldiff lambda-list tail) setf-lambda-list tail))
       (unless (member (car ll) lambda-list-keywords)
	 (setq tail (cdr ll)))))

  What about the setf of values extension that Common Lisp provides syntactic
  space for but does not currently prescribe?  We're not going to allow that for
  setf of generic functions.


2-50 Should we flush multiple-value-prog2, as leading to more discussion than is
warranted by its simplification of the presentation of define-method-combination?

  Kempf: Yes.


2-51 It has been suggested that print-object should take a depth argument.

  Moon strongly disagrees and points to the fourth bullet.  I believe this issue
  was discussed to death on the Common Lisp mailing list a few months or a year ago.
  The point is that every single method for print-object should not have to deal
  with *print-level*; that's unmodular.

  Kempf raised a consistency argument (with defstruct?) but we decided
  not to change print-object.


2-54 slot-missing should be documented in chapter 2

  Gregor:
    slot-missing is a generic function which takes three required
    arguments and an optional fourth argument.  The three required
    arguments are the class of the object, the object and the name of the
    slot.  The fourth argument is the new value for the slot if
    slot-missing is being called by setf of slot-value.  This set of
    arguments allows people to define methods on the metaclass for
    handling slot-missing.  For example, a low performance implementation
    of dynamic slots could work this way.
    
    (defmethod slot-missing ((class dynamic-class) obj slot
			     &optional (nv nvp))
      (if nvp
	  (set-dynamic-slot obj slot nv)
	  (get-dynamic-slot obj slot)))
    
    The default method on slot-missing signals an error of the same name.


Symbol-function (the user callable primitive) needs to be split from the
subprimitive for implementors that gets and sets the "real" function definition
of a symbol.  This is so when a symbol's function definition is a generic
function object, the "real" definition can be something that is easier for the
implementation to call.

  July: We need to say explicitly somewhere that calling symbol-function
  of the name of a generic function is required to return the generic
  function object, not the "real" definition.
  Kempf: I don't see splitting SYMBOL-FUNCTION as an issue for the standard,
  though it may be for certain implementations.
  Moon: Right, the only standardization issue is making sure
  SYMBOL-FUNCTION returns the generic function object, not something internal.
  See earlier discussion of class-names (2-13), which affects symbol-function.


Not all of the "corrections and amendments" handed out at the March 1987
X3J13 meeting in Palo Alto have been put into the document yet.  The
corrections are in but the amendments and the revised explanation of slot
inheritance are awaiting review by the group.
================
SMALL ISSUES NEEDING DISCUSSION

1-19 "... Common Lisp be modified to include the following semantics
for quote in a type specifier:
 (deftype quote (object) '(member ,object)))"
Has any proposal for this been given to the cleanup committee? 

  Yes: ISSUE: TYPE-MEMBER-SINGLETON, Proposal TYPE-MEMBER-SINGLETON:QUOTE 
  It hasn't really gone through the mill yet, though.
  In July Moon volunteered to make sure this happens, but in August
  Moon said he didn't like it and we should use MEMBER in parameter
  specializers instead.


1-24 Should we have a call-next-method? which calls such a next method
if it exists, else returns nil (rather than signalling an error?).  This
seems useful rather than having to define many base methods on object.

  Common Lisp reserves question mark for the user; this could be named
  CALL-NEXT-METHOD-OR-NIL, or something like that.
  Kempf: signalling an error is sufficient, this probably isn't needed.

  In July we wondered whether there should be a way to get a list of
  the remaining methods.  What operations on that list should be
  permitted?
    - checking whether it's nil gives the desired feature
    - checking its length
    - doing something with list elements (presumably method objects)
    - modifying the list is clearly out
    - does the list have dynamic or indefinite extent?    
  This may be expensive enough that it can't substitute for
  CALL-NEXT-METHOD-OR-NIL.

  I think we're awaiting proposals on these two issues, as well as a
  concensus on whether we need these features.


2-30: Note the third paragraph on p.2-30 of 87-002, speaking of signalling an
error when the arbitrary order of two methods affects the result.  I suggest
that this error be mandatory instead of optional.


2-38 need a way to recover documentation of a method-combination type

  July: do this by adding a new value for the second argument to DOCUMENTATION.
  But the whole writeup on DOCUMENTATION is screwy, and we need a new proposal.
  When the CL-Cleanup subcommittee finishes cleaning up the concept of
  "definition" (I think it's waiting for Masinter to propose something)
  then DOCUMENTATION should follow.


2-57 What does with-slots do for slots that exist in the class but don't
have accessors, when :use-accessors t is specified (or defaulted)?

  July: it shadows any outer bindings of the slot name, and if you
  actually access that pseudo-variable, it signals an error.

  Gregor: What if by the time you actually run the body of the method, the slot
  has an accessor? It all hinges on exactly when macro-expansion time is and
  that is not specified.

  There are two issues here:
   (1) Exactly when is the set of names scoped with with-slots determined?
   (2) Exactly when is the presence or absence of an accessor for a name
       determined?


What can be done with method objects, e.g. can one method be added
to more than one generic function?

  Kempf: There may be a problem if the method invokes CALL-NEXT-METHOD.
  [I wasn't able to understand his description of the problem -- Moon]

  Gregor: I believe it should signal an error to attempt to put a method on more
  than one generic function.  My model of this is that if you want to do
  something like that, you can take one function, use it as the method function
  of multiple methods, each of which would be on a different generic function.


I'm not sure if we said anywhere what happens when you call a generic
function and there is no applicable method; I think it ought to signal
an error.

  Gregor:
  This is a generic function like slot-missing.  There is a generic
  function NO-MATCHING-METHOD which is called with the generic function
  as the first argument and the arguments to the generic function as
  the remaining arguments.  This allows people to define a method to
  handle the no matching method case either on the class of the generic
  function or on the individual generic function.  The default method
  for no-matching-method signals an error of the same type.
  The error message should give some information about
  the classes of the parameters, to help debugging.

  CALL-NEXT-METHOD with no more methods should do something similar,
  but not identical.


funcallable-standard-class should be documented.  It is a metaclass.
This is what makes generic function objects funcallable.  There is a slot
that is the actual function that gets called.

  I think Gregor volunteered to propose details.


We need to decide whether class-name of an anonymous class is nil or
signals an error.

  The concensus seems to be to return nil.


What does type-of return when applied to an instance of an anonymous
class?

  Returning NIL is not valid by CLtL's definition of TYPE-OF.
  The choices are either to return the class object itself or
  the name of some superclass that has a name, T if necessary.
================
ISSUES WHOSE STATUS IS UNCLEAR, MAYBE TO BE TABLED

1-17 "It is currently under discussion whether to provide constructs
for giving generic functions local names."  Do we want to have this
discussion, or to punt on this syntax. I recall we did come up with some
reasonable semantics for a GFLET and GFLABELS. 

  In July we decided to defer this.
  2 Aug 87 RPG offered to write a proposal.


2-26  I believe that short form method combination ought to be a macro
in the standard library, and documented there, not in the basic
principles.  I think the standard combinations :append, :and, :or, ...
should also be put in the standard library too.
  
  Kempf agrees.  Moon can't have an opinion until he knows what this
  library is and whether it's going to be as much of a joke as the
  Common Lisp Yellow Pages.


2-46 Last line:  If call-next method is extended ..."  I see no reason
for additional keyword arguments.  

  Moon doesn't remember the issue.  It may have been consistency; if call-next-method
  can specify the arguments, then so can make-method-call.  You need one keyword
  argument to specify the methods and another to specify funcall versus apply.
  It could also have been that call-next-method would be implemented in terms of
  make-method-call, and therefore would need to be able to specify the arguments.


2-6 call-next-method dynamic versus indefinite extent

  The document says it has dynamic extent; we need to be sure that we
  really mean that.  In July we said "implementation flexibility, not
  really a language thing", but I'm damned if I can figure out what
  that means (optimizing calculation of the effective method?).

  Gregor: I am pretty sure what we meant was we didn't want to have to worry
  about the case where someone returns a closure that includes a call
  to call-next-method, and then redefines the class or method structure
  so that the closure would have to call different 'next methods'.

  Moon: Oh, so this is different from extent, because they could do that
  redefinition before the method returns.  So either we should say it
  captures the set of next methods at a particular instant, or it's
  undefined what happens if you redefine.


2-9 semantic difficulties discussion was shortened for the document so much
that much of the point was lost.  At some point we need to decide how much
we want to standardize about this and where we want to say it; in the main
standard or in some kind of implementation guide.

  [no response to this so far, Moon should propose I guess]


2-16 boa-arglist should support &key and &allow-other-keys.
2-18 default boa-arglist to be specified

  Status depends on whether object-creation proposal includes constructors.


Moon: method arglist congruence still doesn't satisfy me.  I have some
ideas about this but unfortunately have not managed to pull them together.

  To be resolved as part of the initialization protocol discussion.


Which symbols defined by the standard go in what package?

  July: I think we said some will go in LISP: and some will go in CLOS: and
  we don't know yet where to draw the line.
  The top level macros and functions should be part of LISP.
  The internal functions specified for the sake of metaclass programming
  can reside in CLOS.
  If CLOS is an optional part of CL, are the symbols in the LISP package
  even when the option is not present?  Probably.


Should we adopt the :component-order class-option from Flavors, as a
simple way for the user to have control of the CPL without making him
write his own algorithm?

  Gregor doesn't like the ability to specify constraints on the ordering
  of classes that only apply conditionally, i.e. if those classes are
  actually present among the superclasses.  He considers this bad style.
  Moon volunteered to write a proposal with some examples, and we agreed
  to resolve this over the mail.

================
PREFIXED SYMBOL NAMES

These two issues appear to be related.

2-18 (:accessor-prefix nil) is not a good way to say "use the slot names
as the accessor names".  We need to fix this.

  We could add another option, or remove the whole prefix feature, and
  require accessor names always to be listed explicitly.
  In July we agreed to discuss this in the mail.


2-57 with-slots :prefix package problem; This was discussed in the mail and
then the ball was dropped.  What's in the document is unworkable because it
depends on the dynamic value of *package* at macro-expansion time, but Common
Lisp doesn't guarantee anything about when macro-expansion occurs.  Moon would
prefer to flush the :prefix option.  An alternative that was discussed was to
use symbol-package of the prefix, both here and in defclass accessor construction,
as the package, relying on the likelihood of prefixes always ending in delimiter
characters and exported symbols never ending in delimiter characters.

  July: We agreed to resolve this in the mail.
  Kempf, Moon: Flush :prefix.
  Gregor: I like the prefix option, although I agree that this is a serious
  problem.

================
ENSURE-GENERIC-FUNCTION

A constellation of issues surrounding the mapping from generic function
names to generic function objects.  This seems to be awaiting a proposal
to pull it all together.

1-18, 2-40 It is not specified whether get-setf-generic-function is setf-able.

  Gregor: make it setf'able, it's just like symbol-function.  Maybe
  rename it to symbol-setf-generic-function?
 
  Moon thinks this would be okay provided it is understood as setting the
  mapping from a name to a generic function, not side-effecting the
  generic function.  See class-name discussion below (2-13).
  Good reason to rename it to symbol-setf-generic-function.

  This set off a discussion of how TRACE should work that maybe doesn't
  bear directly on CLOS.  Kempf is working on a proposal.


2-40 get-setf-generic-function needs an errorp, but it and get-generic-function
should be subsumed by ensure-generic-function which would do all the right things.

  Gregor:
  I propose that we keep get-setf-generic-function, but that we rename it to
  symbol-setf-generic-function.  In addition, I propose that we do the
  following:
  
    ensure-generic-function, add-named-method and any other CLOS
    function that takes the name of a generic function as an argument
    can also take a list like (SETF <symbol>) which means the
    setf-generic function for that argument.
  
  I propose that ensure-generic-function do basically what
  defgeneric-options and defgeneric-options-setf used to do except that
  ensure-generic-function would be a function (that is it would
  evaluate its arguments).  This isn't a problem since
  defgeneric-options didn't take any &body arguments anyways.  The real
  thing that needs to be worked out here is what happens if the generic
  function already exists, but is different in some ways than the
  description in the arguments to ensure-generic-function.

  The relevant options (referring to 2-42) seem to be:
	:lambda-list -- method congruence issue
	:generic-function-class -- covered below
	:method-class -- are existing methods mutated?
  Moon doesn't see any problem with changing these options:
	:argument-precedence-order
	:declare
	:documentation
	:method-combination

Gregor's e-g-f proposal, recovered from mail sent back in February,
and edited only slightly:

ensure-generic-function <symbol>
                        &key (generic-function-class
                               (class-named 'standard-generic-function))
                             (make-existing-function-default-p nil)

If symbol is fboundp to a generic-function of the same class as
generic-function-class then this function does nothing, and
returns the generic function object.

If symbol is fboundp to a generic-function of some other class, the
generic-function class changing protocol is followed, see chapter 3.
Use (class-named 'generic-function) to prevent changing the class
(is this right?  does "of class" here mean typep or eq type-of?)

If symbol not foundp a generic function of generic-function-class is
created and put in symbol's function cell.  There was some contention
over whether there should be a create-p argument to control this, or
the caller should do an fboundp test first.

If symbol is fboundp to a function, and make-existing-function-default-p
is not nil, a generic-function is created, put in the function cell, a
default method is added to the generic-function and the symbol's
previous function cell value is used as the function for the default
method.

If symbol is fboundp to a function and make-existing-function-default-p
is nil an error is signalled.

If symbol names a macro or a special form, an error is signalled.

Thus if this does not signal an error, it returns a generic function
object that is now the function definition of the symbol.

<symbol> can also be (setf <symbol>), as proposed later.  How does the
caller do an fboundp test of this?

Feel free to change the names of the arguments.  Note that this is a
function not a generic-function.

This needs to take additional arguments corresponding to all of the
arguments of defgeneric-options; see make-generic-function on 2-42.

================
CLASS NAMING ISSUE

[I have not yet summarized all the mail on this topic]

================
CLASS REDEFINITION

[I have not yet summarized all the mail on this topic]

================
COMPILER OPTIMIZATION

Kempf 29 Jul 87: There was no mention made of compile time optimization,
which I believe I made some initial proposals on in late April or early May.
I've been meaning to revisit them.

∂20-Aug-87  1525	kempf%hplabsz@hplabs.HP.COM 	Re: Agenda for September meeting    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 20 Aug 87  15:18:52 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 20 Aug 87 13:23:58 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 20 Aug 87 13:22:33 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 20 Aug 87 14:23:19 pdt
Message-Id: <8708202023.AA19448@hplabsz.hpl.hp.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Agenda for September meeting 
In-Reply-To: Your message of Tue, 18 Aug 87 14:46:00 -0400.
             <870818144639.2.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Thu, 20 Aug 87 14:23:16 MST
From: kempf%hplabsz@hplabs.HP.COM

> Earlier I said that I wanted to leave by Friday noon, but in putting
> together the agenda it became clear that 1 1/2 days wasn't enough time.
> Hence we've written the agenda for two full days.  Is that okay with
> everyone?

Yes, this is fine.

> Discuss written proposals on major areas, circulated over the network
> before the meeting and brought to the meeting in hardcopy.  Spend no
> more than 45 minutes on each proposal, determining yes, no, or needs
> further discussion.  Expected areas for proposals: object creation, new
> draft of metaclass chapter, change-class, 1 or 2 others.

I'd like to put in debugging support under the "1 or 2 others" if nobody
has any strong objections. I'll rewrite the proposal based on the comments 
Dave sent and resubmit to the network within the next week. The reason is, 
our developers seem to need it.

> Mail out hardcopies of the latest version of the 87-002 document
> immediately (no further editing is planned, right?).

Yes, this is very definitely needed, as soon as possible.

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

The rest of the agenda looks good to me. I have no particular preference
about where the meeting is held, just as long as the location is mailed
out ahead of time, so I can get there on time.

With regard to the spec documentation, I'd like to put in a vote for an ASCII
version to go on parcvax, along with the portable source, so people don't
have to be working in the dark with it. The ASCII version doesn't
necessarily have to be up to the current level of discussion and 
decision within the committee (indeed, it probably shouldn't) but should
reflect approximately what is implemented. If there is some problem with
deTeXing it, we have some OCR software here which I'd be willing to give
a try at scanning it in with. Alternatively, Linda and Dick's paper from
ECOOP would be a possible source, although it's more of an overview (and
looks like it would probably be easier to scan in).

		jak






∂21-Aug-87  0828	kempf%hplabsz@hplabs.HP.COM 	Re: proposed syntactic cleanups in defmethod  
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 21 Aug 87  08:25:55 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Fri, 21 Aug 87 08:21:12 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Fri, 21 Aug 87 08:20:38 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Fri, 21 Aug 87 09:21:22 pdt
Message-Id: <8708211521.AA25991@hplabsz.hpl.hp.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: proposed syntactic cleanups in defmethod 
In-Reply-To: Your message of Thu, 20 Aug 87 12:29:00 -0400.
             <870820122915.2.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Fri, 21 Aug 87 09:21:19 MST
From: kempf%hplabsz@hplabs.HP.COM



Proposal 1:

> I propose that the DEFMETHOD macro be specified to "refer to" (in the
> sense of CLtL p.160) each specialized parameter.  This means that a
> compiler warning will not occur regardless of whether the body of the
> method does or does not refer to the parameter, 

I support this proposal. I think a good case was made for it.


Proposal 2:

> So I'd like to see the syntax of an individual
> parameter-specializer-name changed to use a different word instead of
> QUOTE, and to use a form that evaluates to the object, instead of the
> object itself.  The form is evaluated at the time the method is defined;
> it is not evaluated each time the generic function is called.  I have
> two suggestions for what word to use, one based on what test is being
> performed and the second based on the Common Lisp type system:

I feel vaguely uneasy about this proposal. Part of the reason is because,
as rpg more forcefully stated somewhat earlier, I do not much like the idea 
of having quoted objects as specializers in the first place. 

The reason for this is as follows. One could view quoted objects as being
a kind of restricted subrange type. Allowing quoted objects means that users 
can define methods which discriminate on individual FIXNUMs or arrays, but
disallowing subranges means they can't define methods which discriminate on
all FIXNUMs or arrays of a particular size. 

One could argue that this is rather an argument for allowing subranges than for
disallowing quoted objects, but I believe that subranges are a distinctly
different kind of thing. In fact, subranges are a kind of type
parameterization, since certain parameters must be supplied at the time the
type is instantiated (as opposed to when an instance is created) and these
parameters are usually of a nature which constrain instances in some manner.
Following through on the FIXNUM example, FIXNUMs can be viewed as an
instance of a more general type, RESTRICTED-INTEGER, which requires a
parameter indicating upper and lower bounds on the size of instances.
Similarly, an individual FIXNUM can be viewed as a member of the type (EQL x).

That said, I think Moon's ADDITIONAL-MAIL-HEADER example:

>   (defmethod additional-mail-headers ((host 'xerox.com))
>     '(:line-fold "No"))

indicates how quoted objects as specifiers might be useful. But one could
just as well write:

    (defmethod additional-mail-headers ((host symbol))

        (case host

            .... ;;various other possibilites

         ( 'xerox.com '(:line-fold "No") )))

Embedded CASE statements suffer the disadvantage that, when changes are
made (for example, adding a new host), then an additional branch must
be added or deleted everywhere. But, with quoted objects as parameter 
specifiers, adding an additional case requires adding new method 
definitions anyway, so I have trouble seeing any gain as opposed to the 
loss of consistency cited above. 

Classes could be used to generalize the mail example:


	(defclass host-name ()
	  (
	    (name
		:type symbol 
		:accessor NIL 
		:initform NIL
             )
           )
           (:reader-prefix NIL))

	(defmethod print-object ((object host-name) stream)
	  (print (name object) stream))

	;;;Various other methods for dealing with host names

        (defmethod additional-mail-headers ((host host-name))

           (case (name host)

            .... ;;various other possibilites

             ( 'xerox.com '(:line-fold "No") )))

Modifications to the host tables would still require adding another branch
to all CASEs, but methods operating on instances of HOST-NAME are likely
to be grouped together, and thus the difference between modifying a CASE
and adding an additional method is not large. After all, I don't think the
point of CLOS was to completely eliminate the need for CASE statements, but
rather to provide users a way of constructing code with generalizes
behaviors and structures.

So I'd actually prefer to eliminate quoted objects entirely.

> I mildly prefer EQL over MEMBER, but I thought I'd open up both
> suggestions for discussion.  Each of these suggests an obvious
> generalization, EQL to other predicates and MEMBER to multiple
> individuals, and the choice might be based on which generalization we
> want people to think about, even if we don't propose to implement the
> generalization.

If the above arguments don't sound convincing, or people just don't have
the energy and want to stick with what we already have, then I'd prefer
introducing some kind of new symbol, rather than using either of these.
The reason is because I'd rather avoid having people generalize, since
either of the generalizations lead in directions which I don't think
we're prepared to address. Something like SINGELTON would be a possibility:

  (defmethod additional-mail-headers ((host (singleton (parse-host "xerox.com"))))
	'(:line-fold "No"))

Proposal 3:

> The final issue has to do with parameter-specializers rather than
> parameter-specializer-names, using the terminology of 87-002 page 1-18.
> I think that adding QUOTE as a type-specifier to Common Lisp is both
> unnecessary and confusing.  (Yes, I know I suggested it.  I was wrong.)

I agree with this (modulo my misgivings about quoted objects as
specializers in the first place); however, again I think that some specific
other symbol (like SINGLETON) would be more appropriate.


∂22-Aug-87  0004	Masinter.pa@Xerox.COM 	Re: proposed syntactic cleanups in defmethod   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Aug 87  00:04:41 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 AUG 87 00:04:47 PDT
Date: 22 Aug 87 00:04 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: proposed syntactic cleanups in defmethod 
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Fri, 21 Aug 87
 09:21:19 MST
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870822-000447-6288@Xerox>

To clarify, are you proposing that:


    (dolist (x *broken-mail-hosts*)
       (defmethod additional-mail-headers ((host (singleton (parse-host
x))) '(:line-fold "No")))

be a reasonable way to assign individual methods to, say, a large number
of individuals?

Implementations will have to be careful to allow objects which have
individual methods to be GCd, won't they?






∂22-Aug-87  0033	Masinter.pa@Xerox.COM 	Re: TRACE Proposal (Version 1)  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 22 Aug 87  00:33:20 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 22 AUG 87 00:32:02 PDT
Date: 22 Aug 87 00:31 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: TRACE Proposal (Version 1) 
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Mon, 10 Aug 87
 11:45:31 MST
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870822-003202-6311@Xerox>

I've managed to convince myself that definition types (which are
primarily for the use of DOCUMENTATION, and a general, programmatic way
of "undoing" a DEFmumble), are pretty much independent of "function
specs", which are handles on ways of getting at things which might have
breakpoints or tracepoints associated with them. 

What I'm saying is that you should go ahead with your proposal for
function-specs in trace/break without worrying about any conflict from
the definition-type proposal which I have not finished writing.



∂22-Aug-87  1837	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: proposed syntactic cleanups in defmethod    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 22 Aug 87  18:37:38 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 218771; Sat 22-Aug-87 21:38:25 EDT
Date: Sat, 22 Aug 87 21:37 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: proposed syntactic cleanups in defmethod 
To: Masinter.pa@Xerox.COM
cc: kempf%hplabsz@hplabs.HP.COM, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <870822-000447-6288@Xerox>
Message-ID: <870822213731.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 22 Aug 87 00:04 PDT
    From: Masinter.pa@Xerox.COM

    To clarify, are you proposing that:

        (dolist (x *broken-mail-hosts*)
           (defmethod additional-mail-headers
                      ((host (singleton (parse-host x))))
             '(:line-fold "No")))

    be a reasonable way to assign individual methods to, say, a large number
    of individuals?

Yes.

    Implementations will have to be careful to allow objects which have
    individual methods to be GCd, won't they?

Not my department.  Any form of individual methods has this problem.

∂24-Aug-87  1146	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS     
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 24 Aug 87  11:46:12 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 24 Aug 87 11:41:54 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 24 Aug 87 11:41:21 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 24 Aug 87 12:42:06 pdt
Message-Id: <8708241842.AA11723@hplabsz.hpl.hp.com>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: ECOOP Reaction to CLOS 
In-Reply-To: Your message of Tue, 18 Aug 87 20:06:00 -0400.
             <870818200622.4.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Mon, 24 Aug 87 12:42:03 MST
From: kempf%hplabsz@hplabs.HP.COM

In <870818-153317-1383@Xerox> kirk writes:

>At any rate, presenting the effects of the proposed inheritance
>algorithm for CLOS would be more understandable if in conjunction with
>presenting the class ordering algorithm, violations of the "implicit
>inheritance - explicit override" rule are clearly marked as such.

Yes, the description in Part 1 of the spec should contain proper
documentation of how slot and class options are default inherited.

In <870818200622.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Moon writes:

> Some comments on characterizing the class precedence list algorithm.
> In my comments I will refer to this set of classes (slots omitted):

> (defclass a (b c w))            w   x  w   y w  x
> (defclass aa (b c d w))          \ /    \ /   \/
> (defclass b (w x))                b      c    d   w
> (defclass c (w y))                 \     |   /   /
> (defclass d (w x))                   \   | /   /
> (defclass w ())                        \ |/  /
> (defclass x ())                          aa
> (defclass y ())

The class a seems to be missing from the diagram, but I'll refrain
from trying to include it, since the result is more confusing that
enlightening.

> We've seen these classes before.  By the rules in 87-002,
> the CPL of a is (a b c w y x) and of aa is (aa b c d w x y).

>     Date: Thu, 9 Jul 87 13:24:38 pdt
>     From: Jim Kempf <kempf%hplabsz@hplabs.HP.COM>

>     The inheritance graph is searched depth first, left to
>     right, up to joins. Superclasses at joins are placed
>     in the class precedence list at the last occurance,
>     rather than the first, since such superclasses are
>     usually more general than their subclasses, and classes
>     at the end of the class precedence list should be more
>     general than those at the beginning. The qualitative
>     effect is to achieve a linearization of the inheritance
>     graph, with more specialized classes at the head of
>     the class precedence list and more general classes at
>     the tail, keeping together groups of classes which occur
>     together in the inheritance graph.

> I like this informal way of explaining it, except that I never figured
> out precisely what "up to joins" means, and depending on the
> interpretation of that phrase, this explanation could be incorrect.
> When the depth first walk of the graph for aa above encounters w above
> c, that's a join.  If it goes on to y, I don't think y is a join,
> nevertheless y is not next in the CPL, x is.

w is, indeed, a join class, since there is more than one line
of inheritance coming out of it. The definition of a join I had in
mind is a class which contributes two or more subclasses to the
CPL calculation. y is not a join, because there is only one line of 
inheritance coming from it (namely y->c->aa). x is also a join, because
there are two lines of inheritance coming from it (namely x->b->aa
and x->d->aa). If we follow the explanation, then, after including
w, we use the local precedence ordering to select x as the next
class to include. In this case, the local precedence ordering takes
priority over other rules and x is included. y is then included after
x.

So a more accurate statement would be:

     Define a join class as a superclass which contributes
     two or more subclasses to a CPL calculation. Define
     the base class as the class for which the CPL calculation
     is being made. To calculate the CPL, the inheritance graph 
     is searched depth first, left to right, up to joins, starting
     with the base class. Join superclasses are placed in the class 
     precedence list at the last occurance, rather than the first, 
     since such superclasses are usually more general than their 
     subclasses (from the base class's point of view), 
     and classes at the end of the class precedence list should be more
     general than those at the beginning. After a join class has
     been inserted, the local precedence ordering for the join
     class is used to start the left to right search again above
     the join. The qualitative effect is to achieve a linearization 
     of the inheritance graph, with more specialized classes at the head of
     the class precedence list and more general classes at
     the tail, keeping together groups of classes which occur
     together in the inheritance graph (i.e. maintaining local
     precedence).

This a a bit more complicated than the original, but more accurate,
I think. Some words about failures to linearize and an example would
also be helpful.




∂24-Aug-87  1254	LGD  	updated spec on SAIL    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

I have made a few minor edits to the drafts of the concepts and functions
chapters that Sonya put out on SAIL last month.  The only changes of note
here are some corrections to the new standard-type-class/superclasses
table in the section "Integrating Types and Classes."
I also tweaked the macros file so that it now prints "Draft" and the date,
so that we can keep our hardcopy drafts straight while we work.
There are also new .dvi files available.

--lgd

∂24-Aug-87  1304	kempf%hplabsz@hplabs.HP.COM 	Re: ECOOP Reaction to CLOS     
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 24 Aug 87  13:04:27 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 24 Aug 87 13:04:04 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 24 Aug 87 13:03:41 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 24 Aug 87 14:04:22 pdt
Message-Id: <8708242004.AA12343@hplabsz.hpl.hp.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: ECOOP Reaction to CLOS 
In-Reply-To: Your message of Mon, 24 Aug 87 12:42:03 -0700.
             <8708241842.AA11723@hplabsz.hpl.hp.com> 
Date: Mon, 24 Aug 87 14:04:19 MST
From: kempf%hplabsz@hplabs.HP.COM


>      Define a join class as a superclass which contributes
>      two or more subclasses to a CPL calculation. Define
>      the base class as the class for which the CPL calculation
>      is being made. To calculate the CPL, the inheritance graph 
>      is searched depth first, left to right, up to joins, starting
>      with the base class. Join superclasses are placed in the class 
>      precedence list at the last occurance, rather than the first, 
>      since such superclasses are usually more general than their 
>      subclasses (from the base class's point of view), 
>      and classes at the end of the class precedence list should be more
>      general than those at the beginning. After a join class has
>      been inserted, the local precedence ordering for the join
                      ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
>      class is used to start the left to right search again above
       ↑↑↑↑↑
>      the join. The qualitative effect is to achieve a linearization 
>      of the inheritance graph, with more specialized classes at the head of
>      the class precedence list and more general classes at
>      the tail, keeping together groups of classes which occur
>      together in the inheritance graph (i.e. maintaining local
>      precedence).

After I mailed this I realized that the  ↑ underscored section should read:

   the local precedence ordering for the join class's leftmost occuring
   subclass 

So integrating, and making a couple of other minor changes, gives:

      Define a join class as a superclass which contributes
      two or more subclasses to a CPL calculation. Define
      the base class as the class for which the CPL calculation
      is being made. To calculate the CPL, the inheritance graph 
      is searched depth first, left to right, up to joins, starting
      with the base class. Join superclasses are placed in the class 
      precedence list at the last (rightmost) occurance, rather than 
      the first (leftmost), since such superclasses are usually more 
      general than their subclasses (from the base class's point of view), 
      and classes at the end of the class precedence list should be more
      general than those at the beginning. After a join class has
      been inserted, the local precedence ordering from the first
      (leftmost) subclass of the join class is used to start the 
      left to right search again above the join. The qualitative effect 
      is to achieve a linearization of the inheritance graph, with 
      more specialized classes at the head of the class precedence list 
      and more general classes at the tail, keeping together groups of 
      classes which occur together in the inheritance graph 
      (i.e. maintaining local precedence).








∂24-Aug-87  1644	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: proposed syntactic cleanups in defmethod    
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Aug 87  16:44:29 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa02900; 24 Aug 87 19:45 EDT
Received: from ti-csl by RELAY.CS.NET id ag16441; 24 Aug 87 19:34 EDT
Received: from Jenner by tilde id AA27526; Mon, 24 Aug 87 15:17:23 CDT
Message-Id: <2765823344-1583937@Jenner>
Date: Mon, 24 Aug 87  15:15:44 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: proposed syntactic cleanups in defmethod
In-Reply-To: Msg of Thu, 20 Aug 87 12:29 EDT from "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>

     I propose that the DEFMETHOD macro be specified to "refer to" (in the
     sense of CLtL p.160) each specialized parameter.  This means that a
     compiler warning will not occur regardless of whether the body of the
     method does or does not refer to the parameter, and the declare ignore
     in the above examples must be removed.  This makes sense intuitively
     if one regards the type check of the argument against the parameter
     specializer as being part of the method; thus any specialized parameter
     is referred to by the type check.
     

Sounds good.
     
     So I'd like to see the syntax of an individual
     parameter-specializer-name changed to use a different word instead of
     QUOTE, and to use a form that evaluates to the object, instead of the
     object itself.  The form is evaluated at the time the method is defined;
     it is not evaluated each time the generic function is called.

I think it is a very good idea.
     
     I mildly prefer EQL over MEMBER, but I thought I'd open up both
     suggestions for discussion.  Each of these suggests an obvious
     generalization, EQL to other predicates and MEMBER to multiple
     individuals, and the choice might be based on which generalization we
     want people to think about, even if we don't propose to implement the
     generalization.

I don't like MEMBER because it looks too much like the CLtL type
specifier and lots of people will think that they can discriminate on
multiple individuals. I am neutral on EQL versus another name as  Kempf
suggested.
     
Patrick.

∂24-Aug-87  1701	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: short form of define-method-combination
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Aug 87  17:01:33 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aj02900; 24 Aug 87 19:46 EDT
Received: from ti-csl by RELAY.CS.NET id ao16441; 24 Aug 87 19:36 EDT
Received: from Jenner by tilde id AA28861; Mon, 24 Aug 87 16:18:11 CDT
Message-Id: <2765827013-1804390@Jenner>
Date: Mon, 24 Aug 87  16:16:53 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: short form of define-method-combination
In-Reply-To: Msg of Wed, 19 Aug 87 13:20 EDT from "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>

     Date: Wed, 19 Aug 87 13:20 EDT
     From: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
     Subject: short form of define-method-combination
     
         Date: Tue, 18 Aug 87 19:06 EDT
         From: Daniel L. Weinreb <DLW@ALDERAAN.SCRC.Symbolics.COM>
     
         I am not enthusiastic about this proposal.  I have always liked having
         the qualifier in the defmethod form explicitly, because it enhances
         readability.
     
     Requiring the qualifier would satisfy my stated wants, provided that the
     qualifier wasn't optional (so there was only one way to write a primary
     method) and wasn't re-interned in the keyword package (so we aren't
     inventing symbols).
     
     However, I don't understand why you think the method-combination type of
     a generic function needs to be repeated in the defmethod, while the rest
     of the contract of the generic function does not need to be repeated.
     It seems to me that the command provided by the programming environment
     to remind one of the arguments expected, values returned, and documentation
     of the generic function can also remind one of the method-combination type.
     If you convince me that the method-combination type deserves special
     treatment, then I'll change my proposal to make the qualifier mandatory
     instead of prohibited.

The fact that we have two ways of defining primary methods for flavors
is a major source of confusion.  I got lots of questions about it.  I am
glad that David Proposes to rectify things.  I would be in favor of
omitting the qualifier, but if Dan objects to it, then requiring the
qualifier is OK too.  To me, the important thing is that the primary
methods have all the same syntax and that we don't end up with two
primary methods for one set of specializers.

Patrick.

∂26-Aug-87  1916	Gregor.pa@Xerox.COM 	Re: proposed syntactic cleanups in defmethod
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 26 Aug 87  19:16:01 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 26 AUG 87 19:15:44 PDT
Date: 26 Aug 87 19:15 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: proposed syntactic cleanups in defmethod
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 20 Aug 87 12:29 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870826-191544-1414@Xerox>

I have certainly been bothered by the same problems with defmethod
syntax you address, but I am not sure about all of these solutions. What
is bothering me is that while they all provide convenience, they make
the defmethod form itself more complicated.  I haven't yet made my mind
up, but I thought I would send out a message to at least say something,
since you said you hoped it could be resolved quickly.

The proposal to make defmethod forms, which actually name specializers
for arguments, refer to those arguments certainly would be convenient.
There are a lot of cases in PCL code where I could remove declare
ignores.  But it makes the defmethod story more complicated.
Particularly, if arguments which are not specialized are also refered
to.  I am not sure this is worth the tradeoff?  But I am not sure it
isn't either.

The second proposal (to evaluate the argument to an EQL or ' specializer
at load time) addresses a much more real problem.  In paricular, without
this, its not possible to use call-next-method inside of methods on
individuals.  That probably makes this worth doing, even it it makes the
defmethod story more complex.

I have no particular opinion on the third proposal.

I would like there to be a simple, clean story which can be used to
correspondence between any given defmethod form, and a call to
add-method, make-instance and ensure-generic-function.  Thats what makes
defmethod nice syntax for add-method the same way defun is nice syntax
for setf of symbol-function.

∂26-Aug-87  2033	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: proposed syntactic cleanups in defmethod    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 26 Aug 87  20:33:36 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 221804; Wed 26-Aug-87 23:34:54 EDT
Date: Wed, 26 Aug 87 23:34 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: proposed syntactic cleanups in defmethod
To: Common-Lisp-Object-System@sail.stanford.edu
In-Reply-To: <870826-191544-1414@Xerox>
Message-ID: <870826233424.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 26 Aug 87 19:15 PDT
    From: Gregor.pa@Xerox.COM

    I would like there to be a simple, clean story which can be used to
    correspondence between any given defmethod form, and a call to
    add-method, make-instance and ensure-generic-function.  Thats what makes
    defmethod nice syntax for add-method the same way defun is nice syntax
    for setf of symbol-function.

I agree that this is desirable.  I don't think the changes I proposed make
the story more or less complicated than it was before.  For example,
evaluating the specification of an individual rather than quoting it only
shows up as evaluating or quoting a particular position in the form resulting
from expansion of defmethod, I would expect.

Since I'm not sure I understand how these meta-level functions are intended
to be used, and since I have never seen the simple clean story written down,
I don't think I am competent to write out the details of how the expansion
of defmethod would be affected by my proposed changes.  Gregor, perhaps you
could take a crack at it?

∂27-Aug-87  0952	kempf%hplabsz@hplabs.HP.COM 	Solutions to Name/Object Mapping for Generic Functions  
Received: from [15.255.16.7] by SAIL.STANFORD.EDU with TCP; 27 Aug 87  09:52:00 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 27 Aug 87 09:51:04 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 27 Aug 87 09:50:38 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 27 Aug 87 10:51:23 pdt
Message-Id: <8708271651.AA07090@hplabsz.hpl.hp.com>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Solutions to Name/Object Mapping for Generic Functions
X-Mailer: mh6.5
Date: Thu, 27 Aug 87 10:51:21 MST
From: kempf%hplabsz@hplabs.HP.COM


Sorry this note has dragged on so long, but the name to object mapping
is a difficult enough problem that I think it requires some thought.

THE PROBLEM AND PROPERTIES OF A GOOD SOLUTION

As my previous note outlined, the problem with making SYMBOL-FUNCTION
sensitive to the environment is that it directly conflicts with the
Common Lisp notion of the symbol's function cell as a global place.
On the other hand, the consequences for CLOS of not somehow making
the metaclass protocol for generic functions sensitive to the environment
are that support for resolving method inheritance at compile time
will not be available in a portable way (it may and probably will be
available in an implementation dependent way, since optimizations
will require it). 

A good solution should somehow avoid either of these extremes. In
addition, the solution should not be such that compilation of a
method causes redefinition of anything funcallable in the compiler's
run time environment, since this could cause bootstrapping to fail.
This particular property rules out, for example, allowing the
symbol's function cell to become like a dynamically bound function
variable.

SOME POSSIBLE SOLUTIONS

The following are some possible solutions:

1) The symbol function cell could be eliminated as a global object and
the name to funcallable object mapping could be maintained within the
environment, as is the case in Scheme.

2) The generic function slot accessor functions could take an
environment argument and return information accordingly. This 
was the solution I believe Patrick proposed. 

3) We could simply leave it up to implementors to supply these
hooks, if they so choose.

Nice properties of each solution are:

1) The existence proof of Scheme and T shows that this solution can be
implemented. It also has a certain elegence.

2) No radical changes in existing Common Lisp implementations would be
needed.

3) No radical changes in the current spec for CLOS would be needed.

Nasty properties of each solution are:

1) Radical changes in existing Common Lisp compilers would be needed.
The issue of a single function/value cell is controversial, this could
be even more so.

2) This would complicate the metaclass protocol for generic functions
considerably. In particular, generic function slot accessors would need
to maintain data structures for mapping environments to methods, and
the dispatch function would need to do the "right" parameter specializer
to method function mapping, namely the one established when the method
was interpreted or loaded.

3) Implementation of object-oriented languages on the metaclass kernel
which resolve method inheritance at run time would have no support.
Optimizations of method lookup would be largely implementation dependent.

I don't like 2 is because it adds additional complexity to
the generic function protocol which I would rather avoid. I actually
like 1 best, but doubt we could ever get it implemented. 
In the interests of wrapping up the loose ends of CLOS as expediently as
possible, I'd like to weigh in in favor of 3. While I think that the
metaclass kernel is an important part of CLOS, most people who want to
use it are more interested in the language for application implementation.
As I hope my previous posting has shown, the CLOS language (or programmer
interface) has no need for maintaining a seperate definition of generic
functions and methods in the compile time environment, since there is
no information about methods and generic functions previously compiled in a
file which needs to be portably transferred from form to form. In addition,
although the lack of this capability made implementation difficult, 
the implementation of CommonObjects on the PCL kernel has shown that
a language which resolves most of method inheritance at compile time
can be done.


∂27-Aug-87  1656	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Solutions to Name/Object Mapping for Generic Functions
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 27 Aug 87  16:55:33 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa09283; 27 Aug 87 19:42 EDT
Received: from ti-csl by RELAY.CS.NET id aa05932; 27 Aug 87 19:31 EDT
Received: from dsg by tilde id AA00730; Thu, 27 Aug 87 16:33:04 CDT
Received: From Jenner By dsg Via CHAOS-NET With CHAOS-MAIL; Thu, 27 Aug 87  15:06:36 CDT
Message-Id: <2766081947-606167@Jenner>
Date: Thu, 27 Aug 87  15:05:47 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: kempf%hplabsz@hplabs.hp.com
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Solutions to Name/Object Mapping for Generic Functions
In-Reply-To: Msg of Thu, 27 Aug 87 10:51:21 MST from kempf%hplabsz@hplabs.hp.com

     
     THE PROBLEM AND PROPERTIES OF A GOOD SOLUTION
     
     
     The following are some possible solutions:
     
     1) The symbol function cell could be eliminated as a global object and
     the name to funcallable object mapping could be maintained within the
     environment, as is the case in Scheme.
     
     2) The generic function slot accessor functions could take an
     environment argument and return information accordingly. This 
     was the solution I believe Patrick proposed. 

     3) We could simply leave it up to implementors to supply these
     hooks, if they so choose.


If you are talking about name-to-generic-function mapping, 2 is not what
I have proposed.  Name-to-generic-function mapping shouldn't depend on
the metaclass protocol since it should behave the same as
name-to-regular-function.  Not being affected by the metaclass protocol,
it can be left to the implementation.  The hook should be specified
though.  If some implementations decide to ignore the environment,
that's fine.  Since the environment is going to be passed explicitly(see
Moon's reponse to my proposal), we either need a new primitive for that,
or change SYMBOL-FUNCTION to accept an environment argument.  A new
primitive for metaclass programmers is probably the best thing to do.
However I object to 3 since it will make serious metaclass programming
non portable.
     

Patrick.

∂27-Aug-87  1908	kempf%hplabsz@hplabs.HP.COM 	Re: Names to Objects and Compiler-environment 
Received: from [15.255.16.7] by SAIL.STANFORD.EDU with TCP; 27 Aug 87  19:06:56 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Wed, 26 Aug 87 10:31:57 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Wed, 26 Aug 87 10:30:39 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Wed, 26 Aug 87 11:28:25 pdt
Message-Id: <8708261728.AA27357@hplabsz.hpl.hp.com>
To: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Names to Objects and Compiler-environment 
In-Reply-To: Your message of Wed, 19 Aug 87 15:21:01 -0500.
             <2765391661-13139657@Jenner> 
Date: Wed, 26 Aug 87 11:28:22 MST
From: kempf%hplabsz@hplabs.HP.COM


THE PROBLEM

The fundamental problem I think we are trying to address with this
proposal is the transfer of information about class definitions
and potentially method definitions from form to form during a
file compilation. Such a transfer will necessary be implementation dependent, 
but we would like to design an interface to the metaclass protocol which 
is portable. The information on these definitions should
either not be a "real" definition or it should be a seperate and shadowing 
definition from the definition in compiler's run time environment (if any).
The alternatives are to either replace the definition in the compiler's
run time environment, or to not propagate any information on class
and method definitions being compiled between forms. If we chose the
former solution (replacing the definition in the compiler's run
time environment) we face a bootstrapping problem, since a method
or class necessary for the compilation of a file may get redefined 
while the file is being compiled, breaking the compiler (admittedly, this
may not occur very often, but, if it does, it could be very disabling).
The latter solution (not propagating any information) would place
an unreasonable burden on programmers using CLOS, since they would be
required to place class definitions and definitions of methods working
on those classes into seperate files. Usual practice in object-oriented
programming is to group class definitions and method definitions into
the same file, for easy reference.

THE PROPOSED SOLUTION

A solution has been proposed in which certain metaclass protocol
functions (generic and otherwise) take parameters which are "environments".
The exact nature of these environment parameters is unspecified, but
in order for them to be accessable to the top level macros DEFCLASS
and DEFMETHOD without adding alot of additional machinery to Common Lisp, 
the most logical choice, as Moon has pointed out, is the macro &ENVIRONMENT 
parameter.

The metaclass functions which Patrick has identified as being involved
in name to object mapping are:

	CLASS-NAMED (aka SYMBOL-CLASS) - maps a symbol to a class 
           object having that name.
	SYMBOL-FUNCTION - maps a symbol naming a (potentially generic)
	   function to the (potentially generic) function object.
	GET-METHOD - ? according to pg. 2-39 of 87-002, this
	   takes a generic function object, list of method qualifiers,
	   and a list of parameter specializers (which, presumably,
	   are also objects) and produces the method.

Sonya has added:

	GET-SETF-GENERIC-FUNCTION - maps a name for a generic
	  function into the generic function for doing the SETF.


I would argue that, of these, CLASS-NAMED and SYMBOL-FUNCTION are
at the right primitive level to discuss. My reasoning is as follows.
As the spec for GET-METHOD indicates, it is not doing a name to
object mapping but rather an object to object mapping. Thus 
the more primitive operations CLASS-NAMED and SYMBOL-FUNCTION can
be used to find the objects, CLASS-NAMED to find the specializer
list, and SYMBOL-FUNCTION to find the generic function. As far
as GET-SETF-GENERIC-FUNCTION goes, it is doing a name to object
mapping, but the mapping is slightly bogus, since the name for a
SETF generic function is created, and the operation could just 
as well be done by passing the generic function object for which the
SETF generic function was desired. The generic function object
might have to keep around information about it's SETF, however. 
Alternatively, the algorithm for generating the SETF name could 
be published (a user can find it simply enough anyway by 
macroexpanding a SETF form) and we are back in the case where 
SYMBOL-FUNCTION is the correct primitive for finding the 
generic function.

Naturally, along with the functions for doing the name to object
mapping, the functions for doing a SETF will require an environment
argument as well. These would be the SETF functions for CLASS-NAMED
and for SYMBOL-FUNCTION.

Additional CLOS functions which Patrick has identified as possibly
requiring an environment argument are: ADD-METHOD, REMOVE-METHOD,
FIND-APPLICABLE-METHODS (presumably for use with CALL-NEXT-METHOD),
and ENSURE-GENERIC-FUNCTION. While these do not explicitly
do name to object mapping, I believe the logic here is the following:

	ADD-METHOD, REMOVE-METHOD - addition and removal of a method from
          a generic function is dependent on the environment, since a
          different method definition may be desired on a generic function
          in the compile time environment from what is available in the
          compiler's run time environment (the "outside" or "top" environment).
        FIND-APPLICABLE-METHODS - the compilation of a CALL-NEXT-METHOD
          form will require access to methods as they are "defined" or,
          at the very least, to the definitions compiled during a file
          compilation, so the "current" definition is used for arranging
          the method call, rather than the definition in the compiler's
          run time environment.
	ENSURE-GENERIC-FUNCTION-This does an implicit name to generic
          function mapping, setting up any existing function (generic
          also?) as a default method. Since it will probably use
          SYMBOL-FUNCTION to retreive the function object bound to
          the symbol's function cell, an environment parameter might
	  be needed to indicate which particular generic function
    	  is required. 
  
Of these, only ENSURE-GENERIC-FUNCTION takes a function name as an
an argument, the others all take generic function and other objects.
Hence, sensitivity to the processing environment need only be included
in ENSURE-GENERIC-FUNCTION, since only it will have to internally
resolve a name to object mapping.

One group of functions Patrick missed in his list is the metaclass
functions on pg. 3-25 of the metaobjec protocol specification. 
They are all defined to take a name for the appropriate metaclass. 
With the exception of DEFINE-METACLASS (which can be a macro anyway, 
and thus use its &ENVIRONMENT parameter), the others could as well 
be defined to operate on a class object which was a metaclass, 
rather than directly on a metaclass name. 

WHY CLASS DEFINITIONS NEED TO BE ENVIRONMENT SENSITIVE

I believe that an excellent case can be made for an environment argument
to CLASS-NAMED, and, correspondingly, that class definitions need to
be made both in the compile time environment (but *not* in the 
compiler's run time environment) and at load time, as usual. 
The arguments presented in the first section indicated why some way
of maintaining information on classes being defined needs to be propagated
between forms during a file compilation, independently of any definitions
in the compiler's run time environment. 

An alternative for doing the definition "for real" is to maintain 
information about definitions being compiled, then have the relevent 
metaclass protocol functions distinguish whether the information about
a particular definition comes from the "for real" definition or from the
partial definition. I do not like this solution because it introduces
an additional element of complexity into the metaclass protocol which
somehow seems unnecessary, and sets up a more sharp distinction between
compiling a definition and evaluating it than simply switching
environments. CommonObjects did things this way, and it slowed down
compilation and made for some nasty case analysis. For example, handling 
the distinction between the following two cases would be nontrivial 
(in each case, the class FOO is also defined in the compiler's run time 
environment):

Case 1:

	(defclass foo () () )
	(setf *global-var* (make-instance 'foo))

Case 2: 

	(defclass foo () () )
	(eval-when (compile)
	  (setf *global-var* (make-instance 'foo)))

Though it could be disputed, I think the intent of Case 1 is to have
MAKE-INSTANCE use the FOO defined immediately above it, and that
the compiler, running in *not-compile-time-mode* (CLtL 69), should
defer instance creation and execution of the SETF until load time,
while, in the second case, instance creation and SETF should get done
at compile time using the definition in the compiler's run time
environment (*compile-time-too* mode) rather than the immediately 
preceeding defintion, (except for KCL, which runs in *compile-time-too* 
mode at the top level, but it is definitely in the minority). 
If a compile time environment is used, then the EVAL-WHEN (COMPILE) 
can simply be viewed as "popping" back to the compiler's run time 
environment within the dynamic scope of the form, and returning to
the compile-time environment when the form ends.

The required behavior from DEFCLASS would be that the establishment
of a name to class object mapping is made via the &ENVIRONMENT
parameter, at compile time, and in the top level environment, at
load time. This suggests some way of obtaining the top level 
environment for inserting the class name to object mapping.
Following Patrick's suggestion, a function GET-CURRENT-ENVIRONMENT
could be used. Another possibility is a special variable, *ENVIRONMENT*, 
which would be bound to the current environment, similarly to how *PACKAGE* 
is bound to the current package. I'd be interested in hearing if
this would have problems, as Moon's comments about GET-CURRENT-ENVIRONMENT
seem to indicate:

>If GET-CURRENT-ENVIRONMENT takes no arguments, then what you have is
>some form of dynamic scoping, rather than lexical scoping, and you can
>get scoping problems.  Symbolics' implementation, and I believe TI's as
>well, currently works this way, using the special variable
>SYS:UNDO-DECLARATIONS-FLAG to inform macro expanders on behalf of which
>environment they are working.  The genesis of this is historical and
>predates lexical scoping.  This causes a number of subtle problems.
>CLOS should not make this mistake.

though I'm not quite sure what sorts of arguments GET-CURRENT-ENVIRONMENT
should have or how this relates to dynamic scoping. The idea with 
*ENVIRONMENT* is that it would be bound to the current macroexpansion 
environment, which may or may not be EQL to the &ENVIRONMENT parameter 
of a macro (*MACROEXPAND-HOOK* could be used to modify whether this is 
true or not) but they would, in any event, be the same "kind" of environment. 
Exactly how the name to object binding is inserted into the environment 
would, of course, be implementation dependent (but this could be 
hidden within CLASS-NAMED).

In addition, DEFCLASS would naturally have to use definitions within
the &ENVIRONMENT parameter for things like determining inheritance 
information necessary at compile time. What kinds of information
would be necessary? For the moment, let's ignore optimization information,
since things get a bit more complicated when it is taken into account.
Given this, we can rule out slot layout and number information, since
WITH-SLOTS :USE-ACCESSORS NIL (the only place it would potentially be needed)
should go through SLOT-VALUE. Possibly the slot :INITFORM (and any 
additional initialization information) would need to be compiled, but
they would not have to be accessed by anyone else. The only really
important piece of information needed would be the SETF generic
function names for inherited slots, since these would be required for
expanding SETF forms at compile time. Most other aspects of inheritance
(modulo optimizations) could be handled at load time or run time.

In order to make things more convenient for the user, we may want
to define an interface function called CLASS-NAMED, which takes the
class out of the current environment, and a metaclass function,
called SYMBOL-CLASS, which requires an environment argument. 
Corresponding SETFs would also be required. But this seems as
if it should be the only modification needed for dealing with
the name to class mapping.

As a side note, I did an experimental implementation of something
similar using the CommonObjects on CommonLoops implementation this spring.
The part modifying CLASS-NAMED to be sensitive to the compilation
environment worked very well, which leads me to believe that implementation
should be possible.

WHY SYMBOL-FUNCTION DOESN'T NEED AN ENVIRONMENT PARAMETER
FOR THE DEFAULT CLOS LANGUAGE

The other part of the initial proposal involved shadowing generic
functions and methods in the compile time environment by making
the name to function mapping dependent on the environment.
The effect would be to require SYMBOL-FUNCTION to have an environment 
parameter, since SYMBOL-FUNCTION and its SETF are the means whereby a
name to (possibly generic) function mapping is established.

Note that any attempt to make the name to function mapping dependent
on the environment will inevitably have some serious reprecussions
for Common Lisp. In particular, the design of Common Lisp assumes
functions are named by symbols in a global name space, partitioned
through packages. These symbols have a globally accessable function
cell, which SYMBOL-FUNCTION, FBOUNDP, MAKFUNBOUND, and other accessor
function access. Thus function names are kind of like special variables
except they can't be dynamically bound, or, more precisely, like global 
variables in other languages (Pascal, for example), where dynamic
binding is not available. The name to function mappings established
by FLET and LABELS are not available via. SYMBOL-FUNCTION.

Referring back to the initial motivation for including environment
sensitivity, namely information propagated from form to form, there
is only one case where one method might need to know something about
another 's definition during compilation: CALL-NEXT-METHOD. However,
ignoring optimizations for the moment, the characterization of
CALL-NEXT-METHOD as lexical in scope and dynamic in extend suggests
lookup of the next method could be done, at the latest, at run time
exactly as method dispatch is done. Knowledge about the classes
of the caller's parameters at compile time could be used to limit 
the run time method search. Various further optimizations are possible,
but the most obvious require only the ability to do method lookup
and linking at load time.

WHY SYMBOL-FUNCTION MAY REQUIRE ENVIRONMENT DEPENDENCY IN THE
METACLASS PROTOCOL

Unfortunately, some object oriented languages resolve method inheritance
fully at compile time. CommonObjects is an example. CommonObjects
has a form similar to CALL-NEXT-METHOD (called CALL-METHOD) which
allows the programmer to specify a particular method on the direct
super (or on itself), and a function call to the method (via. a
special method symbol) is compiled in at compile time. Thus the
CALL-METHOD macro must have access to the symbol at compile time,
and the fasl loader must maintain a compile time to load time 
mapping of the symbol. This is all implementation dependent, of
course, and this particular feature has given us much trouble
in developing the Portable CommonObjects implementation. The
point is, however, that compiling a file of CommonObjects methods
requires information on the methods previously compiled to be
propagated between forms.

As mentioned in the previous section, addition of an environment
parameter to SYMBOL-FUNCTION (and its SETF) would involve a
major change to the semantics of function symbols in Common Lisp.
Since the function cell is a globally accessable place, would
redefining a function in a particular environment still cause
the global definition to change? If so, then bootstrapping problems
could easily occur, since a definition which has just been compiled
should not be used in the compilation process. If not, then the
nature of the function cell as a globally accessable place is
compromised, since function invocations in the compiler's run
time environment will get one definition, while another definition
will be operative in the compilation environment.





	      





∂28-Aug-87  0150	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Re: Agenda for September meeting    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Aug 87  01:50:47 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 217984; Fri 21-Aug-87 10:17:46 EDT
Date: Fri, 21 Aug 87 10:17 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Agenda for September meeting 
To: kempf%hplabsz@hplabs.HP.COM
cc: Moon@STONY-BROOK.SCRC.Symbolics.COM, common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <8708202023.AA19448@hplabsz.hpl.hp.com>
Message-ID: <870821101706.9.SKEENE@JUNCO.SCRC.Symbolics.COM>

    Date: Thu, 20 Aug 87 14:23:16 MST
    From: kempf%hplabsz@hplabs.HP.COM

    With regard to the spec documentation, I'd like to put in a vote for an ASCII
    version to go on parcvax, along with the portable source, so people don't
    have to be working in the dark with it. The ASCII version doesn't
    necessarily have to be up to the current level of discussion and 
    decision within the committee (indeed, it probably shouldn't) but should
    reflect approximately what is implemented. 

Please don't confuse the spec documentation with documentation for an
implementation.    These are two very different things!    


∂28-Aug-87  1912	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Another try on object creation   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 28 Aug 87  19:12:23 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 223738; Fri 28-Aug-87 22:13:25 EDT
Date: Fri, 28 Aug 87 22:13 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Another try on object creation
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870828221318.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

Draft of a new object creation proposal based on CLOS subcommittee
discussions July 2, 1987.

-foo- means the word foo in italics.  FOO means the word foo in boldface.


ONE NEW IDEA YOU HAVEN'T SEEN BEFORE

There is a new lambda-list-keyword, &METHOD-KEY, which is only valid in
DEFGENERIC-OPTIONS and DEFGENERIC-OPTIONS-SETF.  The syntax of the lambda-list
in these macros becomes

  ({-var-}+
   [&optional {-var-}*]
   [&rest -var-]
   { [&key {-var- | ((-keyword- -var-))}* [&allow-other-keys]]
     | [&method-key [&allow-other-keys]] })

The meaning of &METHOD-KEY is that the specific set of named arguments
accepted by the generic function varies depending on the positional arguments.
The named arguments accepted by the generic function for a particular call are
the union of the named arguments accepted by the applicable methods.  There is
no attempt to exclude methods that are applicable but are not actually called.
Note that in standard method combination, all applicable methods are
potentially callable, if CALL-NEXT-METHOD is used.  A method that has &REST,
but not &KEY, does not affect the set of acceptable named arguments.  If the
lambda-list of any applicable method or of the DEFGENERIC-OPTIONS has
&ALLOW-OTHER-KEYS, all named arguments are accepted by the generic function.

The implementation of &METHOD-KEY is in two parts:  The macro expansion of
DEFMETHOD, when the generic function uses &METHOD-KEY, is altered to save a
list of the acceptable named-argument names in a slot of the method object and
to put &ALLOW-OTHER-KEYS into the lambda-list of the function.  If the
lambda-list already contains &ALLOW-OTHER-KEYS, then that symbol is stored in
place of the list of acceptable named-argument names (which would be
infinite).  The function METHOD-NAMED-ARGUMENTS retrieves this list or symbol.
Secondly, the generic-function-to-method dispatching mechanism must check the
validity of the argument list when the generic function uses &METHOD-KEY and
does not use &ALLOW-OTHER-KEYS.  This is accomplished by collecting the
acceptable named-argument names from the applicable methods and checking the
arguments against the union of those lists.  If for any applicable method
METHOD-NAMED-ARGUMENTS returns &ALLOW-OTHER-KEYS, the whole check is skipped.


CONCEPTS TO BE ADDED TO 87-002

-named argument-.  We use the term "named argument" instead of "keyword
argument" (as in CLtL) for &key arguments, because CL-Cleanup issue
KEYWORD-ARGUMENT-NAME-PACKAGE has stated that the names of &key arguments
do not have to be keyword symbols.

-named argument name-.  The symbol that identifies a named argument in
an argument list.  This is typically a keyword, but is not required to be.
The named-argument name should not be confused with the variable name
of the parameter variable.  These two symbols typically have the same
name and are typically in different packages, but that is not required.

-initarg-.  An initarg (initialization argument) is a named argument that
can be used to control object creation and initialization.  The &key
arguments to MAKE-INSTANCE are initargs.  Each initarg has a name, which is
a symbol, and may have a value, which is any Lisp object.  It is often
convenient to use keyword symbols to name initargs, but the name of an
initarg can be any symbol, including NIL.

-initarg list-.  An initarg list (initialization argument list) is a list
of alternating initarg names and values.  Its structure is identical to a
property list and also identical to an &key argument list.  As in those
lists, if an initarg name appears more than once in an initarg list, the
leftmost occurrence supplies the value and the remaining occurrences are
ignored.  The arguments to MAKE-INSTANCE, after the first, are an initarg
list.  As in an &key argument list, :ALLOW-OTHER-KEYS can appear in an
initarg list, and if its value is non-NIL, error-checking of initarg names
is disabled.

-slot-filling initarg-.  An initarg associated with a slot.  If the initarg
has a value, the value is stored into the slot of the newly-created object,
overriding any initform associated with the slot.  -(What about shared
slots?)-  A single initarg can fill more than one slot.

-method-implemented initarg-.  An initarg associated with a method.  When
an object is created, the method is called with the initarg's value as an
argument and the method uses the value in any way it likes.  If the initarg
has no value, the method's lambda-list supplies a default value.  A single
initarg can be implemented by more than one method.  An initarg can be both
slot-filling and method-implemented.


CHANGES TO 87-002 FEATURES

DEFCLASS gets a new :INITARG slot option, which is followed by a symbol.
The symbol becomes the name of a slot-filling initarg for this class.

DEFCLASS gets a new :DEFAULT-INITARGS option, which is followed by an initarg
list.  Each value in this list is a form that is evaluated by MAKE-INSTANCE if
the initarg does not already have a value.  The forms are evaluated in the
lexical environment in which the DEFCLASS form was evaluated.

Method-implemented initargs are defined simply by defining a method for
INITIALIZE-INSTANCE or ALLOCATE-INSTANCE; each named-argument name in the
method's lambda-list becomes a method-implemented initarg for all classes for
which this method is applicable.

Initarg inheritance: The effective set of slot-filling initargs for a class C
is the union of the slot-filling initargs defined by C and its superclasses.
The effective set of method-implemented initargs for a class C is determined
by method inheritance.

Default-initargs inheritance: [same as for the :INITFORM slot option]

Changes to Lambda-list Congruence Rules (p.1-20): Rules 1, 2, and 6 remain
the same, except for wording problems, while rules 3-5 need to be replaced
to implement &METHOD-KEY and to fix the interaction among &KEY, &REST, and
&ALLOW-OTHER-KEYS.  The new rules for congruence are the following:

  These rules define the congruence of a set of lambda-lists, including the
  lambda-list of each method for a given generic function and the lambda-list
  specified with DEFGENERIC-OPTIONS, if present.  For -SETF methods, these
  rules apply to the effective lambda-list produced by combining the two
  specified lambda-lists according to the rules on page nnn.

  1. Each lambda-list must have the same number of required parameters.

  2. Each lambda-list must have the same number of optional parameters.
  Each method can supply a different default for an optional parameter.

  3. If any lambda-list uses &REST, &KEY, or &METHOD-KEY, each lambda-list
  must use one or more of these.  Note that &METHOD-KEY is only valid in
  DEFGENERIC-OPTIONS.

  4. If the DEFGENERIC-OPTIONS does not use &METHOD-KEY, or there is no
  DEFGENERIC-OPTIONS, each method that uses &KEY and does not use
  &ALLOW-OTHER-KEYS must specify the same named-argument names.

  5. The use of &ALLOW-OTHER-KEYS need not be consistent across lambda-lists.

  6. The use of &AUX need not be consistent across methods.

Rules when initargs are duplicated:

  The :INITARG slot-option may be specified more than once for a given slot.

  A single initarg can initialize more than one slot if the same initarg name
  appears in more than one :INITARG slot-option.

  If two initargs that initialize the same slot, with the same or different
  names, are given in the arguments to MAKE-INSTANCE, the leftmost of these
  initargs in the initarg list prevails.

  If two different initargs that initialize the same slot have default values,
  the initarg that appears in a :INITARG slot-option in the most specific
  class prevails, or if they appeared in the same class, the one leftmost in
  the slot-options list prevails.

  It is valid for a given initarg name to be defined more than once as a
  slot-filling initarg, as a method-implemented initarg, or both.


NEW FUNCTIONS TO BE ADDED

In this section, I have only sketched each function, for the sake of brevity.
Full writeups can be constructed once the overall framework has been agreed
upon.  Functions are in alphabetical order.  By coincidence, all functions
listed are generic and expected to specialize on their first argument.

(ALLOCATE-INSTANCE class &method-key &allow-other-keys) => instance

Metausers can replace the system-supplied, implementation-dependent
method for this.

(CHECK-INITARGS class initarg-list)

Metausers could replace the system-supplied method that implements the
normal rules for initarg validity.

(CLASS-ALL-INITARGS class) => list of initarg names (includes inherited)

(CLASS-DIRECT-INITARGS class) => list of initarg names

(CLASS-ALL-INITARG-DEFAULTS class)
   => ((initarg-name default-value-function)...)

(CLASS-DIRECT-INITARG-DEFAULTS class)
   => ((initarg-name default-value-function)...)

(CLASS-ALL-SLOT-INITARGS class) => ((initarg-name slot-name...)...)

(CLASS-DIRECT-SLOT-INITARGS class) => ((initarg-name slot-name...)...)

(COMPUTE-APPLICABLE-METHODS generic argument-list) => list of methods

(DEFAULT-INITARGS class initarg-list) => initarg-list

The system-supplied method implements the :DEFAULT-INITARGS class option.
[This could specialize on instance instead of class, but I don't
see any point to that.]

(ENCACHE-INITARG-INHERITANCE class)

This is called by the system at least once before a class is instantiated,
and is called again whenever anything relevant changes.  System-supplied
methods for this conspire with methods for CHECK-INITARGS, etc., to make
MAKE-INSTANCE faster.  Users with their own caching needs can add methods
for this generic function.

(ENCACHE-METHOD-INHERITANCE class)

(ENCACHE-SLOT-INHERITANCE class)

(INITIALIZE-INSTANCE instance &method-key &allow-other-keys)

Users define :AFTER methods for this to create method-implemented initargs.
The primary method for this is system-supplied and takes care of the
slot-filling initargs.

(MAKE-INSTANCE class &key -initargs-...) => instance

(METHOD-NAMED-ARGUMENTS method) => list of symbols or &ALLOW-OTHER-KEYS

(SLOT-BOUNDP instance slot-name) => boolean

Allows writing INITIALIZE-INSTANCE methods that only initialize slots if they
haven't been initialized already.

(SLOT-MAKUNBOUND instance slot-name) => NIL


PROCEDURAL DEFINITION OF MAKE-INSTANCE

MAKE-INSTANCE behaves as if it was defined as follows, except that certain
optimizations are permitted, as detailed below.

(defmethod make-instance ((class standard-class) &rest initargs)
  (setq initargs (default-initargs class initargs))
  (check-initargs class initargs)  
  (let ((instance (apply #'allocate-instance class initargs)))
    (apply #'initialize-instance instance initargs)
    instance))

(defmethod make-instance ((class-name symbol) &rest initargs)
  (apply #'make-instance (symbol-class class-name) initargs))

Optimization is possible, including inlining and constant-folding of method
lookup and method bodies, provided that the programming environment either
prohibits redefining these methods or updates everything when they are
redefined.  A possible example implementation would be that MAKE-INSTANCE has
a separate method for every class, which is automatically written and compiled
by the system.

This optimization relies on the ENCACHE-INITARG-INHERITANCE generic function
and some unpublished slots of STANDARD-CLASS.

Because of optimization, methods for the generic functions listed may not
actually be called on every call to MAKE-INSTANCE, or may not receive
exactly the arguments that would be expected.  For example, CHECK-INITARGS
may actually be called before DEFAULT-INITARGS rather than after, if it has
already been determined that the default initargs will pass CHECK-INITARGS.

Additional explicit details of permissible optimization will need to be set
forth.


MEETING OF STATED DESIGN GOALS

Lexical proximity of concepts--the declaration of an initarg as valid,
the specification of what it does, and the default if it is not supplied
are all together, in a slot specifier or in a method lambda-list.

Simple ways to do simple things--slot-filling initargs don't require the
user to write any code.  Method-implemented initargs work just like
ordinary function arguments as far as the user is concerned.

Minimal number of new languages--the only addition to Common Lisp is
&METHOD-KEY.

Ability to do everything at some level--the underlying procedural level
is available.  Functions to access all the direct and inherited
information are documented.

Underlying mechanism is exposed so user can use it for other things,
rather than abusing instance creation as the only way to access the
mechanism--the combination of &method-key, method-named-arguments,
compute-applicable-methods, and encache-initarg-inheritance provides
everything the user needs.

∂30-Aug-87  1946	RPG  	Class Precedence List   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

On July 27 Kempf mailed a note about the description of the class
precedence list algorithm. Because I was away until yesterday, I
was not able to respond:

Kempf writes:

	   1) The use of the term "partial order" on pg. 1-15, paragraph 1
	   implies a relation on R which is reflexive, antisymmetric, and
	   transitive. From the text of the paragraph, this relation is
	   presumably the "is a subclass of" relation. However, earlier in
	   the document, reflexivity is explicitly excluded from the "is a
	   subclass of" relation (pg. 1-4, paragraph 3), since a class is
	   defined to be neither a superclass nor a subclass of itself.
	   Either the partial order needs to be replaced with a different
	   order not requiring reflexivity (semiorder, etc.)  or the "is a
	   subclass of" relation needs to be redefined so that it is
	   reflexive. Note that the latter solution is used in more
	   technical treatments of typing systems (e.g. Cardelli and
	   Wegner, Computing Surveys, 17, 1985, pp. 471-522).

Knuth points out that one can define partial orderings using ``less than
or equal'' and so does not require the antisymmetric condition. We should
be more explicit here about it and define the partial ordering on a true
reflexive, antisymmetric, and transitive relation.

Kempf writes:


	   4) The formal description of class precedence list calculation
	   on pg. 1-15, paragraph 3 is lacking a condition. In the third
	   line, it is not sufficient just to require the existence of an
	   index i, but also its minimality.  As a counterexample,
	   consider R := {(c1,c2) (c2,c3) (c3 c5) (c2 c4) (c4 c6)} The
	   inheritance graph for this is....

Well, this is the result of a misreading of the algorithm. However,
this is sufficient to require a rewrite of the description. As an aside
to JAK, let me point out the following: his example was:


		c5  c6
		|   |
		c3  c4
		|   |
		\   /
		 \ /
		  c2
		  |
		  c1

The relations used to define the partial ordering are:
{(c1 c2)(c2 c3)(c2 c4)(c3 c4)(c3 c5)(c4 c6)}

The key one is that c3 precedes c4.

When the CPL is [c1 c2], there is only one class with no predecessors -
C3.

I believe the description of the algorithm to be correct, but I stand accused of
and confess to it being a difficult description. I will volunteer to try to fix
it up.

By the way, have we thought about various means of making the CPL more
accessible, such as what New Flavors does?

∂30-Aug-87  2009	RPG  	Miscellaneous decisions taken or to be taken
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

Moon writes:

  The document says it has dynamic extent; we need to be sure that we
  really mean that.  In July we said "implementation flexibility, not
  really a language thing", but I'm damned if I can figure out what
  that means (optimizing calculation of the effective method?).

The document says ``the binding for the local variable CALL-NEXT-METHOD
has lexical scope and dynamic extent.''

The idea is that a user would not even be allowed to create a closure
that refered to CALL-NEXT-METHOD. I suppose he could, but he'd get some
global defintion for CALL-NEXT-METHOD. We intend to not provide a poor man's
continuation mechanism. I didn't think we even had anything as sophisticated
as hierarchy redefinition in mind when we wrote this. The description needs to
be clearer.

			-rpg-

∂30-Aug-87  2017	RPG  	Agenda   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

The agenda seems fine to me. The key to making the meeting work is for
people to dedicate time to studying the proposals and doing what they
have volunteered to do. I, for example, will get to work on the
anonymous generic function progosal tomorrow, and you will all have it
within a week.

Because I just returned from Europe, I don't even know what arrangements
Linda has made. But, again, there is no territorialness in what they are,
it is a matter of someone volunteering to do the work and then doing it.
Danny was also in Europe, and no one else had stepped forward.

On the document: I earlier promised to produce a minimal TEX macro file
so that people could roll their own. It was a lack of time on my part that
prevented that rather than some sinister plot. I hope I can get that done in
a day and put it out on SAIL along with the TEX sources. The problem with the
current macro file is that it is many dozens of pages long and contains the
book layout definition for all of Lucid's manuals.

			-rpg-

∂30-Aug-87  2024	RPG  	Name That Class!   
To:   Common-lisp-object-system@SAIL.STANFORD.EDU    

Before I left on my ill-fated trip to Europe (where I confronted face-to-face,
once more, my muse) I wrote out some examples of how class objects and their
names interacted. The idea was to explore what it meant to build a hierarchy
with names (using DEFLCASS) and with class objects (blasting fields). I think
these examples are right (I could be wrong) and they might strike some as
odd, they are generally in accord  with acceptable behavior of functions and
the symbols that name them (and DEFSTRUCT names and types as well). I send them
in hopes they might help stimulate thought on the issues:

1. (defclass foo ...)

   (let ((a (class-named 'foo)))
    (defclass foo ...)
    (eq a (class-named 'foo))) => T

This has been agreed to be the best sufficient way to achieve the
old-methods-still-work behavior.

2. (defclass foo ...)

  (let ((c (make-instance 'standard-class)))
   (setf (<various aspects> c) <certain values>) 
   (setf (class-named 'foo) c) 
   (eq (class-named 'foo) c)) => ?

MAKE-INSTANCE is not psychic, so it must cons.  It seems that (DEFLCASS FOO ...)
is equivalent to

   (let ((c (make-instance 'standard-class)))
    (setf (<various aspects> c) <certain values>)
    (setf (class-named 'foo) c)
    c)

Note that there is no similar expression in CLtL to which DEFTSRUCT is
equivalent.  Therefore the EQ must return NIL. This implies that (setf
(class-named ...) ...)  is smart and worries about the EQness between the
previous class, if it exists, and the new one.

3. (let ((c (make-instance 'standard-class)))
    (setf (<various aspects> c) <certain values>)
    (setf (class-named 'foo) c) ;foo otherwise undefined
    (eq (class-named 'foo) c)) => ?

Why should (setf (class-named ...) ...) unnecessarily cons? Therefore
the EQ should return T.

4. (defclass foo ...)
   (defclass baz ...)
 
   (let ((c1 (class-named 'foo))
	 (c2 (class-named 'baz)))
    (setf (class-named 'baz)  (class-named 'foo))
    ;;; (eq c1 c2) => NIL
    (eq (class-named 'foo) (class-named 'baz))) => ?

Because (eq c1 (class-named 'foo)) => T, (eq c1 c2) => NIL, and (eq c2
(class-named 'baz)) => T, this must return NIL.

5. (defclass foo ...)
   (defmethod f ((x foo)) ...) ;no other methods
   (defclass baz ...)
   (defmethod g ((x baz)) ...) ;no other methods
   (setq instance1 (make-instance 'foo))
   (setq instance2 (make-instance 'baz))
   (rotatef (class-named 'foo) (class-named 'baz))
   (f instance1) => well-defined?
   (f instance2) => well-defined?
   (g instance1) => well-defined?
   (g instance2) => well-defined?

The first generic function invocation is well-defined; the second is an
error of some sort; the third is an error of some sort; the fourth is
well-defined.

6. (defclass c1 (c2 c3) ...)
   (defclass c2 ...)
   (defclass c3 ...)
   (defmethod f ((x c2)) ...) ;no other methods
   (setq instance1 (make-instance 'c1))
   ;;; Flush the superclass link from C1 to C2
   (setf (class-super-classes (class-named 'c1)) `(,(class-named 'c3)))
   (f instance1) => well-defined?

I don't know what this should do, but I suspect the expression (f instance1)
is not well-defined because the SETF alters the topology of the graph.

It seems that once a name is given to a class, the symbol that is the
name and the storage for that class are linked forever unless something
like

	(setf (class-named 'foo) nil)

is defined to work.

It is also clear that the the applicability of methods within a class
graph depends on the topology of the graph and not on the substance of the
classes in that graph. If a user were to mistakenly exchange the names of
two classes in a graph at the outset, he would not be able to correct that
naming error using CLASS-NAMED and (SETF (CLASS-NAMED ...) ...) - example
4 shows this. He would have to alter the superclass slots in the classes
surrounding the ones he wishes to switch, according to the technique in 
example 6, assuming that would even work. 

Enjoy!

			-rpg-

∂30-Aug-87  2054	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Class Precedence List       
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 30 Aug 87  20:53:31 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 224284; Sun 30-Aug-87 23:54:35 EDT
Date: Sun, 30 Aug 87 23:54 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Class Precedence List   
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 30 Aug 87 22:46 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870830235432.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 30 Aug 87  1946 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    By the way, have we thought about various means of making the CPL more
    accessible, such as what New Flavors does?

Yes, I signed up to write a proposal that would try to satisfy Gregor's
objections to the proposal I presented previously, as best as I could
understand them.  I haven't done it yet, though.  I've been putting my
time into make-instance instead.

∂31-Aug-87  0802	kempf%hplabsz@hplabs.HP.COM 	Re: Agenda for September meeting    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 31 Aug 87  08:02:20 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Mon, 31 Aug 87 08:00:47 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 31 Aug 87 08:00:25 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 31 Aug 87 09:01:03 pdt
Message-Id: <8708311501.AA16453@hplabsz.hpl.hp.com>
To: "Sonya E. Keene" <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Agenda for September meeting 
In-Reply-To: Your message of Fri, 21 Aug 87 10:17:00 -0400.
             <870821101706.9.SKEENE@JUNCO.SCRC.Symbolics.COM> 
Date: Mon, 31 Aug 87 09:01:00 MST
From: kempf%hplabsz@hplabs.HP.COM

>     Date: Thu, 20 Aug 87 14:23:16 MST
>     From: kempf%hplabsz@hplabs.HP.COM

>     With regard to the spec documentation> , I'd like to put in a vote for an  ASCII
>     version to go on parcvax, along with the portable source, so people don't
>     have to be working in the dark with it. The ASCII version doesn't
>     necessarily have to be up to the current level of discussion and 
>     decision within the committee (indeed, it probably shouldn't) but should
>     reflect approximately what is implemented. 

> Please don't confuse the spec documentation with documentation for an
> implementation.    These are two very different things!    

I hope I'm not. My concern is that, if the process of finalizing the spec 
and the portable implementation continue in tandem, as seems to be happening, 
people will want to have a more accessable copy of the spec. Of course,
there will be differences between the spec and the implementation, and
these should probably be documented. Additionally, should a decision be made
not to pursue the portable implementation (which would be tragic, in my
opinion) then there would be little need. There are lots of people using the
current PCL/half CLOS at universities and such, and I think they'd like to
have a copy.

But I most whole-heartedly agree that the spec and any particular 
implementation of it are seperate.


		



∂31-Aug-87  1914	MLY@AI.AI.MIT.EDU 	RPG's recent typo.   
Received: from AI.AI.MIT.EDU by SAIL.STANFORD.EDU with TCP; 31 Aug 87  19:14:25 PDT
Date: Mon, 31 Aug 87 22:18:06 EDT
From: Richard Mlynarik <MLY@AI.AI.MIT.EDU>
Subject: RPG's recent typo.
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <248781.870831.MLY@AI.AI.MIT.EDU>

Perhaps DEFCLASS could be renamed DEFTSTRUCT.

∂01-Sep-87  1150	Gregor.pa@Xerox.COM 	Re: Name That Class!    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 1 Sep 87  11:49:53 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 01 SEP 87 10:11:53 PDT
Date: 1 Sep 87 10:11 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Name That Class!   
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 30 Aug 87
 20:24 PDT
To: RPG@SAIL.STANFORD.EDU
cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870901-101153-7058@Xerox>

Your first example is right.  But there is a mistaken assumption in your
second example that throws all the others off.  Specifically, you say
that:

                                 It seems that (DEFLCASS FOO ...)
    is equivalent to

       (let ((c (make-instance 'standard-class))) (setf
        (<various aspects> c) <certain values>) (setf (class-named
        'foo) c) c)


But this isn't right.  (defclass foo ...) is equivalent to:

(let* ((existing (class-named 'foo t))
       (new (if existing
                (class-for-redefinition existing)
                (make-instance 'standard-class))))
  (setf (class-named 'foo) new)
  (update-class new ..)
  new)

Given this clarification, its clear that (for instances of
standard-class) the rest of your examples should return:

2. T
3. T
4. T

The point is that class-named has no smarts (remember that as much as
possible we don't want to do things that just couldn't map into a
Lisp-1, and certainly set! has no smarts).  class-for-redefinition is
where all the smarts is.

∂01-Sep-87  1258	RPG  	Name That Class!   
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

It would be nice if it turned out that the relationship between
a class and its name could be as clean as the relationship between
a symbol and its value, but this is not the case: We can already
ask of a class its name.

When I wrote these examples I thought of two parallel activities going
on in two CLOS's right next to each other - one in which a user was using
DEFCLASS to build up a hierarchy and one in which a user was using
anonymous classes to build up the same hierarchy. My assumption about the
equivalence of DEFCLASS and the LET-expression was derived from a belief
that simplicity of model was desirable.

I don't, now, believe that the behaviors I listed in my message are alarming
(though I did originally) because one can imagine a Common Lisp in which

(defun f (...)...)

and

(setf (symbol-function 'f) (function (lambda (...)...)))

are equivalent and similar behaviors hold to the ones in that message (that
is, SETF of SYMBOL-FUNCTION is smart).

We also run into the problem that Common Lisp already treats types as a
sort-of subclass of SYMBOL, and so the tight name-to-object mapping
described in my message is not altogether out of line with an attempt to
integrate classes with types.

We haven't really talked about what DEFCLASS is equivalent to yet,
so I suppose there are now two proposals as to what that might be on
the table.

			-rpg-

∂01-Sep-87  1300	RPG  	Anonymous Generic Function Proposal (Draft 1)    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

There are 3 cases to consider:

	1. Purely anonymous generic functions, corresponding to 
           (function (lambda ...)) in Common Lisp.

	2. A set of named generic functions to be used within a particular
	   body, corresponding to (labels ...) in Common Lisp. An analog
	   to FLET might be appropriate also.

	3. A means of extending a generic function currently defined on a
	   symbol (name). This corresponds to nothing in Common Lisp.

Here is a proposal, inspired by Guy Steele, which covers case 1:

(generic (lambda ...)
	 (lambda ...)
	 (lambda ...)
	 ...))

This special form produces a generic function with the lambda-expressions
as the methods. This is about as similar to the FUNCTION syntax as can
be rationally gotten.

To cover case 2 we define an analog to Common Lisp LABELS, but instead of
functions the user defines methods:

(generic-labels ((foo (...)...)
		 (bar (...) ...)
		 (bar (...) ...)
		 (foo (...)...)
 <body>)

At this point it is easy to extend FLET similarly:
 
(generic-flet ((foo (...)...)
	       (bar (...) ...)
	       (bar (...) ...)
	       (foo (...)...)
 <body>)

The simplest means of producing an anonymous recursive generic function is:

(generic-labels ((self (...)...(self...)...)
		 (self (...)...(self...)...)
		 ...)
 #'self)

Notice that the special form FUNCTION will need to be amended in CLtL to
be able to produce a generic function, but this should be a natural fallout
of making a generic function a subtype of FUNCTION.

Handling case 3 is more difficult, because there is no corresponding
Common Lisp form to do a similar thing for functions.  A danger is to
inadvertently design a form that will also accomplish the dynamic binding
of a function associated with a symbol.

(with-added-methods ((print (...)...)
		     (print (...)...)
		     (read (...)...)
		     (read (...)...)
		     (read (...)...))
 <body>)

Among the things that could have been included in this proposal is 
the ability to have the method functions be able to call each other
without going through the generic function object. However, this obscure
case can be hacked together using add-method etc, and I don't believe
it deserves a special syntax. (It might be so obscure you cannot understand
this description, but that only reinforces my argument.)

			-rpg-

∂01-Sep-87  1823	Bobrow.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 1)     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 1 Sep 87  18:23:50 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 01 SEP 87 18:19:05 PDT
Date: 1 Sep 87 18:18 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Anonymous Generic Function Proposal (Draft 1)    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 01 Sep 87
 13:00 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870901-181905-7824@Xerox>

(with-added-methods ((print (...)...)
		     (print (...)...)
		     (read (...)...)
		     (read (...)...)
		     (read (...)...))
 <body>)



Is this strictly lexical (only calls within the <body> have the added
methods), or is it dynamic (calls from any called function see the
methods, but the methods are removed when the fom is exited).  Both are
useful I think.
  danny

∂01-Sep-87  2317	RPG  	Anonymous Generic Function Proposal (Draft 2)    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

Draft 1 is amended to take into account Danny's comment.

There are 3 cases to consider:

	1. Purely anonymous generic functions, corresponding to 
           (function (lambda ...)) in Common Lisp.

	2. A set of named generic functions to be used within a particular
	   body, corresponding to (labels ...) in Common Lisp. An analog
	   to FLET might be appropriate also.

	3. A means of extending a generic function currently defined on a
	   symbol (name) or lexically. This corresponds to nothing in
	   Common Lisp.

Here is a proposal, inspired by Guy Steele, which covers case 1:

(generic (lambda ...)
	 (lambda ...)
	 (lambda ...)
	 ...))

This special form produces a generic function with the lambda-expressions
as the methods. This is about as similar to the FUNCTION syntax as can
be rationally gotten.

To cover case 2 we define an analog to Common Lisp LABELS, but instead of
functions the user defines methods:

(generic-labels ((foo (...)...)
		 (bar (...) ...)
		 (bar (...) ...)
		 (foo (...)...)
 <body>)

This form produces 2 new generic functions, FOO and BAR. 

At this point it is easy to extend FLET similarly:
 
(generic-flet ((foo (...)...)
	       (bar (...) ...)
	       (bar (...) ...)
	       (foo (...)...)
 <body>)

The simplest means of producing an anonymous recursive generic function is:

(generic-labels ((self (...)...(self...)...)
		 (self (...)...(self...)...)
		 ...)
 #'self)

Both GENERIC-LABELS and GENERIC-FLET produce new generic functions. The
fact that a generic function is already bound to a variable of the same
name or to a symbol is irrelevant to the operation of these forms.

Notice that the special form FUNCTION will need to be amended in CLtL to
be able to produce a generic function, but this should be a natural fallout
of making a generic function a subtype of FUNCTION.

Handling case 3 is more difficult, because there is no corresponding
Common Lisp form to do a similar thing for functions.  A danger is to
inadvertently design a form that will also accomplish the dynamic binding
of a function associated with a symbol.

(with-added-methods <generic-function> (<methods>*) . <body>)

This takes a generic function and a list of methods specified as
lambda-expressions, extends the generic function by adding the appropriate
methods, and then executes the forms in <body> as if they were in a PROGN.
When WITH-ADDED-METHODS exits, the added methods are removed. Any flow of
control out of the WITH-ADDED-METHODS causes the methods to be removed.

Notice that this handles both anonymous and named generic functions.
For example:

(generic-flet ((foo (...)...) (foo (...)...))
 (with-added-methods #'print ((lambda (...)...) (lambda (...)...))
  (with-added-methods #'foo ((lambda (...)...)) <body>)))

			-rpg-

∂02-Sep-87  1149	Bobrow.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 2)     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Sep 87  11:49:10 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 02 SEP 87 11:49:27 PDT
Date: 2 Sep 87 11:49 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Anonymous Generic Function Proposal (Draft 2)    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 01 Sep 87
 23:17 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870902-114927-8581@Xerox>

    When WITH-ADDED-METHODS exits, the added methods are removed.
    Any flow of control out of the WITH-ADDED-METHODS causes the
    methods to be removed.


I still find this ambiguous.

Consider

(defmethod fie (x) 0)

(defun foo (x)
  (with-added-methods fie ((lambda ((x P1)) 17))
      (cons (fie x) (fum x)))

(defun fum (y) (fie y))

(foo (make-instance 'P1))
  ==> (17 . 17)
  or
  ==> (17 . 0)

 



∂02-Sep-87  1224	Pavel.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 2) 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 2 Sep 87  12:24:04 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 02 SEP 87 12:10:50 PDT
Date: Wed, 2 Sep 87 12:10:46 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: Anonymous Generic Function Proposal (Draft 2)
In-reply-to: <870902-114927-8581@Xerox>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870902-121050-8628@Xerox>

Another question about the proposal:  What is the intent with respect to
multi-process environments?  During the time that WITH-ADDED-METHODS is
active, should the other processes see the added methhods or not?  I
would hope not;; this should have the same sort of behaviour as special
variables.

	Pavel

∂02-Sep-87  1534	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Another try on object creation    
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 2 Sep 87  15:34:34 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab03266; 2 Sep 87 17:59 EDT
Received: from ti-csl by RELAY.CS.NET id af13392; 2 Sep 87 17:48 EDT
Received: from Jenner by tilde id AA19802; Wed, 2 Sep 87 16:39:20 CDT
Message-Id: <2766605837-15560752@Jenner>
Date: Wed, 2 Sep 87  16:37:17 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Subject: Re: Another try on object creation
In-Reply-To: Msg of Fri, 28 Aug 87 22:13 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>


     
     
     (defmethod make-instance ((class standard-class) &rest initargs)
       (setq initargs (default-initargs class initargs))
       (check-initargs class initargs)  
       (let ((instance (apply #'allocate-instance class initargs)))
         (apply #'initialize-instance instance initargs)
         instance))
     
     (defmethod make-instance ((class-name symbol) &rest initargs)
       (apply #'make-instance (symbol-class class-name) initargs))

I have a question: Why don't you use a class prototype to call
default-initargs and check-initargs?

Patrick.

∂02-Sep-87  2013	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Another try on object creation    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 2 Sep 87  20:13:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 226977; Wed 2-Sep-87 23:13:58 EDT
Date: Wed, 2 Sep 87 23:13 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Another try on object creation
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <2766605837-15560752@Jenner>
Message-ID: <870902231340.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 2 Sep 87  16:37:17 CDT
    From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
     
	 (defmethod make-instance ((class standard-class) &rest initargs)
	   (setq initargs (default-initargs class initargs))
	   (check-initargs class initargs)  
	   (let ((instance (apply #'allocate-instance class initargs)))
	     (apply #'initialize-instance instance initargs)
	     instance))

    I have a question: Why don't you use a class prototype to call
    default-initargs and check-initargs?

That's the way the notes from the meeting had it, but in my proposal
I changed that for two reasons.  One is that this was the only use
of prototypes, so by changing this we can eliminate the need to expose
that concept; it makes the standard simpler.  The second reason is
a little more complex: in trying to figure out why there was such
apparent randomness, with some functions generic on the instance and
others generic on the class, I decided it must be that functions generic
on the instance can have methods defined by ordinary users, and can
have those methods combined with inheritance, while functions generic
on the class are part of the metaclass protocol and you only write
methods for them if you are doing over part of the implementation.
At the meeting we said that it was "hard to make default-initargs
and check-initargs generic" and left it at that.  If you think about
check-initargs, all the checking has to be in one place; there is
no way to do it by combining inherited methods, each of which checks
one class's initargs.  In fact there is one method for check-initargs
which looks at the slot-initargs and the lambda-lists of the applicable
methods and decides what to do.  Therefore, I decided check-initargs
must be a metaclass method.  The alternative would have been to have
a check-initarg generic function that checks one argument at a time,
which seemed unduly complex.

Less clear is defaulting, but what decided me there was that at the
meeting there was a move to combine default-initargs and check-initargs
into a single operation, in which case they would have to be generic on
the same thing.  I don't really see much usefulness in users defining
their own default-initargs methods, when they are not working at the
metaclass level, so to keep things simple I made that generic on the
class.

It's true that in this formulation you can't do certain customized
defaulting and checking operations except by programming at the
metaclass level.  However, making those two functions generic on the
instance still wouldn't make those operations simple and easy to explain
(see mail discussion of the past few months), and I think at some point
we have to limit the ambitions of CLOS and say that it doesn't replace
all forms of programming.

That's why I proposed it the way I did.  This is not to say that no one
should propose that it work a different way, if they can refute the
arguments above.  For this purpose, default-initargs and check-initargs
should be discussed separately.

∂03-Sep-87  1414	Bobrow.pa@Xerox.COM 	Re: Another try on object creation
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 3 Sep 87  14:14:21 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 03 SEP 87 14:14:38 PDT
Date: 3 Sep 87 14:14 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Another try on object creation
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 2 Sep 87 23:13 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870903-141438-10242@Xerox>

Patrick Asked
    Why don't you use a class prototype to call
        default-initargs and check-initargs?

Moon had two arguments for this
    One is that this was the only use of prototypes, 
    so by changing this we can eliminate the
    need to expose that concept; it makes the standard simpler. 

The concept of class-prototype must be introduced for other reasons in
the metaobject protocol, so I don't buy this reason.

    The second reason is ... functions generic on the class are
    part of the metaclass protocol and you only write methods for them
    if you are doing over part of the implementation.

My intuition (expressed in our initial propposal) was that
default-initargs, check-initargs etc were really user (instance)
business.  However, I now agree with Moon that these mechanisms for
initialization (except for user-defined :after methods) are more closely
associated with the implementation of a class and hence are metaclass
methods. Ordinary users would rarely want to change them -- especially
if these methods are not guaranteed to be called each time (i.e.
optimized away) except at some great cost.  Since I think these
optimizations are important in the standard case, I am happy to leave
default-initargs and check-initargs specialized on the metaclass.

I do have another question on the initialization proposal though.  Why
do we need &method-key?  Why not make the congruence rules for generic
functions be those Moon described for &method-key i.e. the acceptable
named arguments for a generic function are the union of the named
arguments of the methods, or &allow-other-keys.  The one feature this
eliminates is the ability to define a generic function for which all
methods must have exactly the same named arguments.  This seems a small
loss, and we gain by not having to add another lambda-keyword.  

Another question.  What happens if a method is invoked with a named
argument that it is not prepared to receive?  Is it a run-time error?
It is easy to construct examples where this could happen.

∂03-Sep-87  1705	kempf%hplabsz@hplabs.HP.COM 	Re: Solutions to Name/Object Mapping for Generic Functions   
Received: from [15.255.16.7] by SAIL.STANFORD.EDU with TCP; 3 Sep 87  17:04:47 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Tue, 1 Sep 87 16:00:08 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 1 Sep 87 15:59:35 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 1 Sep 87 17:00:18 pdt
To: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
Cc: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Solutions to Name/Object Mapping for Generic Functions 
In-Reply-To: Your message of Thu, 27 Aug 87 15:05:47 -0500.
             <2766081947-606167@Jenner> 
Date: Tue, 01 Sep 87 17:00:15 MST
Message-Id: <3994.557535615@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM

>      
>      THE PROBLEM AND PROPERTIES OF A GOOD SOLUTION
>      
>      
>       The following are some possible solutions:
>      
>      1) The symbol function cell could be eliminated as a global object and
>      the name to funcallable object mapping could be maintained within the
>      environment, as is the case in Scheme.
>      
>      2) The generic function slot accessor functions could take an
>      environment argument and return information accordingly. This 
>      was the solution I believe Patrick proposed. 

>      3) We could simply leave it up to implementors to supply these
>      hooks, if they so choose.


> If you are talking about name-to-generic-function mapping, 2 is not what
> I have proposed.  

Yes, you are right. What I should have said is that it is *similar* to
what you proposed. The original proposal mentioned modifying ADD-METHOD,
GET-METHOD, REMOVE-METHOD, FIND-APPLICABLE-METHODS, and
ENSURE-GENERIC-FUNCTION to take environment arguments, which are all part
of the metaclass protocol, in addition to SYMBOL-FUNCTION:

	> 2- CLOS functions that must have an environment argument:
	>
	> CLASS-NAMED and its SETF form,
	> ADD-METHOD,
	> GET-METHOD,
	> REMOVE-METHOD,
	> FIND-APPLICABLE-METHODS,
	> ENSURE-GENERIC-FUNCTION.

I believe the intention was, however, that they should pass the 
environment on to SYMBOL-FUNCTION or use it in some implementation 
dependent manner.

What 2 is proposing is to decouple modification of SYMBOL-FUNCTION to
take an environment parameter, which I believe will have serious
reprecussions for Common Lisp semantics, from the metaclass protocol
modifications. Modification of SYMBOL-FUNCTION would be the essense of
1.

>		 Name-to-generic-function mapping shouldn't depend on
> the metaclass protocol since it should behave the same as
> name-to-regular-function.  

If SYMBOL-FUNCTION is modified to take an environment argument, then
the name-to-regular-function mapping is going to change too. A
metacircular definition of the Common Lisp interpreter might look like;


    (cond

         <other things>

       ( (fboundp (first form))
         (apply (symbol-function (first form)) argument-list)
       )

       <more other things>
    )

Changing SYMBOL-FUNCTION means this becomes;

    (cond

         <other things>

       ( (fboundp (first form))
         (apply (symbol-function (first form) <environment>) argument-list)
       )

        <more other things>
    )

But what environment? The current one? The base one? Modification of
SYMBOL-FUNCTION means that semantics of function application in Common
Lisp must be changed, becoming more like Scheme. Now, I have no objection
to this (in fact, I think it would be an improvement) but some compiler
writers and application developers might. Note that this semantic change
is very different from the one generic functions introduce, because it
involves global (environment) rather than local (parameter classes)
information, and hence could require larger modifications to existing
code.


>		Not being affected by the metaclass protocol,
> it can be left to the implementation.  The hook should be specified
> though.  If some implementations decide to ignore the environment,
> that's fine.  Since the environment is going to be passed explicitly (see 
> Moon's reponse to my proposal), we either need a new primitive for that,
> or change SYMBOL-FUNCTION to accept an environment argument. A new
> primitive for metaclass programmers is probably the best thing to do.

I'm not quite sure what the "or" is here. I understand the proposal for
primitives to access the environment, but I don't understand where
the hook could be, other than through the metaclass method lambda lists.

A way to work around this difficulty might be the following. Instead of
modifying the name to generic function mapping to be sensitive to the
environment, we modify the generic function object to slot value mapping
to use the environment. This was supposed to be the essence of 2. Thus
information on methods being compiled can be stored in the generic function
object, but invocation of the generic function would get definitions
in the compiler's run time environment. This complicates the object to
slot value mapping somewhat, but avoids the problem with changing the
semantics of SYMBOL-FUNCTION. The idea is that the generic function
remembers the environment in which it was defined for funcalling purposes,
and otherwise uses the current environment for maintaining information
about definitions being compiled. Admittedly, this is a halfway solution,
but would involve less drastic modifications to Common Lisp, I think.

> However I object to 3 since it will make serious metaclass programming
> non portable.

It will restrict the class of object-object oriented languages which
can be portably implemented using the metaclass protocol to those which don't
require information on methods being compiled to be portably available
in the compile time environment. Note that CommonObjects is in this class,
and we have gotten around the problems by some monumental kludges and
some portable importabilities, ie., things which each implementor of
PCL needed to customize to their system. That particular part of
CommonObjects on CommonLoops was the most difficult to do, and the
one which breaks most often. The tradeoff for CLOS is that the metaclass
protocol would be simpler, and no modification of the base Common Lisp
semantics would be needed, meaning we could probably converge on a solution
more quickly.


∂03-Sep-87  1838	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Another try on object creation    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 3 Sep 87  18:37:57 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 227853; Thu 3-Sep-87 21:39:00 EDT
Date: Thu, 3 Sep 87 21:38 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Another try on object creation
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870903-141438-10242@Xerox>
Message-ID: <870903213846.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 3 Sep 87 14:14 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    ....
    Another question.  What happens if a method is invoked with a named
    argument that it is not prepared to receive?  Is it a run-time error?
    It is easy to construct examples where this could happen.

I'll answer the rest of your message later, because I want to think a bit,
but the answer to this question is that functions defined with defmethod
receive their arguments in exactly the same way as functions defined with
defun.  So it does whatever CLtL says and the implementation implements.

∂04-Sep-87  1058	Bobrow.pa@Xerox.COM 	Re: Anonymous Generic Function Proposal (Draft 2)     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Sep 87  10:58:23 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 87 08:56:41 PDT
Date: 4 Sep 87 08:56 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Anonymous Generic Function Proposal (Draft 2)    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 01 Sep 87
 23:17 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870904-085641-11164@Xerox>

Dick and I had a discussion about with-added-methods.  We came to the
following conclusion about handling Case 3.

(with-added-methods <generic-function> (<methods>*) . <body>)

This takes a generic function and a list of methods specified as
lambda-expressions, creates a copy of the generic function and extends
it by adding the given methods.  Within the lexical scope of the form,
(in <body>) appearances of <generic-function> refer to the extended
generic-function.  with-added-methods does not affect the original
definition of <generic-function>.

This answers my question --

    (defmethod fie (x) 0)

    (defun foo (x)
      (with-added-methods fie ((lambda ((x P1)) 17))
          (cons (fie x) (fum x)))

    (defun fum (y) (fie y))

    (foo (make-instance 'P1)) ==> (17 . 0)


And it answers Pavel's query:
    During the time that WITH-ADDED-METHODS is active, should the
    other processes see the added methods or not?  I would hope not!
Correct.

To obtain a special version of print with added methods, one uses
   (with-added-methods #'print ((lambda (...)...) (lambda (...)...))
      #'print)
and passes the returned generic function as an argument.  Note that
since the generic function is copied on entry, this specialized print is
not affected by later global changes to the print generic function.

∂04-Sep-87  1112	Lanning.pa@Xerox.COM 	WITH-SLOTS, "virtual" slots, and the meta-object protocol 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 4 Sep 87  11:12:21 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 04 SEP 87 11:10:36 PDT
Date: 4 Sep 87 11:10 PDT
Sender: Lanning.pa@Xerox.COM
From: Stanley's Tool Works <Lanning.pa@Xerox.COM>
Subject: WITH-SLOTS, "virtual" slots, and the meta-object protocol
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870904-111036-11421@Xerox>

Start with the standard x/y v rho/theta example:

(defclass position () (x y))
(defmethod rho ((p position)) ...)
(defmethod theta ((p position)) ...)
(defmethod-setf rho ((p position)) (value) ...)
(defmethod-setf theta ((p position)) (value) ...)

What if a user of the POSITION class writes the following method:

(defmethod zoom ((p position) n)
	(with-slots (p)
		(setf rho (* n rho))))

How is this going to work?  Presumably the WITH-SLOTS macro consults the
class to find out what vars should be treated as slot references, but
the notion that RHO and THETA are slots has not been made explicit.  How
does the writer of the POSITION class tell the class about these
"virtual" slots?  Perhaps there should be macros that let you write

(defaccessor rho ((p position)) ...)
(defaccessor-setf rho ((p position)) ...)

or maybe a new method-qualifier so you could write

(defmethod rho :accessor ((p position)) ...)
(defmethod-setf rho :accessor ((p position)) ...)

I guess there could also be another class-option added to DEFCLASS, but
even if there were, something like these macros would be needed.


----- smL

∂08-Sep-87  1221	RPG  	WITH-ADDED-METHODS 
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

There is, I think, a better syntax for WITH-ADDED-METHODS
than what Danny sent out. That syntax was one we discussed
in the context of a slightly different semantics.

(with-added-methods ((foo (...)...)
		     (bar (...) ...)
		     (bar (...) ...)
		     (foo (...)...)
 <body>)

This takes the possibly already existing generic functions, FOO and BAR,
copies them, adds the new methods to them as specified, and then
executes <body>.

If no generic function exists, it is created. Previously defined generic
functions are not altered by the action of this construct.

The bindings of FOO and BAR have indefinite extent.

			-rpg-

∂09-Sep-87  1124	Bobrow.pa@Xerox.COM 	Updating Obsolete Instances  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Sep 87  11:24:45 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 SEP 87 11:20:17 PDT
Date: 9 Sep 87 11:20 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Updating Obsolete Instances
To: common-lisp-object-system@SAIL.STANFORD.EDU
cc: Bobrow.pa@Xerox.COM
Message-ID: <870909-112017-15101@Xerox>

One of the open questions we should resolve next week is what the
protocol should be for updating obsolete instances (instances of
obsolete classes).  I present here a radically simpler proposal than the
ones we were most recently considering, though it bears strong
resemblance to some that were discussed earlier.

Proposal:

A class becomes obsolete when it is redefined (directly or indirectly),
the instance slots it specifies changes, AND it has one or more
instances.  For classes that are instances of standard-class, we support
a protocol to update instances whose structure becomes obsolete.

If a class becomes obsolete, then we say its instances are obsolete
instances. Let c-new be the class specified by the new class definition.
Let obsolete-slots be the names of those slots that are not included in
the new definition, added-slots be the names of the new slots added, and
common-slots be the rest.  

Effectively what happens is that all the obsolete instances become a
subclass of a newly defined class that has as direct-superclasses
(obsolete-class c-new).  Hence, all methods applicable to instances of
the new class are applicable to the old instances. 

However, the first time an attempt is made to access a slot-value of the
obsolete instance, the structure of the instance is updated to the
current structure before the slot-value completes.  The updating is done
(effectively) as follows:

1) Values of all slots in the old instance are saved
2) The structure of the instance is made to correspond to the structure
specified by the current class definition (and it is an instance of
class c-new)
3) Values of all common-slots are inserted in the new instance structure
in the same named slot
4) The generic function obsolete-instance-updated is called.  Its
arguments are the instance (now with the new structure) and a property
list containing the names and values of the obsolete-slots.  There is a
method on standard-object for obsolete-instance-updated

(defmethod obsolete-instance-updated
   ((updated-instance standard-object) obsolete-slot-values)
...)

This method initializes (from initform) any slot in the new structure
that is not already bound.  Slots without initforms are not touched.

Note that by specializing obsolete-instance-updated, one can do work
before or after, or instead of the initialization of unbound slots. 

To enable users to cause instances to be updated without having to add a
phony slot, or some other abomination, we provide a generic-function:

(make-class-obsolete class)

with a method for standard-class that has the appropriate effect.

DISADVANTAGES
1) This proposal specifies that updating will not happen until a slot is
accessed.  Perhaps this is too restrictive on implementations.

2) Methods applicable to the old class, but no longer current are not
usable.

3) This proposal does not support sequential updating of a chain of
obsolete structures. The only information it provides is the set of
obsolete-slots and values.  We could make it possible to determine which
version of the obsolete class was involved in the update by passing the
obsolete-class as a second argument to updating-obsolete-instance.  But
I don't think this is worth it. 
 

ADVANTAGES
1) It specifies exactly when the update will happen, and hence is
guaranteed to minimize the work done; that is, no instance is updated
until it needs to be.  It is possible to test if an instance is obsolete
by checing its type (seeing if its class is a subclass of
obsolete-class).

2) It ameliorates a problem we were discussing about how long what
methods must be kept around etc.  No old versions of methods are kept.

3) It is simple to explain.  Only one instance and class is involved in
updating-obsolete-instance, and the obsolete-slot information is passed
explicitly. The default behavior is what I claim is usually wanted. 

    

∂09-Sep-87  1630	Bobrow.pa@Xerox.COM 	Re: proposed syntactic cleanups in defmethod
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Sep 87  16:30:24 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 09 SEP 87 16:30:51 PDT
Date: 9 Sep 87 16:30 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: proposed syntactic cleanups in defmethod
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Thu, 20 Aug 87 12:29 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870909-163051-15667@Xerox>

    I propose that the DEFMETHOD macro be specified to "refer to"
    (in the sense of CLtL p.160) each specialized parameter.

I think this is a fine idea.

    One of the most common mistakes of beginning Lisp programmers
    is omitting quote marks or putting them in the wrong place. 
    Actually, it's not only beginning programmers who do this.  I still
    do it myself sometimes, and I believe I have seen Danny Bobrow do
    it.
I never do 'that'', do I??

    The other problem with methods on individuals is that the
    current syntax [for defmethod] is awkward when the individual is
anything other
    than a symbol or a number

The intent was that for other cases, one would use the add-method form
which evaluates its arguments.  However, I don't at all mind seeing a
change that makes defmethod easier to use for this case.  And I agree
that evaluating the argument is useful, and using single quote may be a
more error prone as a syntax than a fully spelled keyword.

Of EQL and MEMBER, I prefer EQL since the form (MEMBER X) looks too easy
to extend with a Y and Z.  But I would prefer not to suggest extensions
unless we are prepared to follow through on them soon.  For this reason
some other word might be better.   How about
(THIS x) as being mnemonic and short.

    I think that adding QUOTE as a type-specifier to Common Lisp is
    both unnecessary and confusing.  (Yes, I know I suggested it.  I
    was wrong.) Instead, the parameter-specializer for a method on an
    individual should be (MEMBER object), the type-specifier that
    Common Lisp already defines for this purpose.  Note that there is
    no particular reason why the parameter-specializer should be the
    same as the parameter-specializer-name; they're already not the
    same for methods on classes.

A problem with this may be that the type specifier is used in the
specializers argument of add-method, and again this could lead to
unwarranted extrapolation.  On the other hand, if you are using
add-method perhaps you are immune to unwarranted speculation.

∂09-Sep-87  2114	Moon@STONY-BROOK.SCRC.Symbolics.COM 	User control of the CPL
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 9 Sep 87  21:14:10 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 230758; Wed 9-Sep-87 22:43:07 EDT
Date: Wed, 9 Sep 87 22:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: User control of the CPL
To: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870909224238.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

  Should we adopt the :component-order class-option from Flavors, as a
  simple way for the user to have control of the CPL without making him
  write his own algorithm?
  
    Gregor doesn't like the ability to specify constraints on the
  ordering of classes that only apply conditionally, i.e. if those
  classes are actually present among the superclasses.  He considers
  this bad style.   Moon volunteered to write a proposal with some
  examples, and we agreed to resolve this over the mail.

PROPOSAL:

The :precedence option to defclass is written (:precedence C1 C2 C3 ...)
where the C's are class names.  This specifies that C1 must precede C2
in the CPL, C2 must precede C3, etc.  This defclass option may appear
any number of times.

The default if no :precedence option is specified for a class C with
direct superclasses C1, C2, ..., Cn is (:precedence C C1 C2 ... Cn).  To
completely eliminate all precedence constraints, specify (:precedence C).

In the notation used on page 1-14 of 87-002, the :precedence option
allows direct control over Rc.  Each ordered pair (C1,C2) in Rc is
specified by writing (:precedence C1 C2).  :precedence with more than
two class names is simply a convenient abbreviation for multiple
:precedence options.

OPTIONS:

Optionally we could add an additional requirement that each Ci in a
:precedence option in the defclass for C must be either C or one of C's
direct superclasses.  I am opposed to this, for reasons which should
become clear from the examples.  It doesn't hurt to have extra ordered
pairs in Rc that do not affect the CPL.  Another way of saying this is
that the :precedence option is useful both for relaxing the precedence
constraints, compared with the default, and for adding additional
constraints to the default constraints.

Optionally we could add an additional stipulation that regardless of the
use of :precedence options, a class always precedes its direct
superclasses.  Specifically, in (defclass C (C1 C2 C3) () ...), the
effect of (:precedence C C1), (:precedence C C2), and (:precedence C C3)
is always present; in addition, if the user does not specify a
:precedence option, defclass supplies (:precedence C1 C2 C3).  This
would slightly simplify the following section, but it seems like a
kludgey restriction on how much control over the precedence relations
the user is permitted.  I have found applications that would not work
with this restriction, so I oppose adding this restriction.

Optionally we could add a restriction that a :precedence option in the
defclass for C may not specify that another class precedes C.  Flavors
has such a restriction, however I believe it to be unnecessary and I
oppose making this restriction in CLOS.

EFFECT ON CPL ALGORITHM:

The first and third paragraphs on page 1-15 of 87-002 would need to be
changed.  The statement "there can be only one such candidate class" is
no longer true once the user can relax the constraints using the
:precedence option.  A more complex disambiguation rule is necessarily
required.  I suggest replacing the first paragraph on 1-15 with:

  Sometimes there are several classes from Sc with no predecessors.  In
  this case, we select one of these candidate classes according to the
  following rule:  Traverse the superclasses of each member of the CPL
  found so far, associating the number (d*n*n)-(i*n)+b with the class at
  depth d and breadth b in the tree rooted at the ith element of the CPL
  found so far (make it a tree by considering only the first occurrence
  in breadth-first order of each class).  n is the number of classes
  involved (the initial length of Sc).  Choose the candidate with the
  smallest associated number, considering the minimum if several numbers
  are associated with one class.  This algorithm selects a unique
  candidate because no two associated numbers are equal.

  A class is always the first element of its own CPL.  Thus the CPL
  computed so far, used in the above rule, can never be empty.  This
  implies an additional check: when computing the CPL of C, if (C',C) is
  an element of R, signal an error reporting that it is invalid for C'
  to precede C.
 
The above rule is the simplest rule I could find that is compatible with
the 87-002 rule.  Other rules I considered were not compatible with the
87-002 rule and had additional undesirable properties.  Note that in all
cases when the :precedence option is not used this rule produces the
same answer as the one in 87-002, and produces it in essentially the
same way.  In this case d=1 for the winning candidate.

There are more efficient implementations than computing all the numbers
and then finding the minimum number, however that's the easiest way I could
find to explain it.  An actual implementation could traverse all the trees
in parallel, in a suitable order, and take the first candidate it encounters.

Note that the last sentence in the first paragraph on 1-15 is irrelevant
to the paragraph and repeats what was already said in the last paragraph
on 1-14, so I would simply remove it.

The third paragraph on 1-15 could be replaced with a more precise
specification of the rule quoted above, if desired.


EXAMPLES:

For brevity I have omitted from R all pairs involving the class t.

;Two superclasses and we don't care about their order
;CPL=(example2 example super-2 super-1 t) 
;R={(example-2,example),(example,super-1),(example,super-2),(super-2,super-1)}
(defclass example (super-1 super-2) ()
  (:precedence example super-1)
  (:precedence example super-2))
(defclass example-2 (example super-2 super-1) ())

;Two mixins that can be used separately but they interact and therefore
;if they are used together, they must be used in a certain order to work.
;Specifically, mixin-2 must be before mixin-1.
(defclass base-class () ())
(defclass use-1 (mixin-1 base-class) ())
(defclass use-2 (mixin-2 base-class) ())
(defclass use-both (mixin-1 mixin-2 base-class) ())
(defclass use-both-2 (use-1 use-2) ())
(defclass mixin-1 (base-class) ()
  (:precedence mixin-2 mixin-1 base-class))
(defclass mixin-2 (base-class) ()
  (:precedence mixin-2 mixin-1 base-class))
;use-1 and use-2 will not accidentally include the other mixin
;use-both will get an error for inconsistent precedence constraints
;use-both-2 will get a CPL of (use-both-2 use-1 use-2 mixin-2 mixin-1 base-class t)
;R={(use-both-2,use-1),(use-1,use-2),(use-1,mixin-1),(mixin-1,base-class),
;   (use-2,mixin-2),(mixin-2,base-class),(mixin-2,mixin-1)}

;"Gross example" that helped me shoot down various other rules for
;resolving topological sort ambiguities
;CPL is (a c b e d t)
;R is {(a,b),(b,d),(c,b),(e,d)}.
(defclass a (b d) ())
(defclass b (c) ()
  (:precedence b))
(defclass c () ()
  (:precedence c b))
(defclass d (e) ()
  (:precedence d))
(defclass e () ()
  (:precedence e d))

;Two examples taken from actual (ugh, bletch) window code:

;This one shows two mixins that have an ordering constraint among them,
;but are not always used together.  Rather than rely on any class that
;includes both to specify the constraint correctly, we specify it here.
;The user is adding more constraints to the default constraints.
(DEFCLASS DONT-SELECT-WITH-MOUSE-MIXIN (ESSENTIAL-WINDOW) ()
  ;; If TV:SELECT-MIXIN is present, we must
  ;; override its :NAME-FOR-SELECTION method
  (:PRECEDENCE TV:DONT-SELECT-WITH-MOUSE-MIXIN
	       TV:SELECT-MIXIN
	       TV:ESSENTIAL-WINDOW))

;This one shows a class that is just a bundle of useful mixins, but doesn't
;want to constrain the order of those mixins.
;The user is specifying fewer than the default constraints
(DEFCLASS WINDOW (STREAM-MIXIN BORDERS-MIXIN LABEL-MIXIN SELECT-MIXIN
		  GRAPHICS-MIXIN MINIMUM-WINDOW) ()
  ;; The mixins already come with almost all necessary constraints.
  ;; Relax the constraints that would normally be implied by the above list
  ;; of components, so that subclasses of WINDOW can rearrange things.
  ;; Put the label inside the border.
  (:PRECEDENCE BORDERS-MIXIN LABEL-MIXIN)
  ;; For esthetics, force WINDOW to precede MINIMUM-WINDOW
  (:PRECEDENCE WINDOW MINIMUM-WINDOW))

∂10-Sep-87  1101	kempf%hplabsz@hplabs.HP.COM 	Meeting on Sept. 17-18    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Sep 87  11:01:20 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 10 Sep 87 10:57:15 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 10 Sep 87 08:44:19 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 10 Sep 87 09:48:14 pdt
To: common-lisp-object-system@sail.stanford.edu
Subject: Meeting on Sept. 17-18
X-Mailer: mh6.5
Date: Thu, 10 Sep 87 09:48:11 MST
Message-Id: <4135.558287291@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM


Has the location of the meeting next week been resolved? If so, could
someone post the place and time? Thanks.

		jak

PS: Our phone connection in Andover was down for about a week, so
apologies if this information has already been posted.

∂10-Sep-87  1250	Bobrow.pa@Xerox.COM 	Re: Meeting on Sept. 17-18   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 10 Sep 87  12:50:19 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 10 SEP 87 12:50:44 PDT
Date: 10 Sep 87 12:50 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Meeting on Sept. 17-18
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Thu, 10 Sep 87
 09:48:11 MST
To: kempf%hplabsz@hplabs.HP.COM
cc: common-lisp-object-system@sail.stanford.edu
Message-ID: <870910-125044-16719@Xerox>

Jim,
The meeting will be at Xerox, starting at 9AM on Sept 17.  Come to the
visitors entrance, and ask for me or Gregor. We will have some coffee,
juice and pastries in the room, as well as a recording whiteboard.
  danny

∂10-Sep-87  2248	kempf%hplabsz@hplabs.HP.COM 	Trace Proposal (Version 2)
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 10 Sep 87  22:47:54 PDT
Received: from hplms2 by hplabs.HP.COM with TCP ; Thu, 10 Sep 87 19:54:27 pdt
Received: from hplabsz.hpl.hp.com by hplms2; Thu, 10 Sep 87 13:12:34 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Thu, 10 Sep 87 14:16:56 pdt
To: common-lisp-object-system@sail.stanford.edu
Subject: Trace Proposal (Version 2)
X-Mailer: mh6.5
Date: Thu, 10 Sep 87 14:16:53 MST
Message-Id: <7309.558303413@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM

Here is an updated draft of the debugging proposal. The proposal is on two
levels, a "command language" level for interactive use and a "metaobject
level" for implementation and easy language extension. The command language
level consists of the TRACE macro, for causing information
about the execution of funcallable objects to be displayed. The metaobject
level consists of a generic function, TRACE-EXECUTION,
for arranging, in an implementation dependent manner,
that this information be displayed.  Note that the TRACE macro definition
is slightly incompatible with CLtL, since only one funcallable object at a
time can be specified. This was included to facilitate addition of
a :BREAK option, which, as Moon pointed out in his reply to the
original posting, would have been difficult with the original.
The CLtL UNTRACE macro would also be modified.

With regard to Moon's suggestion that the function-spec's are similar
to the proposed documentation or definition type, Larry Masinter indicated 
that we should go ahead independently. However, I like the suggestion, 
and have therefore modified the TRACE specification 
to refer to the documentation type. In the event that no modification
of the current CLtL specification of documentation types is forthcoming 	
(or is delayed), the current one should be sufficient with
the addition of documentation types for CLOS entities  and any for 
implementation dependent tracable items (e.g. local functions). 
This is noted in addition.

With regard to Moon's question about whether the following sequence:

  (defun foo () ...)
  (setq f #'foo)
  (trace foo)
  (funcall f)

generates trace output, the answer is, no. The intent of the
proposal is that when TRACE is used with a symbol as a function spec,
then invocations of the function are only traced when the function
is invoked via the definition in that symbol's global function cell.
Similarly, when TRACE-EXECUTION is called with a symbol and no
optional environment parameter, tracing occurs only when invocation
is through the symbol's global function cell. Implementations
may choose to provide tracing when a function is invoked through
application of the function definition object directly, or, as in the
case above, when the function definition is applied under another
name. In such an implementation, the above example could be rewritten
as:

  (defun foo () ...)
  (setq f #'foo)
  (trace (function (symbol-function 'foo)))
  (funcall f)

or the TRACE-EXCEUTION generic function could be called:

  (trace-execution (symbol-function 'foo))

Thus, if an implementation is unable to support tracing through
the function definition object, the implementor could chose to
not support the FUNCTION function spec.

I hope we can discuss this at next week's meeting, if perhaps only
briefly in case there is not much time.

			jak

Font information: UPPERCASE indicates bold, *word* indicates italics

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

>>>>>>>>>>>>>

Addition to 87-002

>>>>>>>>>>>>>


TRACE *{function-spec}* &KEY (:BREAK NIL)	*[Macro]*
UNTRACE  *{function-spec}*		*[Macro]*

Invoking TRACE with a function specification causes the
function specified to be traced. Henceforth whenever a specified
function is invoked, information about the call, the arguments passed,
and the returned values, if any, will be printed to the stream that is
the value of *TRACE-OUTPUT*. If the keyword argument :BREAK is T,
then the BREAK function will be called after the trace information
is printed. UNTRACE causes printing of trace information for the
specified function to cease.

A *function-spec* is either a symbol naming a function (i.e. a symbol
whose global function cell is bound to a function definition object)
or a list whose first element is a documentation type, and 
whose tail indicates which particular function of that type should 
be traced. Documentation types are described in the description of
the DOCUMENTATION function. The complete set of documentation types,
and thus *function-specs*, will necessarily be implementation dependent, 
however, here are several *function-specs* which every implementation is 
required to support:

*symbol*-Invocation of the function named by *symbol* via. *symbol*'s
global function cell are traced.

(SETF *symbol* )-If the generalized variable reference indicated by
*symbol* is tracable, then invocations of the function implementing
the SETF operation will be traced.

(METHOD *generic-function-name* *parameter-specializer-name-list*)-
If the method whose parameter specializer list and generic function
name indicated is tracable, then invocations through the generic 
function name will be traced.

(MACRO-FUNCTION *symbol*)-If *symbol* has a global macro function definition,
then invocations of the macro function through *symbol* will be traced.

Some *function-specs* which may be available in particular implementations
are:

(LOCAL-FUNCTION *symbol* *environment*)-Invocations of the lexically 
defined function named *symbol* defined in *environment* are traced.

(LOCAL-MACRO-FUNCTION *symbol* *environment*)-Invocations of the lexically
defined macro named *symbol* defined in *environment* are traced.

(FUNCTION *function-definition-object*)-Invocations of the function
definition object are traced, regardless of whether through the global 
function definition cell in a symbol or by direct application of the
function definition object.

Implementations are encouraged to provide for tracing as many kinds
of funcallable objects as possible.

>>>>>>>>>>>>>

Additions to the List of Documentation Types on pg. 440 of CLtL:

>>>>>>>>>>>>>

METHOD - returns documentation for methods defined with DEFMETHOD.

MACRO-FUNCTION - returns documentation for macros defined with DEFMACRO.

LOCAL-FUNCTION - returns documentation for functions defined with
  FLET or LABELS.

LOCAL-MACRO-FUNCTION - returns documentation for macros defined with
MACROLET.

>>>>>>>>>>>>>

Addition to 87-003

>>>>>>>>>>>>>

TRACE-EXECUTION *object* &OPTIONAL *env* &KEY (:BREAK NIL)  *[Generic Function]*

TRACE-EXECUTION discriminates on *object* to select an implementation
specific method that arranges for the executable entity associated
with *object* to be traced. The optional *env* environment parameter is for 
those implementations which require environmental information to
arrange for tracing to occur. Implementations are required to provide
TRACE-EXECUTION as the system level entry point for implementing TRACE
functionality. If the :BREAK keyword argument is T, arrangement is made for
the BREAK function to be called after trace information is printed.

The exact nature and number of methods associated with TRACE-EXECUTION
will differ, depending on what function specifications are supported
by TRACE, but every implementation needs to support the following 
methods:

SYMBOL-The function indicated by the symbol will be traced when invoked
in the environment. If the symbol names a function which is a globally 
defined macro and no environment parameter is passed, then tracing will 
occur when the global macro function is invoked. If the function definition 
is bound to the symbol's global function definition cell and no environment 
parameter is passed, then invocations of the function via. its global 
name will be traced. If an environment argument is passed, then the symbol
is taken to name a local function or local macro function and only 
invocations when the environment is the same as the environment parameter 
will be traced, provided the implementation can arrange for it.

METHOD-The method function is traced when invoked.

GENERIC-FUNCTION-The generic function is traced when the discriminator
code is invoked.

Some methods which may be available in particular implementations
are:

FUNCTION-Invocation of the function is traced, regardless
of whether invocation is through a named symbol. 

Implementations are encouraged to provide as many methods as is possible.














∂11-Sep-87  0827	skeene@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Sep 87  08:27:40 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 231837; Fri 11-Sep-87 11:28:56 EDT
Date: Fri, 11 Sep 87 11:28 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Miscellaneous decisions taken or to be taken
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870820131023.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <870911112819.1.SKEENE@JUNCO.SCRC.Symbolics.COM>

    Date: Thu, 20 Aug 87 13:10 EDT
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
 
    I have updated my file of miscellaneous decisions taken or to be taken,
    based on mail received in response to the last time I mailed this out
    (two weeks ago).  If anyone doesn't see their response included, or
    thinks their favorite issue is missing, please let me know and I will
    apologize for my error and add it.  


    p2-19 Values: I thought we agreed that all top level forms should return
    the object.  It says here defclass "returns the name of the class"
    p2-22 Same comment as 2-19, for defgeneric-options
    2-24 ditto for defgeneric-options-setf

      In July we decided to return the object for all CLOS defxxx functions (being
      inconsistent with Common Lisp, but consistent within CLOS).  The document file
      has been updated.

We did decide this, and the document file reflects it.   When I was
making these changes, I noticed that the only top-level form that
doesn't fit this model very well is DEFINE-METHOD-COMBINATION.  I think
it should return the name of the type of method combination, not the the
object that represents the type of method combination.  Programmers
never use method-combination object; they always use its name.    The
reason we decided that DEFCLASS should return the class object (and so
on) is because the class object is useful.   But the object representing
a method combination type is an implementation detail, and not useful to
the programmer.  

I'd like to propose that we make an exception in this case, and have 
DEFINE-METHOD-COMBINATION return the name of the method combination 
type. 

∂11-Sep-87  1023	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Miscellaneous decisions taken or to be taken    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Sep 87  10:23:23 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 231942; Fri 11-Sep-87 13:24:41 EDT
Date: Fri, 11 Sep 87 13:24 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Miscellaneous decisions taken or to be taken
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870911112819.1.SKEENE@JUNCO.SCRC.Symbolics.COM>
Message-ID: <870911132423.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Fri, 11 Sep 87 11:28 EDT
    From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>

	Date: Thu, 20 Aug 87 13:10 EDT
	From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

	  In July we decided to return the object for all CLOS defxxx functions (being
	  inconsistent with Common Lisp, but consistent within CLOS).  The document file
	  has been updated.

    We did decide this, and the document file reflects it.   When I was
    making these changes, I noticed that the only top-level form that
    doesn't fit this model very well is DEFINE-METHOD-COMBINATION.  I think
    it should return the name of the type of method combination, not the the
    object that represents the type of method combination.  Programmers
    never use method-combination object; they always use its name.    The
    reason we decided that DEFCLASS should return the class object (and so
    on) is because the class object is useful.   But the object representing
    a method combination type is an implementation detail, and not useful to
    the programmer.  

    I'd like to propose that we make an exception in this case, and have 
    DEFINE-METHOD-COMBINATION return the name of the method combination 
    type. 

The real problem here is that there is no object that represents a type
of method combination.  In other words, the meta-object protocol does not
directly model method combination.  Perhaps a meta-object theorist can
suggest how to fix this.  Otherwise, I agree that DEFINE-METHOD-COMBINATION
should return the name.

∂11-Sep-87  1034	skeene@STONY-BROOK.SCRC.Symbolics.COM 	short form of define-method-combination  
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Sep 87  10:34:19 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 231964; Fri 11-Sep-87 13:35:32 EDT
Date: Fri, 11 Sep 87 13:34 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: short form of define-method-combination
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870911133455.2.SKEENE@JUNCO.SCRC.Symbolics.COM>


The following text came from Moon's message on Miscellaneous Decisions:

----------

2-26  I believe that short form method combination ought to be a macro
in the standard library, and documented there, not in the basic
principles.  I think the standard combinations :append, :and, :or, ...
should also be put in the standard library too.
  
  Kempf agrees.  Moon can't have an opinion until he knows what this
  library is and whether it's going to be as much of a joke as the
  Common Lisp Yellow Pages.

----------

It's not clear to me who suggested putting the short form of
DEFINE-METHOD-COMBINATION into the library, but I strongly disagree 
with the idea.   

The short form of DEFINE-METHOD-COMBINATION satisfies the design goal of
"providing simple ways to do simple things".   Many, probably most, of
the commonly-needed types of method combination can be defined that way,
with one line of code.    

The way I see it, CLOS is organized in two levels.

The Programmer Interface is sufficient for most programmers to do most
things they need to do.    The Meta-Object protocol lets programmers do
almost anything they could ever want to do, but it requires extra
effort.   Many aspects of the programmer interface are just convenience
features, in that the programmer could achieve the same effect, with
greater effort, using the Meta-object operators.   However, the
programmer interface is here because it makes CLOS much more usable.

Similarly, DEFINE-METHOD-COMBINATION has two levels -- the short form
and the long form.   The short form is just a convenience feature for
the long form, but it makes declarative method combination much more
usable.   I don't see any advantage in removing it from the CLOS
standard.   

∂11-Sep-87  1154	Bobrow.pa@Xerox.COM 	[kempf%hplabsz@hplabs.HP.COM: Re: Updating Obsolete Instances ] 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  11:53:58 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 11:48:09 PDT
Date: 11 Sep 87 11:47 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: [kempf%hplabsz@hplabs.HP.COM: Re: Updating Obsolete Instances ]
To: common-lisp-object-system@sail.stanford.edu
Message-ID: <870911-114809-18010@Xerox>


To: Danny Bobrow <Bobrow.pa>
Subject: Re: Updating Obsolete Instances 
X-Mailer: mh6.5
In-Reply-To: Your message of 09 Sep 87 11:20:00 -0700.
             <870909-112017-15101@Xerox> 
Date: Thu, 10 Sep 87 18:14:39 MST
Message-Id: <9967.558317679@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM


General comments: This proposal seems to simplify class changing
and instance updating considerably. It is certainly the simplest
and most direct proposal advanced so far, and reduces the amount
of overhead for class changing.

> A class becomes obsolete when it is redefined (directly or indirectly),
> the instance slots it specifies changes, AND it has one or more
> instances.  For classes that are instances of standard-class, we support
> a protocol to update instances whose structure becomes obsolete.

If the class has no instances, does it simply become undefined?
Assuming this is so, it should be added to the spec. Also, 
need the change class protocol be applied to a class in which none 
of the slot definitions have changed?

> Effectively what happens is that all the obsolete instances become a
> subclass of a newly defined class that has as direct-superclasses
> (obsolete-class c-new).  Hence, all methods applicable to instances of
> the new class are applicable to the old instances. 

Very nice! This would take care of the problem of how to have the methods
applicable for the new class do the updating without impacting method
invocation performance on new instances, nor requiring classes to keep
pointers to all instances created.

> However, the first time an attempt is made to access a slot-value of the
> obsolete instance, the structure of the instance is updated to the
> current structure before the slot-value completes.  The updating is done
> (effectively) as follows:

> 1) Values of all slots in the old instance are saved
> 2) The structure of the instance is made to correspond to the structure
> specified by the current class definition (and it is an instance of
> class c-new)
> 3) Values of all common-slots are inserted in the new instance structure
> in the same named slot
> 4) The generic function obsolete-instance-updated is called.  Its
> arguments are the instance (now with the new structure) and a property
> list containing the names and values of the obsolete-slots.  There is a
> method on standard-object for obsolete-instance-updated

> (defmethod obsolete-instance-updated
>    ((updated-instance standard-object) obsolete-slot-values)
> ..)

> This method initializes (from initform) any slot in the new structure
> that is not already bound.  Slots without initforms are not touched.

What about a change in allocation type? For example, if the old
class had a slot whose allocation was :INSTANCE and the new :CLASS,
then does SLOT-VALUE on this slot return the new :CLASS allocated
value? If so, then DEFCLASS or OBSOLETE-INSTANCE-UPDATED should at least warn
the user that the allocation type has changed. Similarly for an
old :CLASS allocation changing to :INSTANCE. Also, if the :TYPE option
is used to type a new slot with a type which is incompatible with
the old, the user should be warned.

> To enable users to cause instances to be updated without having to add a
> phony slot, or some other abomination, we provide a generic-function:

> (make-class-obsolete class)

> with a method for standard-class that has the appropriate effect.

Yes, this is definitely needed.

> DISADVANTAGES
> 2) Methods applicable to the old class, but no longer current are not
> usable.

I don't quite understand this. What do you mean by "current"?

> 3) This proposal does not support sequential updating of a chain of
> obsolete structures. The only information it provides is the set of
> obsolete-slots and values.  

Since updating is hookable, users can do this themselves if they want.

Another disadvantage is that methods which use WITH-SLOTS will
still have references to slots which no longer exist, although
attempting to reference those slots will cause the instance to
update itself. But this will also be true if the slot accessor functions 
are used directly, since they will be undefined when the new class
is defined without the old slots.

An additional problem is that the obsolete classes will remain hanging
around even after all the instances are updated, unless they and the
update methods are keeping track of the number of instances around,
and they can undefine themselves once all instances are updated.
Note this won't require them to keep track of instances, just the
number created.

Looking at the semantic difficulties section on pg. 2-9 for CHANGE-CLASS,
the difficulties with changing an instance inside a method seem to
be eliminated, since, although the class changes, all methods
applicable before the change are still applicable afterwards, since
the class precedence list is only being shortened from the more 
specialized end. This means that the effective method calculation
need not be redone. Problems with optimizing slot access will
still occur, but the specification for WITH-SLOTS should probably
indicate that optimization at level 3 will not remove access
through the SLOT-VALUE function unless safety is also set to 0.

Finally, it would probably be a good idea to drastically limit what the  
user can do with an obsolete class, like not letting the user create an 
instance of it directly. Should the user be allowed to cause an obsolete class
to become current again? My general inclination is to say probably
not. This would drift into undo-like facilites, which are best left
to the programming environment. Also, it would definitely not be
a good idea to allow use of the obsolete class as a parameter
specializer, nor to inherit from it, otherwise the semantic difficulties
with methods could recur, since the set of applicable methods and 
effective method might change during method application.


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

∂11-Sep-87  1154	Bobrow.pa@Xerox.COM 	Re: Updating Obsolete Instances   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  11:54:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 11:48:45 PDT
Date: 11 Sep 87 11:48 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Updating Obsolete Instances 
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Thu, 10 Sep 87
 18:14:39 MST
To: common-lisp-object-system@sail.stanford.edu
cc: Bobrow.pa@Xerox.COM,kempf%hplabsz@hplabs.HP.COM
Message-ID: <870911-114845-18011@Xerox>

    > A class becomes obsolete when it is redefined (directly or
    > indirectly), the instance slots it specifies changes,
    > AND it has one or more instances.  For classes that are
    > instances of standard-class, we support a protocol
    > to update instances whose structure becomes obsolete.

   If the class has no instances, does it simply become undefined?

No, it simply becomes redefined.  The only reason to obsolete a class is
so that instances can be updated.  One can radically redefine a class
that has no instances, and no obsolete class need be created.

    What about a change in allocation type? For example, if the old
    class had a slot whose allocation was :INSTANCE and the new :CLASS,
    then does SLOT-VALUE on this slot return the new :CLASS allocated
    value?
Changing an aloocation from :instance to :class of course makes a class
obsolete (if it has instances).  This was supposed to be covered by the
phrase "the instance slots it specifies changes".  Simlarly for the
change the other way.  SLOT-VALUE on this slot should return the new
:CLASS allocated value in any methods.

    DEFCLASS or OBSOLETE-INSTANCE-UPDATED should at least warn the
    user that the allocation type has changed. 
I don't understand the general Common  Lisp policy about warnings.  When
should DEFCLASS warn?  Does DEFUN warn when it is redefining a function?
I don't think OBSOLETE-INSTANCE-UPDATED should ever warn, since clearly
this is dominated by the warning about change of the class.

    Also, if the :TYPE option is used to type a new slot with a
    type which is incompatible with the old, the user should be warned.
This need not cause a class to be obsoleted.  It might cause the
accessors to be updated if they are the ones that check the type.
We do need to decide if an error is signalled if
 (sef (slot-value ...)...) 
tries to violate a type restriction.

    > DISADVANTAGES
    > 2) Methods applicable to the old class, but no longer current
    > are not usable.
   I don't quite understand this. What do you mean by "current"?
I was referring to an earlier discussion where it was suggested that
methods that were applicable to old instances, but have since been
changed or deleted be kept for use with the now obsolete instances.  For
example, if the definition of point changed from using x and y, to using
rho and theta, the method that computed rho would no longer be needed
(should be replaced by a simple accessor).  Would the old computation be
kept around.  I am answering this with a NO.

    Another disadvantage is that methods which use WITH-SLOTS will
    still have references to slots which no longer exist, although
    attempting to reference those slots will cause the instance to
    update itself. But this will also be true if the slot accessor
    functions  are used directly, since they will be undefined when the
    new class is defined without the old slots.
I think this is intrinsic to any redefinition of a class.

    An additional problem is that the obsolete classes will remain
    hanging around even after all the instances are updated, unless
    they and the update methods are keeping track of the number of
    instances around, and they can undefine themselves once all
    instances are updated. Note this won't require them to keep track
    of instances, just the number created.
This might be handled by the garbage collector.  If there is no pointer
maintained from a superclass to an obsolete subclass, and obsolete
classes have no name, then the only pointers to the obsolete class will
be in the instances.  When there are no more instances, the obsolete
class will be collected.

    Looking at the semantic difficulties section on pg. 2-9 for
    CHANGE-CLASS
I did not propose that this protocol for obsoleteinstances replace the
CHANGE-CLASS protocol.  I have always thought it a mistake to confound
these two cases.  For CHANGE-CLASS, both the classes involved are still
current (not obsolete), and hence a CLASS-CHANGED method can be called.
  
    The difficulties with changing an instance inside a method seem
    to be eliminated, since, although the class changes, all methods
    applicable before the change are still applicable afterwards, since
    the class precedence list is only being shortened from the more 
    specialized end.
For CHANGE-CLASS, the user can change an instance of any class to any
other (e.g. from a window to an automobile) and the only guaraneed
intersection of the class precedence list is OBJECT.

    Problems with optimizing slot access will still occur, but the
    specification for WITH-SLOTS should probably indicate that
    optimization at level 3 will not remove access through the
    SLOT-VALUE function unless safety is also set to 0.
There are numerous problems with fully optimized slot-value calls.  In
another message I propose a protocol to deal with this problem.

    Finally, it would probably be a good idea to drastically limit
    what the   user can do with an obsolete class, like not letting the
    user create an  instance of it directly. Should the user be allowed
    to cause an obsolete class to become current again? My general
    inclination is to say probably not. This would drift into
    undo-like facilites, which are best left to the programming
    environment. Also, it would definitely not be a good idea to allow
    use of the obsolete class as a parameter specializer, nor to
    inherit from it, otherwise the semantic difficulties with methods
    could recur, since the set of applicable methods and  effective
    method might change during method application.

I agree.  Obsolete classes should resist all changes including
production of new instances.  This probably requires an
obsolete-metaclass as well as an obsolete-class to implement cleanly.

∂11-Sep-87  1204	skeene@STONY-BROOK.SCRC.Symbolics.COM 	proposal for arguments for call-next-method   
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Sep 87  12:04:35 PDT
Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 232100; Fri 11-Sep-87 15:05:48 EDT
Date: Fri, 11 Sep 87 15:05 EDT
From: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>
Subject: proposal for arguments for call-next-method 
To: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870911150510.5.SKEENE@JUNCO.SCRC.Symbolics.COM>
Character-Type-Mappings: (1 0 (NIL 0) (NIL :ITALIC NIL) "CPTFONTI")
Fonts: CPTFONT, CPTFONTI


In July we agreed that call-next-method should take arguments.   I
gathered together information from the various messages and came up with
the following text, which I propose should go into the CALL-NEXT-RECORD
section in Chapter 2.    This text doesn't deal with other issues about
CALL-NEXT-METHOD, such as the dynamic extent or CALL-NEXT-METHOD-OR-NIL
issues.

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

When {\bf call-next-method} is called with no arguments, it passes the 
current method's original arguments to the next method.  Neither 
argument defaulting, nor using {\bf setq}, nor rebinding variables with
the same names as parameters of the method affects the values {\bf
call-next-method} passes to the method it calls. 

When {\bf call-next-method} is called with arguments, the next method is
called with those arguments.  When providing arguments to {\bf
call-next-method}, the following rule must be satisfied or an error is
signalled:  The set of methods applicable for a changed set of arguments
for {\bf call-next-method} must be the same as the set of applicable 
methods for the original arguments to the method.ε1 ε0 If {\bf call-next-method} 
is called with arguments but omits optional arguments, the next method 
defaults those arguments.  Optimizations of the error checking are possible 
but they should be invisible to the programmer.

∂11-Sep-87  1314	Bobrow.pa@Xerox.COM 	Deoptimizing Slot Access
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  13:14:06 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 13:14:37 PDT
Date: 11 Sep 87 13:14 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Deoptimizing Slot Access
To: Common-Lisp-Object-System@Sail.stanford.edu
cc: Bobrow.pa@Xerox.COM
Message-ID: <870911-131437-18190@Xerox>


The metaclass protocol provides for a mechanism whereby implementations
can optimize slot access for instances of certain classes.  This
protocol is discussed in another message.  This message is concerned
with a related problem.

Suppose we have 
(defclass c1 () (x y))

and 
(defmethod m1 ((i c1)) (slot-value i 'x))

and the latter method is compiled so that slot-access is optimized.

The suppose we define:

(defclass c2 (c1)
    ((x :allocation :special))
  (:metaclass special-class))

where for classes with metaclass special-class, slot access for slots
with allocation :special it is inappropriate to use the optimized code.
Then in order to make method m1 usable for instances of class c2, it
would be nice to be able to cause a trap in the optimized code for
accessing that slot for instances of c2.  We propose that there be a
standard way to cause this to happen for methods originally defined on
instances of standard class, and that the trap call
slot-value-using-class.  

We propose two generic functions in the metaobject protocol associated
with this behaviour.  The contract for each and the methods for
standard-class are described below: 

deoptimize-slot-accesses (class  slotd)
   Calling this generic-function on an instance <class> of
standard-class and <slotd> of standard-slot-description will ensure
that, in any method applicable to instances of <class>, all accesses to
the slot described by <slotd> in <class>  will call
slot-value-using-class.  If this is not possible for these arguments, an
error is signalled.
  For standard-class, an error will be signalled only if slotd is not a
slot in the class.

can-deoptimize-slot-accesses-p (class slot-description)
 Returns T if deoptimize-slot-access will not signal an error.



This facility could be used to implement the cahnge in access when a
slot allocation is changed for a particular slot from :instance in a
superclass to :class in a subclass.

Methods specialized on classes are recorded.  If one allows slot access
to be optimized for uses of with-slots in functions not specialized on a
class, then all such uses must be recorded so that they can be found by
deoptimize-slot-accesses. 


∂11-Sep-87  1335	Bobrow.pa@Xerox.COM 	Re: User control of the CPL  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  13:35:44 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 13:35:19 PDT
Date: 11 Sep 87 13:35 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: User control of the CPL
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Wed, 9 Sep 87 22:42 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870911-133519-18239@Xerox>

If we wanted to have an additional mechanism for controlling the set of
pairs in partial order that determines the class precedence list, then I
suppose this proposal is a reasonable one.  However, after looking at
the examples, I felt that the gain in potential simplicity for people
who wanted to exert indirect control over the class precedence list is
more than offset by the extremely nonintuitive (to me) behaviors that
are possible to obtain from this yet another programming language.

The example for the window system would better be done by a special
program that knows how to construct window classes out of descriptions
of desired behaviors.  Assuming that users know an entire complex of
class names but not about constraints among class use seems an
inappropriate intermediate position.  Naive users who want to construct
a mix and match window class ought to be given a mini-expert system to
help, because constraints can easily be more than those simply
resolvable by class ordering.  

∂11-Sep-87  1447	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: User control of the CPL 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 11 Sep 87  14:47:24 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 232298; Fri 11-Sep-87 17:42:39 EDT
Date: Fri, 11 Sep 87 17:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: User control of the CPL
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870911-133519-18239@Xerox>
Message-ID: <870911174243.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 11 Sep 87 13:35 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    The example for the window system would better be done by a special
    program that knows how to construct window classes out of descriptions
    of desired behaviors.

I don't see why the fact that the Zetalisp window system is badly designed
should be a design criterion for CLOS.  I only included those examples
because for me it was a convenient source of examples drawn from a real
program.

∂11-Sep-87  1641	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: Updating Obsolete Instances  
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 11 Sep 87  16:41:05 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ah03509; 11 Sep 87 19:25 EDT
Received: from ti-csl by RELAY.CS.NET id ah01016; 11 Sep 87 19:18 EDT
Received: from Jenner by tilde id AA08017; Fri, 11 Sep 87 17:42:43 CDT
Message-Id: <2767387349-12962022@Jenner>
Date: Fri, 11 Sep 87  17:42:29 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: Updating Obsolete Instances
In-Reply-To: Msg of 9 Sep 87 11:20 PDT from Danny Bobrow <Bobrow.pa@xerox.com>

     
     If a class becomes obsolete, then we say its instances are obsolete
     instances. Let c-new be the class specified by the new class definition.
     Let obsolete-slots be the names of those slots that are not included in
     the new definition, added-slots be the names of the new slots added, and
     common-slots be the rest.  

I am confused here.  Are you giving up the fact that c-new is eql to the
class object existing just before the redefinition? 
     
     Effectively what happens is that all the obsolete instances become a
     subclass of a newly defined class that has as direct-superclasses
     (obsolete-class c-new).  Hence, all methods applicable to instances of
     the new class are applicable to the old instances. 

I am confused here too.  Do you mean that obsolete-class does not have
any method applicable to it?

     
     3) This proposal does not support sequential updating of a chain of
     obsolete structures. The only information it provides is the set of
     obsolete-slots and values.  We could make it possible to determine which
     version of the obsolete class was involved in the update by passing the
     obsolete-class as a second argument to updating-obsolete-instance.  But
     I don't think this is worth it. 

I think that supporting sequential update is important. With machines
able to run weeks instead of hours without running out of memory or
crashing, people will want to redefine existing classes without having
to think about the ten previous updates while writing their
obsolete-instance-updated method.

∂11-Sep-87  1657	Bobrow.pa@Xerox.COM 	Re: User control of the CPL  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  16:57:37 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 16:57:55 PDT
Date: 11 Sep 87 16:57 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: User control of the CPL
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 11 Sep 87 17:42 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870911-165755-1193@Xerox>

    Date: 11 Sep 87 13:35 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

        The example for the window system would better be done by a
        special program that knows how to construct window classes out
        of descriptions of desired behaviors.


    Date: Fri, 11 Sep 87 17:42 EDT
    From: David A. Moon
    I don't see why the fact that the Zetalisp
    window system is badly designed should be a design criterion for
    CLOS.  I only included those examples because for me it was a
    convenient source of examples drawn from a real program.

I did not mean to criticize the window system design (I didn't think you
were defending it).  It was a good example to show how constraints
between classes might arise naturally.

But I don't think that complex constructions of that kind (even for a
well designed system) can or should be mediated by a very simple set of
ordering constraints.  If there are only one or two extra ordering
constraints, then combined classes that embody the combined order
constraint in the superclass order will do, and if it is more complex
than that, then a real interactive system for construction from parts
would be more appropriate, I think.

∂11-Sep-87  2030	Bobrow.pa@Xerox.COM 	Re: User control of the CPL  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  16:57:37 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 16:57:55 PDT
Date: 11 Sep 87 16:57 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: User control of the CPL
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 11 Sep 87 17:42 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870911-165755-1193@Xerox>

    Date: 11 Sep 87 13:35 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

        The example for the window system would better be done by a
        special program that knows how to construct window classes out
        of descriptions of desired behaviors.


    Date: Fri, 11 Sep 87 17:42 EDT
    From: David A. Moon
    I don't see why the fact that the Zetalisp
    window system is badly designed should be a design criterion for
    CLOS.  I only included those examples because for me it was a
    convenient source of examples drawn from a real program.

I did not mean to criticize the window system design (I didn't think you
were defending it).  It was a good example to show how constraints
between classes might arise naturally.

But I don't think that complex constructions of that kind (even for a
well designed system) can or should be mediated by a very simple set of
ordering constraints.  If there are only one or two extra ordering
constraints, then combined classes that embody the combined order
constraint in the superclass order will do, and if it is more complex
than that, then a real interactive system for construction from parts
would be more appropriate, I think.

∂11-Sep-87  2057	Bobrow.pa@Xerox.COM 	Re: Updating Obsolete Instances   
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  20:57:39 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 17:52:06 PDT
Date: 11 Sep 87 17:52 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Updating Obsolete Instances
In-reply-to: Patrick H Dussud <DUSSUD%Jenner@ti-csl.CSNET>'s message of
 Fri, 11 Sep 87 17:42:29 CDT
To: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870911-175206-1258@Xerox>

         If a class becomes obsolete, then we say its
         instances are obsolete instances. Let c-new be the class
         specified by the new class definition. Let obsolete-slots be
         the names of those slots that are not included in the new
         definition, added-slots be the names of the new slots added,
         and common-slots be the rest.  
    I am confused here.  Are you giving up the fact that c-new is
    eql to the class object existing just before the redefinition? 
No.  I should have been more explicit.  c-new is EQL to the original
class, but has the new description.

         Effectively what happens is that all the obsolete
         instances become a subclass of a newly defined class that has
         as direct-superclasses (obsolete-class c-new).  Hence, all
         methods applicable to instances of the new class are
         applicable to the old instances. 

    I am confused here too.  Do you mean that obsolete-class does
    not have any method applicable to it?
The only method on obsolete-class that I know about is
slot-value-using-class, and it causes the updating to happen.

         3) This proposal does not support sequential updating
         of a chain of obsolete structures. The only information it
         provides is the set of obsolete-slots and values.  We could
         make it possible to determine which version of the obsolete
         class was involved in the update by passing the obsolete-class
         as a second argument to updating-obsolete-instance.  But I
         don't think this is worth it. 

    I think that supporting sequential update is important. With
    machines able to run weeks instead of hours without running out of
    memory or crashing, people will want to redefine existing classes
    without having to think about the ten previous updates while
    writing their obsolete-instance-updated method.

I am not convinced that people would really use this.  My model is that
they would continue to edit the obsolete-instance-updated each time if
there was significant work to do; and most of the time the obsolete
instances would probably not be used, even if the classes changed often.
But of course I am flaming about "usual programming practice".  For
Loops, we had the simplest version of this feature (it always just saved
obsolete slot values on a property list), and we had no complaints. I
often ran in the same image for a week or two at a time, doing extensive
development.

∂11-Sep-87  2057	Bobrow.pa@Xerox.COM 	Re: Miscellaneous decisions taken or to be taken 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  20:57:33 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 17:41:24 PDT
Date: 11 Sep 87 17:41 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Miscellaneous decisions taken or to be taken
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 11 Sep 87 13:24 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870911-174124-1245@Xerox>

       I'd like to propose that we make an exception in this
        case, and have  DEFINE-METHOD-COMBINATION return the name of
        the method combination  type. 

    The real problem here is that there is no object that
    represents a type of method combination.  In other words, the
    meta-object protocol does not directly model method combination. 
    Perhaps a meta-object theorist can suggest how to fix this. 
    Otherwise, I agree that DEFINE-METHOD-COMBINATION should return the
    name.
As a representative of the meta-theorist camp, I want to agree that the
appropriate thing to return in this case is the name.
  danny

∂11-Sep-87  2058	Bobrow.pa@Xerox.COM 	Re: short form of define-method-combination 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Sep 87  20:57:50 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 SEP 87 18:45:11 PDT
Date: 11 Sep 87 18:45 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: short form of define-method-combination
In-reply-to: Sonya E. Keene <skeene@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 11 Sep 87 13:34 EDT
To: skeene@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870911-184511-1302@Xerox>

    It's not clear to me who suggested putting the short form of
    DEFINE-METHOD-COMBINATION into the library, but I strongly disagree
     with the idea.   

I cannot tell a lie.  It was I.

    The short form of DEFINE-METHOD-COMBINATION satisfies the
    design goal of "providing simple ways to do simple things".   Many,
    probably most, of the commonly-needed types of method combination
    can be defined that way, with one line of code.    

Are there other simple cases other than ones that are predefined e.g.
:and :append ...?  I thought you had already defined the useful ones
(REF Symbolic manual).

    The Programmer Interface is sufficient for most programmers to
    do most things they need to do.    

I am suggesting that a library that is first class (it consists of
standard implementations of useful things) be included with the
standard.  The rule should be, if an implementation includes a feature
like this (has the same name) it should be equivalent to this one.
Library programs would be straightforward programming excercises for
some of the less frequently used programming tools.  In addition to
DEFINE-METHOD-COMBINATION in the short form, I would put in there
functions like 
  all-class-slot-names class &optional allocation
and other simple uses of mapcar over some of the basic data structures.
We can even add something like classes to implement active values, slot
properties, dynmaic slots, and a few other of the features that we took
out of the standard but a significant number of users seem to be
reinventing.

    I don't see any advantage in removing it from the CLOS
    standard.   
The advantage I see is that it allows us another level beyond the basic
programmer's interface.  There is a three level structure

1) Metaobject protocol (fine grain control of the implementmentation)
2) Programmers Interface (what I use everyday)
3) Programmer's library (Useful things I might do on accasion)

If we can make level 3 real for CLOS (meaning it is as standardized as
the spec -- but is in a library), perhaps we can even push this idea
into Common Lisp itself.

∂14-Sep-87  1346	Gregor.pa@Xerox.COM 	Re: Miscellaneous decisions taken or to be taken 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 14 Sep 87  13:46:33 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 87 13:43:33 PDT
Date: 14 Sep 87 13:43 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Miscellaneous decisions taken or to be taken
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Fri, 11 Sep 87 13:24 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870914-134333-2880@Xerox>

Well, if you believe that define-method-combination expands something
like this:

(define-method-combination AND ..)  ==>

(defmethod compute-effective-method-internal
          ((generic-function standard-generic-function)
           (type (eql 'and))
           ..)
  ..)

Then the appropriate object would be the method on
compute-effective-method-internal or whatever the name of the generic
function the following method is documented to call.

(defmethod compute-effective-method-internal
          ((generic-function standard-generic-function)
           ..)
  (compute-effective-method-internal
     generic-function
     (slot-value generic-function 'method-combination-type)
     ..))

∂14-Sep-87  1439	Bobrow.pa@Xerox.COM 	Uninitialized Slots
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 14 Sep 87  14:39:42 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 87 14:39:45 PDT
Date: 14 Sep 87 14:39 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Uninitialized Slots
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870914-143945-2999@Xerox>

Moon noted:
    2-19 uninitialized slots should be an error to reference, not
    be defined to return an unstandardized value with no error.  I'm
    willing not to require that it signals an error if people feel that
    would be an undue burden, otherwise I prefer that reading an
    uninitialized slot signals an error.

    In July we decided that signalling an error here should
    depend on the declared safety level. 


Rather than signal an error directly, I propose that a generic-function
be called, dependent in the same way on safetty level:

slot-uninitialized (class instance slot-name)

where class is the class of the instance.  The method on standard-class
signals an error. Among other things, this allows an easy implementation
of default values in classes, a current feature of Loops, Strobe and
KEE.

∂14-Sep-87  1446	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Miscellaneous decisions taken or to be taken
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Sep 87  14:46:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 233579; Mon 14-Sep-87 17:47:10 EDT
Date: Mon, 14 Sep 87 17:47 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Miscellaneous decisions taken or to be taken
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870914-134333-2880@Xerox>
Message-ID: <870914174715.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 14 Sep 87 13:43 PDT
    From: Gregor.pa@Xerox.COM

    Well, if you believe that define-method-combination expands something
    like this:

    (define-method-combination AND ..)  ==>

    (defmethod compute-effective-method-internal
	      ((generic-function standard-generic-function)
	       (type (eql 'and))
	       ..)
      ..)

    Then the appropriate object would be the method on
    compute-effective-method-internal or ....

I disagree.  That method object is -part of the implementation of- the
method combination type, but it does not -represent- the method
combination type in the same sense that a class object -represents- a
class and a method object -represents- a method, in the meta-object
world's -model- of what the system is doing.  Switching to speaking
operationally from speaking philosophically, there aren't operations on
that method object that will tell you things about the
method-combination type.  If I'm wrong here then I -really- don't
understand meta-objects (which is of course possible).

∂14-Sep-87  1510	Gregor.pa@Xerox.COM 	Re: Miscellaneous decisions taken or to be taken 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 14 Sep 87  15:10:47 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 87 15:11:01 PDT
Date: 14 Sep 87 15:10 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Miscellaneous decisions taken or to be taken
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 14 Sep 87 17:47 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870914-151101-3059@Xerox>

No, I think you are right, that method object doesn't really represent
the method combination type.  I was kind of kidding.

BUT, if as part of a particular implementation, you decided to store the
information which "represents" the method combination type as some
datastructure rather than just having it be 'inline' in the code of the
method; storing it in the method object might be reasonable.

That sentence is contorted, but what I mean is that both of the
following expansioons for define-method-combination are reasonable:

(define-method-combination :FOO ..)

(defmethod mumble (..)
  (let ((info (GET ':FOO 'METHOD-COMBINATION-TYPE)))
    ...)))


(let ((method (make-instance 'dmc-method ...)))
  (setf (method-function method)
        #'(lambda (..)
            (let ((info (SLOT-VALUE METHOD 'INFO))) ..)))
  (add-method #'mumble method))

Of course in the second example, the stuff stored inside the method is
just a "random" structure in the same way the stuff stored on the plist
is.   I am just trying to show that the documented existence of the
method object can be used like this to hold the structure.  This also
make it possible for the GC to collect that "random structure" if the
method is dropped on the floor.

∂14-Sep-87  1511	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Uninitialized Slots    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Sep 87  15:11:45 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 233609; Mon 14-Sep-87 18:12:28 EDT
Date: Mon, 14 Sep 87 18:12 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Uninitialized Slots
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870914-143945-2999@Xerox>
Message-ID: <870914181233.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 14 Sep 87 14:39 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

    Moon noted:
	2-19 uninitialized slots should be an error to reference, not
	be defined to return an unstandardized value with no error.  I'm
	willing not to require that it signals an error if people feel that
	would be an undue burden, otherwise I prefer that reading an
	uninitialized slot signals an error.

	In July we decided that signalling an error here should
	depend on the declared safety level. 

    Rather than signal an error directly, I propose that a generic-function
    be called, dependent in the same way on safetty level:

    slot-uninitialized (class instance slot-name)

    where class is the class of the instance.  The method on standard-class
    signals an error. Among other things, this allows an easy implementation
    of default values in classes, a current feature of Loops, Strobe and
    KEE.

I'm happy with this.  I'll edit it into the document from which "Moon noted"
came (I hope tonight to mail out the last version of that document before
this week's meeting).

∂14-Sep-87  1532	kempf%hplabsz@hplabs.HP.COM 	Re: User control of the CPL    
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 14 Sep 87  15:31:05 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Mon, 14 Sep 87 15:25:16 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Mon, 14 Sep 87 15:52:50 pdt
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: User control of the CPL 
X-Mailer: mh6.5
In-Reply-To: Your message of Wed, 09 Sep 87 22:42:00 -0400.
             <870909224238.7.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Mon, 14 Sep 87 15:52:46 MST
Message-Id: <4795.558654766@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM


> The default if no :precedence option is specified for a class C with
> direct superclasses C1, C2, ..., Cn is (:precedence C C1 C2 ... Cn).  To
> completely eliminate all precedence constraints, specify (:precedence C).

> In the notation used on page 1-14 of 87-002, the :precedence option
> allows direct control over Rc.  Each ordered pair (C1,C2) in Rc is
> specified by writing (:precedence C1 C2).  :precedence with more than
> two class names is simply a convenient abbreviation for multiple
> :precedence options.

It sounds from this that you are thinking here about controlling the
local precedence order using the :PRECEDENCE option (please correct
me if I'm wrong), but I don't think that's necessary. A user can control 
the local precedence order by simply changing the order of the supers 
in the super list. The problems come when trying to impose some kind of 
global control over the CPL.

> Optionally we could add an additional requirement that each Ci in a
> :precedence option in the defclass for C must be either C or one of C's
> direct superclasses.  I am opposed to this, for reasons which should
> become clear from the examples.  It doesn't hurt to have extra ordered
> pairs in Rc that do not affect the CPL.  Another way of saying this is
> that the :precedence option is useful both for relaxing the precedence
> constraints, compared with the default, and for adding additional
> constraints to the default constraints.

See comment above.

> Optionally we could add an additional stipulation that regardless of the
> use of :precedence options, a class always precedes its direct
> superclasses.  Specifically, in (defclass C (C1 C2 C3) () ...), the
> effect of (:precedence C C1), (:precedence C C2), and (:precedence C C3)
> is always present; in addition, if the user does not specify a
> :precedence option, defclass supplies (:precedence C1 C2 C3).  This
> would slightly simplify the following section, but it seems like a
> kludgey restriction on how much control over the precedence relations
> the user is permitted.  I have found applications that would not work
> with this restriction, so I oppose adding this restriction.

I tend to think that this stipulation may be necessary, however, I'm
open to examples where it may not. From my reading of the examples
included at the end of the base note, I couldn't find any where
this stipulation would make the example not possible. The reason I think it 
should be included is that I think it fits the mental model of inheritance as
specialization, which is how I think we'd like to encourage people to
think about inheritance in the default CLOS language. If people want
to use the metaobject protocol to write their own inheritance algorithm,
then they should be able to do whatever they want. People who want to 
think about inheritance differently can write a CALCULATE-CLASS-PRECEDENCE
-LIST method customized to do things differently. 

Also, putting in this stipulation (e.g. a class always preceeds it's 
direct superclasses) reinforces the concept of local precedence order, 
which means that programmers can deal with a class and its superclasses
as a kind of logical unit.

>>>>>>>>

While I'm not sure about this particular proposal, I am in favor of
some kind of user control over the CPL calculation, but for different
reasons. For the case where the inheritance graph cannot be linearized,
the user should be given the option of being able to control the
linearization and specify the global precedence ordering when conflicts
occur, without having to write a CALCULATE-CLASS-PRECEDENCE-LIST method.
Whether this control comes in the form of a continuable error when
the default algorithm fails (in which case, the user is invited to
supply a consistent list, perhaps interactively) or as a class option
in which the user supplies some global precedence constraint or some
other way is not that important, as long as it fits in well with
the rest of CLOS. Some form of control is needed, however.

Additionally, the class freezing proposal which was briefly
discussed last spring as an optimization procedure would be another
case where a user controlled the CPL calculation. In that case, 
the CPL of a "frozen" class would need to be treated as a unit for
any subclass inheriting from the frozen class. The result would be
the same as a user defined constraint on the CPL, except the constraint
would be on the entire CPL of the super and not on a subsection. 
There are other aspects to class freezing as well 
(disallowing redefinitions for example).

It would be nice if both these needs could be united into 
one, perhaps with a new generic function or macro in the user interface
section which gives the user control over the CPL (or part thereof)
in a manner consistent with the rest of the user level language, rather
than a new constraint language, but maybe that's hoping for too much.

For random changes to the CPL, I think that using the metaobject protocol
would probably be best.

				jak

∂14-Sep-87  1547	Masinter.pa@Xerox.COM 	Re: Uninitialized Slots    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 14 Sep 87  15:47:12 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 87 15:47:28 PDT
Date: 14 Sep 87 15:47 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Uninitialized Slots
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Mon, 14 Sep 87 18:12 EDT
To: Bobrow.pa@Xerox.COM
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Message-ID: <870914-154728-3159@Xerox>

There are really serious problems with having a well-defined operation
(like calling slot-uninitialized) depend on the "declared safety level".

The only things that should depend on the declared safety level are
whether an error is signalled when it "should be". Otherwise, the safety
level must enter into the language semantics rather than being just a
"hint".


∂14-Sep-87  1642	Bobrow.pa@Xerox.COM 	Re: Agenda for September meeting  
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 14 Sep 87  16:42:23 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 87 16:42:35 PDT
Date: 14 Sep 87 16:42 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Agenda for September meeting
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s
 message of Tue, 18 Aug 87 14:46 EDT
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
cc: Common-Lisp-Object-System@sail.stanford.edu
Message-ID: <870914-164235-3253@Xerox>

    Discuss written proposals on major areas, circulated over the
    network before the meeting and brought to the meeting in hardcopy.
A number of proposals have appeared over the network.  How should they
appear in hardcopy.  Do you intend to extract what you think are the
current proposals, or should we have distributed resposnsibility.  Seems
like the latter is fairer, but we ought to have a list of the expected
proposals.  Do you have a list of such proposals that need separate
write-ups?  e.g.

generic-labels, with-added-methods (RPG)
obsolete instances (dgb)
object creation (dam)
call-next-method (sk)
...

To be included in misc decisions file???
1.
...

∂14-Sep-87  2058	Moon@STONY-BROOK.SCRC.Symbolics.COM 	Re: Agenda for September meeting 
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Sep 87  20:58:01 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 233805; Mon 14-Sep-87 23:29:36 EDT
Date: Mon, 14 Sep 87 23:29 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Agenda for September meeting
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870914-164235-3253@Xerox>
Message-ID: <870914232936.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 14 Sep 87 16:42 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>

	Discuss written proposals on major areas, circulated over the
	network before the meeting and brought to the meeting in hardcopy.
    A number of proposals have appeared over the network.  How should they
    appear in hardcopy.  Do you intend to extract what you think are the
    current proposals, or should we have distributed resposnsibility.  Seems
    like the latter is fairer, but we ought to have a list of the expected
    proposals.

It will have to be distributed responsibility.  Due to other commitments
I will not be able to do any significant amount of additional work to
prepare for the meeting.  I don't think I will even be able to send out
a substantially revised version of the miscellaneous issues and
decisions file.  I'd like each person who has proposed something to
bring at least one hardcopy of their proposal (I assume we can get things
copied at PARC).  I'll bring hardcopies of things I have proposed and of
all the mail that I had thought was worth saving.

    Do you have a list of such proposals that need separate write-ups?

Here's the list I made earlier today of issues that were discussed in the
mail since the last meeting, excluding very small issues.  This covers
about 85 messages.  Next to each one I put names of people who I noticed
having enough to say to count as a proposal.  I may have missed some people.
Large issues are listed first, but otherwise there is no particular order.

  Object Creation (Moon, possibly Gregor)
  Class Redefinition (Bobrow, Moon, Dussud)
  Class and Generic Function Naming (everybody?)
  Local Generics, Methods (RPG)
  Class Precedence (Moon, possibly RPG, possibly Kempf)
  Trace (Kempf)
  &key lambda-list congruence (Bobrow, Moon)
  Short form of define-method-combination (Moon, Bobrow)
  call-next-method with arguments (SKeene)
  call-next-method closure extent (RPG)
  Defmethod syntax for methods on individuals (Moon)
  Virtual slots for with-slots ((Lanning))
  Uninitialized Slots (Bobrow)

∂14-Sep-87  2129	Bobrow.pa@Xerox.COM 	Re: Names to Objects and Compiler-environment    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 14 Sep 87  21:29:11 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 14 SEP 87 17:17:19 PDT
Date: 14 Sep 87 17:17 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Names to Objects and Compiler-environment 
In-reply-to: kempf%hplabsz@hplabs.HP.COM's message of Wed, 26 Aug 87
 11:28:22 MST
To: kempf%hplabsz@hplabs.HP.COM
cc: DUSSUD%Jenner%ti-csl.CSNet@relay.cs.net,
 common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870914-171719-3304@Xerox>

After reading the messages sent, I think that only the following very
simple name to object mapping interface should be supported.In general,
there must be (effectively) different objects in the different
environments, since objects in a compiler environment canot be allowed
to interact with the runtime objects; optimizations that minimize
copying should be invisible to the user.  With this the other
generic-functions that Patrick suggested should be extended can be left
as they are.  

Name To Object Generic Functions.

symbol-class symbol &optional environment 
  ==> class or NIL
symbol-function symbol &optional environment  ****
   ==> function or NIL
symbol-setf-function symbol &optional environment
   ==> function or NIL


**** Change to Common Lisp -- We should argue for it.


The generic-functions above all support setf forms:

(setf (symbol-class symbol &optional environment) class)
  ==> class

(setf (symbol-function symbol &optional environment) function)
  ==> function

(setf (symbol-setf-function symbol &optional environment) function)
  ==> function


If the value argument for any of these forms is NIL, then this is
equivalent to the corresponding CMAKUNBOUND, or FMAKUNBOUND  ****

**** Change to Common Lisp -- We should argue for it.


For the Object to Name mapping, CLOS should provide the generic
functions:

class-name class
  ==> symbol

function-name function
  ==> symbol


These return a symbol.  The return value is only considered a hint.
There is no guarantee that a symbol returned is a name for the class
(function), or if NIL is returned, the class or function does not have a
name.

∂15-Sep-87  0923	RPG  	Uninitialized Slots
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

If we use Moon's proposed behavior

    ``In July we decided that signalling an error here should
    depend on the declared safety level. ''

the proper terminology, according to my not-as-yet-adopted terminology
for error situations, is that accessing an uninitialized slot should
signal an error.

I believe Danny's proposal has the difficult-to-justify property of
encouraging users to write code whose correct behavior depends on the
safety level used during compilation. That is, if we provide a
generic function that is invoked upon some erroneous but common situation,
users will pack useful code into the methods on that function.

Danny writes:

	   ``Rather than signal an error directly, I propose that a
	   generic-function be called, dependent in the same way on safety
	   level....  Among other things, this allows an easy
	   implementation of default values in classes, a current feature
	   of Loops, Strobe and KEE.''

			-rpg-

∂15-Sep-87  0935	RPG  	Proposals
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

I will bring hardcopies of my proposals. I will clean them up considerably
beforehand, but you can get the drift from the mail.

			-rpg-

∂15-Sep-87  1009	kempf%hplabsz@hplabs.HP.COM 	Re: Proposals   
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 15 Sep 87  10:09:05 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 15 Sep 87 10:05:13 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 15 Sep 87 11:09:47 pdt
To: common-lisp-object-system@sail.stanford.edu
Subject: Re: Proposals 
X-Mailer: mh6.5
In-Reply-To: Your message of 15 Sep 87 09:35:00 -0700.
Date: Tue, 15 Sep 87 11:09:43 MST
Message-Id: <12363.558724183@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM

> 
> I will bring hardcopies of my proposals. I will clean them up considerably
> beforehand, but you can get the drift from the mail.

I'll do the same.

			jak


∂15-Sep-87  1356	Bobrow.pa@Xerox.COM 	Re: Uninitialized Slots 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 15 Sep 87  13:56:16 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 15 SEP 87 13:55:06 PDT
Date: 15 Sep 87 13:55 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Uninitialized Slots
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 15 Sep 87
 09:23 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870915-135506-4468@Xerox>

    If we use Moon's proposed behavior

        ``In July we decided that signalling an error here
        should depend on the declared safety level. ''

    the proper terminology, according to my not-as-yet-adopted
    terminology for error situations, is that accessing an
    uninitialized slot should signal an error.

    I believe Danny's proposal has the difficult-to-justify
    property of encouraging users to write code whose correct behavior
    depends on the safety level used during compilation. That is, if we
    provide a generic function that is invoked upon some erroneous but
    common situation, users will pack useful code into the methods on
    that function.

Given this argument, I suggest we back off on the commitment that there
can be compilation of slot-access that depends on the declared safety
level for standard instances.  I propose that for standard-class the
system should ALWAYS call slot-uninitialized if an uninitialized slot is
accessed.    It should be easy to build a metaclass that can provide
more optimized access for production compilation.    

∂15-Sep-87  1627	kempf%hplabsz@hplabs.HP.COM 	Re: Updating Obsolete Instances (and CHANGE-CLASS) 
Received: from HPLABS.HP.COM by SAIL.STANFORD.EDU with TCP; 15 Sep 87  16:26:27 PDT
Received: from hplabsz.hpl.hp.com by hplms2; Tue, 15 Sep 87 16:22:07 pdt
Return-Path: <kempf@hplabsz>
Received: from hplabsz by hplabsz; Tue, 15 Sep 87 17:26:39 pdt
To: Danny Bobrow <Bobrow.pa@Xerox.COM>
Cc: common-lisp-object-system@sail.stanford.edu
Subject: Re: Updating Obsolete Instances (and CHANGE-CLASS)
X-Mailer: mh6.5
In-Reply-To: Your message of 11 Sep 87 11:48:00 -0700.
             <870911-114845-18011@Xerox> 
Date: Tue, 15 Sep 87 17:26:36 MST
Message-Id: <15740.558746796@hplabsz>
From: kempf%hplabsz@hplabs.HP.COM


>     Looking at the semantic difficulties section on pg. 2-9 for
>     CHANGE-CLASS
> I did not propose that this protocol for obsolete instances replace the
> CHANGE-CLASS protocol.  I have always thought it a mistake to confound
> these two cases.  For CHANGE-CLASS, both the classes involved are still
> current (not obsolete), and hence a CLASS-CHANGED method can be called.
>   
>     The difficulties with changing an instance inside a method seem
>     to be eliminated, since, although the class changes, all methods
>     applicable before the change are still applicable afterwards, since
>     the class precedence list is only being shortened from the more 
>     specialized end.
> For CHANGE-CLASS, the user can change an instance of any class to any
> other (e.g. from a window to an automobile) and the only guaraneed
> intersection of the class precedence list is OBJECT.

I was under the impression that CHANGE-CLASS was primarily there for
updating of obsolete instances. Since this proposal decouples the two,
CHANGE-CLASS/CLASS-CHANGED as currently formulated seems to be even
weaker.

I believe that user defined coercions are probably a good idea, but that they
should be integrated with the Common Lisp COERCE function (CLtL, pg.
51-52) rather than through a new function. Considering the already full
agenda for this week's meeting, I hesitate to suggest that we discuss this 
(though I will come with a written up proposal, in case we have time). Both
CHANGE-CLASS and CLASS-CHANGED can be replaced by making COERCE a
generic function. The "destructive in-place modification" property which
seems to be the reason for CLASS-CHANGED can simply be the default behavior
for COERCE when called with a CLOS object. Optionally, a flag parameter could 
be included to control this behavior. In any event, the semantic difficulties
mentioned in the spec and the statement "the generic function
CLASS-CHANGED is not intended to be called by the programmer" at the
beginning of the CLASS-CHANGED description seem to indicate that something
more is needed on this.

			jak









∂15-Sep-87  1916	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Another try on object creation 
Received: from [128.81.41.223] by SAIL.STANFORD.EDU with TCP; 15 Sep 87  19:16:07 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 163152; Tue 15-Sep-87 21:55:00 EDT
Date: Tue, 15 Sep 87 21:54 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Another try on object creation
To: Common-Lisp-Object-System@SAIL.STANFORD.EDU
In-Reply-To: <870903-141438-10242@Xerox>
Message-ID: <870915215412.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 3 Sep 87 14:14 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>
    ....
    Why
    do we need &method-key?  Why not make the congruence rules for generic
    functions be those Moon described for &method-key i.e. the acceptable
    named arguments for a generic function are the union of the named
    arguments of the methods, or &allow-other-keys.  The one feature this
    eliminates is the ability to define a generic function for which all
    methods must have exactly the same named arguments.  This seems a small
    loss, and we gain by not having to add another lambda-keyword.  

I tried this out in the version of the proposal that I will bring to the
meeting, and it seems to work out fairly well.

    Another question.  What happens if a method is invoked with a named
    argument that it is not prepared to receive?  Is it a run-time error?
    It is easy to construct examples where this could happen.

In 87-002, the answer was very simple: methods work the same as ordinary
functions in this respect, and whatever CLtL says happens, happens.
With the introduction of &method-key, that's still true when &method-key
is not used, but when &method-key is used, the situation cannot happen
because the generic-function-to-method dispatching mechanism is defined
to do the checking.  With your proposal to make &key work like
&method-key, the situation you mention can never happen.

CLtL p.62 says named-argument name mismatch "is an error", so the
argument list validity checking in the generic-function-to-method
dispatching mechanism should conform to that and signal an error under
implementation-dependent control.

∂15-Sep-87  2006	Moon@SAPSUCKER.SCRC.Symbolics.COM 	Re: Anonymous Generic Function Proposal (Draft 2)      
Received: from [128.81.41.223] by SAIL.STANFORD.EDU with TCP; 15 Sep 87  20:06:06 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 163174; Tue 15-Sep-87 23:07:47 EDT
Date: Tue, 15 Sep 87 23:06 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Anonymous Generic Function Proposal (Draft 2)    
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: <870904-085641-11164@Xerox>
Message-ID: <870915230654.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 4 Sep 87 08:56 PDT
    From: Danny Bobrow <Bobrow.pa@Xerox.COM>
    ....
    To obtain a special version of print with added methods, one uses
       (with-added-methods #'print ((lambda (...)...) (lambda (...)...))
	  #'print)
    and passes the returned generic function as an argument.  Note that
    since the generic function is copied on entry, this specialized print is
    not affected by later global changes to the print generic function.

This actually brings up an interesting point.  PRINT is not a generic
function, PRINT-OBJECT is.  If you change this example to specify
#'print-object instead of #'print, you realize that this is fairly
useless.  The documentation of print-object says that the user is not
supposed to call it; it is called automatically by the system functions
such as PRINT, WRITE, and ~S.  Making a copy of print-object with some
new methods is fairly useless, since there is no way to get the system
functions to call it.  This is simply one instance of a general problem
with interfaces.

I don't think any mechanism that isn't essentially equivalent to dynamic
binding of function definitions will solve this problem.  I'm not convinced
that CLOS actually needs to solve this problem though.

This point is somewhat off the main track of the anonymous generic function
proposal, and I do not consider it an argument against that proposal.

∂20-Sep-87  1904	Gregor.pa@Xerox.COM 	fixing our problems with setf
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 20 Sep 87  19:04:01 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 20 SEP 87 19:03:42 PDT
Date: 20 Sep 87 19:03 PDT
From: Gregor.pa@Xerox.COM
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@Sail.Stanford.edu
cc: Gregor.pa@Xerox.COM
Message-ID: <870920-190342-9834@Xerox>

Unless we can get setf 'fixed' in the entire language, I propose that we
solve our problems with setf by eliminating all the setf features from
CLOS (except automatically generated writer methods).  That means get
rid of the ability to say (setf <foo>) to defmethod, symbol-function,
generic-function-labels, generic-flet and the others.

My belief is that we are geting into trouble because we are confusing
(generic) function naming with defining setf macros.  This gets us
screwed because setf is a macro in yet another namespace and doesn't
interact real well with our stuff.

Put another way, there isn't (right now) anything called defun-setf.  If
you want to do that you have to do (something like):

(defsetf foo |setf FOO|)

(defun |setf FOO| (x new-value) ...)


Given that, I don't see whats so wrong with having to do:

(defsetf bar |setf BAR|)

(defmethod |setf BAR| ((x boat) new-value) ..)


∂21-Sep-87  0911	Bobrow.pa@Xerox.COM 	Re: fixing our problems with setf 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Sep 87  09:11:32 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 87 09:10:49 PDT
Date: 21 Sep 87 09:10 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: fixing our problems with setf
In-reply-to: Gregor.pa's message of 20 Sep 87 19:03 PDT
To: Gregor.pa@Xerox.COM
cc: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870921-091049-10309@Xerox>

    Unless we can get setf 'fixed' in the entire language, I
    propose that we solve our problems with setf by eliminating all the
    setf features from CLOS (except automatically generated writer
    methods).  That means get rid of the ability to say (setf <foo>) to
    defmethod, symbol-function, generic-function-labels, generic-flet
    and the others.

I also found our discussion last week of setf very uncomfortable, since
it doesn't work in the same way in the rest of Common Lisp.  In
particular, the contrast between

(defmethod (setf foo) (a b) (c) ...)

which is legal (note -- no specializers)

and

(defun (setf foo) (a b) (c) ...)

which is unfortunately nonsense.  I was also struck by the lack of a
local version of setf. 

So much as I hate to agree with Gregor, I think we should follow changes
to Common Lisp with respect to setf, not lead it. I would hope that
someone would ask the cleanup committee to consider this issue. 

  danny

∂21-Sep-87  1109	RPG  	Issues on Dynamic Extent for CALL-NEXT-METHOD    
To:   Common-lisp-object-system@SAIL.STANFORD.EDU    

Here is a summary of the issues that Danny and I discussed with
regard to the extent of CALL-NEXT-METHOD last thursday and Friday.

The basic question is whether CALL-NEXT-METHOD ought to have dynamic
or indefinite extent. We have already agreed that it has lexical scope.
The crux of the matter is whether one can return a closure that
invokes CALL-NEXT-METHOD and thereby cause control to pass back
into the generic function.

In this discussion, all reference to Common Lisp code is to code written
without the use of macros.

Consider a generic function, GF, in which some number of methods are
defined. Suppose that one of them looks like this:

(defmethod GF (...) ... (throw C #(lambda () (call-next-method)))...)

and that all of them but the default method invokes CALL-NEXT-METHOD,
the intention being that all of the methods get run in inside-out order.

If C is later invoked, do we intend the cascade of method invocations
in inside-out order to continue where it left off?

Argument 1, in favor of indefinite extent.

The methods as defined within GF are like LABELS functions, and CALL-NEXT-METHOD
is analogous to calling one of these LABELS functions from inside another.
If we use CALL-NEXT-METHOD to define some internal control structure in
which the methods are individual parts of the control structure, then this
is no different from defining a similar control structure using local
functions.

Argument 2 (rebuttal to 1), in favor of dynamic extent.

A generic function is a black box once defined and invoked, and it
does not make good sense to be able to suspend execution of a generic
function at a method boundary with the possibility of proceeding that
execution later. Imagine doing this while performing a method combination.

Argument 3 (rebuttal to 2), in favor of indefinite extent.

You are free to do that with a tangled web of LABELS functions, so what's
the difference?

Argument 4 (answer to 3), in favor of dynamic extent.

When you capture a labels environment, you do not capture any hidden state
as you do with CALL-NEXT-METHOD. With function invocation you can either
see directly the function to be called [(foo 1 2 3) calls foo] or else you
can see the variable whose value is the function to be called [(funcall
*foo* 1 2 3) calls the value of *foo*]. CALL-NEXT-METHOD contains a hidden
`list' of methods left to be invoked. Common Lisp provides for no capture of
hidden state, so why do it here?

Argument 5, (rebuttal to 4), in favor of indefinite extent.

The hidden state in CALL-NEXT-METHOD is no different from the hidden
state of the function cell or the variable that controls which
function will be called.

Argument 6, in favor of dynamic extent.

Besides, your reduction of methods to LABELS functions has explanatory
power but no predictive power in this case. That is, we cannot rely
on reducibility as an accurate reflection of semantics.
Here is an example:

(defun even-odd (n)
 (let ((odds 0)(evens 0))
  (tagbody
   l1 (when (< n 1) (return-from even-odd (values evens odds)))
   l2 (if (evenp n) (go l3)(go l4))
   l3 (incf evens) (go l5)
   l4 (incf odds)  (go l5)
   l5 (decf n) (go l1))))

This behavior can be reduced to this:

(defun even-odd (n)
 (let ((evens 0)(odds 0))
  (labels ((l1 () 
            (block even-odd 
	     (when (< n 1) (return-from even-odd (values evens odds)))
	     (l2)))
	   (l2 ()
	    (block even-odd
             (if (evenp n) (l3)(l4))))
	   (l3 ()
	    (block even-odd
            (incf evens) (l5)))
	   (l4 ()
	    (block even-odd
             (incf odds) (l5)))
	   (l5 ()
	    (block even-odd
             (decf n) (l1))))
  (l1))))

This might explain TAGBODY and GO in this case, but we cannot
take this sort of reduction to be an equivalence, because we can
now alter the second definition in such a way that the mapping back to
TAGBODY and GO is not valid:

Change the definition of L3 to:

	   (l3 ()
	    (block even-odd
             (incf evens) 
	     (when (= n 20) 
	      (return-from even-odd #'(lambda () (l5))))
	     (l5)))

If we do

  (even-odd 100)

we get a closure, and if we invoke it the computation continues
and returns 50, 50.

Now let's change the TAGBODY and GO definition the same way:

   l3 (incf evens)
      (when (= n 20) #'(lambda () (go l5)))
      (go l5)

When we do (even-odd 100), we get a closure, but invoking it
causes a runtime error to be signaled.

Had we chosen to define TAGBODY and GO within Common Lisp to
be equivalent to a LABELS form, then the reduction would have
predictive power. Therefore, assuming that the reduction is
valid simply begs the question.

Argument 7 (rebuttal to 6), in favor of indefinite extent.

What are you talking about!!  That sounds bogus to me.  Methods are more
like functions than they are like TAGBODY labels, and CALL-NEXT-METHOD is
like a function call, because you can return from it.

Argument 8 (summary), in favor of dynamic extent.

The reason that TAGBODY and GO is not reduced to LABELS is to allow
implementors to do a better job with GO than with function call.  Maybe
there's a fast way to do CALL-NEXT-METHOD if there isn't a dubious feature
to implement, especially when hardly anyone will use that feature.

Argument 9 (summary), in favor of indefinite extent.

Let's make the whole thing simpler by not instituting this funny
dynamic extent constraint that no real programmers understand
anyway.

[rpg: I would only care if there were some performance issue,
as in Argument 8, but I doubt there is, and I doubt it's important.]

			-rpg-

∂21-Sep-87  1121	RPG  	New Trivial Issue: Implicit Blocks in Methods    
To:   common-lisp-object-system@SAIL.STANFORD.EDU    

Common Lisp defines DEFUN to put an implicit block around the
body of the function.

(defun foo (...) <body>) => (defun foo (...)(block foo <body>))

Does DEFMETHOD do the same thing?

(defmethod foo (...) <body>) => (defmethod foo (...)(block foo <body>))?

Suppose there is a generic function named FOO with some methods.
If there is an implicit block named FOO, then the form

	(return-from foo <value>)

will return from the method. If the invocation of the method was
from CALL-NEXT-METHOD, control returns to the point-of-call.

Suppose we really wanted to return from the generic function FOO?
The only way would be to put a CATCH around the invocation of it,
and therefore a programmer could not exit a generic function from within
a method.

Alternative 1. DEFMETHOD includes an implicit block of the same name as
the method, and the programmer cannot exit a generic function summarily.

Alternative 2. Generic functions have an implicit block if the same name
around them, and the programmer has to explicitly include a block
name in his DEFMETHOD if that's what he wants.

Alternative 3. Invent some new way of exiting.
E.g.  ...(return-from-generic-function ...)...

Alternative 1 might shaft some people, and certainly it makes a
raft of code harder to write. But how often does someone want to
summarily exit a generic function?

Alternative 2 probably is implemented with something like a CATCH, and so
it slows down generic function invocation a little.

Alternative 3 adds some hair and also has implementation implications.

			-rpg-

∂21-Sep-87  1159	Moon@STONY-BROOK.SCRC.Symbolics.COM 	New Trivial Issue: Implicit Blocks in Methods        
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Sep 87  11:59:23 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 237734; Mon 21-Sep-87 15:01:03 EDT
Date: Mon, 21 Sep 87 15:00 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: New Trivial Issue: Implicit Blocks in Methods    
To: common-lisp-object-system@SAIL.STANFORD.EDU
In-Reply-To: The message of 21 Sep 87 14:21 EDT from Dick Gabriel <RPG@SAIL.STANFORD.EDU>
Message-ID: <870921150018.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 21 Sep 87  1121 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    Common Lisp defines DEFUN to put an implicit block around the
    body of the function.

    (defun foo (...) <body>) => (defun foo (...)(block foo <body>))

    Does DEFMETHOD do the same thing?

    (defmethod foo (...) <body>) => (defmethod foo (...)(block foo <body>))?

This is what we do in Flavors, and people seem to find it useful.

    Suppose there is a generic function named FOO with some methods.
    If there is an implicit block named FOO, then the form

	    (return-from foo <value>)

    will return from the method. If the invocation of the method was
    from CALL-NEXT-METHOD, control returns to the point-of-call.

    Suppose we really wanted to return from the generic function FOO?
    The only way would be to put a CATCH around the invocation of it,
    and therefore a programmer could not exit a generic function from within
    a method.

That's right.  Typically the CATCH would be in a :AROUND method.  Sometimes
people define special method-combination types that establish this sort of
control structure, also.  (define-method-combination or) is about the simplest
way to do it.

    Alternative 1. DEFMETHOD includes an implicit block of the same name as
    the method, and the programmer cannot exit a generic function summarily.

Alternative 1 is what Flavors does now.

    Alternative 2. Generic functions have an implicit block if the same name
    around them, and the programmer has to explicitly include a block
    name in his DEFMETHOD if that's what he wants.

I don't think alternative 2 can work within the philosophy of Common
Lisp, because a method is not lexically inside of its generic function.

    Alternative 3. Invent some new way of exiting.
    E.g.  ...(return-from-generic-function ...)...

THROW suffices.

∂21-Sep-87  1231	Bobrow.pa@Xerox.COM 	Re: New Trivial Issue: Implicit Blocks in Methods     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Sep 87  12:31:41 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 87 12:00:20 PDT
Date: 21 Sep 87 11:57 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: New Trivial Issue: Implicit Blocks in Methods    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 21 Sep 87
 11:21 PDT
To: RPG@SAIL.STANFORD.EDU
cc: common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870921-120020-10687@Xerox>

    Alternative 1. DEFMETHOD includes an implicit block of the same
    name as the method, and the programmer cannot exit a generic
    function summarily.

    Alternative 2. Generic functions have an implicit block if the
    same name around them, and the programmer has to explicitly include
    a block name in his DEFMETHOD if that's what he wants.

    Alternative 3. Invent some new way of exiting. E.g. 
    ...(return-from-generic-function ...)...

How about:
Alternative 4.   Named generic functions have an implicit block around
them with a constructed name e.g. for FOO:
   |generic-function FOO|
This need not be coded in the generic-function unless at least one of
the methods uses the feature. 

If this is not good, then I vote for 1 on the basis of Dick's last
comment:
     But how often does someone want to summarily exit a generic
    function?

∂21-Sep-87  1232	Bobrow.pa@Xerox.COM 	Re: Issues on Dynamic Extent for CALL-NEXT-METHOD     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Sep 87  12:31:50 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 87 12:00:22 PDT
Date: 21 Sep 87 11:59 PDT
Sender: Bobrow.pa@Xerox.COM
From: Danny Bobrow <Bobrow.pa@Xerox.COM>
Subject: Re: Issues on Dynamic Extent for CALL-NEXT-METHOD    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 21 Sep 87
 11:09 PDT
To: RPG@SAIL.STANFORD.EDU
cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870921-120022-10688@Xerox>

I agree with Dick's summary of the argument we had.  I also think the
dominating argument is:
    Argument 9 (summary), in favor of indefinite extent.

    Let's make the whole thing simpler by not instituting this
    funny dynamic extent constraint that no real programmers understand
    anyway.

  danny

∂21-Sep-87  1246	Masinter.pa@Xerox.COM 	Re: fixing our problems with setf    
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Sep 87  12:46:13 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 87 12:38:36 PDT
Date: 21 Sep 87 12:38 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: fixing our problems with setf
In-reply-to: Danny Bobrow <Bobrow.pa>'s message of 21 Sep 87 09:10 PDT
To: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870921-123836-10807@Xerox>

I urge you to lead the cleanup committee rather than follow it in this
area, i.e., go ahead with your proposal of how SETF within CLOS ought to
work, and we can construct a cleanup for the rest of CL as well.

You can annotate the section with a footnote to the effect that the
reasonable of this section is conditional on a concurrent change to the
general way in which CL handles SETF, which is in preparation.

I'm afraid of a deadlock situation, where CLOS and CL-Cleanup are
waiting for each other; I don't think it will do anyone any good.

I don't see any harm in your assuming some changes to the rest of CL to
accomodate CLOS when the reasons are justified -- as I think they are in
this case.

∂21-Sep-87  1312	Gregor.pa@Xerox.COM 	Re: fixing our problems with setf 
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Sep 87  13:12:48 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 87 13:13:16 PDT
Date: 21 Sep 87 13:13 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: fixing our problems with setf
In-reply-to: Masinter.pa's message of 21 Sep 87 12:38 PDT
To: Masinter.pa@Xerox.COM
cc: Common-Lisp-Object-System@Sail.Stanford.edu
Message-ID: <870921-131316-10876@Xerox>

My proposal for how to cleanup setf in common lisp is compatible with
the suggestion I am making for CLOS.

I will try to send a 'test balloon' message to the cleanup committee
about this soon.

∂21-Sep-87  1334	Moon@STONY-BROOK.SCRC.Symbolics.COM 	fixing our problems with setf    
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 21 Sep 87  13:34:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 237933; Mon 21-Sep-87 16:35:56 EDT
Date: Mon, 21 Sep 87 16:35 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: fixing our problems with setf
To: Common-Lisp-Object-System@Sail.Stanford.edu
In-Reply-To: <870920-190342-9834@Xerox>
Message-ID: <870921163510.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 20 Sep 87 19:03 PDT
    From: Gregor.pa@Xerox.COM

    Unless we can get setf 'fixed' in the entire language, I propose that we
    solve our problems with setf by eliminating all the setf features from
    CLOS (except automatically generated writer methods).  That means get
    rid of the ability to say (setf <foo>) to defmethod, symbol-function,
    generic-function-labels, generic-flet and the others.

I'd hate to see unmotivated (from the user point of view) incompatibility
between automatically generated writer methods and methods the user could
write herself.  That just makes the language seem more complicated.

    My belief is that we are geting into trouble because we are confusing
    (generic) function naming with defining setf macros.  This gets us
    screwed because setf is a macro in yet another namespace and doesn't
    interact real well with our stuff.

I think this is a fair summary of the problem.  I also don't think
fixing setf in the entire language is difficult.  The following example
is taken directly from a Symbolics Common Lisp Listener:

(defun testcase (x) (cadr x))
TESTCASE
(defun (setf testcase) (x new-value) (setf (cadr x) new-value))
(SETF TESTCASE)
(mexp)
Type End to stop expanding forms

Macro form → (setf (testcase list) 105) → 
(FUNCALL #'(SETF TESTCASE) LIST 105)

Macro form → 
NIL
(setq list '(1 2 3))
(1 2 3)
(testcase list)
2
(setf (testcase list) 5)
5
list 
(1 5 3)

The basic idea that is going on here is that the mere existence of a function
named (setf foo) is sufficient to tell setf all it needs to know about foo.
In the meeting last week, we were talking about defining this function and
calling defsetf as two separate acts, and I think that may be where the
trouble arose.  If we simply say that setf is extended with this new mechanism
for setf-functions, which is in addition to the setf-macros defined by
defsetf and define-setf-method, then everything should work.  The only
complexity is defining what happens if someone is unfortunate enough to
try to define both a setf-function and a setf-macro for the same function.

The problem here is that this once again raises the spectre of function-specs.
Perhaps we should just press forward with the assumption that everyone who
hated function-specs in the past has forgotten about that.

Gregor: Perhaps you can use this as raw material for a cleanup proposal?
Do you need any help on that?

∂21-Sep-87  1555	Gregor.pa@Xerox.COM 	Re: New Trivial Issue: Implicit Blocks in Methods     
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Sep 87  15:55:18 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 87 15:55:19 PDT
Date: 21 Sep 87 15:55 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: New Trivial Issue: Implicit Blocks in Methods    
In-reply-to: Danny Bobrow <Bobrow.pa>'s message of 21 Sep 87 11:57 PDT
To: Bobrow.pa@Xerox.COM
cc: RPG@SAIL.STANFORD.EDU, common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870921-155519-11188@Xerox>

An implicit block around the body of the method is what PCL does now.  I
believe this is what we should do in CLOS.  This should go in the
section which describes the defmethod macro.

∂21-Sep-87  1611	@RELAY.CS.NET:DUSSUD%Jenner@TI-CSL.CSNET 	Re: New Trivial Issue: Implicit Blocks in Methods    
Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 21 Sep 87  16:11:36 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa21445; 21 Sep 87 18:01 EDT
Received: from ti-csl by RELAY.CS.NET id ah22745; 21 Sep 87 17:46 EDT
Received: from Jenner by tilde id AA20307; Mon, 21 Sep 87 16:06:51 CDT
Message-Id: <2768245790-4638470@Jenner>
Date: Mon, 21 Sep 87  16:09:50 CDT
From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
To: common-lisp-object-system@SAIL.STANFORD.EDU
Subject: Re: New Trivial Issue: Implicit Blocks in Methods    
In-Reply-To: Msg of 21 Sep 87  1121 PDT from Dick Gabriel <RPG@sail.stanford.edu>

     Date: 21 Sep 87  1121 PDT
     From: Dick Gabriel <RPG@sail.stanford.edu>
     Subject: New Trivial Issue: Implicit Blocks in Methods    
     
     
     Common Lisp defines DEFUN to put an implicit block around the
     body of the function.
     
     (defun foo (...) <body>) => (defun foo (...)(block foo <body>))
     
     Does DEFMETHOD do the same thing?
     
     (defmethod foo (...) <body>) => (defmethod foo (...)(block foo <body>))?
     
     Suppose there is a generic function named FOO with some methods.
     If there is an implicit block named FOO, then the form
     
     	(return-from foo <value>)
     
     will return from the method. If the invocation of the method was
     from CALL-NEXT-METHOD, control returns to the point-of-call.
     
     Suppose we really wanted to return from the generic function FOO?
     The only way would be to put a CATCH around the invocation of it,
     and therefore a programmer could not exit a generic function from within
     a method.
     
     Alternative 1. DEFMETHOD includes an implicit block of the same name as
     the method, and the programmer cannot exit a generic function summarily.

It sounds like a good idea.
     
     Alternative 2. Generic functions have an implicit block if the same name
     around them, and the programmer has to explicitly include a block
     name in his DEFMETHOD if that's what he wants.

This would mean that violate the scoping rule of a block name (it is
lexical).
     
     Alternative 3. Invent some new way of exiting.
     E.g.  ...(return-from-generic-function ...)...
I think that this feature won't be used enough to justify the trouble.
People will program it using catch and throw.


Patrick.

∂21-Sep-87  1615	Masinter.pa@Xerox.COM 	Re: Issues on Dynamic Extent for CALL-NEXT-METHOD        
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 21 Sep 87  16:15:47 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 21 SEP 87 16:10:30 PDT
Date: 21 Sep 87 16:10 PDT
From: Masinter.pa@Xerox.COM
Subject: Re: Issues on Dynamic Extent for CALL-NEXT-METHOD    
In-reply-to: Dick Gabriel <RPG@SAIL.STANFORD.EDU>'s message of 21 Sep 87
 11:09 PDT
To: RPG@SAIL.STANFORD.EDU
cc: Common-lisp-object-system@SAIL.STANFORD.EDU
Message-ID: <870921-161030-11218@Xerox>

I prefer dynamic extent.

a) I can easily imagine implementations of CLOS where there is a
performance pena