Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Aug 88 13:29:19 EDT Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 11 Aug 88 10:21:25 PDT Received: by decwrl.dec.com (5.54.5/4.7.34) id AA08505; Thu, 11 Aug 88 10:20:18 PDT Date: Thu, 11 Aug 88 10:20:18 PDT Message-Id: <8808111720.AA08505@decwrl.dec.com> From: piazza%lisp.DEC@decwrl.dec.com (Jeffrey Piazza) To: kempf@sun.com Subject: Re: declare in with-slots From: DECWRL::"kempf@Sun.COM" "11-Aug-88 0806 PDT" 11-AUG-1988 11:09:28.36 >Just because the expansion is relatively simple doesn't, of course, mean that >it's really the "right" thing to do. Are we talking religion or engineering? If the former, then count me in as a lang-nostic. :-) Sometimes it's hard to tell the difference. Seriously, there is rarely ever a single "right" way to engineer anything. There are usually pros and cons on both sides. The "pro" of this solution is that it is simple, the "con" is that it treats type declarations for pseudo variables differently from those for lexical variables or other declarations. I tend to believe that in engineering as elsewhere, "separate but equal" facilities are never really "equal". Declarations are ultimately handled by the interpreter/compiler (even if you change a "declare" into a "the"), and I anticipate lossage if macros try to intercept them beforehand. I'm just not confident that declarations are understood well enough for this to be well-behaved. >What if I, a random user, wish to write e.g. my own "with-file-attributes" >macro, that lets me access things like the read and write dates for a file as >symbol-macrolet "variables". Not being an implementor, I don't have access to >the system declaration-parsing stuff, so I can't support declarations in the >way you're proposing for with-slots and with-accessors. I cry "no fair". This is a valid point, but I wonder if it isn't in the same category as generalized code walkers. When I write a generalized code walker, I expect this level of hair, while with-file-attributes seems like it should be simple to write. >I am aware of no other macro which has to parse declarations -- they just get >pushed off to some special form or other. I think that, for what you're >trying to do, you have to make symbol-macrolet be a special form, and do >declaration processing there. Two points here. First, though I've got no objection either way on making symbol-macrolet be a special form, the goal of Common Lisp was (and I think still is) to limit the number of special forms. Well, we could give up, say, GO, and that would make for fewer special forms :-). I think that "pseudovariables" represent a real change in the language semantics, and require a special form. (As you probably know, my personal preference would be to remove symbol-macrolet altogether, rather than introduce a new special form. But if you keep the feature, I think you have to pay the price of a special form to realize it.) Second, I think it would be a mistake to confuse general declaration parsing with parsing of declarations for pseudovariables. Symbol-macrolet will have to do declaration parsing for pseudovariable declarations in any event. If symbol-macrolet were a special form, it would be the interpreter/ compiler that parsed out the declarations, just as it does for real variables. I think it would be a mistake NOT to unify declarations for pseudovariables with declarations for real variables. While there are no macros which currently do declaration parsing, there are plenty which do parsing (like defstruct). Defstruct gets to define the syntax it's parsing, which makes it altogether different. We're talking about having with-slots "skim" some declaration text, extract the bits it thinks it's interested in, and then put back what's left, so the interpreter or compiler can see it. As a point of reference, HP Lisp had a special form called let-pseudo whose semantics were identical to symbol-macrolet, and were used for a similar purpose, namely to provide lexical scopes in which slot names could be used as pseudovariables for slot access. Type declarations included in the class definition were included in the substitution form for the pseudovariable. I don't recall if declarations for pseudovariables were parsed (perhaps someone still having access to HP Lisp could check), but I wouldn't be suprised if they were. If let-pseudo is really symbol-macrolet in disguise, then it's not exactly independent evidence. Also, if let-pseudo is/was a special form, then it doesn't really apply to the question of macros that parse declarations. You can put all kinds of declarations in a special form; it won't make me unhappy. /JEP  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Aug 88 11:17:56 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 11 Aug 88 08:10:33 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA24336; Thu, 11 Aug 88 08:07:26 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-4.0) id AA02372; Thu, 11 Aug 88 08:07:44 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA11766; Thu, 11 Aug 88 08:06:24 PDT Message-Id: <8808111506.AA11766@suntana.sun.com> To: piazza%lisp.DEC@decwrl.dec.com (Jeffrey Piazza) Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: declare in with-slots In-Reply-To: Your message of Wed, 10 Aug 88 09:50:50 -0700. <8808101650.AA24519@decwrl.dec.com> Date: Thu, 11 Aug 88 08:06:21 -0700 From: kempf@Sun.COM >Just because the expansion is relatively simple doesn't, of course, mean that >it's really the "right" thing to do. Are we talking religion or engineering? If the former, then count me in as a lang-nostic. :-) Seriously, there is rarely ever a single "right" way to engineer anything. There are usually pros and cons on both sides. The "pro" of this solution is that it is simple, the "con" is that it treats type declarations for pseudo variables differently from those for lexical variables or other declarations. >What if I, a random user, wish to write e.g. my own "with-file-attributes" >macro, that lets me access things like the read and write dates for a file as >symbol-macrolet "variables". Not being an implementor, I don't have access to >the system declaration-parsing stuff, so I can't support declarations in the >way you're proposing for with-slots and with-accessors. I cry "no fair". This is a valid point, but I wonder if it isn't in the same category as generalized code walkers. >I am aware of no other macro which has to parse declarations -- they just get >pushed off to some special form or other. I think that, for what you're >trying to do, you have to make symbol-macrolet be a special form, and do >declaration processing there. Two points here. First, though I've got no objection either way on making symbol-macrolet be a special form, the goal of Common Lisp was (and I think still is) to limit the number of special forms. Second, I think it would be a mistake to confuse general declaration parsing with parsing of declarations for pseudovariables. Symbol-macrolet will have to do declaration parsing for pseudovariable declarations in any event. While there are no macros which currently do declaration parsing, there are plenty which do parsing (like defstruct). As a point of reference, HP Lisp had a special form called let-pseudo whose semantics were identical to symbol-macrolet, and were used for a similar purpose, namely to provide lexical scopes in which slot names could be used as pseudovariables for slot access. Type declarations included in the class definition were included in the substitution form for the pseudovariable. I don't recall if declarations for pseudovariables were parsed (perhaps someone still having access to HP Lisp could check), but I wouldn't be suprised if they were. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Aug 88 13:01:59 EDT Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 10 Aug 88 09:51:58 PDT Received: by decwrl.dec.com (5.54.5/4.7.34) id AA24519; Wed, 10 Aug 88 09:50:50 PDT Date: Wed, 10 Aug 88 09:50:50 PDT Message-Id: <8808101650.AA24519@decwrl.dec.com> From: piazza%lisp.DEC@decwrl.dec.com (Jeffrey Piazza) To: Gregor.pa@xerox.com Subject: Re: declare in with-slots From: DECWRL::"Gregor.pa@Xerox.COM" "8-Aug-88 1018 PDT" 8-AUG-1988 To: Jeffrey Piazza , Glenn Andrew Kramer (declare (t-terminated-list y)) ...) This declaration is clearly illegal according to CLtL. That's why I said "extension". Page 158, paragraph 4 says: ( ...) is an abbreciation for (TYPE ...) provided is one of the types appearing in Table 4-1. The reason this extension is a bad idea transcends with-slots and friends of course. No portable program analyzing program can analyze code that uses this extension. I believe that's false. A portable PAP can't use the declaration information, that's all. Of course, that might be a big lose, but declarations (except SPECIAL) aren't supposed to affect semantics. It would depend on what your PAP was trying to find out. But, if a given implementation does in fact make this extension, it could just smarten up its with-slots (or symbol-macrolet) implementation to understand this case. That's true. I was thinking in terms of a portable implementation, which would be impossible. While you're thinking about this, consider what would happen if Common Lisp were extended to allow: (with-slots (x y z) ... (locally (declare (fixnum y)) ...) ...) [CL doesn't currently allow this, but there's some sentiment to make this extension.] Now with-slots would have to parse the entire body to get this right. As would a large number of other forms that could be affected by this change. Putting the declare mechanism inside of symbol-macrolet, might be percieved to "solve" this problem. It seems to me that the real problem with this case would be profusion of declaration hair though. What's the point of symbol-macrolet, then, if not to be the form which says "pretend foo is a variable, even though it's not"? You're suggesting that only with-slots wants to play "let's pretend," and that there's some different roles that symbol-macrolet fills? I doubt it... This code from Jim Kempf shows how I was intending to have with-slots expand, and shows clearly why I didn't think symbol-macrolet was the place to support this. Just because the expansion is relatively simple doesn't, of course, mean that it's really the "right" thing to do. What if I, a random user, wish to write e.g. my own "with-file-attributes" macro, that lets me access things like the read and write dates for a file as symbol-macrolet "variables". Not being an implementor, I don't have access to the system declaration-parsing stuff, so I can't support declarations in the way you're proposing for with-slots and with-accessors. I cry "no fair". I am aware of no other macro which has to parse declarations -- they just get pushed off to some special form or other. I think that, for what you're trying to do, you have to make symbol-macrolet be a special form, and do declaration processing there. /JEP PS on a slight tangent: What's the meaning of: (with-slots (x y z) ... (locally (declare (special y)) ...y...) ...) Is the y inside the locally the special variable or the slot? I believe the current definition would make it the slot. I also believe that's anomolous.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Aug 88 13:27:22 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Aug 88 10:20:22 PDT Received: from Semillon.ms by ArpaGateway.ms ; 08 AUG 88 10:19:22 PDT Date: Mon, 8 Aug 88 10:18 PDT From: Gregor.pa@Xerox.COM Subject: Re: declare in with-slots To: Jeffrey Piazza , Glenn Andrew Kramer , kempf@Sun.COM, David N Gray cc: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <19880802205147.3.GREGOR@PORTNOY.parc.xerox.com>, <8808031410.AA03551@decwrl.dec.com>, , <8808041525.AA20536@suntana.sun.com>, <2795711083-4281424@Kelvin> Message-ID: <19880808171852.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 3 Aug 88 07:10:42 PDT From: piazza%lisp.DEC@decwrl.dec.com (Jeffrey Piazza) As to the suggested patch: No, it won't really work. Declare's are pretty much the province of special forms, and with-slots et al won't, in general, be able to parse the declare's, let alone interpret them correctly. For example, a common extension to declare allows: (deftype t-terminated-list () '(or cons (member t))) (with-slots (x y z) (declare (t-terminated-list y)) ...) This declaration is clearly illegal according to CLtL. Page 158, paragraph 4 says: ( ...) is an abbreciation for (TYPE ...) provided is one of the types appearing in Table 4-1. The reason this extension is a bad idea transcends with-slots and friends of course. No portable program analyzing program can analyze code that uses this extension. But, if a given implementation does in fact make this extension, it could just smarten up its with-slots (or symbol-macrolet) implementation to understand this case. While you're thinking about this, consider what would happen if Common Lisp were extended to allow: (with-slots (x y z) ... (locally (declare (fixnum y)) ...) ...) [CL doesn't currently allow this, but there's some sentiment to make this extension.] Now with-slots would have to parse the entire body to get this right. As would a large number of other forms that could be affected by this change. Putting the declare mechanism inside of symbol-macrolet, might be percieved to "solve" this problem. It seems to me that the real problem with this case would be profusion of declaration hair though. What's the point of symbol-macrolet, then, if not to be the form which says "pretend foo is a variable, even though it's not"? You're suggesting that only with-slots wants to play "let's pretend," and that there's some different roles that symbol-macrolet fills? I doubt it... This code from Jim Kempf shows how I was intending to have with-slots expand, and shows clearly why I didn't think symbol-macrolet was the place to support this. Of course it is just as easy to put this in symbol-macrolet as far as I am concerned. The expansion of with-slots would be something like: (symbol-macrolet ( (x (the fixnum (slot-value 'x obj))) (y (the fixnum (slot-value 'y obj))) (z (the fixnum (slot-value 'z obj))) ) (locally ... ) -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Aug 88 21:38:49 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 5 Aug 88 18:33:11 PDT Received: from Semillon.ms by ArpaGateway.ms ; 05 AUG 88 18:23:27 PDT Date: Fri, 5 Aug 88 18:21 PDT From: Gregor.pa@Xerox.COM Subject: Re: description language classes & the Meta-Object Protocol To: John Rose cc: common-lisp-object-system@sail.stanford.edu, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8808051925.AA05986@lukasiewicz.sun.com> Message-ID: <19880806012130.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 5 Aug 88 12:25:14 PDT From: jrose@Sun.COM (John Rose) I'm going to describe a way I'd like to use the Meta-Object Protocol. Hopefully, readers of this list will either tell me why it's a misuse, or assure me that the Meta-Object Protocol will support what I have in mind. Danny and I spent some time talking about this, and I plan to send a message about this next week once I finish the current round of hacking. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 5 Aug 88 19:10:59 EDT Received: from Riesling.ms by ArpaGateway.ms ; 05 AUG 88 15:46:52 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 05 AUG 88 15:45:04 PDT Received: by ti.com id AA20934; Fri, 5 Aug 88 17:35:57 CDT Received: from SI by tilde id AA05139; Fri, 5 Aug 88 17:18:27 CDT Message-Id: <2795811648-642518@SI> Sender: OREN@SI.csc.ti.com Date: Fri, 5 Aug 88 17:20:48 CDT From: LaMott Oren To: CommonLoops.pa@Xerox.COM Subject: Misc. PCL patches I don't read this mailing list (yet), so forgive me if any of these have been discussed before. I'm working with *pcl-system-date* "7/7/88 (beta) July 7th PCL" and made the following patches: ;;; Reason: Common-lisp allows macros to define declarations. ;;; Patch PCL to allow this also. ; From the MACROS file (defun extract-declarations (body &optional environment) (declare (values documentation declarations body)) (let (documentation declarations form) (when (and (stringp (car body)) (cdr body)) (setq documentation (pop body))) (loop (when (null body) (return)) (setq form (car body)) (cond ((and (listp form) (eq (car (SETQ form (macroexpand form environment))) 'declare)) (pop body) (dolist (declaration (cdr form)) (push declaration declarations))) (t (return)))) (values documentation (and declarations `((declare ,.declarations))) body))) ;;; Reason: Explorer DEFSTRUCT has a bug where an inefficient predicate ;;; gets generated the first time its compiled. Redefine ;;; IWMC-CLASS-P with an efficient definition. (This makes some ;;; PCL applications run TWICE as fast) ;; In the TI-LOW file (proclaim '(inline IWMC-CLASS-P)) (defun IWMC-CLASS-P (thing) (typep thing 'iwmc-class)) ;;; Reason: slotd-name is used a LOT, and is only 2 instructions long (2 aref's) ;;; Unfortunately, slotd-name isn't defined until after its used, so ;;; this won't help unless PCL is compiled twice... (at least the SLOTS file) (proclaim '(inline slotd-name)) ;;; Reason: Optimize initialize-instance for the common case ;;; where there are less than two slot-initargs. ;;; This is not as effective as it could be, because slot-initargs ;;; sometimes contains a list with duplicate entries, for example: ;;; ;;; (defclass foo1 () ;;; ((slot :initform nil :initarg :slot))) ;;; ;;; (defclass foo2 (foo1) ;;; ((slot :initform nil :initarg :slot))) ;;; ;;; The slotd for slot in foo2 will be (:slot :slot) ;;; (Somebody please fix this, I don't know where to look...) ;; from the MKI file: (defmethod initialize-instance ((object object) &rest initargs) (let* ((class (class-of object)) (slotds (class-slots class))) (dolist (slotd slotds) (let ((slot-name (slotd-name slotd)) (slot-initargs (slotd-initargs slotd))) ;; Initialize slot from initargs (when slot-initargs (if (cdr slot-initargs) ;; more than one initarg (labels ((walk-backwards (tail) (if (null tail) nil (progn (walk-backwards (cddr tail)) (let ((key (pop tail)) (val (pop tail))) (when (memq key slot-initargs) (setf (slot-value object slot-name) val))))))) (walk-backwards initargs)) ;; Optimize for the common-case of only one initarg (let* ((not-found '#.(gensym)) (val (getf initargs (car slot-initargs) not-found))) (unless (eq val not-found) (setf (slot-value object slot-name) val))))) ;; If no initarg found, try the initfunction. (unless (slot-boundp object slot-name) (let ((initfunction (slotd-initfunction slotd))) (when initfunction (setf (slot-value object slot-name) (funcall initfunction )))))))))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Aug 88 16:41:27 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 5 Aug 88 13:31:42 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA04593; Fri, 5 Aug 88 13:29:18 PDT Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-4.0) id AA09117; Fri, 5 Aug 88 13:29:59 PDT Received: by lukasiewicz.sun.com (4.0/SMI-4.0) id AA05986; Fri, 5 Aug 88 12:25:14 PDT Date: Fri, 5 Aug 88 12:25:14 PDT From: jrose@Sun.COM (John Rose) Message-Id: <8808051925.AA05986@lukasiewicz.sun.com> To: common-lisp-object-system@sail.stanford.edu Subject: description language classes & the Meta-Object Protocol [This is a message which I sent a week and a half ago to the commonloops mailing list. I have since learned that this is a more appropriate list to mail such discussions to, so I'm reposting. If you've already seen this, sorry for the redundancy. I've changed nothing in the message. -- John Original header: Date: Mon, 25 Jul 88 16:12:16 PDT To: commonloops.pa@xerox.com] I'm going to describe a way I'd like to use the Meta-Object Protocol. Hopefully, readers of this list will either tell me why it's a misuse, or assure me that the Meta-Object Protocol will support what I have in mind. Start with a description language L. That is, terms in L denote predicates over some universe U; they describe objects in U. (You could also call L a pattern language.) There is some efficient Lisp function L-APPLY which applies an L-term to a U-object and returns T or NIL, depending on whether the term describes the object. There is one other property of L: There is a Lisp function L-LESSP which takes any two L-terms t1, t2 and compares them, returning T or NIL, depending on whether t1 entails t2 for all U-objects. This is a partial order on the description language. Think of it this way: Less specific terms are greater than more specific ones. Finally, define *L-TOP* to be the L-term which is greater than all other L-terms (the least specific element). (It is possible and useful to make L into a lattice by adding Lisp functions L-MEET and L-JOIN, but I don't think that is necessary for this discussion.) I'd like to define a Meta-Class L-CLASS which models L. In particular, each L-term would correspond to an L-CLASS. An L-term's L-CLASS would have as instances all U-objects which match the L-term. Note that an L-CLASS does not necessarily support MAKE-INSTANCE: As befits a description language, the L-CLASSes merely impose structure on a pre-existing space of U-objects. Methods arguments can be specialized with L-CLASS specializers; such arguments are assumed to be U-objects, and the method is applied only to arguments that match the specializer. That is, the L-CLASS protocol wraps the method body with code which uses L-APPLY to filter out U-objects which don't match the specializer. This is just like STANDARD-CLASS dispatching, except that L-APPLY can interpret L-terms using any algorithm whatsoever. If a generic is applied to a U-object, there will in general be several methods which apply; they must be ordered most specific first. The computation of this ordering is done with the L-LESSP predicate. This works much like STANDARD-CLASS method ordering. When the specializers of applicable methods are not linearly ordered (this case corresponds to class multiple inheritance) , the L-CLASS must specify some sort of linearization, so that CALL-NEXT-METHOD will be useful. In any case, when a U-object is handed to a generic function with L-CLASS specializers, only methods with specializers that correctly describe the U-object are invoked, and then in a reasonable order determined by description specificity. You know, object oriented languages supply two very distinct services that are often confused: Representation management, and argument dispatching. Abstract types can be built from concrete representations, often drawn from a rich set of possibilities (e.g., C++). Abstract functions can be built, piece by piece, from methods, each applicable to a limited set of arguments; the OOL supplies the glue logic which makes sure that each method gets the right kinds of arguments. The distinction between the two services is based on this observation: It is not necessary that the set of representations be identical with the set of dispatchable types. (In practice, it's often useful to tightly coordinate the two services, since the OOL system can then optimize representations for fast dispatch.) Description language classes supply the argument dispatch service only. (By contrast, facilities like DEFSTRUCT construct representations without dispatch services.) For concreteness, I'll give several examples of description languages that could be usefully treated as meta-classes: * Common Lisp types The Common Lisp type system is a description language. L-APPLY is TYPEP, and L-LESSP is SUBTYPEP, although the SUBTYPEP relation is not as rich as the corresponding mathematical subtyping relation. * standard classes If you forget about slots and consing, you can treat standard classes as predicates over their objects. This example is just a special case of the previous. * object identity The EQL specializers support a trivial description language, where all classes are singletons (except *L-TOP*, which is the type T). Here, L-APPLY is only EQL (apart from *L-TOP*) and so is L-LESSP. * Lisp structure patterns Someone from the functional programming community wanted to have specializers which were structure templates. Often the pattern matching incorporates the binding of variables to matched substructures for later access. This sort of thing is extremely useful. (For example, Lisp compilers seem always to have some a destructuring case macro, with which they analyze program syntax.) Interestingly, L-LESSP is straightforward to define for destructuring patterns; it roughly consists of applying the second pattern to the first. * user-interface event patterns This is the application which I've been recently thinking about, which triggered this note. User-interface modules often want to filter the events they see to some small set of "interesting" events. This can be done with an event pattern. Suppose a key event has three attributes: 1. key making the transition, 2. type of transition (e.g., up, down, click), and 3. modifier key state. Then an event pattern would specify a value for each attribute, or specify a wildcard of some sort. Clearly this is a description language. (In fact, it is a product language, made from three languages, one for each attribute.) It is easy to define L-APPLY and L-LESSP. If a module wanted to handle a class of events, it could define a method on an appropriate generic function, specialized to the desired event pattern. The event-pattern meta-class would have the responsibility of building the glue logic to dispatch incoming events to the correct handler. It's good to centralize this logic, because it can then be optimized more readily, and redundant tests eliminated. CLOS double dispatch would help here too: Event handlers could be specialized both to consumer-object mixins and event types. * string regular expressions The theory of regular languages is well understood, and regular expressions are useful in a wide variety of settings. A regular expression meta-class could be used to define complex string handling functions in a modular fashion. Regular languages can be compared for specificity, so an L-LESSP predicate can be defined. Also, efficient methods are known for matching several regular expressions at once to a single string; the meta-class would use these methods to build efficient dispatch ("glue") logic, as in the previous example. * knowledge base queries Pick your favorite database query language. It certainly supports an L-APPLY operation, and probably also supports an L-LESSP. Now, with the right L-CLASS, you can define generic functions over database entries. (It may be more useful to manipulate __sets__ of entries, so U would then be a power set of some sort. This does not hinder the applicability of CLOS.) I hope I have shown that (1) description languages are common and useful, that (2) a general class of description languages are amenable to treatment within the CLOS generic function framework, and that (3) descriptions are very useful as defmethod specializers. The conclusion is that the designers of the Meta-Object protocol should be sure to provide for arbitrary description languages (of the L-APPLY/L-LESSP sort). Finally, here are some smaller open questions about description language classes, along with some possible answers: * How should the L-CLASS specify a linearization of a partially ordered set of applicable methods? [It is sometimes useful to signal an error if there is not a linear ordering available. This could the default, with a hook for other more permissive behavior.] * What if the L-LESSP relation is not always effectively computable? (E.g., LISP:SUBTYPEP gives up sometimes.) [Allow the L-LESSP relation to give up, and treat this outcome like incomparability. It should be possible to signal an error here, while still doing something permissive on true incomparability.] * If the L-term has "wildcards" in it, how should the L-CLASS mediate the binding of the corresponding U-object subparts to names for use in method bodies? [I believe the current protocol (e.g., DEFINE-METHOD-COMBINATION) provides enough hooks for this. The hook which asks a meta-class for dispatch code should also accept LET-bindings, which would be constructed along with the dispatch code, and wrapped around the affected method body.] * What sort of syntax should L-CLASS specializers have? [The (EQL ...) syntax should be extended, I think. The basic idea is that EQL is a meta-class name, and the arguments to it are handed to the meta-class constructor, which then builds the appropriate class object. This is probably already the intention of the CLOS designers, but I want to affirm that choice.] Let me close with a suggestive example: (DEFMETHOD EVAL ((X (FORM `(,F . ,A)))) (APPLY (EVAL `#',F) (MAPCAR #'EVAL A))) (DEFMETHOD EVAL ((X (FORM `(IF ,P ,A ,B)))) (IF (EVAL P) (EVAL A) (EVAL B))) This example uses a hypthetical description language called FORM, whose terms are backquoted constructors, interpreted in reverse. (Or, if you like, declaratively as opposed to imperatively.) Note that the specificity ordering ensures that IF forms will not get passed to the first method, even though they match its specializer. -- John  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 5 Aug 88 14:51:18 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 05 AUG 88 11:22:43 PDT Return-Path: Redistributed: CommonLoops.pa Received: from ucbarpa.Berkeley.EDU ([10.0.0.78]) by Xerox.COM ; 05 AUG 88 11:19:33 PDT Received: by ucbarpa.Berkeley.EDU (5.59/1.28) id AA07035; Fri, 5 Aug 88 11:19:00 PDT Received: from frisky by franz (3.2/3.14) id AA23433; Fri, 5 Aug 88 11:16:40 PDT Received: by frisky (3.2/3.14) id AA06992; Fri, 5 Aug 88 11:13:49 PDT From: franz!frisky!jkf@ucbarpa.Berkeley.EDU (John Foderaro) Return-Path: Message-Id: <8808051813.AA06992@frisky> To: franz!ucbarpa!Xerox.COM!Gregor.pa@ucbarpa.Berkeley.EDU Cc: franz!ucbarpa!Xerox.COM!CommonLoops.pa@ucbarpa.Berkeley.EDU, franz!tech@ucbarpa.Berkeley.EDU Subject: Re: 8/2/88 PCL and Allegro 3.0 In-Reply-To: Your message of Thu, 04 Aug 88 17:21:00 PDT. <19880805002149.9.GREGOR@PORTNOY.parc.xerox.com> Date: Fri, 05 Aug 88 11:13:46 PDT >> From: franz!ucbarpa!Xerox.COM!Gregor.pa >> Yes, this is true. Its kind of unfortunate that this doesn't work in >> ExCL since having a generic function as the method function of a method >> is perfectly legal in CLOS. When we get a chance, we should fix this. I've now fixed this locally and the resulting fin instance variable accessor code is faster than it was before, so it is a win in more ways than one. I'll run it through some tests today and then send the changes to you. -john foderaro  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 5 Aug 88 13:15:17 EDT Received: from Salvador.ms by ArpaGateway.ms ; 05 AUG 88 09:43:41 PDT Return-Path: Redistributed: CommonLoops.pa Received: from media-lab.media.mit.edu ([18.85.0.2]) by Xerox.COM ; 05 AUG 88 09:42:05 PDT Received: from waterloo.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA01484; Fri, 5 Aug 88 12:41:36 EDT Received: by waterloo (3.2/4.8) id AA01642; Tue, 5 Jul 88 12:41:28 EDT Date: Tue, 5 Jul 88 12:41:28 EDT From: Michael Sokolov Message-Id: <8807051641.AA01642@waterloo> To: CommonLoops.pa@Xerox.COM Subject: with-slots bug (still) In the 8/1 PCL, running in Lucid, the following error occurs: (defclass foo () (x y) (:accessor-prefix)) (defclass bar () (z w)) (defmethod foobar ((f foo) (b bar)) (with-slots (x y) f (setf y (+ x (w b))))) (setq f (make-instance 'foo :x 1 :y 1)) (setq b (make-instance 'bar :w 1 :z 1)) Now, (foobar f b) produces the following: OOPS> >>Error: X has no global value SYMBOL-VALUE: Required arg 0 (S): X :A Abort to Lisp Top Level :C Try evaluating X again Here is a Lucid backtrace and walk up the stack - I don't know how helpful this is, but it can't hurt to include it! Please keep me posted - Mike Sokolov -> :b SYMBOL-VALUE <- PCL::STD-INSTANCE-ACCESS-PV <- (LAMBDA (#:G20212) (DECLARE (PCL::VARIABLE-REBINDING #:G20212 F)) (PCL::STD-INSTANCE-ACCESS-PV #:G20212 (QUOTE 0) (+ X #))) <- LET <- BLOCK <- PROGN <- LET <- |(PCL::METHOD FOOBAR (FOO BAR))| <- PCL::NOTICE-M ETHODS-CHANGE-2 <- EVAL <- REPL <- EVAL <- EVAL <- unnamed function <- unnamed function -> :n PCL::STD-INSTANCE-ACCESS-PV: Original code: (PCL::STD-INSTANCE-ACCESS-PV #:G20212 (QUOTE 0) (+ X (W B))) Local 0 (G20212): # -> :n (LAMBDA (#:G20212) (DECLARE (PCL::VARIABLE-REBINDING #:G20212 F)) (PCL::STD-INSTANCE-ACCESS-PV #:G20212 (QUOTE 0) (+ X #))): Original code: ((LAMBDA (#:G20212) (DECLARE #) (PCL::STD-INSTANCE-ACCESS-PV #:G20212 # #)) F) Local 0 (G20212): # -> :n LET: Original code: (LET ((#:G20212 F)) (DECLARE (PCL::VARIABLE-REBINDING #:G20212 F)) (PCL::STD-INSTANCE-ACCESS-PV #:G20212 (QUOTE 0) (+ X #))) -> :n BLOCK: Original code: (BLOCK FOOBAR (LET (#) (DECLARE #) (PCL::STD-INSTANCE-ACCESS-PV #:G20212 # #))) -> :n PROGN: Original code: (PROGN (SETQ PCL::.PV. (LET* # #)) (PROGN F B) (BLOCK FOOBAR (LET # # #))) -> :n LET: Original code: (LET ((PCL::.ISL. #) (PCL::.PV. NIL)) (SETQ PCL::.PV. (LET* # #)) (PROGN F B) (BLOCK FOOBAR (LET # # #))) Local 0 (.ISL.): (# (Y) NIL) Local 1 (.PV.): # -> :n |(PCL::METHOD FOOBAR (FOO BAR))|: Original code: (NAMED-LAMBDA |(PCL::METHOD FOOBAR (FOO BAR))| (F B) (DECLARE (PCL::CLASS B BAR) (PCL::CLASS F FOO)) (LET (# #) (SETQ PCL::.PV. #) (PROGN F B) (BLOCK FOOBAR #))) Local 0 (F): # Local 1 (B): # -> :n PCL::NOTICE-METHODS-CHANGE-2: Required arg 0 (GENERIC-FUNCTION): # Required arg 1 (ARGS): (# #) -> :n EVAL: Required arg 0 (X): (FOOBAR F B) ->  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 5 Aug 88 11:28:15 EDT Received: from Riesling.ms by ArpaGateway.ms ; 05 AUG 88 07:58:21 PDT Return-Path: Redistributed: CommonLoops.pa Received: from siemens.siemens.com ([129.73.7.1]) by Xerox.COM ; 05 AUG 88 07:57:09 PDT Received: by siemens.siemens.com (5.54/1.15) id AA16635; Fri, 5 Aug 88 10:52:44 EDT From: msch@ztivax.siemens.com (M. Schneider-Hufschmidt) Date: Fri, 5 Aug 88 16:55:50 -0200 Message-Id: <8808051455.AA22830@ztivax.uucp> Received: by ztivax.uucp; Fri, 5 Aug 88 16:55:50 -0200 To: CommonLoops.pa@Xerox.COM, gregor.pa@Xerox.COM Subject: Version of 2 August 88 There are apparently two small bugs in this version. 1. Since compat.lisp is no longer in pcl you should take it out of the system-definition. 2. Under Xerox-Lyric the fix-early-generic-functions in fixup.lisp tries to aref on a ptr-hunk. The bug seems to be inserted by the change of reader/writer-method-slot-name in methods.lisp. Taking the change back caused pcl to compile and load nicely. However, I can't tell for sure that everything works correct like this. ;;;; from defsys.lisp (defsystem pcl *pcl-directory* ;; file load compile files which port ;; environment environment force the of ;; recompilation ;; of this file ((rel-6-patches t t () rel-6) ;; ... (dcode-pre1 t t (defs low fin dcode)) (fixup t t (boot defs low fin)) (high t t (boot defs low fin)) ; (compat t t ()) compat is gone! (7debug t t () rel-7) )) ;;;; from methods.lisp: (defmethod reader/writer-method-slot-name ((m standard-reader/writer-method)) #+:Xerox-Lyric (slot-value--class m 'slot-name) #-:Xerox-Lyric (slot-value m 'slot-name)) Matthias  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 4 Aug 88 20:51:22 EDT Received: from Semillon.ms by ArpaGateway.ms ; 04 AUG 88 17:24:43 PDT Date: Thu, 4 Aug 88 17:21 PDT From: Gregor.pa@Xerox.COM Subject: Re: 8/2/88 PCL and Allegro 3.0 To: John Foderaro cc: Rob Pettengill , franz!sw.MCC.COM!ext-bug-franz@ucbarpa.Berkeley.EDU, franz!xerox.com!gregor.pa@ucbarpa.Berkeley.EDU, franz!tech@ucbarpa.Berkeley.EDU, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8808042133.AA05261@frisky> Message-ID: <19880805002149.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Thu, 04 Aug 88 14:33:18 PDT From: franz!frisky!jkf@ucbarpa.Berkeley.EDU (John Foderaro) The problem with 8/2/88 pcl is that (make-specializable 'describe) is being eval'ed twice: once when compiling high.cl and once when loading high.cl Yes, this is true. Its kind of unfortunate that this doesn't work in ExCL since having a generic function as the method function of a method is perfectly legal in CLOS. When we get a chance, we should fix this. But, it doesn't make sense for make-specializable to make the same thing specializable twice. I have modified make-specializable to not touch the function if it is already generic. I changed the version that is already on arisia, and have included a patch in this message. Anyone running 8/2/88 should make this change. ;from methods.lisp (defun make-specializable (function-name &key (arglist nil arglistp)) (cond ((not (null arglistp))) ((not (fboundp function-name))) ((fboundp 'function-arglist) ;; function-arglist exists, get the arglist from it. (setq arglist (function-arglist function-name))) (t (error "The :arglist argument to make-specializable was not supplied~%~ and there is no version of FUNCTION-ARGLIST defined for this~%~ port of Portable CommonLoops.~%~ You must either define a version of FUNCTION-ARGLIST (which~%~ should be easy), and send it off to the Portable CommonLoops~%~ people or you should call make-specializable again with the~%~ :arglist keyword to specify the arglist."))) (let ((original (and (fboundp function-name) (symbol-function function-name))) (generic-function (make-instance 'standard-generic-function :name function-name)) (nrequireds 0)) (if (generic-function-p original) original (progn (dolist (arg arglist) (if (memq arg lambda-list-keywords) (return) (incf nrequireds))) (setf (symbol-function function-name) generic-function) (when arglistp (setf (generic-function-pretty-arglist generic-function) arglist)) (when original (add-named-method function-name () (make-list nrequireds :initial-element 't) arglist original)) generic-function)))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 4 Aug 88 16:32:36 EDT Received: from Burger.ms by ArpaGateway.ms ; 04 AUG 88 13:04:09 PDT Return-Path: Redistributed: commonloops.pa Received: from mitre-bedford.ARPA ([26.3.0.66]) by Xerox.COM ; 04 AUG 88 13:02:02 PDT Posted-From: The MITRE Corp., Bedford, MA Received: from localhost by linus.MENET (3.2/4.7) id AA06543; Thu, 4 Aug 88 15:58:57 EDT Posted-Date: Thu, 04 Aug 88 15:58:55 EDT Message-Id: <8808041958.AA06543@linus.MENET> To: CommonLoops.pa@Xerox.COM Subject: Bug in walker under KCL Date: Thu, 04 Aug 88 15:58:55 EDT From: pc%linus@mitre-bedford.ARPA There's a slight bug in the walker under KCL (so locally defined functions are ignored). The definition of with-augmented-environment-internal in walk.lsp should be: (defun with-augmented-environment-internal (env functions macros) (unless env (setq env (list nil nil nil))) (dolist (f functions) (push `(,(car f) . (function . (,#'unbound-lexical-function . nil))) (second env))) (dolist (m macros) (push `(,(car m) . (macro . ( ,(cadr m) . nil))) (second env))) By the way, macroexpand-1 in KCL ignores the environment argument. This has been more-or-less fixed in AKCL (version 1.50), Bill Schelter's "Altered KCL". - Penny  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Aug 88 14:40:06 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 4 Aug 88 11:34:31 PDT Received: by ti.com id AA10039; Thu, 4 Aug 88 13:33:30 CDT Received: from Kelvin by tilde id AA02949; Thu, 4 Aug 88 13:23:04 CDT Message-Id: <2795711083-4281424@Kelvin> Sender: GRAY@Kelvin.csc.ti.com Date: Thu, 4 Aug 88 13:24:43 CDT From: David N Gray To: kempf@Sun.COM Cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU Subject: Re: declare in with-slots In-Reply-To: Msg of Thu, 04 Aug 88 08:25:30 -0700 from kempf@Sun.COM > though, as Glenn Kramer has pointed out, the declaration is actually > redundent because the types can be deduced from the class definition. That assumes that you know the class of the object expression; the compiler might know, but a macro would not. The type lookup could be done at either the WITH-SLOTS or SYMBOL-MACROLET level, but whichever one does it would have to be a special form. -- David Gray  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 4 Aug 88 13:50:27 EDT Received: from Semillon.ms by ArpaGateway.ms ; 04 AUG 88 10:30:38 PDT Date: Thu, 4 Aug 88 10:28 PDT From: Gregor.pa@Xerox.COM Subject: Re: 8-1 pcl fails to compile in Coral 1.2.1 To: rabin.pa@Xerox.COM cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: The message of 3 Aug 88 14:18 PDT from rabin.pa Message-ID: <19880804172806.2.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: 3 Aug 88 14:18 PDT From: rabin.pa 8-1 pcl fails to compile in Coral 1.2.1 Late in the compilation, while attempting to execute MAKE-SPECIALIZABLE on DESCRIBE, the compiler breaks ... This problem is fixed in the 8/2/88 version of PCL. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 4 Aug 88 11:36:11 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 4 Aug 88 08:28:30 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA12267; Thu, 4 Aug 88 08:25:58 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-4.0) id AA27693; Thu, 4 Aug 88 08:26:39 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA20536; Thu, 4 Aug 88 08:25:33 PDT Message-Id: <8808041525.AA20536@suntana.sun.com> To: David N Gray Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: declare in with-slots In-Reply-To: Your message of Wed, 03 Aug 88 16:49:27 -0500. <2795636967-5097451@Kelvin> Date: Thu, 04 Aug 88 08:25:30 -0700 From: kempf@Sun.COM >The correct syntax is: > > (multiple-value-bind (x y z) > (multiple-return-value-function a b c) > (declare (fixnum x y z)) > > ... > ) OK, so how about: (with-slots (x y z) obj (declare (fixnum x y z)) ... ) though, as Glenn Kramer has pointed out, the declaration is actually redundent because the types can be deduced from the class definition. Other declarations, like compilation optimization and special declarations, cannot, however. There is a question of whether those should be allowed. The expansion of with-slots would be something like: (symbol-macrolet ( (x (the fixnum (slot-value 'x obj))) (y (the fixnum (slot-value 'y obj))) (z (the fixnum (slot-value 'z obj))) ) (locally ... ) ) so the expansion would, indeed, have to check for type declarations on the pseudovariables. symbol-macrolet does not, however. If type declarations are allowed, then the question of what to do should a conflict between the declaration of types in the class and the local declaration occurs. There are a number of options here, everything from leaving it up to the implementation to decide to checking if the local declaration is wider than the declaration in the class (e.g. a local declaration of number when the class declared the slot to be fixnum) and signalling an error. Having a narrower declaration (e.g. a local declaration of fixnum when the class declared the slot to be number) could have important uses in some cases. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 19:57:52 EDT Received: from Semillon.ms by ArpaGateway.ms ; 03 AUG 88 16:38:39 PDT Date: Wed, 3 Aug 88 16:36 PDT From: Gregor.pa@Xerox.COM Subject: new version of PCL To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest Message-ID: <19880803233622.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There is a new version of PCL in the /pcl on arisia.xerox.com. You can use anonymous FTP to retrieve it. (arisia's address is 13.1.100.206) The major difference in this version of PCL is that it runs in KCL (and IBCL). Another major difference is that class and method definition should be much faster. Bugs which causes large amounts of needless computation when classes and methods were defined have been fixed. Thanks to Ken Anderson, and John Dawes for pointing this out. See the notes.text file for more details. See the get-pcl.text file for more information about the contents of the /pcl directory. Sorry about the short time between yesterday's release and todays. I felt the new changes were worth releasing right away. As usual, use, enjoy and send bug reports. Gregor -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Aug 88 18:43:44 EDT Received: from SPAR-20.SPAR.SLB.COM by SAIL.Stanford.EDU with TCP; 3 Aug 88 15:37:54 PDT Date: Wed, 3 Aug 1988 15:37 PDT Message-ID: From: Glenn Andrew Kramer To: Gregor.pa@XEROX.COM Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: declare in with-slots In-reply-to: Msg of 2 Aug 1988 13:51-PDT from Gregor.pa at Xerox.COM One other point to be made with respect to declarations and with-slots is that the types of the slots may already be declared in the class definition. If a slot is declared to be fixnum in the defclass, then it should automatically be treated as such in the body of a with-slots, without having to place another explicit declaration.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Aug 88 18:10:36 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 3 Aug 88 15:04:50 PDT Received: by ti.com id AA02329; Wed, 3 Aug 88 17:03:57 CDT Received: from Kelvin by tilde id AA08593; Wed, 3 Aug 88 16:48:23 CDT Message-Id: <2795636967-5097451@Kelvin> Sender: GRAY@Kelvin.csc.ti.com Date: Wed, 3 Aug 88 16:49:27 CDT From: David N Gray To: kempf@SUN.COM Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: declare in with-slots In-Reply-To: Msg of Wed, 03 Aug 88 11:47:10 -0700 from kempf@SUN.COM > I'm not sure I understand what all the fuss is about. Currently in > Common Lisp, the following is not allowed; > > (multiple-value-bind (x y z) > (declare (fixnum x y z)) > (multiple-return-value-function a b c) > > ... > ) The correct syntax is: (multiple-value-bind (x y z) (multiple-return-value-function a b c) (declare (fixnum x y z)) ... ) > It would, of course, be nice to be able to do the above, just as it > would for with-slots, but the following also works in at least one > CL I've used: > > (multiple-value-bind (x y z) > (multiple-return-value-function a b c) > > (locally > (declare (fixnum x y z)) > > ... > ) > ) It may be allowed, but it doesn't seem very useful because it doesn't change the fact that tagged value slots have to be used. -- David Gray  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 18:08:52 EDT Received: from Semillon.ms by ArpaGateway.ms ; 03 AUG 88 14:22:59 PDT Date: Wed, 3 Aug 88 14:20 PDT From: Gregor.pa@Xerox.COM Subject: Re: update-method-inheritance To: CommonLoops.pa@Xerox.COM cc: kanderso@WILMA.BBN.COM, kanderson@WILMA.BBN.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <19880803171018.8.GREGOR@PORTNOY.parc.xerox.com> Message-ID: <19880803212038.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 3 Aug 88 10:10 PDT From: Gregor.pa At the end of this message is a patch for the 8/1/88 version of PCL which I believe corrects all of these problems. It should have the performance characteristics you want, and shouldn't have any of the previous bugs. I haven't tested it, but I believe this patch can also be loaded into the 7/20, and perhaps even into St. Patrick's Day PCL. I should have pointed out before that the code which has actually been added to PCL includes some more improvments to make method loading faster. Specifically, it arranges for the list direct-generic-functions to not be recomputed all the time. I didn't include this in the patch because it can't be patched in the same way, but it will be in the next release. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Aug 88 14:55:36 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Aug 88 11:50:09 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA28905; Wed, 3 Aug 88 11:47:53 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-4.0) id AA12009; Wed, 3 Aug 88 11:48:33 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA18770; Wed, 3 Aug 88 11:47:24 PDT Message-Id: <8808031847.AA18770@suntana.sun.com> To: common-lisp-object-system@sail.stanford.edu Subject: Re: declare in with-slots In-Reply-To: Your message of Wed, 03 Aug 88 10:19:32 -0700. <8808031719.AA12130@rainbow-warrior.lucid.com> Date: Wed, 03 Aug 88 11:47:10 -0700 From: kempf@Sun.COM I'm not sure I understand what all the fuss is about. Currently in Common Lisp, the following is not allowed; (multiple-value-bind (x y z) (declare (fixnum x y z)) (multiple-return-value-function a b c) ... ) Seems to me with-slots and with-accessors falls into the same category. It would, of course, be nice to be able to do the above, just as it would for with-slots, but the following also works in at least one CL I've used: (multiple-value-bind (x y z) (multiple-return-value-function a b c) (locally (declare (fixnum x y z)) ... ) ) As to people not liking with-slots because it is Yet Another Scoping Mechanism, I feel the same about the multiple value constructs, but some people like them. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 13:39:41 EDT Received: from Semillon.ms by ArpaGateway.ms ; 03 AUG 88 10:24:16 PDT Date: Wed, 3 Aug 88 10:18 PDT From: Gregor.pa@Xerox.COM Subject: Re: interactions between defclass and type specifier To: Angela Dappert-Farquhar cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8808031131.AA03807@ztivax.uucp> Message-ID: <19880803171831.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 3 Aug 88 13:31:14 -0200 From: adf@ztivax.siemens.com (Angela Dappert-Farquhar) I have a bug I don't really understand: We defined (defclass member ()()) and this messes up the type checks with specifier 'member'. (typep 'a '(member a b c)) returns NIL instead of T. I don't know in how far PCL changed the type system or where this interaction could occur. Could you give me a hint? What other class names would one have to watch out? I dont have problems with (defclass and () ()) and (typep 'a (and symbol t)) or something like this. In CLOS, class names are valid as type specifiers. So are class objects. PCL implements this by defining a type with the same name as the class, whenever a named class is defined. This doesn't really conform to the spec since it doesn't work if someone uses setf of find-class to move around class objects, but it is the closest I can get in portable code. So, you shouldn't define any classes whose name is the same as the name of any existing type specifier. Why you were able to win with AND, I have no idea, this should not have worked, and is not legal in CLOS. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 13:39:26 EDT Received: from Semillon.ms by ArpaGateway.ms ; 03 AUG 88 10:21:16 PDT Date: Wed, 3 Aug 88 10:10 PDT From: Gregor.pa@Xerox.COM Subject: Re: update-method-inheritance To: kanderso@WILMA.BBN.COM cc: kanderson@WILMA.BBN.COM, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: The message of 2 Aug 88 14:34 PDT from kanderso@WILMA.BBN.COM Message-ID: <19880803171018.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Tue, 02 Aug 88 17:34:21 -0400 From: kanderso@WILMA.BBN.COM Have you thought about my message on this at all? This seems to cause a lot on unncessary invailatation when a new class is defined (old-cpl is NIL). In that case does anything really need to be invalidated? If not, can't we at least make old-cpl contain the class T. I'd like to be able to prove this theoretically to myself one way or another, but i figure you could come up with an obvious counter example, if there is one. I have spent some time thinking about this. The first thing I discovered was that the code that was already in PCL was completely wrong. There were cases in which it did not update generic functions that needed to be updated. As you (and others) noticed, there were many other cases where it updated too many generic functions. At the end of this message is a patch for the 8/1/88 version of PCL which I believe corrects all of these problems. It should have the performance characteristics you want, and shouldn't have any of the previous bugs. I haven't tested it, but I believe this patch can also be loaded into the 7/20, and perhaps even into St. Patrick's Day PCL. Please try this out and let me know if it works for you. Unless some problem arises, these changes will all be in the next release. ;;;-*-Mode:LISP; Package:(PCL Lisp 1000); Base:10; Syntax:Common-lisp -*- ;;; ;;; Patch for 8/1/88 PCL to correct bug of invalidating all generic functions ;;; whenever a class is defined. ;;; ;;; This patch should be loaded into an already running PCL. ;;; (in-package 'pcl) (defvar *the-class-object* (find-class 'object)) (defclass standard-class (class) ((name :initform nil :accessor class-name) (class-precedence-list :initform (list *the-class-object* *the-class-t*) :accessor class-precedence-list :accessor class-class-precedence-list) (local-supers :initform () :accessor class-local-supers) (local-slots :initform () :accessor class-local-slots) (direct-subclasses :initform () :accessor class-direct-subclasses) (direct-methods :initform () ; :accessor class-direct-methods ;This is defined by hand ;during bootstrapping. ) (forward-referenced-supers :initform () :accessor class-forward-referenced-supers) (no-of-instance-slots :initform 0 :accessor class-no-of-instance-slots) (instance-slots :initform ()) (non-instance-slots :initform () :accessor class-non-instance-slots) (wrapper :initform nil :accessor class-wrapper) (direct-generic-functions :initform () :accessor class-direct-generic-functions) (prototype :initform nil) (options :initform () :accessor class-options) (constructors :initform () :accessor class-constructors) (all-default-initargs :initform () :accessor class-all-default-initargs))) (defmethod update-method-inheritance ((class standard-class) old-cpl new-cpl) (let ((already-done ())) (unless (equal old-cpl new-cpl) (let ((shared-tail (shared-tail old-cpl new-cpl))) (dolist (old old-cpl) (unless (memq old shared-tail) (setq already-done (update-method-inheritance-1 old already-done)))) (dolist (new new-cpl) (unless (memq new old-cpl) (setq already-done (update-method-inheritance-1 new already-done)))))))) (defun update-method-inheritance-1 (class already-done) (let ((methods (class-direct-methods class))) (dolist (method methods) (let ((gf (method-generic-function method))) (if (null gf) (error "A method still on a class, has no generic function?") (unless (memq gf already-done) (push gf already-done) (invalidate-generic-function gf))))) already-done)) (defun shared-tail (l1 l2) (let ((r2 (reverse l2))) (labels ((recur (t1) (cond ((null t1) ()) (t (recur (cdr t1)) (cond ((null r2) (return-from shared-tail (cdr t1))) ((eq t1 l1) (return-from shared-tail l1)) ((eq (car t1) (pop r2))) (t (return-from shared-tail (cdr t1)))))))) (recur l1)))) -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Aug 88 13:31:16 EDT Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 3 Aug 88 10:24:28 PDT Received: by labrea.stanford.edu; Wed, 3 Aug 88 10:22:44 PDT Received: from rainbow-warrior.lucid.com by edsel id AA01559g; Wed, 3 Aug 88 10:18:11 PDT Received: by rainbow-warrior id AA12130g; Wed, 3 Aug 88 10:19:32 PDT Date: Wed, 3 Aug 88 10:19:32 PDT From: Patrick Dussud Message-Id: <8808031719.AA12130@rainbow-warrior.lucid.com> To: Gregor.pa@xerox.com Cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: Gregor.pa@Xerox.COM's message of Tue, 2 Aug 88 13:51 PDT <19880802205147.3.GREGOR@PORTNOY.parc.xerox.com> Subject: declare in with-slots Date: Tue, 2 Aug 88 13:51 PDT From: Gregor.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest Line-Fold: no We never discussed how people could use declare inside of with-slots. I don't think we ever thought of it. But to at least one of my users, this is a serious bug. Here is an idea for how to fix this. I am not enough of a declaration expert to know if this can work. All of what I say here also applies to with-accessors. Allow declarartions to appear in front of the with-slots body. These declarations affect the pseudo-bindings performed by the with slots. They talk about the value which will be returned by evaluating one of the pseudo variables and the values which will be stored in the pseudo variables. The SPECIAL declaration is, of course, now allowed. So, for example: (with-slots (x y z) (declare (fixnum x y z)) (setq z (* x y))) The syntax makes sense. Note that I didn't layer this directly into symbol-macrolet. We could of course put it there, but it seemed to me that it was more appropriate for this to be something which the caller of symbol-macrolet handles. I could pretty easily be convinced that I am wrong about this. ------- I think that it has to be put in symbol-macrolet as well. If not, the work that has to be done in with-slot is beig enough so the layering is totally useless. Maybe making with-slots and with-accessors special forms and forget about symbol-macrolet is a good solution. The context is narrower that we originally proposed, so the semantics issue will be easier to nail down. Patrick.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 12:50:50 EDT Received: from Semillon.ms by ArpaGateway.ms ; 03 AUG 88 09:45:41 PDT Date: Wed, 3 Aug 88 09:43 PDT From: Gregor.pa@Xerox.COM Subject: Re: Where is arisia To: Michael Sokolov cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8808031505.AA00577@waterloo> Message-ID: <19880803164301.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 3 Aug 88 11:05:57 EDT From: Michael Sokolov Eager to get the latest version of PCL, I tried to ftp arisia, only to find it isn't my hosts file. Could you send the address? I believe Arisia's Internet address is 13.1.100.206. Its down right now, so I can't be certain. It should be up in an hour or so. Try that address and see if it works for you. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Aug 88 11:57:47 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 3 Aug 88 08:52:40 PDT Received: by ti.com id AA05029; Wed, 3 Aug 88 10:50:48 CDT Received: from Kelvin by tilde id AA28918; Wed, 3 Aug 88 10:35:22 CDT Message-Id: <2795614606-3753982@Kelvin> Sender: GRAY@Kelvin.csc.ti.com Date: Wed, 3 Aug 88 10:36:46 CDT From: David N Gray To: Jeffrey Piazza Cc: Common-Lisp-Object-System@SAIL.Stanford.Edu Subject: RE: declare in with-slots In-Reply-To: Msg of Wed, 3 Aug 88 07:10:42 PDT from Jeffrey Piazza I agree with Piazza's sentiment that it is not reasonable to expect macros to comprehend the semantics of declarations. This appears to be another reason why SYMBOL-MACROLET ought to be a special form; then it could accept declarations, and WITH-SLOTS could just pass them through. (But I'm not necessarily endorsing the notion that type declarations need to be supported here.) -- David Gray  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 11:19:24 EDT Received: from Riesling.ms by ArpaGateway.ms ; 03 AUG 88 08:08:34 PDT Return-Path: Redistributed: CommonLoops.pa Received: from media-lab.media.mit.edu ([18.85.0.2]) by Xerox.COM ; 03 AUG 88 08:06:11 PDT Received: from waterloo.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA19141; Wed, 3 Aug 88 11:06:04 EDT Received: by waterloo (3.2/4.8) id AA00577; Wed, 3 Aug 88 11:05:57 EDT Date: Wed, 3 Aug 88 11:05:57 EDT From: Michael Sokolov Message-Id: <8808031505.AA00577@waterloo> To: Gregor.pa@Xerox.COM Cc: CommonLoops.pa@Xerox.COM Subject: Where is arisia Eager to get the latest version of PCL, I tried to ftp arisia, only to find it isn't my hosts file. Could you send the address? Thanks, Mike Sokolov  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 11:03:24 EDT Received: from Salvador.ms by ArpaGateway.ms ; 03 AUG 88 07:45:33 PDT Return-Path: Redistributed: commonloops.pa Received: from saqqara.cis.ohio-state.edu ([128.146.8.98]) by Xerox.COM ; 03 AUG 88 07:44:00 PDT Received: by saqqara.cis.ohio-state.edu (5.54/2.0) id AA15621; Wed, 3 Aug 88 10:41:59 EDT Date: Wed, 3 Aug 88 10:41:59 EDT From: welch@saqqara.cis.ohio-state.edu (Arun Welch) Message-Id: <8808031441.AA15621@saqqara.cis.ohio-state.edu> To: commonloops.pa@Xerox.COM Subject: PCL environmental stuff for Xerox machines Could someone put the environmental files (pcl-env) for xerox dmachines on arisia, hopefully files for medley as well as lyric? ...arun  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 3 Aug 88 10:18:45 EDT Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 3 Aug 88 07:12:15 PDT Received: by decwrl.dec.com (5.54.5/4.7.34) id AA03551; Wed, 3 Aug 88 07:10:42 PDT Date: Wed, 3 Aug 88 07:10:42 PDT Message-Id: <8808031410.AA03551@decwrl.dec.com> From: piazza%lisp.DEC@decwrl.dec.com (Jeffrey Piazza) To: Gregor.pa@xerox.com Subject: RE: decalre in with-slots > We never discussed how people could use declare inside of with-slots. I > don't think we ever thought of it. My problem all along with with-slots and symbol-macrolet has been that they haven't been thought through. It's not simple to mount this charade that slots are "just like" variables. I've come in too late on this work to have said this earlier, but I will predict now that you will find still other problems with symbol-macrolet as time goes by. As to the suggested patch: No, it won't really work. Declare's are pretty much the province of special forms, and with-slots et al won't, in general, be able to parse the declare's, let alone interpret them correctly. For example, a common extension to declare allows: (deftype t-terminated-list () '(or cons (member t))) (with-slots (x y z) (declare (t-terminated-list y)) ...) In Common Lisp, you can't tell that t-terminated-list is a type, and, even if you could, you couldn't be sure that this meant (declare (type t-terminated-list y)). (It might mean (declare (ftype ...)), which would have nothing at all to do with the _variable_ y.) While you're thinking about this, consider what would happen if Common Lisp were extended to allow: (with-slots (x y z) ... (locally (declare (fixnum y)) ...) ...) [CL doesn't currently allow this, but there's some sentiment to make this extension.] Now with-slots would have to parse the entire body to get this right. > Note that I didn't layer this directly into symbol-macrolet. We could > of course put it there, but it seemed to me that it was more appropriate > for this to be something which the caller of symbol-macrolet handles. I > could pretty easily be convinced that I am wrong about this. What's the point of symbol-macrolet, then, if not to be the form which says "pretend foo is a variable, even though it's not"? You're suggesting that only with-slots wants to play "let's pretend," and that there's some different roles that symbol-macrolet fills? I doubt it... /JEP  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 3 Aug 88 07:51:32 EDT Received: from Salvador.ms by ArpaGateway.ms ; 03 AUG 88 04:32:31 PDT Return-Path: Redistributed: commonloops.pa Received: from siemens.siemens.com ([129.73.7.1]) by Xerox.COM ; 03 AUG 88 04:30:08 PDT Received: by siemens.siemens.com (5.54/1.15) id AA12475; Wed, 3 Aug 88 07:28:10 EDT From: adf@ztivax.siemens.com (Angela Dappert-Farquhar) Date: Wed, 3 Aug 88 13:31:14 -0200 Message-Id: <8808031131.AA03807@ztivax.uucp> Received: by ztivax.uucp; Wed, 3 Aug 88 13:31:14 -0200 To: commonloops.pa@Xerox.COM Subject: interactions between defclass and type specifier I have a bug I don't really understand: We defined (defclass member ()()) and this messes up the type checks with specifier 'member'. (typep 'a '(member a b c)) returns NIL instead of T. I don't know in how far PCL changed the type system or where this interaction could occur. Could you give me a hint? What other class names would one have to watch out? I dont have problems with (defclass and () ()) and (typep 'a (and symbol t)) or something like this. Angela adf%ztivax.siemens.com@siemens.com  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 2 Aug 88 18:03:17 EDT Received: from Salvador.ms by ArpaGateway.ms ; 02 AUG 88 14:33:17 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 02 AUG 88 14:29:17 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: 88/8/1 PCL patches Date: Tue, 02 Aug 88 17:28:50 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880802-143317-1180@Xerox> Gregor, Here are the remaining patches i've had to make to get the latest PCL to run through my test cases. Basicially they cover: 1. Jim Larus' performance improvements. 2. Class redefinition infinite loop. 3. Angela Dappert-Farquhar's with-slots-internal--class and related function. 4. Eliminate need for class-direct-generic-functions. 5. Fix some differences between 7-1 and 7-2 debugger. I realize, you plan to rework some of these, but 2 & 3 are needed to make PCL useable now. ;;;-*-Mode:LISP; Package:(PCL LISP 1000); Base:10; Syntax:Common-lisp; Patch-File: Yes -*- ;;; Patches to "8/1/88 (beta) Laguna Seca PCL" ;;; Patches that must be made in the sources files are commented out here with ;;; "#+patched-in-sources". #|| Questions: ? Why does make-parameter-references produce a warning? ? Can the logand's and logxor's in dcode be replaced by %logand and %logxor? ? Should the debugger ignore more internal functions? To Do: o mki -> make-instance. o Remove extra defmethod print-object in methods.lisp o add ignore declarations to keep compiler quiet. o Fix iterate compiler problem in 7.1 o extend Jim larus's fixnum patch to pair logand arguments for machines that only optimize binary arguments. BUGS: o specializer (eql fred) works but (eql 'fred) as in CLOS doesn't. o supress lispm's redefinition warnings for setf methods. o C-E in debugger or M-. on a method can't find it unless it has been ZMAC'd o tracing methods doesn't work ||# (in-package 'pcl) ;;; ;;; Patch DCODE.LISP ;;; 2. The following changes (marked with JL) force a few more critical ;;; operations to be open-coded. #+patched-in-sources (defmacro generic-function-cache-offset (mask &rest classes) (let ((cache-numbers (mapcar #'(lambda (class) `(the fixnum (object-cache-no ,class ,mask))) ; JL classes))) (if (cdr cache-numbers) `(logand ,mask (logxor ,@cache-numbers)) `(logand ,mask ,@cache-numbers)))) #+patched-in-sources (defmacro generic-function-cache-entry (cache offset offset-from-offset) `(memory-block-ref ,cache (+ (the fixnum ,offset) ; JL (the fixnum ,offset-from-offset)))) ; JL ;;; ;;; Patch FIXUP.LISP ;;; Avoid warning. #+lispm #+patched-in-sources (si:allow-redefinition 'print-iwmc-class 'defun) ;;; ;;; Patch HIGH.LISP ;;; Class redefinition infinite loop. (defvar *changing-classes* () "Stack of changing classes.") (defmethod slot-value-using-class ((class obsolete-class) object slot-name &optional dont-call-slot-missing-p default) (if (member class *changing-classes* :test #'eq) (call-next-method) (progn (let ((*changing-classes* (cons class *changing-classes*))) (change-class object (cadr (slot-value class 'class-precedence-list)))) (slot-value-using-class (class-of object) object slot-name dont-call-slot-missing-p default)))) ;;; ;;; Patch LOW.LISP ;;; Jim Larus speed up for stock hardware. #+patched-in-sources (defmacro cache-key-from-wrappers ((size words-per-entry &optional (op 'logxor)) &rest wrappers) (when (or (not (numberp size)) (not (numberp words-per-entry))) (error "Using cache-key-from-wrappers improperly.~@ The size and words-per-entry arguments must be unquoted numbers.")) (when (not (member op '(nil logand logxor))) (error "Using cache-key-from-wrappers improperly.~@ If supplied, the op argument must be an unquoted symbol, and~@ one of LOGAND and LOGXOR.")) ;; Convert the wrapper forms into forms which will fetch the wrapper's ;; cache number. That is what we really need to work with. (setq wrappers (mapcar #'(lambda (w) `(the fixnum (wrapper-cache-no ,w))) wrappers)) ; JL (cond ((and (null (cdr wrappers)) (= size 2)) (car wrappers)) ((eq op 'logand) `(%logand ,(make-memory-block-mask size words-per-entry) ,.wrappers)) ((eq op 'logxor) `(%logand ,(make-memory-block-mask size words-per-entry) (%logxor ,.wrappers))))) ;;; ;;; Patch LOW.LISP ;;; 3. Finally, the following two macros (add to excl-low.lisp) optimize ;;; the trivial cases of a couple of operations. Yes, the compiler should ;;; do this. Yes, the one arg case does occur in practice (in fact, in ;;; the discriminator code for methods with a single discriminated ;;; argument). #+patched-in-sources (defmacro %logand (&rest args) (cond ((null args) `(logand)) ((cdr args) `(logand .,args)) (t (car args)))) ; JL #+patched-in-sources (defmacro %logxor (&rest args) (cond ((null args) `(logxor)) ((cdr args) `(logxor .,args)) (t (car args)))) ; JL ;;; I don't have performance numbers for the latter two ;;; optimizations, but I remember that they were on the order of a 20% ;;; reduction in the execution time for Curare. ;;; ;;; Patch METHODS.LISP ;;; Jim Larus' 20% speedup. #|| 1. Increase the size of the constant GENERIC-FUNCTION-CACHE-SIZE from 32 to 64 (methods.lisp). This decreased the execution time of Curare by 20-33%. In one test, the number of calls on PCL::LOOKUP-METHOD-INTERNAL (i.e., the cache-miss code) fell from 5224 to 1335. Interestingly, most of these calls came from built-in methods, mainly INITIALIZE, INITIALIZE-FROM-INIT-PLIST, INITIALIZE-FROM-DEFAULTS, etc., defined on all classes. ||# #+patched-in-sources (defconstant generic-function-cache-size 64) ;;; ;;; Patch SLOTS.LISP ;;; From: Angela Dappert-Farquhar (defmacro with-slot-internal--class ((class object slot-name createp) &body cases) (let ((temp1 (gensym)) (temp2 (gensym)) (createp-var (gensym)) (instance-case (cdr (assq :instance cases))) (dynamic-case (cdr (assq :dynamic cases))) (class-case (cdr (assq :class cases))) (nil-case (cdr (assq nil cases)))) `(prog (,temp1 ;The Horror! Its a PROG, ,temp2 ;but its in a macro so.. (,createp-var ,createp)) (cond ((setq ,temp1 (slotd-position ,slot-name (class-instance-slots ,class))) ;; We have the slots position in the instance slots. Convert ;; that to the slots index and then cache the index and return ;; the result of evaluating the instance-case. (setq ,temp1 (%convert-slotd-position-to-slot-index ,temp1)) (let ((wrapper (validate-class-wrapper ,object))) (class-wrapper-cache-cache-entry wrapper (class-wrapper-slot-value-offset wrapper ,slot-name) ,slot-name ,temp1)) (return (let ,(and (car instance-case) `((,(caar instance-case) ,temp1))) . ,(cdr instance-case)))) ((setq ,temp1 (find-slotd ,slot-name (class-non-instance-slots ,class))) ;; We have a slotd -- this is some sort of declared slot. (ecase (slotd-allocation ,temp1) (:class (return (let ,(and (car class-case) `((,(caar class-case) ,temp1))) . ,(cdr class-case)))) ((:none nil) (go nil-case)) (:dynamic (setq ,createp-var :dynamic ,temp2 (slotd-initform ,temp1)))))) ;; When we get here, either: ;; - we didn't find a slot-description for this slot, so try to ;; find it in the dynamic slots creating it if createp-var is ;; non-null. ;; - we found a :dynamic slot-description, createp-var got set ;; to :dynamic and we dropped through to here where we try ;; to find the slot. If we find it we return the loc. If ;; not we create it and initialize it to its default value. (multiple-value-setq (,temp1 ,createp-var) (dynamic-slot-loc--class ,object ,slot-name ,createp-var)) (when ,temp1 (when (and ,createp-var ,temp2) (setf (car ,temp1) (eval ,temp2))) (let (,@(and (caar dynamic-case) `((,(caar dynamic-case) ,temp1))) ,@(and (cadar dynamic-case) `((,(cadar dynamic-case) ,createp-var)))) (return . ,(cdr dynamic-case)))) nil-case ;; This slot is either explicitly declared :allocation nil (we ;; jumped here by (GO NIL-CASE) or there is no declaration for ;; this slot and we didn't find it in the dynamic-slots, we fell ;; through from the dynamic lookup above. (let ,(and (car nil-case) `((,(caar nil-case) ,temp1))) (RETURN . ,(cdr nil-case)))))) ;;; Patch and recompile (defun slot-value-using-class--class-internal (class object slot-name dont-call-slot-missing-p default) (with-slot-internal--class (class object slot-name nil) (:instance (index) (get-static-slot--class object index)) (:dynamic (loc newp) (if (eq newp t) (setf (car loc) default) (car loc))) (:class (slotd) (slotd-initform slotd)) (nil () (PROGN (unless dont-call-slot-missing-p (slot-missing object slot-name)) DEFAULT)))) ;;; recompile (defun put-slot-using-class--class-internal (class object slot-name new-value dont-call-slot-missing-p) (with-slot-internal--class (class object slot-name dont-call-slot-missing-p) (:instance (index) (setf (get-static-slot--class object index) new-value)) (:dynamic (loc) (setf (car loc) new-value)) (:class (slotd) (setf (slotd-initform slotd) new-value)) (nil () (unless dont-call-slot-missing-p (slot-missing object slot-name))))) ;;; Recompile (defmethod slot-allocation-using-class ((class standard-class) object slot-name) (with-slot-internal--class (class object slot-name nil) (:instance () :instance) (:dynamic () :dynamic) (:class () :class) (nil () nil))) ;;; ;;; Patch STD-CLASS.LISP ;;; KRA: Eliminate need for class-direct-generic-functions. #+patched-in-sources (defmethod update-method-inheritance ((class standard-class) old-cpl new-cpl) (declare (ignore class)) (unless (eq old-cpl new-cpl) (dolist (old old-cpl) (unless (member old new-cpl) (dolist (old-gf (class-direct-methods old)) (invalidate-generic-function (method-generic-function old-gf))))) (dolist (new new-cpl) (unless (member new old-cpl) (dolist (new-gf (class-direct-methods new)) (if (null (method-generic-function new-gf)) ;; There are occasional methods with null generic-function slots. ;; Report if you find one. (print (list 'REPORT-BUG-TO-KEN new-gf)) (invalidate-generic-function (method-generic-function new-gf)))))))) ;;; For anyone that needs it. (defmethod class-direct-generic-functions ((class standard-class)) (let ((gfs ())) (map 'nil #'(lambda (m) (pushnew (method-generic-function m) gfs)) (class-direct-methods class)) gfs)) ;;; This is what i want, but i can't pull it through the metabraid. #+patched-in-sources (defmethod-setf class-direct-methods ((class standard-class)) (nv) (put-slot--class class 'direct-methods nv)) ;;; ;;; Patch STD-CLASS.LISP ;;; part of class redefintion bug. (defun update-slots--class (class) (let* ((cpl (class-precedence-list class)) (obsolete-class nil) (local-slots (class-local-slots class)) (slots ()) (instance-slots ()) (non-instance-slots ())) ;; If I saved accessor/reader prefixes somewhere, I could save time ;; here. Also, if merge actually kept track of whether something ;; changed that would save time. (merge-accessor/reader-prefixes local-slots (class-options class)) (check-accessor/reader-compatibility local-slots) (setq slots (order-slotds class (collect-slotds class local-slots cpl) cpl)) (dolist (slot slots) (if (eq (slotd-allocation slot) ':instance) (push slot instance-slots) (push slot non-instance-slots))) (setq instance-slots (reverse instance-slots) non-instance-slots (reverse non-instance-slots)) (update-slot-accessors--class class instance-slots non-instance-slots) ;; If there is a change in the shape of the instances then the ;; old class is now obsolete. Make a copy of it, then fill ;; ourselves in properly and obsolete it. (when (and (class-has-instances-p class) (not (same-shape-slots-p (class-instance-slots class) instance-slots))) (setq obsolete-class (copy-class class))) (setf (class-no-of-instance-slots class) (length instance-slots)) (setf (class-instance-slots class) instance-slots) (setf (class-non-instance-slots class) non-instance-slots) (when obsolete-class (flush-class-caches class) (make-class-obsolete class obsolete-class)))) ;;; (make-class-obsolete class (copy-class class))))) ; KRA: BUG? ;;; ;;; Patch 7DEBUG.LISP ;;; Fix differences between 7-1 and 7-2. (in-package 'debugger) (defun show-all-compiled-7-1 (&optional show-source-file-p) (let* ((*printing-monitor-message* t) (frame *current-frame*) (function (frame-function frame))) (format t "~V~S~" *emphasis-character-style* (function-name-for-debugger frame)) (when show-source-file-p (print-function-source-file function)) (format t "~2%") ;; Print the arguments, including the rest-arg which is a local (let ((local-start (print-frame-args *current-frame* 1 t))) (cond ((frame-active-p *current-frame*) ;; Print the rest of the locals, if the frame is active (print-frame-locals *current-frame* local-start 1) (format t "~%~VDisassembled code:~" *deemphasis-character-style*) (show-all-compiled-1 frame function) ;; This kludge is to prevent the prompt from triggering a **MORE** ;; when it comes out on the bottom line of the window (if (memq :notice (send standard-output :which-operations)) (send standard-output :notice :input-wait))))))) (defun show-all-compiled-7-2 (&optional show-source-file-p) (let* ((*printing-monitor-message* t) (frame *current-frame*) (function (frame-function frame))) (format t "~V~S~" *emphasis-character-style* (FUNCTION-NAME-FOR-DEBUGGER FRAME)) ;; KRA: (lframe-function-name *current-language* function nil)) (when show-source-file-p (print-function-source-file function)) (format t "~2%") ;; Print the arguments, including the rest-arg which is a local (let ((local-start (print-frame-args *current-frame* 1 t))) (cond ((frame-active-p frame) ;; Print the rest of the locals, if the frame is active (print-frame-locals frame local-start 1) (lframe-show-code-for-function *current-language* frame function (lframe-show-source-code-p *current-language*) :brief nil) ;; This kludge is to prevent the prompt from triggering a **MORE** ;; when it comes out on the bottom line of the window (when (memq :notice (send standard-output :which-operations)) (send standard-output :notice :input-wait))))))) (defun genera-7-2-p () (cl:member :genera-release-7-2 cl:*features*)) (cl:setf (cl:symbol-function 'show-all-compiled) (if (genera-7-2-p) #'show-all-compiled-7-2 #'show-all-compiled-7-1))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Aug 88 17:20:37 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 2 Aug 88 14:09:01 PDT Received: from Semillon.ms by ArpaGateway.ms ; 02 AUG 88 13:53:08 PDT Date: Tue, 2 Aug 88 13:51 PDT From: Gregor.pa@Xerox.COM Subject: declare in with-slots To: common-lisp-object-system@sail.stanford.edu Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest Message-ID: <19880802205147.3.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no We never discussed how people could use declare inside of with-slots. I don't think we ever thought of it. But to at least one of my users, this is a serious bug. Here is an idea for how to fix this. I am not enough of a declaration expert to know if this can work. All of what I say here also applies to with-accessors. Allow declarartions to appear in front of the with-slots body. These declarations affect the pseudo-bindings performed by the with slots. They talk about the value which will be returned by evaluating one of the pseudo variables and the values which will be stored in the pseudo variables. The SPECIAL declaration is, of course, now allowed. So, for example: (with-slots (x y z) (declare (fixnum x y z)) (setq z (* x y))) Becomes: (progn (setf (the fixnum (slot-value 'z)) (* (the fixnum (slot-value 'x)) (the fixnum (slot-value 'x))))) If this makes sense, a cleanup proposal should do the trick. Note that I didn't layer this directly into symbol-macrolet. We could of course put it there, but it seemed to me that it was more appropriate for this to be something which the caller of symbol-macrolet handles. I could pretty easily be convinced that I am wrong about this. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 2 Aug 88 16:09:50 EDT Received: from Semillon.ms by ArpaGateway.ms ; 02 AUG 88 12:49:49 PDT Date: Tue, 2 Aug 88 12:45 PDT From: Gregor.pa@Xerox.COM Subject: Re: new version of PCL To: Rob Pettengill cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8808021926.AA10903@perseus.sw.mcc.com> Message-ID: <19880802194543.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Tue, 2 Aug 88 14:26:14 CDT From: Rob Pettengill 1. There appears to be an extra comma in boot.lisp Yes, there is a typo in this file in 8/1/88 PCL. I have fixed the version of the file on arisia.xerox.com, so you can either ftp a new version, or make the following patch. ;from boot.lisp (defun expand-defmethod-internal (generic-function-name qualifiers specialized-lambda-list body env) (declare (values fn-form specializers doc) (ignore qualifiers)) (multiple-value-bind (documentation declarations real-body) (extract-declarations body) (multiple-value-bind (parameters lambda-list specializers) (parse-specialized-lambda-list specialized-lambda-list) (let* ((required-parameters (mapcar #'(lambda (r s) (declare (ignore s)) r) parameters specializers)) (parameters-to-reference (make-parameter-references specialized-lambda-list required-parameters declarations generic-function-name specializers)) (class-declarations `(declare ,@(remove nil (mapcar #'(lambda (a s) (and (symbolp s) (neq s 't) `(class ,a ,s))) parameters specializers)))) (method-lambda ;; Remove the documentation string and insert the ;; appropriate class declarations. The documentation ;; string is removed to make it easy for us to insert ;; new declarations later, they will just go after the ;; cadr of the method lambda. The class declarations ;; are inserted to communicate the class of the method's ;; arguments to the code walk. (let () `(lambda ,lambda-list ,class-declarations ,@declarations (progn ,@parameters-to-reference) (block ,(if (listp generic-function-name) (cadr generic-function-name) generic-function-name) ,@real-body)))) (call-next-method-p nil) ;flag indicating that call-next-method ;should be in the method definition (next-method-p-p nil) ;flag indicating that next-method-p ;should be in the method definition (save-original-args nil) ;flag indicating whether or not the ;original arguments to the method ;must be preserved. This happens ;for two reasons: ; - the method takes &mumble args, ; so one of the lexical functions ; might be used in a default value ; form ; - call-next-method is used without ; arguments at least once in the ; body of the method (original-args ()) (applyp nil) ;flag indicating whether or not the ;method takes &mumble arguments. If ;it does, it means call-next-method ;without arguments must be APPLY'd ;to original-args. If this gets set ;true, save-original-args is set so ;as well (slots (mapcar #'list required-parameters)) (plist ()) (walked-lambda nil)) (flet ((walk-function (form context env) (cond ((not (eq context ':eval)) form) ((not (listp form)) form) ((eq (car form) 'call-next-method) (setq call-next-method-p 't) (setq save-original-args (not (cdr form))) form) ((eq (car form) 'next-method-p) (setq next-method-p-p 't) form) ((and (eq (car form) 'function) (cond ((eq (cadr form) 'call-next-method) (setq call-next-method-p 't) (setq save-original-args 't) form) ((eq (cadr form) 'next-method-p) (setq next-method-p-p 't) form) (t nil)))) ((and (or (eq (car form) 'slot-value) (eq (car form) 'set-slot-value)) (symbolp (cadr form)) (constantp (caddr form))) (multiple-value-bind (parameter class) (can-optimize-access (cadr form) env) (declare (ignore parameter)) (if class (ecase (car form) (slot-value (optimize-slot-value class form)) (set-slot-value (optimize-set-slot-value class form))) form))) ((eq (car form) 'standard-instance-access) (multiple-value-bind (parameter class) (can-optimize-access (cadr form) env) (if class (optimize-standard-instance-access class parameter form slots) form))) (t form)))) (setq walked-lambda (walk-form method-lambda env #'walk-function)) ;; Scan the lambda list to determine whether this method ;; takes &mumble arguments. If it does, we set applyp ;; and save-original-args true. ;; ;; This is also the place where we construct the original arguments ;; lambda list if there has to be one. (dolist (p lambda-list) (if (memq p lambda-list-keywords) (if (eq p '&aux) (let ((aux (memq '&aux lambda-list))) (dolist (a aux) (push a original-args)) (return nil)) (progn (setq applyp t save-original-args t) (push '&rest original-args) (push (make-symbol "AMPERSAND-ARGS") original-args) (return nil))) (push (make-symbol (symbol-name p)) original-args))) (setq original-args (if save-original-args (nreverse original-args) ())) (multiple-value-bind (ignore walked-declarations walked-lambda-body) (extract-declarations (cddr walked-lambda)) (declare (ignore ignore)) (when (some #'cdr slots) (setq slots (sort-slots-into-isl slots)) (setq plist (list* :isl slots plist)) (setq walked-lambda-body (add-pv-binding walked-lambda-body plist required-parameters specializers))) (when (or next-method-p-p call-next-method-p) (setq plist (list* :needs-next-methods-p 't plist))) (values `(function ,(if (or call-next-method-p next-method-p-p) (add-lexical-functions-to-method-lambda walked-declarations walked-lambda-body `(lambda ,lambda-list ,@walked-declarations ,.walked-lambda-body) original-args lambda-list save-original-args applyp call-next-method-p next-method-p-p) `(lambda ,lambda-list ,@walked-declarations ,.walked-lambda-body))) specializers documentation plist))))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 21:21:00 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 18:12:50 PDT Date: Mon, 1 Aug 88 18:10 PDT From: Gregor.pa@Xerox.COM Subject: new version of PCL To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest Message-ID: <19880802011000.0.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There is a new version of PCL available. It is NOT on parcvax.xerox.com. parcvax is being decommisioned, so PCL is going to be distributed by placing it on arisia.xerox.com. The new version of PCL is on arisia.xerox.com in the /pcl directory. As before, you can access that directory with username "anonymous" and password "anonymous". You should read the get-pcl.text file for complete information on the contents of that directory. The major difference between this version of PCL and the 7/20/88 version is that the :initform for :class allocated slots is now evaluated when the class is defined. This is an old bug which should have been fixed a long time ago. The other problems with with-slots which have also been reported in the past week are fixed in this version as well. As usual, use, enjoy and send bug reports. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 20:43:42 EDT Received: from Salvador.ms by ArpaGateway.ms ; 01 AUG 88 17:37:40 PDT Return-Path: Redistributed: CommonLoops.pa Received: from fs3.cs.rpi.edu ([128.213.1.14]) by Xerox.COM ; 01 AUG 88 17:35:45 PDT Received: by fs3.cs.rpi.edu (5.54/1.2-RPI-CS-Dept) id AA04432; Mon, 1 Aug 88 20:26:27 EDT Date: Mon, 1 Aug 88 20:34:43 EDT From: harrisr@turing.cs.rpi.edu (Richard Harris) Received: by turing.cs.rpi.edu (3.2/1.2-RPI-CS-Dept) id AA13042; Mon, 1 Aug 88 20:34:43 EDT Message-Id: <8808020034.AA13042@turing.cs.rpi.edu> To: CommonLoops.pa@Xerox.COM Subject: describe-instance In the definition of describe-instance, in high.lisp, change the line (dynamic-slots (iwmc-class-dynamic-slots object)) to (dynamic-slots (cond ((iwmc-class-p object) (iwmc-class-dynamic-slots object)) ((funcallable-instance-p object) (funcallable-instance-dynamic-slots object)) (t nil))) to allow describe-instance to work for funcallable-instances. Rick Harris  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 18:41:51 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 15:37:36 PDT Date: Mon, 1 Aug 88 15:34 PDT From: Gregor.pa@Xerox.COM Subject: :class vs :initform To: CommonLoops.pa@Xerox.COM Message-ID: <19880801223452.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no The next version of pcl finally fixes the bug which prevented the initform for :class allocation slots from being evaluated when the class was defined. Here is a test case: (defclass foo () ((a :initform (+ 1 2) :allocation :class))) # ;; This returns 3 rather than the (+ 1 2) it used to return. (slot-value (make-instance 'foo) 'a) 3 I am sending this out as a separate message to warn everyone that this change is coming. This version of PCL will be released sometime in the next couple of days. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 18:20:47 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 15:15:31 PDT Date: Mon, 1 Aug 88 15:12 PDT From: Gregor.pa@Xerox.COM Subject: Re: get-setf-generic-function To: Kerry Kimbrough cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <2795196702-5977045@Sierra> Message-ID: <19880801221211.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 29 Jul 88 14:31:42 CDT From: Kerry Kimbrough This is not in Ch. 2 of June 88 CLOS. Is it in Ch. 3? Or is there now a different standard CLOS interface? The idea is that we are relying on the issue of setf function specs being resolved properly by X3J13. So, we don't need a special function since there will be something liek symbol-function which will do the job for us. This may have been overoptimistic on our part. PCL still has get-setf-generic-function. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 18:20:35 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 15:06:28 PDT Date: Mon, 1 Aug 88 15:00 PDT From: Gregor.pa@Xerox.COM Subject: Re: PCL releases To: Kerry Kimbrough cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <2795186633-5372121@Sierra> Message-ID: <19880801220049.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 29 Jul 88 11:43:53 CDT From: Kerry Kimbrough I've been working with the 7/7 version. But now, although I've received no notice that a newer PCL is available, I've seen references to the 7/20 version. Can I get a clarification of the PCL release policy? What is the most recent version? What future versions are currently planned? Is there a regular schedule of releases? What's the best way to stay up-to-date? What's the plan for coming into full CLOS conformance? What I'm trying to do is distribute a public-domain CLOS-based system with the necessary patches so that it will work for those users for whom PCL is the house CLOS. I'd prefer to target the most recent and most stable version of PCL. I'd prefer not to develop my own patches for CLOS conformance if these are already planned. I'd prefer to minimize the risk of conflicts between my patches and those that are posted to the net in the future. And, naturally, I'd prefer to ship ASAP. Currently, we are in a fairly active phase of PCL development. The goal is to bring PCL into conformance with chapter 1 and 2 of the CLOS spec, and to implement the metaobject protocol we are writing up for chapter 3. I would expect that in the next month or so there will be quite a few releases of PCL. My hope is that these will happen about once a week. Each of these releases will be different in only a small number of ways from the previous release. This is part of our continuing plan to ease users along the path to full CLOS. The best way to stay up to date is to get new versions of PCL whenever they are announced. Sometimes versions are announced as being beta-test versions. For some people, it makes sense to wait until non beta-test version is announced. The current version is 7/20/88. I expect there will be a new version in a couple of days which will include all the changes to 7/20 that have been mailed out. This version will be a "normal" release, that is it will not be a beta-test version. Without knowing more about exactly which aspects of full CLOS you are depending on, I can't advise you more about how to organize your CLOS conformance patches. If you let me know about this, I may be able to help you, or even adjust the priority of things we are working on here. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 17:15:31 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 13:49:25 PDT Return-Path: Redistributed: commonloops.pa Received: from SUMEX-AIM.Stanford.EDU ([10.0.0.56]) by Xerox.COM ; 01 AUG 88 13:46:43 PDT Date: Mon, 1 Aug 88 13:43:18 PDT From: Vaughan Johnson Subject: re: PCL releases To: commonloops.pa@Xerox.COM cc: vjOHNSON@SUMEX-AIM.Stanford.EDU Message-ID: <12419036192.73.VJOHNSON@SUMEX-AIM.Stanford.EDU> I haven't seen any response to Kerry Kimbrough's msg of 29 July, about PCL releases. I'm in a similar situation and would like to see the answers to his questions. Thanks, Vaughan Johnson -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 15:13:29 EDT Received: from Burger.ms by ArpaGateway.ms ; 01 AUG 88 11:46:17 PDT Return-Path: Redistributed: CommonLoops.pa Received: from ai.CEL.FMC.COM ([10.6.0.11]) by Xerox.COM ; 01 AUG 88 11:44:11 PDT Received: from unixb.CEL.FMC.COM (unixb.ARPA) by ai.CEL.FMC.COM with Sendmail (4.12/4.7) id AA09908; Mon, 1 Aug 88 10:54:01 pdt Received: by unixb.CEL.FMC.COM with Sendmail (1.2/4.7) id AA10559; Mon, 1 Aug 88 10:53:15 pdt From: sharma@cel.fmc.com (Uma Kant Sharma) Message-Id: <8808011753.AA10559@unixb.CEL.FMC.COM> Date: 01 Aug 88 10:53:13 PDT (Mon) To: liew@aramis.rutgers.edu Cc: CommonLoops.pa@Xerox.COM, sharma@cel.fmc.com Subject: Re: Some typos in tthe 7/20/88 release In-Reply-To: Your message of Mon, 1 Aug 88 10:17:44 EDT. <8808011417.AA13184@constance.rutgers.edu> Please remove my name from this mailing list. This does not belong to me. May be, it is for dsharma@ai.cel.fmc.com. I am sharma@ai.cel.fmc.com Thanks. -UK Sharma.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 14:33:37 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 11:21:39 PDT Date: Mon, 1 Aug 88 11:16 PDT From: Gregor.pa@Xerox.COM Subject: Re: duplicate slots in permutation vectors To: kanderso@WILMA.BBN.COM cc: CommonLoops.pa@Xerox.COM, kanderson@WILMA.BBN.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: The message of 1 Aug 88 08:18 PDT from kanderso@WILMA.BBN.COM Message-ID: <19880801181658.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Mon, 01 Aug 88 11:18:47 -0400 From: kanderso@WILMA.BBN.COM I noticed that every slot reference, even duplicates as in BAZZ2 above, are given there own position in the permutation vector. The ISL is ((baz baz)) rather than ((baz)). The following patch avoids duplicates by making SLOTS a nested alist: ((parameter (slot optimized-form ...) ...) ...)] Thanks, this was a bug I was intending to fix. The design was to have it be this new way, but I hadn't yet coded it. I have included your changes in my sources and they will be in the next release. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 14:33:26 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 11:11:48 PDT Date: Mon, 1 Aug 88 11:07 PDT From: Gregor.pa@Xerox.COM Subject: Re: with-slots, the saga continues To: kanderso@WILMA.BBN.COM cc: CommonLoops.pa@Xerox.COM, kanderson@WILMA.BBN.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: The message of 1 Aug 88 06:49 PDT from kanderso@WILMA.BBN.COM Message-ID: <19880801180759.7.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Mon, 01 Aug 88 09:49:39 -0400 From: kanderso@WILMA.BBN.COM In EXPAND-WITH-SLOTS, shouldn't the BODY of a WITH-SLOTS be walked like it was a PROGN? Here's a patch that seems to work: Thanks for this fix, I have made it in the sources here and it will be in the next release. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 14:33:13 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 11:09:56 PDT Date: Mon, 1 Aug 88 11:06 PDT From: Gregor.pa@Xerox.COM Subject: Re: [barmar@Think.COM: MULTIPLE-VALUE-SETQ and SYMBOL-MACROLET interaction] To: Eric Benson cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807292208.AA00306@blacksox.lucid.com> Message-ID: <19880801180608.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 29 Jul 88 15:08:12 pdt From: Eric Benson MULTIPLE-VALUE-CALL is the wrong thing to use here, since it forces the number of values to match the number of variables. The correct thing is to use MULTIPLE-VALUE-BIND. Here is a modified version of EXPAND-WITH-SLOTS-INTERNAL: Thanks. I made this change in the sources here. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 14:33:02 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 AUG 88 11:07:09 PDT Date: Mon, 1 Aug 88 11:03 PDT From: Gregor.pa@Xerox.COM Subject: Re: Some typos in tthe 7/20/88 release To: liew@aramis.rutgers.edu cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8808011417.AA13184@constance.rutgers.edu> Message-ID: <19880801180351.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Mon, 1 Aug 88 10:17:44 EDT From: liew@aramis.rutgers.edu (liew) I have just been compiling the 7/20/88 release on a Sun-4 (both the 4.0 and 3.2 OS) using Franz's Allegro CL 3.0.1 I found a few typos in the following files At some point along the line, you must be using a buggy file transfer mechanism. Neither of these typos appear in the original sources. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 11:27:51 EDT Received: from Salvador.ms by ArpaGateway.ms ; 01 AUG 88 08:19:34 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 01 AUG 88 08:17:45 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: duplicate slots in permutation vectors Date: Mon, 01 Aug 88 11:18:47 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880801-081934-1279@Xerox> (defmethod bazz2 ((foo foo)) (with-slots (baz) foo (push nil baz))) I noticed that every slot reference, even duplicates as in BAZZ2 above, are given there own position in the permutation vector. The ISL is ((baz baz)) rather than ((baz)). The following patch avoids duplicates by making SLOTS a nested alist: ((parameter (slot optimized-form ...) ...) ...)] ;;; In VECTOR.LISP (defun sort-slots-into-isl (slots) ;; Returns the ISL corresponding to the SLOTS data structure build during walking a ;; method body. (let ((pv-offset -1)) (mapcar #'(lambda (s) (mapcar #'(lambda (e) (INCF PV-OFFSET) ;; CLEVERLY SIDE EFFECT WALKED-LAMBDA. (DOLIST (FORM (CDR E)) (SETF (SECOND (THIRD FORM)) PV-OFFSET)) (car e)) (cdr s))) (mapcar #'(lambda (s) (cons (car s) (sort (cdr s) #'(lambda (a b) (string-lessp (symbol-name (car a)) (symbol-name (car b))))))) slots)))) (defun optimize-standard-instance-access (class parameter form slots) ;; Returns an optimized form corresponding to FORM. Optimized forms are interned ;; on SLOTS, a nested alist, so they can be side effected later to put in their ;; pv-offsets. (destructuring-bind (ignore instance slot-name . new) form (setq slot-name (reduce-constant slot-name)) (let ((entry (assq parameter slots))) (if (null entry) (error "Can't optimize instance access because there is no entry~@ for this class in the required parameters of this method.~@ There is an inconsistency in the method body optimization~@ data structures. Report this as a bug.") (LET ((SLOT-ENTRY (ASSQ SLOT-NAME (CDR ENTRY)))) (UNLESS SLOT-ENTRY (PUSH (SETQ SLOT-ENTRY (LIST SLOT-NAME)) (CDR ENTRY))) (LET* ((OPTIMIZED-FORM `(,(OPTIMIZE-STANDARD-INSTANCE-ACCESS-INTERNAL CLASS) ,INSTANCE ',SLOT-NAME ,@NEW)) (INTERNED-FORM (MEMBER OPTIMIZED-FORM (CDR SLOT-ENTRY)))) (IF INTERNED-FORM (FIRST INTERNED-FORM) (PROGN (PUSH OPTIMIZED-FORM (CDR SLOT-ENTRY)) OPTIMIZED-FORM))))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 10:22:24 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 AUG 88 07:19:32 PDT Return-Path: Redistributed: CommonLoops.pa Received: from constance.rutgers.edu ([128.6.5.50]) by Xerox.COM ; 01 AUG 88 07:18:01 PDT Received: by constance.rutgers.edu (5.59/1.15) id AA13184; Mon, 1 Aug 88 10:17:44 EDT Date: Mon, 1 Aug 88 10:17:44 EDT From: liew@aramis.rutgers.edu (liew) Message-Id: <8808011417.AA13184@constance.rutgers.edu> To: CommonLoops.pa@Xerox.COM Subject: Some typos in tthe 7/20/88 release Reply-To: liew@aramis.rutgers.edu I have just been compiling the 7/20/88 release on a Sun-4 (both the 4.0 and 3.2 OS) using Franz's Allegro CL 3.0.1 I found a few typos in the following files dcode.lisp: in line 391 in the macro (defmacro pre-make-caching-discriminating-functions ... it should be `(pre-make-templated-function-constructor and not `(pre-mke-templated-function-constructor low.lisp: in line 791 the function should be defined as (defun make-templated-function-constructor-constructor and not (defun make-tempated-function-constructor-constructor -chun liew liew@aramis.rutgers.edu  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Aug 88 09:58:54 EDT Received: from Salvador.ms by ArpaGateway.ms ; 01 AUG 88 06:49:28 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 01 AUG 88 06:47:38 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: with-slots, the saga continues Date: Mon, 01 Aug 88 09:49:39 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880801-064928-1181@Xerox> In PCL 7/20/88: 1. After installing the latest with-slots patches, i came accross the following bug: (defclass foo () ((bar :initform nil) (baz :initform nil))) (defmethod bazz ((foo foo)) (with-slots (bar baz) foo (cons baz bar))) ; Expands OK. (defmethod bazz ((foo foo)) (with-slots (baz) foo baz)) ; Expansion fails, BAZ declared ; special. (defmethod bazz2 ((foo foo)) (with-slots (baz) foo baz ; This BAZ not expanded. baz)) ; This BAZ is expanded. In EXPAND-WITH-SLOTS, shouldn't the BODY of a WITH-SLOTS be walked like it was a PROGN? Here's a patch that seems to work: (defun expand-with-slots (specs body env gensym instance translate-fn) `(let ((,gensym ,instance)) ,@(and (symbolp instance) `((declare (variable-rebinding ,gensym ,instance)))) ,gensym ,@(CDR (walk-form `(PROGN ,@BODY) ; KRA: Walk body as a PROGN. env #'(lambda (f c e) (declare (ignore e)) (expand-with-slots-internal specs f c translate-fn))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jul 88 19:29:08 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 29 JUL 88 16:14:17 PDT Return-Path: Redistributed: CommonLoops.pa Received: from coyote.stanford.edu ([36.12.0.2]) by Xerox.COM ; 29 JUL 88 16:13:08 PDT Received: by coyote.stanford.edu; Fri, 29 Jul 88 16:11:53 PDT Date: Fri, 29 Jul 88 16:11:53 PDT From: Jean-Francois Rit To: Gregor.pa@Xerox.COM Cc: CommonLoops.pa@Xerox.COM In-Reply-To: Gregor.pa@xerox.com's message of Mon, 11 Jul 88 15:28 PDT <19880711222847.1.GREGOR@PORTNOY.parc.xerox.com> Subject: new version of PCL Message-ID: <880729-161417-6487@Xerox> How can I ftp to parcvax.xerox.com? All my attempts failed at login, either by trying my name or anonymous. Also, where can I find the specification of CLOS? Jean-Francois Rit Tel: (415) 723 3796 CS Dept Robotics Laboratory e-mail: rit@coyote.stanford.edu Cedar Hall B7 Stanford, CA 94305-4110  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jul 88 18:55:01 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 29 JUL 88 15:44:56 PDT Return-Path: Redistributed: CommonLoops.pa Received: from labrea.stanford.edu ([36.8.0.47]) by Xerox.COM ; 29 JUL 88 15:43:33 PDT Received: by labrea.stanford.edu; Fri, 29 Jul 88 15:42:42 PDT Received: from blacksox.lucid.com by edsel id AA11491g; Fri, 29 Jul 88 15:11:26 PDT Received: by blacksox id AA00306g; Fri, 29 Jul 88 15:08:12 pdt Date: Fri, 29 Jul 88 15:08:12 pdt From: Eric Benson Message-Id: <8807292208.AA00306@blacksox.lucid.com> To: Gregor.pa@Xerox.COM Cc: CommonLoops.pa@Xerox.COM In-Reply-To: Gregor.pa@xerox.com's message of Fri, 29 Jul 88 11:10 PDT <19880729181046.9.GREGOR@PORTNOY.parc.xerox.com> Subject: [barmar@Think.COM: MULTIPLE-VALUE-SETQ and SYMBOL-MACROLET interaction] MULTIPLE-VALUE-CALL is the wrong thing to use here, since it forces the number of values to match the number of variables. The correct thing is to use MULTIPLE-VALUE-BIND. Here is a modified version of EXPAND-WITH-SLOTS-INTERNAL: (defun expand-with-slots-internal (specs form context translate-fn &aux entry) (cond ((not (eq context :eval)) form) ((symbolp form) (if (setq entry (assoc form specs)) (funcall translate-fn (cadr entry)) form)) ((not (listp form)) form) ((member (car form) '(setq setf)) ;; Have to be careful. We must only convert the form to a SETF ;; form when we convert one of the 'logical' variables to a form ;; Otherwise we will get looping in implementations where setf ;; is a macro which expands into setq. (let ((kind (car form))) (labels ((scan-setf (tail) (if (null tail) nil (walker::relist* tail (if (setq entry (assoc (car tail) specs)) (progn (setq kind 'setf) (funcall translate-fn (cadr entry))) (car tail)) (cadr tail) (scan-setf (cddr tail)))))) (let (new-tail) (setq new-tail (scan-setf (cdr form))) (walker::recons form kind new-tail))))) ((eq (car form) 'multiple-value-setq) (let* ((vars (cadr form)) (gensyms (mapcar #'(lambda (i) (declare (ignore i)) (gensym)) vars))) `(multiple-value-bind ,gensyms ,(caddr form) .,(mapcar #'(lambda (v g) `(setf ,v ,g)) vars gensyms)))) (t form)))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jul 88 16:13:09 EDT Received: from Burger.ms by ArpaGateway.ms ; 29 JUL 88 12:49:07 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 29 JUL 88 12:48:12 PDT Received: by ti.com id AA21060; Fri, 29 Jul 88 14:47:56 CDT Received: from dsg by tilde id AA00456; Fri, 29 Jul 88 14:37:19 CDT Received: From Sierra By dsg Via CHAOS-NET With CHAOS-MAIL; Fri, 29 Jul 88 14:32:03 CDT Message-Id: <2795196702-5977045@Sierra> Sender: KK@Sierra.csc.ti.com Date: Fri, 29 Jul 88 14:31:42 CDT From: Kerry Kimbrough To: CommonLoops.pa@Xerox.COM Subject: get-setf-generic-function This is not in Ch. 2 of June 88 CLOS. Is it in Ch. 3? Or is there now a different standard CLOS interface?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jul 88 14:28:29 EDT Received: from Semillon.ms by ArpaGateway.ms ; 29 JUL 88 11:16:03 PDT Date: Fri, 29 Jul 88 11:11 PDT From: Gregor.pa@Xerox.COM Subject: [barmar@Think.COM: MULTIPLE-VALUE-SETQ and SYMBOL-MACROLET interaction] To: CommonLoops.pa@Xerox.COM cc: Barmar@Think.com Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest Included-msgs: <19880729021542.8.BARMAR@OCCAM.THINK.COM>, The message of 28 Jul 88 19:15 PDT from barmar@Think.COM, The message of 28 Jul 88 19:15 PDT from Barry Margolin Message-ID: <19880729181102.0.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no This message from Barmar points out an ommission in the spec, and a bug in the current version of PCL. This is fixed in the next version of PCL, and a patch is included at the end of this message. Date: Thu, 28 Jul 88 19:15 PDT From: Barry Margolin In CLOS, the way to access slots as if they were lexical variables is to use WITH-SLOTS, which uses SYMBOL-MACROLET to macroexpand occurrences of the slot names into (SLOT-VALUE ') forms. It also converts any SETQ special forms into SETF forms. But what about MULTIPLE-VALUE-SETQ? If SETQ is allowed to assign slot variables then so should MULTIPLE-VALUE-SETQ. To install this patch and save time: 1) edit boot.lisp 2) compile boot.lisp in an already loaded pcl 3) put this changes in their own file, with (in-package 'pcl) 4) compile and load that file in your running pcl You do not need to recompile or reload your application. ;from boot.lisp (defmacro with-slots (slots instance &body body &environment env) (let ((gensym (gensym))) (expand-with-slots (mapcar #'(lambda (ss) (if (symbolp ss) (list ss ss) ss)) slots) body env gensym instance #'(lambda (s) `(slot-value ,gensym ',s))))) (defmacro with-accessors (slot-accessor-pairs instance &body body &environment env) (let ((gensym (gensym))) (expand-with-slots slot-accessor-pairs body env gensym instance #'(lambda (a) `(,a ,gensym))))) (defun expand-with-slots (specs body env gensym instance translate-fn) `(let ((,gensym ,instance)) ,@(and (symbolp instance) `((declare (variable-rebinding ,gensym ,instance)))) ,gensym ,@(walk-form body env #'(lambda (f c e) (declare (ignore e)) (expand-with-slots-internal specs f c translate-fn))))) (defun expand-with-slots-internal (specs form context translate-fn &aux entry) (cond ((not (eq context :eval)) form) ((symbolp form) (if (setq entry (assoc form specs)) (funcall translate-fn (cadr entry)) form)) ((not (listp form)) form) ((member (car form) '(setq setf)) ;; Have to be careful. We must only convert the form to a SETF ;; form when we convert one of the 'logical' variables to a form ;; Otherwise we will get looping in implementations where setf ;; is a macro which expands into setq. (let ((kind (car form))) (labels ((scan-setf (tail) (if (null tail) nil (walker::relist* tail (if (setq entry (assoc (car tail) specs)) (progn (setq kind 'setf) (funcall translate-fn (cadr entry))) (car tail)) (cadr tail) (scan-setf (cddr tail)))))) (let (new-tail) (setq new-tail (scan-setf (cdr form))) (walker::recons form kind new-tail))))) ((eq (car form) 'multiple-value-setq) (let* ((vars (cadr form)) (gensyms (mapcar #'(lambda (i) (declare (ignore i)) (gensym)) vars))) `(multiple-value-call #'(lambda ,gensyms .,(mapcar #'(lambda (v g) `(setf ,v ,g)) vars gensyms)) ,(caddr form)))) (t form))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jul 88 14:28:05 EDT Received: from Semillon.ms by ArpaGateway.ms ; 29 JUL 88 11:14:21 PDT Date: Fri, 29 Jul 88 11:10 PDT From: Gregor.pa@Xerox.COM Subject: [barmar@Think.COM: MULTIPLE-VALUE-SETQ and SYMBOL-MACROLET interaction] To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest Included-msgs: <19880729021542.8.BARMAR@OCCAM.THINK.COM>, The message of 28 Jul 88 19:15 PDT from barmar@Think.COM, The message of 28 Jul 88 19:15 PDT from Barry Margolin Message-ID: <19880729181046.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no This message from Barmar points out an ommission in the spec, and a bug in the current version of PCL. This is fixed in the next version of PCL, and a patch is included at the end of this message. Date: Thu, 28 Jul 88 19:15 PDT From: Barry Margolin In CLOS, the way to access slots as if they were lexical variables is to use WITH-SLOTS, which uses SYMBOL-MACROLET to macroexpand occurrences of the slot names into (SLOT-VALUE ') forms. It also converts any SETQ special forms into SETF forms. But what about MULTIPLE-VALUE-SETQ? If SETQ is allowed to assign slot variables then so should MULTIPLE-VALUE-SETQ. To install this patch and save time: 1) edit boot.lisp 2) compile boot.lisp in an already loaded pcl 3) put this changes in their own file, with (in-package 'pcl) 4) compile and load that file in your running pcl You do not need to recompile or reload your application. ;from boot.lisp (defmacro with-slots (slots instance &body body &environment env) (let ((gensym (gensym))) (expand-with-slots (mapcar #'(lambda (ss) (if (symbolp ss) (list ss ss) ss)) slots) body env gensym instance #'(lambda (s) `(slot-value ,gensym ',s))))) (defmacro with-accessors (slot-accessor-pairs instance &body body &environment env) (let ((gensym (gensym))) (expand-with-slots slot-accessor-pairs body env gensym instance #'(lambda (a) `(,a ,gensym))))) (defun expand-with-slots (specs body env gensym instance translate-fn) `(let ((,gensym ,instance)) ,@(and (symbolp instance) `((declare (variable-rebinding ,gensym ,instance)))) ,gensym ,@(walk-form body env #'(lambda (f c e) (declare (ignore e)) (expand-with-slots-internal specs f c translate-fn))))) (defun expand-with-slots-internal (specs form context translate-fn &aux entry) (cond ((not (eq context :eval)) form) ((symbolp form) (if (setq entry (assoc form specs)) (funcall translate-fn (cadr entry)) form)) ((not (listp form)) form) ((member (car form) '(setq setf)) ;; Have to be careful. We must only convert the form to a SETF ;; form when we convert one of the 'logical' variables to a form ;; Otherwise we will get looping in implementations where setf ;; is a macro which expands into setq. (let ((kind (car form))) (labels ((scan-setf (tail) (if (null tail) nil (walker::relist* tail (if (setq entry (assoc (car tail) specs)) (progn (setq kind 'setf) (funcall translate-fn (cadr entry))) (car tail)) (cadr tail) (scan-setf (cddr tail)))))) (let (new-tail) (setq new-tail (scan-setf (cdr form))) (walker::recons form kind new-tail))))) ((eq (car form) 'multiple-value-setq) (let* ((vars (cadr form)) (gensyms (mapcar #'(lambda (i) (declare (ignore i)) (gensym)) vars))) `(multiple-value-call #'(lambda ,gensyms .,(mapcar #'(lambda (v g) `(setf ,v ,g)) vars gensyms)) ,(caddr form)))) (t form))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jul 88 13:34:42 EDT Received: from Semillon.ms by ArpaGateway.ms ; 29 JUL 88 10:07:23 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 29 JUL 88 10:03:19 PDT Received: by ti.com id AA20215; Fri, 29 Jul 88 12:03:02 CDT Received: from dsg by tilde id AA25547; Fri, 29 Jul 88 11:49:16 CDT Received: From Sierra By dsg Via CHAOS-NET With CHAOS-MAIL; Fri, 29 Jul 88 11:44:00 CDT Message-Id: <2795186633-5372121@Sierra> Sender: KK@Sierra.csc.ti.com Date: Fri, 29 Jul 88 11:43:53 CDT From: Kerry Kimbrough To: CommonLoops.pa@Xerox.COM Subject: PCL releases I've been working with the 7/7 version. But now, although I've received no notice that a newer PCL is available, I've seen references to the 7/20 version. Can I get a clarification of the PCL release policy? What is the most recent version? What future versions are currently planned? Is there a regular schedule of releases? What's the best way to stay up-to-date? What's the plan for coming into full CLOS conformance? What I'm trying to do is distribute a public-domain CLOS-based system with the necessary patches so that it will work for those users for whom PCL is the house CLOS. I'd prefer to target the most recent and most stable version of PCL. I'd prefer not to develop my own patches for CLOS conformance if these are already planned. I'd prefer to minimize the risk of conflicts between my patches and those that are posted to the net in the future. And, naturally, I'd prefer to ship ASAP.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jul 88 21:58:31 EDT Received: from Semillon.ms by ArpaGateway.ms ; 28 JUL 88 18:46:38 PDT Date: Thu, 28 Jul 88 18:43 PDT From: Gregor.pa@Xerox.COM Subject: Re: Other rewrites for merge-methods-into-list To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807251521.AA01254@zaphod.prime.com> Message-ID: <19880729014328.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Mon, 25 Jul 88 10:21:03 EST From: doug@zaphod.LOCAL (Douglas Rand) In a with-slots the variable cannot be the same symbol as a slot name. For example, the following code fails: (with-slots (x y) x (list x y)) (with-accessors ((x foo-x) (y foo-y)) x (list x y)) Anyone who runs into this problem with with-slots or with-accessors should make the following changes to their boot.lisp file. The most efficient way to make this change is: 1) Make the changes to boot.lisp. 2) Recompile boot.lisp. 3) Put the changes in a seperate file, with (in-package 'pcl) at the top. 4) Compile and load that file into your existing image with PCL and your code loaded. This will save you a lot of unecessary recompilation and reloading. ;from boot.lisp (defmacro with-slots (slots instance &body body &environment env) (let ((gensym (gensym))) (expand-with-slots (mapcar #'(lambda (ss) (if (symbolp ss) (list ss ss) ss)) slots) body env gensym instance #'(lambda (s) `(slot-value ,gensym ',s))))) (defmacro with-accessors (slot-accessor-pairs instance &body body &environment env) (let ((gensym (gensym))) (expand-with-slots slot-accessor-pairs body env gensym instance #'(lambda (a) `(,a ,gensym))))) (defun expand-with-slots (specs body env gensym instance translate-fn) `(let ((,gensym ,instance)) ,@(and (symbolp instance) `((declare (variable-rebinding ,gensym ,instance)))) ,gensym ,@(walk-form body env #'(lambda (f c e) (declare (ignore e)) (expand-with-slots-internal specs f c translate-fn))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jul 88 21:58:16 EDT Received: from Semillon.ms by ArpaGateway.ms ; 28 JUL 88 18:21:18 PDT Date: Thu, 28 Jul 88 18:17 PDT From: Gregor.pa@Xerox.COM Subject: bug in 7/20 PCL To: CommonLoops.pa@Xerox.COM Message-ID: <19880729011747.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There is a bug in the 7/20 version of PCL which can cause calls to aref with a list as an argument. This happens inside of methods which have calls to slot-value in them. Anyone who is using the 7/20 version of PCL should make these changes. 1) Make these 4 changes to vector.lisp. 2) In a already loaded pcl, recompile vector.lisp. 3) Get a fresh lisp and reload PCL and your program. You don't need to recompile your code. ;from vector.lisp (defun lookup-pv-1 (isl w0 i0) (let* ((cache *pv-cache-1*) (mask *pv-cache-1-mask*) (offset (%logand mask (%logxor (object-cache-no isl mask) (validate-wrapper i0 w0))))) (without-interrupts (if (and (eq (%svref cache offset) isl) (eq (%svref cache (%1+ offset)) w0)) (aref cache (%+ offset 2)) (let ((pv (with-interrupts (lookup-pv-miss isl w0)))) (setf (%svref cache offset) isl) (setf (%svref cache (%1+ offset)) w0) (setf (%svref cache (%+ offset 2)) pv)))))) (defun lookup-pv-2 (isl w0 i0 w1 i1) (let* ((cache *pv-cache-2*) (mask *pv-cache-2-mask*) (offset (%logand mask (%logxor (object-cache-no isl mask) (validate-wrapper i0 w0) (validate-wrapper i1 w1))))) (without-interrupts (if (and (eq (%svref cache offset) isl) (eq (%svref cache (%1+ offset)) w0) (eq (%svref cache (%+ offset 2)) w1)) (aref cache (%+ offset 4)) (let ((pv (with-interrupts (lookup-pv-miss isl w0 w1)))) (setf (%svref cache offset) isl) (setf (%svref cache (%1+ offset)) w0) (setf (%svref cache (%+ offset 2)) w1) (setf (%svref cache (%+ offset 3)) pv)))))) (defun lookup-pv-3 (isl w0 i0 w1 i1 w2 i2) (let* ((cache *pv-cache-3*) (mask *pv-cache-3-mask*) (offset (%logand mask (%logxor (object-cache-no isl mask) (validate-wrapper i0 w0) (validate-wrapper i1 w1) (validate-wrapper i2 w2))))) (without-interrupts (if (and (eq (%svref cache offset) isl) (eq (%svref cache (%1+ offset)) w0) (eq (%svref cache (%+ offset 2)) w1) (eq (%svref cache (%+ offset 3)) w2)) (aref cache (%+ offset 4)) (let ((pv (with-interrupts (lookup-pv-miss isl w0 w1 w2)))) (setf (%svref cache offset) isl) (setf (%svref cache (%1+ offset)) w0) (setf (%svref cache (%+ offset 2)) w1) (setf (%svref cache (%+ offset 3)) w2) (setf (%svref cache (%+ offset 4)) pv)))))) (defun lookup-pv-n (isl &rest wrappers-and-instances) (let* ((cache *pv-cache-n*) (mask *pv-cache-n-mask*) (offset (object-cache-no isl mask))) (doplist (wrapper instance) ;Slight abuse of this macro, wrappers-and-instances ;but what the hell. (setq offset (boole boole-xor offset (validate-wrapper instance wrapper)))) (setq offset (%logand mask offset)) (without-interrupts (if (and (eq (%svref cache offset) isl) (let ((cached-wrappers (%svref cache (+ offset 1))) (tail wrappers-and-instances)) (loop (cond ((neq (car cached-wrappers) (car tail)) (return nil)) ((or (null cached-wrappers) (null tail)) (return t)) (t (setq cached-wrappers (cdr cached-wrappers) tail (cddr tail))))))) (%svref cache (+ offset 2)) (with-interrupts (let* ((wrappers (gathering ((ws (collecting))) (doplist (w i) wrappers-and-instances (gather w ws)))) (pv (apply #'lookup-pv-miss isl wrappers))) (without-interrupts (setf (%svref cache offset) isl (%svref cache (+ offset 1)) wrappers (%svref cache (+ offset 2)) pv)))))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jul 88 21:57:42 EDT Received: from Burger.ms by ArpaGateway.ms ; 28 JUL 88 16:05:25 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 28 JUL 88 16:00:16 PDT Received: by ti.com id AA11939; Thu, 28 Jul 88 12:03:13 CDT Received: from dsg by tilde id AA28270; Thu, 28 Jul 88 11:56:46 CDT Received: From Sierra By dsg Via CHAOS-NET With CHAOS-MAIL; Thu, 28 Jul 88 11:51:31 CDT Message-Id: <2795100677-207747@Sierra> Sender: KK@Sierra.csc.ti.com Date: Thu, 28 Jul 88 11:51:17 CDT From: Kerry Kimbrough To: CommonLoops.pa@Xerox.COM Subject: Another expand-defmethod-internal bug Version: 7/7 System: TI Explorer Using kanderson's recently-posted version of this, I found the following change necessary to avoid errors running setf methods. **** original (block ,generic-function-name ,@real-body)))) **** modified (block ,(IF (LISTP generic-function-name) (SECOND generic-function-name) generic-function-name) ,@real-body)))) ***************  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jul 88 09:31:56 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 28 JUL 88 06:21:12 PDT Return-Path: Redistributed: commonloops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 28 JUL 88 06:19:29 PDT To: Masayuki Ida cc: commonloops.pa@Xerox.COM Subject: Re: confirmation on EQL In-reply-to: Your message of Wed, 27 Jul 88 14:56:09 +0200. <8807270556.AA14316@kepa.cc.aoyama.junet> Date: Thu, 28 Jul 88 09:23:25 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880728-062112-3088@Xerox> Yes, in the latest 7/20/88 pcl (defmethod foo ((x (eql a))) ...) works but, (defmethod foo ((x (eql 'a))) ...) doesn't work.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jul 88 02:06:00 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 JUL 88 22:59:13 PDT Return-Path: Redistributed: commonloops.pa Received: from uunet.UU.NET ([192.12.141.129]) by Xerox.COM ; 27 JUL 88 22:56:57 PDT Received: from mcvax.UUCP by uunet.UU.NET (5.59/1.14) with UUCP id AA06531; Thu, 28 Jul 88 01:56:41 EDT Received: by mcvax.cwi.nl; Thu, 28 Jul 88 06:44:43 +0200 (MET) Received: from cl.cam.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa22543; 27 Jul 88 18:58 BST Via: harlqn; 27 Jul 88 18:51 BST (UK.AC.Cam.Cl.gnnt) Received: from jung.harlqn.uucp (jung) by harlqn.uucp; Wed, 27 Jul 88 17:21:24 BST Received: by jung.harlqn.uucp (3.2/SMI-3.2) id AA02868; Wed, 27 Jul 88 17:23:38 BST Date: Wed, 27 Jul 88 17:23:38 BST Message-Id: <8807271623.AA02868@jung.harlqn.uucp> To: commonloops.pa@Xerox.COM From: Chris Richardson Sender: mcvax!harlqn.co.uk!chris@uunet.UU.NET Subject: Info on Chapter 3 We would also be interested in obtaining a draft of Chapter 3 of the CLOS specification. Thanks. chris richardson ------------------------------------------------------------------------------ Harlequin Ltd. chris@harlqn.uucp Barrington Hall chris@uk.co.harlqn Barrington ..!uunet!mcvax!ukc!harlqn!chris Cambridge CB2 5RG 0223 872522 (National) England +44-223-872522 (International) -------------------------------------------------------------------------------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jul 88 22:49:42 EDT Received: from Riesling.ms by ArpaGateway.ms ; 27 JUL 88 19:33:12 PDT Return-Path: Redistributed: commonloops.pa Received: from fs3.cs.rpi.edu ([128.213.1.14]) by Xerox.COM ; 27 JUL 88 19:31:41 PDT Received: by fs3.cs.rpi.edu (5.54/1.2-RPI-CS-Dept) id AA17288; Wed, 27 Jul 88 22:11:22 EDT Date: Wed, 27 Jul 88 22:11:51 EDT From: harrisr@turing.cs.rpi.edu (Richard Harris) Received: by turing.cs.rpi.edu (3.2/1.2-RPI-CS-Dept) id AA21017; Wed, 27 Jul 88 22:11:51 EDT Message-Id: <8807280211.AA21017@turing.cs.rpi.edu> To: commonloops.pa@Xerox.COM Subject: KCL I have a group of patches to KCL which enable me to run PCL, CLX, and a simple PCL-based window system. These patches are (nearly) independent of Bill Schelter's KCL patches. I have a file created by calling diff -c akcl-file changed-file >> diff for every changed file, which I am willing to distribute. My mail address is harrisr@turing.cs.rpi.edu Rick Harris A) load-time-eval support (for pcl) cmpeval.lsp: c1symbol-fun: reverse checks for (macro-function fname) and (get fname 'compiler-macro) pcl/kcl-low: load-time-eval definition: (defmacro load-time-eval (form) `(progn ,form)) (si:define-compiler-macro load-time-eval (form) `'(si:|#,| . ,form)) B) &environment fix defmacro.lsp cmplam.lsp pcl/defsys: skip kcl-patches C) describe and inspect of structures and pcl instances describe.lsp D) eval-when handling, symbol interning, #, handling ... 1) interning of symbols and evaluation of #, at load time is much closer to what happens at read time, 2) top-level package operations do not (and do not need to) get run before anything else in the file can be loaded, 3) the functions MAKE-PACKAGE, IN-PACKAGE, SHADOW, SHADOWING-IMPORT, EXPORT, UNEXPORT, USE-PACKAGE, UNUSE-PACKAGE, IMPORT, PROVIDE, REQUIRE, and PROCLAIM behave as though calls to them were wrapped in (EVAL-WHEN (LOAD COMPILE EVAL) ...) and all other function calls behave as though they were wrapped in (EVAL-WHEN (LOAD EVAL) ...) 4) EVAL-WHEN is useful in macros again, and 5) the CL macros DEFMACRO, DEFSTRUCT, DEFVAR, DEFPARAMETER, DEFCONSTANT, DEFTYPE, DEFSETF, and DEFINE-SETF-METHOD wrap (EVAL-WHEN (LOAD COMPILE EVAL) ...) around the forms they produce. cmpaux.c: change set_VV() read.d: string_to_object: use standard_read_object_non_recursive instead of read_object to avoid a problem with #0= (spurious Duplicate definitions message) sfasl.c: use initialize_file() in fasload() unixfasl.c: add initialize_file() and use it in fasload() defstruct.lsp: use eval-when in CL macros evalmacros.lsp: use eval-when in CL macros predlib.lsp: use eval-when in CL macros typep: (typep v '(array x)) works now (for all v and (legal) x) setf.lsp: use eval-when in CL macros cmpenv.lsp: vv changes, add-* changes cmpmain.lsp: changes to data-file output call t1expr-top rather than t1expr cmptop.lsp: vv changes,top-level changes,add t1expr-top,change ctop-write,... basic_kcl.c: replaces sys_kcl.c (I haven't yet made the necessary changes to sys_kcl.c) makebasic: replaces unixport/makefile (until I fix sys_kcl.c) E) add (unsigned_byte 8) array-element-type (for clx) array.c: add aet_byte support gbc.c: add aet_byte support number.c: add fixbyte() sequence.d: add aet_byte support typespec.c: add aet_byte support arraylib.lsp: find-subtype macro for use in make-array cmptype.lsp: type>= change, ...  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jul 88 20:10:02 EDT Received: from Burger.ms by ArpaGateway.ms ; 27 JUL 88 16:36:25 PDT Return-Path: <@RELAY.CS.NET:ida%cc.aoyama.junet@UTOKYO-RELAY.CSNET> Redistributed: commonloops.pa Received: from RELAY.CS.NET ([10.4.0.5]) by Xerox.COM ; 27 JUL 88 16:33:55 PDT Received: from relay2.cs.net by RELAY.CS.NET id ac25001; 27 Jul 88 4:42 EDT Received: from utokyo-relay by RELAY.CS.NET id dl26262; 27 Jul 88 4:23 EDT Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET) id AA27584; Wed, 27 Jul 88 16:04:09 JST Received: by kepa.cc.aoyama.junet (3.2/6.3Junet-1.0) id AA14316; Wed, 27 Jul 88 14:56:09 JST Date: Wed, 27 Jul 88 14:56:09 JST From: Masayuki Ida Return-Path: Message-Id: <8807270556.AA14316@kepa.cc.aoyama.junet> To: commonloops.pa@Xerox.COM Subject: confirmation on EQL Cc: ida%cc.aoyama.junet%UTOKYO-RELAY.CSNet@relay.cs.net I am using March 88 version of PCL. (defmethod foo ((x (eql a))) ...) is OK for PCL. And is interpreted as an individual method for symbol A. But, CLOS specification 88-002R tells the form for EQL-specializer form should be evaluated. I should rewrite the above defmethod to (defmethod foo ((x (eql 'a))) ...) || to conform CLOS spec. Do the July version have no problem on conformance as for eql-thing ? Masayuki Ida  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jul 88 17:19:30 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 JUL 88 13:53:25 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 27 JUL 88 13:51:54 PDT Received: by WILMA.BBN.COM id aa10462; 27 Jul 88 16:47 EDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: 7/7 bugs Date: Wed, 27 Jul 88 16:50:00 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880727-135325-1728@Xerox> Here are some questions, bug reports, and bug fixes for 7/7/88 PCL: 1. Question: Why is DEFINE-BUILT-IN-CLASSES no longer a macro? I presume it is to avoid the explicit COMPILE the old version had. What is the right way for users to add their own built ins? 2. Question: In METHODS.LISP and probably elsewhere there are methods specialized on T when they should be specialized on GENERIC-FUNCTION, say. Is there a good reason for this? Specializing them on T invalidates them unnecesarily every time a new class is defined. 3. Bug: On 3600's M-. only finds method definitions that have been seen by ZMACS, not just loaded it. 4. Gregor's latest version of expand-with-slots had an argument reversed. This version seems to work: (defun expand-with-slots (specs whole body env gensym instance translate-fn) (DECLARE (IGNORE WHOLE)) ; KRA (walk-form `(let ((,gensym ,instance)) ,@(and (symbolp instance) `((declare (variable-rebinding ,gensym ,instance)))) ,GENSYM ; KRA: avoid compiler warnings ,@body) env #'(lambda (f c e) (declare (ignore e)) (expand-with-slots-internal specs f c translate-fn)))) 5. EXPAND-DEFMETHOD-INTERNAL didn't seem to work right when a method contained a CALL-NEXT-METHOD because variables like .ISL. and .PV. were declared special. This version also fixes Jim Larus' complaint about IGNORE declarations. (defun expand-defmethod-internal (generic-function-name qualifiers specialized-lambda-list body env) (declare (values fn-form specializers doc) (ignore qualifiers)) (multiple-value-bind (documentation declarations real-body) (extract-declarations body) (multiple-value-bind (parameters lambda-list specializers) (parse-specialized-lambda-list specialized-lambda-list) (let* ((required-parameters (mapcar #'(lambda (r s) (declare (ignore s)) r) parameters specializers)) (parameters-to-reference (remove nil (FLET ((IGNORED-P (S) ; Is S declared ignored? (DOLIST (D (CDR (FIRST DECLARATIONS))) (WHEN (AND (EQ (FIRST D) 'IGNORE) (MEMBER S (CDR D))) (RETURN T))))) (mapcar #'(lambda (s r) (declare (ignore r)) (and (listp s) (NOT (IGNORED-P (CAR S))) (car s))) specialized-lambda-list required-parameters)))) (class-declarations `(declare ,@(remove nil (mapcar #'(lambda (a s) (and (symbolp s) (neq s 't) `(class ,a ,s))) parameters specializers)))) (method-lambda ;; Remove the documentation string and insert the ;; appropriate class declarations. The documentation ;; string is removed to make it easy for us to insert ;; new declarations later, they will just go after the ;; cadr of the method lambda. The class declarations ;; are inserted to communicate the class of the method's ;; arguments to the code walk. (let () `(lambda ,lambda-list ,class-declarations ,@declarations ,@PARAMETERS-TO-REFERENCE (block ,generic-function-name ,@real-body)))) (call-next-method-p nil) ;flag indicating that call-next-method ;should be in the method definition (next-method-p-p nil) ;flag indicating that next-method-p ;should be in the method definition (save-original-args nil) ;flag indicating whether or not the ;original arguments to the method ;must be preserved. This happens ;for two reasons: ; - the method takes &mumble args, ; so one of the lexical functions ; might be used in a default value ; form ; - call-next-method is used without ; arguments at least once in the ; body of the method (original-args ()) (applyp nil) ;flag indicating whether or not the ;method takes &mumble arguments. If ;it does, it means call-next-method ;without arguments must be APPLY'd ;to original-args. If this gets set ;true, save-original-args is set so ;as well (slots (mapcar #'list required-parameters)) (plist ()) (walked-lambda nil)) (flet ((walk-function (form context env) (cond ((not (eq context ':eval)) form) ((not (listp form)) form) ((eq (car form) 'call-next-method) (setq call-next-method-p 't) (setq save-original-args (not (cdr form))) form) ((eq (car form) 'next-method-p) (setq next-method-p-p 't) form) ((and (eq (car form) 'function) (cond ((eq (cadr form) 'call-next-method) (setq call-next-method-p 't) (setq save-original-args 't) form) ((eq (cadr form) 'next-method-p) (setq next-method-p-p 't) form) (t nil)))) ((and (or (eq (car form) 'slot-value) (eq (car form) 'set-slot-value)) (symbolp (cadr form)) (constantp (caddr form))) (multiple-value-bind (parameter class) (can-optimize-access (cadr form) env) (declare (ignore parameter)) (if class (ecase (car form) (slot-value (optimize-slot-value class form)) (set-slot-value (optimize-set-slot-value class form))) form))) ((eq (car form) 'standard-instance-access) (multiple-value-bind (parameter class) (can-optimize-access (cadr form) env) (if class (optimize-standard-instance-access class parameter form slots) form))) (t form)))) (maybe-warn-about-redundant-ignores declarations parameters-to-reference generic-function-name specializers) (setq walked-lambda (walk-form method-lambda env #'walk-function)) ;; Scan the lambda list to determine whether this method ;; takes &mumble arguments. If it does, we set applyp ;; and save-original-args true. ;; ;; This is also the place where we construct the original arguments ;; lambda list if there has to be one. (dolist (p lambda-list) (if (memq p lambda-list-keywords) (if (eq p '&aux) (let ((aux (memq '&aux lambda-list))) (dolist (a aux) (push a original-args)) (return nil)) (progn (setq applyp t save-original-args t) (push '&rest original-args) (push (make-symbol "AMPERSAND-ARGS") original-args) (return nil))) (push (make-symbol (symbol-name p)) original-args))) (setq original-args (if save-original-args (nreverse original-args) ())) (multiple-value-bind (ignore walked-declarations walked-lambda-body) (extract-declarations (cddr walked-lambda)) (declare (ignore ignore)) (when (some #'cdr slots) (setq slots (sort-slots-into-isl slots)) (setq plist (list* :isl slots plist)) (setq walked-lambda-body (add-pv-binding walked-lambda-body plist required-parameters specializers)) (SETQ WALKED-LAMBDA `(LAMBDA ,LAMBDA-LIST ; KRA where should this go? ,@WALKED-DECLARATIONS ,.WALKED-LAMBDA-BODY))) (when (or next-method-p-p call-next-method-p) (setq plist (list* :needs-next-methods-p 't plist))) (values `(function ,(if (or call-next-method-p next-method-p-p) (add-lexical-functions-to-method-lambda walked-declarations walked-lambda-body walked-lambda original-args lambda-list save-original-args applyp call-next-method-p next-method-p-p) `(lambda ,lambda-list ,@walked-declarations ,.walked-lambda-body))) specializers documentation plist)))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Jul 88 20:11:20 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 JUL 88 14:56:46 PDT Return-Path: Redistributed: CommonLoops.pa Received: from paris.Berkeley.EDU ([128.32.150.46]) by Xerox.COM ; 26 JUL 88 14:53:16 PDT Received: by paris.Berkeley.EDU (5.57/1.25) id AA01222; Tue, 26 Jul 88 14:52:55 PDT From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus) Message-Id: <8807262152.AA01222@paris.Berkeley.EDU> To: Gregor.pa@Xerox.COM, CommonLoops.pa@Xerox.COM Cc: franz!smh@ginger.Berkeley.EDU, franz!layer@ginger.Berkeley.EDU Subject: Notes on the efficiency of the new version of PCL (7/20/88 beta) Reply-To: larus@ginger.Berkeley.EDU Date: Tue, 26 Jul 88 14:52:48 PDT Gregor, The new version of PCL runs about as fast as my old, hacked up version of PCL. However, there are a few simple changes that increase its speed by about 50% or more. (All numbers are from test runs of "Curare", a large program transformation system that I built on top of PCL). The measurements were made in Allegro CL 3.0beta running on a Sun 3/75 with 16MB. Some of the changes are Allegro-dependent and some should work in any CL. However, even the Allegro optimizations are likely to be helpful for other CLs. 1. Increase the size of the constant GENERIC-FUNCTION-CACHE-SIZE from 32 to 64 (methods.lisp). This decreased the execution time of Curare by 20-33%. In one test, the number of calls on PCL::LOOKUP-METHOD-INTERNAL (i.e., the cache-miss code) fell from 5224 to 1335. Interestingly, most of these calls came from built-in methods, mainly INITIALIZE, INITIALIZE-FROM-INIT-PLIST, INITIALIZE-FROM-DEFAULTS, etc., defined on all classes. 2. The following changes (marked with JL) force a few more critical operations to be open-coded. ; dcode.lisp: (defmacro generic-function-cache-offset (mask &rest classes) (let ((cache-numbers (mapcar #'(lambda (class) `(the fixnum (object-cache-no ,class ,mask))) ; JL classes))) (if (cdr cache-numbers) `(logand ,mask (logxor ,@cache-numbers)) `(logand ,mask ,@cache-numbers)))) (defmacro generic-function-cache-entry (cache offset offset-from-offset) `(memory-block-ref ,cache (+ (the fixnum ,offset) ; JL (the fixnum ,offset-from-offset)))) ; JL ; low.lisp (defmacro cache-key-from-wrappers ((size words-per-entry &optional (op 'logxor)) &rest wrappers) (when (or (not (numberp size)) (not (numberp words-per-entry))) (error "Using cache-key-from-wrappers improperly.~@ The size and words-per-entry arguments must be unquoted numbers.")) (when (not (member op '(nil logand logxor))) (error "Using cache-key-from-wrappers improperly.~@ If supplied, the op argument must be an unquoted symbol, and~@ one of LOGAND and LOGXOR.")) ;; Convert the wrapper forms into forms which will fetch the wrapper's ;; cache number. That is what we really need to work with. (setq wrappers (mapcar #'(lambda (w) `(the fixnum (wrapper-cache-no ,w))) wrappers)) ; JL (cond ((and (null (cdr wrappers)) (= size 2)) (car wrappers)) ((eq op 'logand) `(%logand ,(make-memory-block-mask size words-per-entry) ,.wrappers)) ((eq op 'logxor) `(%logand ,(make-memory-block-mask size words-per-entry) (%logxor ,.wrappers))))) 3. Finally, the following two macros (add to excl-low.lisp) optimize the trivial cases of a couple of operations. Yes, the compiler should do this. Yes, the one arg case does occur in practice (in fact, in the discriminator code for methods with a single discriminated argument). (defmacro %logand (&rest args) (cond ((null args) `(logand)) ((cdr args) `(logand .,args)) (t (car args)))) ; JL (defmacro %logxor (&rest args) (cond ((null args) `(logxor)) ((cdr args) `(logxor .,args)) (t (car args)))) ; JL I don't have performance numbers for the latter two optimizations, but I remember that they were on the order of a 20% reduction in the execution time for Curare. /Jim  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Jul 88 15:15:10 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 JUL 88 12:03:39 PDT Return-Path: Redistributed: commonloops.pa Received: from postgres.Berkeley.EDU ([128.32.149.1]) by Xerox.COM ; 26 JUL 88 11:59:26 PDT Received: by postgres.Berkeley.EDU (5.57/1.26) id AA01084; Tue, 26 Jul 88 11:59:05 PDT Date: Tue, 26 Jul 88 11:59:05 PDT From: dcmartin%postgres.Berkeley.EDU@berkeley.edu (David C. Martin) Message-Id: <8807261859.AA01084@postgres.Berkeley.EDU> To: larry@postgres.Berkeley.EDU Subject: shared-class demo.. Cc: commonloops.pa@Xerox.COM this is a uuencode, compressed tar file. to unpack, uudecode in /tmp then uncompress and then untar. to run, compile and load pcl.cl, shared-class.cl and test.cl. the Sample file shows something of the speed and functionality. dcm ps. for PCL 03/17/88 ---- cut here ----- begin 664 soh-demo.tar.Z M'YV0<,:P<2$0@,&#"!,J7,BPH<.'$",>!$'1!@T:( !0C &CAHR,%$'(L'$# M9,B-,6K,L$&1AHP;*6'0B!'C(T6/-VAHE,BSI\^?0(,*'4JTJ-&C2),JA;BC M*8@6*EJ :/*&3!D=()@DF0)E!P@H8<:L"7/FZMO4_*XH1,& M#]8A;]JT>>.F!9LT<^ \C:J@Z8["3O'"R2,GS1DT=$"@&),"1(P<.%A**5-V M[AP0;\R H(.F#(@J;M+8*2-G3AHZ>4"+'A+FKYDWR5]U?6;0"[YCOZ M#8@Z;5F &/-FL?*]9-*8R:,\C!LR(*+/H=-83!TZIDD#!C$G-)T[8>28MH[] M]1S?9-Z,J=.FS-PP=-(0ORT'A/78<-0A!QQOM.7?=2#<\1H:;WP'@AEEF#9> M:>J)$=L9 M''"4D1X(:;CA'QML+-=<&F5\QIYO)D:V(FDHGN@B8XY!!L*,-:Z'H'B?Y2A' M<',,YR.5:=CH'XXZ]M>C;W/4@2-N^;EQ1G;RT6//;Y)QQOP <9=&M[5Z6-H@9)G'GKJ);A@@Y$%5L:H9H2IW!V-T0&> MCQ_J)X>'P FGGQLN4$1%BH-F:FALM"HJ':-IA %"&V&L4:2C(*CW89%SXO?L M>X:IR&NM:;X6AAAI_'4HK5C::L9YZ9G&WX$ "DA@6]&"D$1D@'D(HH@D@B " M6SS.(8*NI+U;!A[G=NDICVW \1>E"::7X5QYN.";;R0$\1V#&SH]=+30XW)LL-46NTT);=749;3@'==>]R60V.,JC0(*1I/69WT)G!02 M"JN-L:H<*3B=P. GH9#G'&BT0%>H9>2MMV1T!*[ X(Y3A((9=;CA][.5%QYY MX$Y#W>ZE5S^;-11H?5M&Q620'30*9]?'.@@XIB$9"FVQ(=H;8JCQ:^23)V!" M>F2TP&N =*@@> (HL%'&:D&FUK33%(D A7K& MC8 M7 ?RZ(;SFI9&?6E1PQ,6P$/*!D)ML"""Q1@ S<(0;")#73PVQM_ MP-6KY/G)87X( @C0$H0I3,$/)9A8 O-W-]/L< [Z(T\9=(?"PMVA-#Y" 94J M6 <@.>J" ;3."!\X0<%9;H4GVHYZ7B@"/^" !3B@ PUM" (K!$$*20B"$)A0 MA"GH (+TKXH:%Y''A\KH8 QN D0Y^"(,?: "# M0^J0A-'KX7+\YS@4$.LU/B1A"^Q0FSJ8AG^2@>0'_=0B2N9-!UI47B"WV(;@ MG7)4,M/>E.KE2A#HX%SE&TTM=: ][H&@ET/$ *2@:++60E#+\8QB0X80I4"((3AE"$,IXQ MC6MLXQMS*$?8O:&.D9F,^C+HP&X&SX];RJ(@85C(0R9RD8T,XR,?&$E23G*9 MEP1/*!^XR4Y^9WZ$>Z"1G-JEESH3YTR0GV>#)#N+O,ST$ MG\,V0P;6'+G@?19P"'CM*YZ[DR9%9 M038>;\W!KX!-X= R>MF_WE,P$I3J29Q2ELAX-:^_2V'AVD*'.$#VAQP%66@E MMUBO-!9AHI&@9A^K1&M*$+1/I:W>G.*:,_0I2*P!T;(>AX+DXL9A'E2J1;'2 MHZ6."#2]^QT(_""QNPJ7M*O[49"\2D(C(<@JKE$/=DBH6?FI@'Y/[6<)80M" M;>I1OA$,KA4U:LVI84>2T:6B+<45FQ&<0)11%6YM1U,DW'[U4>CYS&TR1P;5 M2H:W2[RF$TGH/Z>0SZI9M>CD^$N'Z*&*#BM\\.>("CNC^HBU9FA!@&E44:;Z M\+ .U6H9I"H"JH(8JSH&%%;)"U8SB!5>DI7.6>^JUJZV]:V0,LU<]]0?;YTV MNWM];E\]&U@T#+:P0W[JE$B9V!0RML$\RJV8RZIDRAJ)/)B]YVXY&V$ M%EYP:2&+6K_E.92K* RQOI"' MNNIRK0[$.DZACD/78C/H^],U;BJ,9LPJEL=LFP.%M=E5?%4'QK7^9S,>&!KWV + M6-78$TBOXVM KK/![K.5]-*[%ATS0$@][5O.>$2/=A 86.T['WI1S2#SJCSH MV"WH?4,/?W>-1;71/B]^8/JNMYX;_;/>5?K@FQ[?'B*^BB.6NN/9U'E3Y$_84W-&(Q9D81I+(Q"2LQ1X MF(=ZN(<&@3C]$CUI51!\.(@1$1(V8!$FP4@V$ ,F(1(DT8@AD1(UH!(M\1(S MD!(U 0,L01$P 0,SL!.$&(JB.(JD6(JF>(IXV"Y0T0)48158H15"L8JBXQ10P";S(DMXH1?$ 8M0 M )/@&61$1?;40;+(Q53D">V5HUZ%1EX817)Z!6* 24QTD&5<1F9 0*;T1DE MQ%6"DAK60BJ HBW\H1LGTRY0T"Q=$GZK!KT6"CV6(;M@H_34BG^@2FF ABILC&@(BKVJ"6GDAJ= MLBJMHD6P\AWAUY82R2^YHB 5XR"1)RP)4BS'0CN-@1O,LB7.PA=--H^$TAIQ M.1NUL2VYT2W?$B[C,B,>ES'I(BNNXRX.0E9;LSCU4IHH,AZ/29$/\EP>&2 # M$I(%5 5NAT0*AJJIL)S4! M"*EBX8-: G^5JD#,T3'J0B_V$AN[MF:C&EJN1#FX\X/]H6J68Q5ODRM#8URX MP598UW^ 4QG LWNS6AJU2JVXZJAY43>PDIN'$JPY&ES%.CC'JB6B^H=B*EPM MUJP^5&G1"GG(BH+72J/M BYC "*?$9#BPFZCD2%B 2AL:!JT8EG#VE8\&G-A M 2(@4 *,JJGY\Y,YH&KUHCPF,00@?G5BM!]B]DE63! C)2 M:VJ*!0+@95I=*U=S(0=Y\+79$UYS,R>.*QDF2Z:VP,5I[5CE2)$( 1-, 57R3$>HXU&BW-YL#HI,#%DR[31YA54&$AV:ZB% MPW7]0;EYP+;XZA3ZRJ^_667[M$V @K#LJEL+^[/[&K1PNX; UD K:VHBBP(0 M6Y8AJ$DX.X@W.FMK%,"[GZQK_.4R,V%\!E,< 65U>'"UY4DR$296J^3!%@JR/18V1Y<;'G\R;(,\Z6:Q^=%4JOTBF& MY[*I1[ZS;+[JUSK% 0+_*AC<<30$2\EX)1KN&Z;PRZ(Q-\_K"M#Q1;'V$3V7 MG'.2?$(@<*YZH[EVS+,\AM!X$K53&XX*B;7U/&1=>[AQ;- *9-$*'L8#U3#T;O6=F6R2_/-"S0STVAQRI0JI+ISL% MW:C!A5T:+4DA1SEY,SQP4#S9,09ST#$\Q]>:Y-=N$K>AJEJ@%-*$K4 _;-)6 MC-@6]=B1#0GEE+*@0$V98E^#J.C0P+,YUL,=1 M1DV=2C4$:,QY/ ML 3*H0;($1EG8!QA4!J7HI K'M>L62L%:S+8XUZW0Z8_+&#T]09)VN1FIU_X MUGQDRK-VASM>''=ERAYH^GE4WCE[@^4)O,"240+>[3-Y-$"A>N5>+LK8)^9Y M9]QE/@9GGN9,K<%M#N52#D'S5CA<#"[#K,W7E7K2MSH95>=QZT$IWA]D#L.5 MP>@9HN""A^@75N&.&E^-/M_X"^EPU^CU--P2^\7&S5H=[.!,"MXPS-6FG-8_ M;,DI_>9>L^I@#.FMON4D?=P/73E/S>FJ;N:/OL#U1(47>&1X#MZ4C.IG^NL> ME;W"+*T:L^D4;N9:=.&N_"_ ;3DC+.D&[EUQ.LS?W;V^_E$7 M)TD,SW'82M ?^]R0/!58? DF$19G=03I&(AO*R_HM_Q&O'0CGWQ([DH$&\7 M%V\I/V*2=/(.E?*JAV&Q&V_ \X85_RS$AO&GZBT;S[XO5SD]MV[M-MKK)D?- M1]D4!?*N7NHF7;"54:RB;6-B;SE2YP?,.QX1Y^*!*O>)Q=%A3\97-/5\\6>2 M$389C_72O/620?8T9O9;/O(S7?*[3CC*/7*/_#1P;=^&K5TZ:JC];@8^RJX? MC,D1+!FK.JFKDZOC?:E$JFHK/SN$CG.!O3^CJK\\%_+VRT\N'?L1//MGST^F;L>@Y#W.?1CMHH5L(F%'=HMY[?Q<> ):KM7OX3AP M:VKXUOJ*!X='D[%U.("H6/[F_Q"WM:#GCXJ&>!&)J(F,J!$4,1(E(?]Z(Z(W M4!(@X!*'.(DT< ,R :$A$D$ V( *%I_"# !*L %R !1$0 I&N$O:8R_T-&C MQ(Q5,!J:@BR%$N%GPXZ4;--2;VI+.(S#11$ %<513&[B4(V!+J6H4M#%.S=5 M9[F$!"B5WE*,]Z!2@4H;P0$5R *?"PRL-6I*!QJ0Z8770& -A%,W4$O%&WS" M Q/5@YXM@ M'I"4N*DC* )% FT)49OG9V!)NBE^L/QV1MS: WZ&S@% W @Q>D1X*$LR, 2 MB*CJH'\H"VIJ#M2&]/"XC. >%($PP 7T0248J';?&\ /=+ %*D+]-KXN'KCH M$X)0#Z(8)$A+*"'%T8&9, M:ASD$."[>%LR A0$DXP%C/"/B$K?(8Q,-)! MPU:X#.& [1!"LZ:Q2<,6T MC836\AD6@"!"H%T"@0 14 U>PAN^DGD(#X$@ MBPD0B*,A'C@H* 7SX>> .2.L'Z*/'P@X+"+)88;XL U@B'U(#1. -70H(H ) MR! ID*"\UN#84DEC!N2 X(%*%F'EH@'G,!*B0YKH#@6A1*2)&C$R7, 5 W,@ M(F$1B1/Q.D7!"/$9AN)#M(?-T+6400 DITKB2?P3(H (#(&IP 5[A$*$B:9! M!M H,ANN* &'(H\<17Z1*1($\EAY9H!Z# =HD.V13>0 V&9BA21*7K$T*'+ M>%DX\F6;;X<].]_W?HR9N4)F'R,[6AU]19^:LG76N0P//F)\\BS_U[)X%+'U& M*T9<=O-&4\!//*\&*(H,$2*2?XHH_H4$^@>)4,(,R'^5Z 9<(H]@ T;" %P) M-> \L;I2!VKHW6\C@;AO6D/#&$<4H<,< '?,1(RHBV0)MS #.@"DF$&A"CU MV*%(E Z@ 3/ :9PCIY1/AL ZP@PUH 6PHR\" HS R- #!D-SN #E( 18@[C0 M'@EI" 0!Y5 %ID 04 \0"#X %MB-&B'0'@:$9(-3$A>@AV8AL(3,[>E,/1' MMA 9#,BE^$OPZ05,BM;P LB3>6H3+\!CA($\\ +J$5^P3TS#!="G M*=1J0= M,9'1H5.DR!5IGUQD5W0#,3)LT$@;N3[NDQ?3D6QA((A()G )@^2;&))M@44: MR?.$)&7DDH1+-_(%I#^!8#**0!.81F-D"@ ^@W%.TLDZ:2=F!(VH$3;B1M;D MXZ (3B (-(%V-H NK$4!8!*2 I]8832 ),P%+J#2)0!*# &:$">]()4(%."0(^ M9:@DE:92"J#*(J J9XA*M"%KTIR@$W7"3MR)G(PG=9)5XDD]B2B%9?@(B .Q M(!Y$.Y 01>5)& )(( @D 4YI+"G"". !4P#U9:H6D 22G8B2 2IA!LP$'^ L M0X*9A ),X ED@8#(O%BEJU0 Y])6UA UV2=UI9OLE7$2GM!)'5 NA^6>K)8A M(26NQ)8X*!.EI@28(4$F]DM?% 0>9:2LEC@Q+DK"A8DI\^2AI);"\EIFR^>Q M+;ME!A$),P!;)?XDPL^)6; )'LF 2RH.),$7"6#26CO*,/$QC M"1;+])8A2GIY)^UES_25^C)H&LNA62R-I='DBEQ2:?I) MIHDPQ>+"C)J0$F!63;E(,3/EQ:R6:Q-3?D M)U($)ED>86!?U)4ZF@,$8&7Q.*_'/HB)@$160AF&U*#YX4_8DTPZ+H:&96"> MJ^JN\=#^< *@C0(8 P%B-%@G'P)"S@!E $YH ;@@!'5!MJ"G5N1RJ%J?@M; M"F>R42M!I75 E6I25UH93@)-0(>[]%<()-:@' 1@+56FE\67GM)4RDDA!XWP M4QM!$\W29'I+LV0N1:;/U,Y%4_#02K9(D*BFEJ&0!$!N>D'+YQ&%'*MTCD"E M^H! ; ='B(NK2I*H3\D!3(4I*Y4[Q!0$W "5@!'"Z3*5 \J!)K $@SI.M=$T M#:;5= *]TI/@3'DI+@4!%16:Y@%IVD\CZJJ@"TV#$Q%4;GI0$VHA(:D-M9SJ MB',:3T$ #A@)&74,M%,W^DXO!^]+'!],?U27X' M;IBB5?2*9M&]N46[:/3XHB" AEZ$D6E"R6BK1*-8U8V:T?HI -OH&XVC6Y21 M=E50Z4?)*D]%7%-I;^D) %9<$D*1>U!D0#E'J1B6G#]6?6JZ)ZANWJ4&]J#' MLO+2E!I9/>HU#:G[KR:,3,7J3T78EKC'!L7+40.M#F&M(B*[05=%. M5T9K34%J,2VTVM6BEM9$BUK!ZTIEK3G P);7%WM6DV&Z.UHD3^T]OL'1]@1. ME8-[@*R+S#VH\B@D#L7!>Q,CR.R]H=/W#M[?NY-63^,5/HNR7Q!?UU!\V._4 MZCI56TLB'[&=?.PN8ET^[$AMJZVUO;;8-MMJVVW+;;NMM_VVX-;:/L 7)?YD MU-.H@%@G*)K!,"7$+(<248..Z(DZ5^@^PN6A M<(UN#A2X2M<00MU6N#>"(L*ENK30ZE(>'&Q84=]Q=:7#D@##-N591L MFH7T?5QAA?V>XCVAU^2Y61)8%2EDBQ&>A$$T*0YR=#]$N2D0()'''A5-4 MO):NQ6! M&M:YF%E<(J0]^XR'2:*7Z?AWC6)U_!^LL0[X!)-8L92F"\1Z.Z_ MG*@.TR(H;+S\]B6JV]/[$44O[%;Q&FI%Q-DFOF+& M1>EK?-\A6PR^AG=RZL3$6Q1%[WKU&$LQ^C8VHM(7D5MA/$H"37XY M+(#7^I0/CTEFC-$OWM_TE3ZD&65\*I:1)6%&;&9_'V.%X68HX#."LS8@SOY2 M.;/ G2&=76!VYG3^!-J:/RJO\LDU?Q4A\)G 6@/[+(/T,[L"IG+C$PVW/\$W M8@3@"/\:$7&T?Y'HA"+'_6>)4L)(<(XW 3I*1QA,A(NP$0Y%VI$S."SO"!XE MH84" >0Q7T![+"3O,3XJ@/D8)>KC?<0!^7$_*@?_:!T 9+<< P,R M%QG(HI4@%^1I<)#O])9X"Z9Q5SDE/0*?OA'5DD4.8BS9)$TQ%P2$7])TA0FJ1J4Y)%3 MD;-:4LJ).4 ! end  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Jul 88 15:14:25 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 26 JUL 88 11:44:07 PDT Return-Path: Redistributed: commonloops.pa Received: from moon.src.honeywell.com ([129.30.1.10]) by Xerox.COM ; 26 JUL 88 11:42:02 PDT Return-Path: Received: from pavo.SRC.Honeywell.COM by moon.src.honeywell.com (5.59/smail2.1/05-12-87) id AA16662; Tue, 26 Jul 88 13:39:35 CDT Posted-Date: Tue, 26 Jul 88 13:38:03 CDT Received: by pavo.src.honeywell.com (3.2/SMI-3.2) id AA07626; Tue, 26 Jul 88 13:38:03 CDT Date: Tue, 26 Jul 88 13:38:03 CDT From: alarson@src.honeywell.com (Aaron Larson) Message-Id: <8807261838.AA07626@pavo.src.honeywell.com> To: commonloops.pa@Xerox.COM Subject: bug in pcl::slot-exists-p pcl-system-date = "3/17/88 St. Patrick's Day PCL" lisp implementation = Franz Inc. Extended Common Lisp 2.0 (9/8/87 8:24) (pcl::slot-exists-p obj 'slot-name) returns true for all slot names. Probable cause is the following from slots.lisp: (defun slot-value-using-class--class-internal (class object slot-name dont-call-slot-missing-p default) (with-slot-internal--class (class object slot-name nil) (:instance (index) (get-static-slot--class object index)) (:dynamic (loc newp) (if (eq newp t) (setf (car loc) default) (car loc))) (:class (slotd) (slotd-initform slotd)) (nil () (unless dont-call-slot-missing-p (slot-missing object slot-name))))) Should be something like: (nil () (if dont-call-slot-missing-p (return-from slot-value-using-class--class-internal default) (slot-missing object slot-name))))) For some reason just giving the default rather than using a return-from did not work. Since I noticed this in a non exported function, I didn't spend much time tracking down why. The definition of the function is unchanged in the latest release as well.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Jul 88 11:54:29 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Jul 88 08:47:37 PDT Received: from JUNCO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 438595; Tue 26-Jul-88 11:47:05 EDT Date: Tue, 26 Jul 88 11:46 EDT From: Sonya E. Keene Subject: where I'm going, etc. To: common-lisp-object-system@sail.stanford.edu Message-ID: <19880726154638.0.SKEENE@JUNCO.SCRC.Symbolics.COM> I will be leaving Symbolics this Friday, and my new job is not Lisp-related or CLOS-related. I'm sorry to say that this means I won't be able to continue going to meetings at X3J13, or keeping up with the rest of the CLOS work. I hope to be able to stay on the CLOS mailing list at my new company, and maybe help out with editing of the Meta-object chapter now and then. I did finish writing my book, about one day after we voted to accept CLOS. The book will be available within a couple of weeks. It's called "Object-Oriented Programming in Common Lisp: A Programmer's Guide to CLOS", and it is being published by Addison-Wesley and Symbolics Press. I hope everyone will read and enjoy it. I have many mixed feelings about leaving this community, especially when my book is just about to be published, and while there is still much work to be done on the Meta-object protocol and on the Common Lisp specification itself. Certainly, working with the CLOS group has been a great honor, a wonderful learning experience, and a lot of fun over the last two years. My new job will be a real departure, although it is still in the computer software field. The company is called "ITP boston" and they do factory-automation software. They are spinning off a company to develop and market a product, and I'll be leading the documentation effort of the new spinoff. I looked for a job that would allow me to continue my CLOS and Lisp work, but I didn't find anything that really felt right. Maybe something will eventually turn up in that field for me, and you'll see me at meetings again. In any case, if you're in Boston and want to meet me for lunch or dinner, GIVE ME A CALL! I'd very much like to keep in touch. If the phone numbers below change for any reason, ask David Moon where I am. My home phone is: 617-648-4323 (Arlington, Mass.) On August 8, my work phone will be: 617-499-4200 (Cambridge)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 Jul 88 00:59:57 EDT Received: from Semillon.ms by ArpaGateway.ms ; 25 JUL 88 21:53:58 PDT Return-Path: Redistributed: CommonLoops.pa Received: from avalon.berkeley.edu ([128.32.149.8]) by Xerox.COM ; 25 JUL 88 21:51:47 PDT Received: by avalon.berkeley.edu (5.57/1.26) id AA00236; Mon, 25 Jul 88 21:38:27 PDT Message-Id: <8807260438.AA00236@avalon.berkeley.edu> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: Andreas Paepcke Cc: CommonLoops.pa@Xerox.COM Precedence: special-delivery In-Reply-To: Your message of Mon, 25 Jul 88 13:25:15 PDT <10410.585865515@hplap> Subject: Re: Allocating Instances Date: Mon, 25 Jul 88 21:38:19 PDT Sender: dcmartin%avalon.Berkeley.EDU@Berkeley.EDU I must fully agree w/ Andreas. In my implementation of the shared-object hierarchy, much like Andreas' PCLOS, I made use of the ability of a metaclass to define its own allocate-instance. Although use and ease are not rigorous arguments, the fact that every object is an instance of some class leads me to speculate that you must define a standard-instance just as you have defined a standard-class in order to make the system pure. I don't see how limiting the metaclass protocol to not allow definition of the allocation of instance will do anything except render useless a major portion of that protocol. As for the previous letter about making an instance of a font and checking to see if the font has already been made, the solution of using MAKE-FONT and having the functions FIND-FONT and CACHE-FONT do the work does not allow for a consistent function naming when creating an instance of a class. I see two solutions to this problem: 1) create a new metaclass which caches references to its instances based on some key in allocate instance and (if possible) redefine the make-instance function to be a method so that you can redefine the behaviour or redefine initialize to check for a cache-miss (maybe a special?) and only do initialization on misses; or 2) make the constructor function of a class accessible and use it in make-instance to gain specialization. dcm  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jul 88 21:40:47 EDT Received: from Burger.ms by ArpaGateway.ms ; 25 JUL 88 18:33:44 PDT Return-Path: Redistributed: CommonLoops.pa Received: from hplabs.HP.COM ([15.255.16.7]) by Xerox.COM ; 25 JUL 88 18:32:55 PDT Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Mon, 25 Jul 88 12:24:12 PST Received: from hplap.HPL.HP.COM (hplap.hpl.hp.com) by hplms2.HP.COM; Mon, 25 Jul 88 13:23:46 pdt Received: from hplap by hplap.HPL.HP.COM; Mon, 25 Jul 88 13:25:17 pdt To: Gregor.pa@Xerox.COM Cc: CommonLoops.pa@Xerox.COM Subject: Allocating Instances X-Mailer: mh6.5 Date: Mon, 25 Jul 88 13:25:15 PDT Message-Id: <10410.585865515@hplap> From: Andreas Paepcke In the context of keeping information with CLOS instances by using additional fields in the iwmc-class-static-slots vector, you say that this will not be supported: > This trick is undocumented, and will not be supported as such by CLOS or > in any documented way by PCL. This technique does, however, seem to be a capability rooted in a metaclass' inalienable right to allocate instances. Presumably, a metaclass can allocate instances any way it likes, as long as its slot access mechanisms are adjusted accordingly. Your remark seems to indicate that instance allocation will no longer be in the realm of metaclass design. Unless I misunderstand the implication of your statement, I'd be interested in the reasoning behind this, because I could imagine cases in which a metaclass could benefit from customizing the shape of instances. Andreas  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jul 88 19:47:44 EDT Received: from Burger.ms by ArpaGateway.ms ; 25 JUL 88 16:12:48 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM ([10.7.0.2]) by Xerox.COM ; 25 JUL 88 16:11:31 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA29274; Mon, 25 Jul 88 16:09:55 PDT Received: from lukasiewicz.sun.com ([192.29.43.175]) by snail.sun.com (4.0/SMI-4.0) id AA15020; Mon, 25 Jul 88 16:10:34 PDT Received: by lukasiewicz.sun.com (4.0/SMI-4.0) id AA00588; Mon, 25 Jul 88 16:12:16 PDT Date: Mon, 25 Jul 88 16:12:16 PDT From: jrose@Sun.COM (John Rose) Message-Id: <8807252312.AA00588@lukasiewicz.sun.com> To: commonloops.pa@Xerox.COM Subject: description language classes & the Meta-Object Protocol I'm going to describe a way I'd like to use the Meta-Object Protocol. Hopefully, readers of this list will either tell me why it's a misuse, or assure me that the Meta-Object Protocol will support what I have in mind. Start with a description language L. That is, terms in L denote predicates over some universe U; they describe objects in U. (You could also call L a pattern language.) There is some efficient Lisp function L-APPLY which applies an L-term to a U-object and returns T or NIL, depending on whether the term describes the object. There is one other property of L: There is a Lisp function L-LESSP which takes any two L-terms t1, t2 and compares them, returning T or NIL, depending on whether t1 entails t2 for all U-objects. This is a partial order on the description language. Think of it this way: Less specific terms are greater than more specific ones. Finally, define *L-TOP* to be the L-term which is greater than all other L-terms (the least specific element). (It is possible and useful to make L into a lattice by adding Lisp functions L-MEET and L-JOIN, but I don't think that is necessary for this discussion.) I'd like to define a Meta-Class L-CLASS which models L. In particular, each L-term would correspond to an L-CLASS. An L-term's L-CLASS would have as instances all U-objects which match the L-term. Note that an L-CLASS does not necessarily support MAKE-INSTANCE: As befits a description language, the L-CLASSes merely impose structure on a pre-existing space of U-objects. Methods arguments can be specialized with L-CLASS specializers; such arguments are assumed to be U-objects, and the method is applied only to arguments that match the specializer. That is, the L-CLASS protocol wraps the method body with code which uses L-APPLY to filter out U-objects which don't match the specializer. This is just like STANDARD-CLASS dispatching, except that L-APPLY can interpret L-terms using any algorithm whatsoever. If a generic is applied to a U-object, there will in general be several methods which apply; they must be ordered most specific first. The computation of this ordering is done with the L-LESSP predicate. This works much like STANDARD-CLASS method ordering. When the specializers of applicable methods are not linearly ordered (this case corresponds to class multiple inheritance) , the L-CLASS must specify some sort of linearization, so that CALL-NEXT-METHOD will be useful. In any case, when a U-object is handed to a generic function with L-CLASS specializers, only methods with specializers that correctly describe the U-object are invoked, and then in a reasonable order determined by description specificity. You know, object oriented languages supply two very distinct services that are often confused: Representation management, and argument dispatching. Abstract types can be built from concrete representations, often drawn from a rich set of possibilities (e.g., C++). Abstract functions can be built, piece by piece, from methods, each applicable to a limited set of arguments; the OOL supplies the glue logic which makes sure that each method gets the right kinds of arguments. The distinction between the two services is based on this observation: It is not necessary that the set of representations be identical with the set of dispatchable types. (In practice, it's often useful to tightly coordinate the two services, since the OOL system can then optimize representations for fast dispatch.) Description language classes supply the argument dispatch service only. (By contrast, facilities like DEFSTRUCT construct representations without dispatch services.) For concreteness, I'll give several examples of description languages that could be usefully treated as meta-classes: * Common Lisp types The Common Lisp type system is a description language. L-APPLY is TYPEP, and L-LESSP is SUBTYPEP, although the SUBTYPEP relation is not as rich as the corresponding mathematical subtyping relation. * standard classes If you forget about slots and consing, you can treat standard classes as predicates over their objects. This example is just a special case of the previous. * object identity The EQL specializers support a trivial description language, where all classes are singletons (except *L-TOP*, which is the type T). Here, L-APPLY is only EQL (apart from *L-TOP*) and so is L-LESSP. * Lisp structure patterns Someone from the functional programming community wanted to have specializers which were structure templates. Often the pattern matching incorporates the binding of variables to matched substructures for later access. This sort of thing is extremely useful. (For example, Lisp compilers seem always to have some a destructuring case macro, with which they analyze program syntax.) Interestingly, L-LESSP is straightforward to define for destructuring patterns; it roughly consists of applying the second pattern to the first. * user-interface event patterns This is the application which I've been recently thinking about, which triggered this note. User-interface modules often want to filter the events they see to some small set of "interesting" events. This can be done with an event pattern. Suppose a key event has three attributes: 1. key making the transition, 2. type of transition (e.g., up, down, click), and 3. modifier key state. Then an event pattern would specify a value for each attribute, or specify a wildcard of some sort. Clearly this is a description language. (In fact, it is a product language, made from three languages, one for each attribute.) It is easy to define L-APPLY and L-LESSP. If a module wanted to handle a class of events, it could define a method on an appropriate generic function, specialized to the desired event pattern. The event-pattern meta-class would have the responsibility of building the glue logic to dispatch incoming events to the correct handler. It's good to centralize this logic, because it can then be optimized more readily, and redundant tests eliminated. CLOS double dispatch would help here too: Event handlers could be specialized both to consumer-object mixins and event types. * string regular expressions The theory of regular languages is well understood, and regular expressions are useful in a wide variety of settings. A regular expression meta-class could be used to define complex string handling functions in a modular fashion. Regular languages can be compared for specificity, so an L-LESSP predicate can be defined. Also, efficient methods are known for matching several regular expressions at once to a single string; the meta-class would use these methods to build efficient dispatch ("glue") logic, as in the previous example. * knowledge base queries Pick your favorite database query language. It certainly supports an L-APPLY operation, and probably also supports an L-LESSP. Now, with the right L-CLASS, you can define generic functions over database entries. (It may be more useful to manipulate __sets__ of entries, so U would then be a power set of some sort. This does not hinder the applicability of CLOS.) I hope I have shown that (1) description languages are common and useful, that (2) a general class of description languages are amenable to treatment within the CLOS generic function framework, and that (3) descriptions are very useful as defmethod specializers. The conclusion is that the designers of the Meta-Object protocol should be sure to provide for arbitrary description languages (of the L-APPLY/L-LESSP sort). Finally, here are some smaller open questions about description language classes, along with some possible answers: * How should the L-CLASS specify a linearization of a partially ordered set of applicable methods? [It is sometimes useful to signal an error if there is not a linear ordering available. This could the default, with a hook for other more permissive behavior.] * What if the L-LESSP relation is not always effectively computable? (E.g., LISP:SUBTYPEP gives up sometimes.) [Allow the L-LESSP relation to give up, and treat this outcome like incomparability. It should be possible to signal an error here, while still doing something permissive on true incomparability.] * If the L-term has "wildcards" in it, how should the L-CLASS mediate the binding of the corresponding U-object subparts to names for use in method bodies? [I believe the current protocol (e.g., DEFINE-METHOD-COMBINATION) provides enough hooks for this. The hook which asks a meta-class for dispatch code should also accept LET-bindings, which would be constructed along with the dispatch code, and wrapped around the affected method body.] * What sort of syntax should L-CLASS specializers have? [The (EQL ...) syntax should be extended, I think. The basic idea is that EQL is a meta-class name, and the arguments to it are handed to the meta-class constructor, which then builds the appropriate class object. This is probably already the intention of the CLOS designers, but I want to affirm that choice.] Let me close with a suggestive example: (DEFMETHOD EVAL ((X (FORM `(,F . ,A)))) (APPLY (EVAL `#',F) (MAPCAR #'EVAL A))) (DEFMETHOD EVAL ((X (FORM `(IF ,P ,A ,B)))) (IF (EVAL P) (EVAL A) (EVAL B))) This example uses a hypthetical description language called FORM, whose terms are backquoted constructors, interpreted in reverse. (Or, if you like, declaratively as opposed to imperatively.) Note that the specificity ordering ensures that IF forms will not get passed to the first method, even though they match its specializer. -- John  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jul 88 16:57:42 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 25 JUL 88 13:45:43 PDT Date: 25 Jul 88 13:44 PDT From: Stan Lanning Subject: Re: managing a resource of instances In-reply-to: hmuller@Sun.COM (Hans Muller)'s message of Mon, 25 Jul 88 13:26:12 PDT To: hmuller@Sun.COM (Hans Muller) cc: CommonLoops.PA@Xerox.COM Message-ID: <880725-134543-9175@Xerox> I think this is a good reason why programs should provide their own constructors instead of using MAKE-INSTANCE as their public interface to object creation. If you defined your own MAKE-FONT function, you could accomplish exactly what you want: (defun MAKE-FONT (&rest initargs) (or (FIND-FONT initargs) (CACHE-FONT (apply #'MAKE-INSTANCE 'font initargs) initargs))) ----- smL  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jul 88 16:38:14 EDT Received: from Riesling.ms by ArpaGateway.ms ; 25 JUL 88 13:26:38 PDT Return-Path: Redistributed: CommonLoops.PA Received: from Sun.COM ([10.7.0.2]) by Xerox.COM ; 25 JUL 88 13:25:02 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA24811; Mon, 25 Jul 88 13:23:26 PDT Received: from cumulus.sun.com by snail.sun.com (4.0/SMI-4.0) id AA07690; Mon, 25 Jul 88 13:24:05 PDT Received: by cumulus.sun.com (3.2/SMI-3.2) id AA11687; Mon, 25 Jul 88 13:26:12 PDT Date: Mon, 25 Jul 88 13:26:12 PDT From: hmuller@Sun.COM (Hans Muller) Message-Id: <8807252026.AA11687@cumulus.sun.com> To: CommonLoops.PA@Xerox.COM Subject: managing a resource of instances How would one set up make-instance to do the following for some class, say FONT. When creating an instance of a font check to see if a font with the same initialization arguments has been created already. If so then return the old font instance otherwise return a new one. The CLOS definition for make-instance looks like this: (defmethod make-instance ((class standard-class) &rest initargs) (setq init-args (default-initargs class initargs)) ... (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance)) I suppose what I'd like to do is gain control after initargs has been bound and then just return an old instance if one existed that had been created with the same initargs. Unfortunately this can't be done directly. What one could do is specialize allocate-instance - make it try and find an appropriate old instance - and specialize initialize-instance - make it a noop when given an old instance. The principal flaw with this is that allocate-instance isn't part of the exported CLOS interface. Seems a little underhanded to depend on it. Is there a "right" way to do this? Thanks, Hans Muller  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jul 88 15:05:29 EDT Received: from Burger.ms by ArpaGateway.ms ; 25 JUL 88 11:54:59 PDT Return-Path: Redistributed: CommonLoops.pa Received: from paris.Berkeley.EDU ([128.32.150.46]) by Xerox.COM ; 25 JUL 88 11:53:58 PDT Received: by paris.Berkeley.EDU (5.57/1.25) id AA10489; Mon, 25 Jul 88 11:52:26 PDT From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus) Message-Id: <8807251852.AA10489@paris.Berkeley.EDU> To: Kiuchi.pa@Xerox.COM Cc: CommonLoops.pa@Xerox.COM Subject: Re: Bug in 7/20/88 (beta) PCL In-Reply-To: Your message of 25 Jul 88 11:11:00 PDT. <880725-112510-8784@Xerox> Reply-To: larus@ginger.Berkeley.EDU Date: Mon, 25 Jul 88 11:52:21 PDT Thanks for your explaination. I can't say that I understand the rationale for this design decision, but that is a problem that should be brought up elsewhere. /Jim  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jul 88 14:42:22 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 25 JUL 88 11:33:08 PDT Return-Path: Redistributed: commonloops.pa Received: from prost.llnl.gov ([128.115.19.16]) by Xerox.COM ; 25 JUL 88 11:29:31 PDT Received: by prost.llnl.gov (3.2/1.14) id AA16591; Mon, 25 Jul 88 11:26:04 PDT Date: Mon, 25 Jul 88 11:26:04 PDT From: daven@prost.llnl.gov (David Nelson) Message-Id: <8807251826.AA16591@prost.llnl.gov> To: commonloops.pa@Xerox.COM Subject: Info on Chapter 3 I know that Chapter 3 (Meta-Object Protocol) is not yet final. However, some people here are exploring class and category description issues in Mathematics (specifically, Differential Geometry and Analysis), and would be very interested in the tools available for describing metaclasses, methods of inheritance, genericity, and the like. Is it possible to get ahold of a description of the current thinking of the CLOS design committee (collective, cabal, community, conspiracy, or whatever :-) on what the meta-object protocol is shaping up to be? Thanx, Dave Nelson (daven@crg.llnl.gov)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jul 88 14:42:11 EDT Received: from Semillon.ms by ArpaGateway.ms ; 25 JUL 88 11:25:10 PDT Date: 25 Jul 88 11:11 PDT From: kiuchi.pa@Xerox.COM Subject: Re: Bug in 7/20/88 (beta) PCL In-reply-to: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus)'s message of Sun, 24 Jul 88 15:30:29 PDT To: larus@ginger.Berkeley.EDU cc: kiuchi.pa@Xerox.COM, CommonLoops.pa@Xerox.COM Reply-to: Kiuchi.pa@Xerox.COM Message-ID: <880725-112510-8784@Xerox> In CLOS spec. Charper2 2-40 defmethod, fourth paragraph in Remarks:, there is a description: " The exapnsion of the defmethod macro "refer to" each specialized parameter(see the description od ignore in Common Lisp: The Language. p. 160). This includes parameters that have an explicit parameter specializer name of t. This means that a compiler warning does not occur if the body of the method does not refer to a specialized parameter." This mean all specailized parameters should be referenced and ignore declarations are redundant for specailized parameters. Yasuhiko Kiuchi  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jul 88 18:40:43 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUL 88 15:33:20 PDT Return-Path: Redistributed: CommonLoops.pa Received: from paris.Berkeley.EDU ([128.32.150.46]) by Xerox.COM ; 24 JUL 88 15:32:10 PDT Received: by paris.Berkeley.EDU (5.57/1.25) id AA16285; Sun, 24 Jul 88 15:30:35 PDT From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus) Message-Id: <8807242230.AA16285@paris.Berkeley.EDU> To: Gregor.pa@Xerox.COM, CommonLoops.pa@Xerox.COM Subject: Bug in 7/20/88 (beta) PCL Reply-To: larus@ginger.Berkeley.EDU Date: Sun, 24 Jul 88 15:30:29 PDT The following method gets (two!) warning messages when compiled: (defmethod foo ((a bar)) (declare (ignore a)) nil) Warning: In defmethod FOO (BAR), there is a redundant ignore declaration for the A parameter. Warning: variable A is used yet it was declared ignored The problem arises because of the useless PROGN that DEFMETHOD inserts into the body of this method. (Perhaps you only meant to insert this form for functions that call CALL-NEXT-METHOD?) /Jim  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jul 88 20:47:18 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUL 88 17:42:04 PDT Date: Fri, 22 Jul 88 17:39 PDT From: Gregor.pa@Xerox.COM Subject: bug in 7/20/88 PCL To: CommonLoops.pa@Xerox.COM Message-ID: <19880723003926.0.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There is a bug in the 7/20/88 PCL which will prevent slot-value from working in certain methods where there are calls to slot-value with more than one slot-name. The following patch should be made to the file vector.lisp. You can load this function into an existing PCL. You don't have to reload PCL, or recompile or reload your code. ;from vector.lisp (defun pv-access-trap (instance offset isl &optional (new-value nil nvp)) (let ((slot-name nil) (i 0)) (dolist (per-class-slots (cdr isl)) (dolist (slot per-class-slots) (when (= i offset) (return (setq slot-name slot))) (incf i))) (when (null slot-name) (error "Internal Error:~@ Unable to determine the name of the slot from the PV-OFFSET~@ and the ISL. This results from inconsistency between the~@ PV-OFFSET this access was told to use and the ISL for the~@ method.")) (if nvp (put-slot-using-class (class-of instance) instance slot-name new-value) (slot-value-using-class (class-of instance) instance slot-name)))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jul 88 19:19:00 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUL 88 16:02:05 PDT Date: Fri, 22 Jul 88 15:57 PDT From: Gregor.pa@Xerox.COM Subject: Re: method discrimination on persistent objects To: Larry Rowe cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807061906.AA13139@postgres.Berkeley.EDU> Supersedes: <19880722013224.5.GREGOR@PORTNOY.parc.xerox.com>, <19880722164004.9.GREGOR@PORTNOY.parc.xerox.com>, <19880722225535.6.GREGOR@PORTNOY.parc.xerox.com> Comments: version 4 Message-ID: <19880722225737.7.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Oh hell. One more random typo fixed. This is version 4. This message is a version of the db-class stuff with all the changes incorporated. Typos are fixed, and the stuff which makes inherited slot accesses be deoptimized is included. I have spent a little time thinking about the question you asked. I haven't answered sooner because I have been to busy to type in a long reply. I am still too busy so this will be a short reply. Once I get back from the Lisp conference I will be able to send more. It seems to me that having make-instance return an object-id rather than an object itself is causing problems. I think a form of your third solution is the way to go. Here are some ideas about how to do it in PCL. Some of this is undocumented PCL, and will change in the next few months. But there is a corresponding part to all of this in the Chapter 3 we are working on. We will define a new metaclass called db-class. The feature of this metaclass is that it will store the values of the slots for its metainstances in the database. The only thing stored in core will be the object-id of the instance. This implementation has an important problem which could be fixed later. It allocates space for the database slots in core even though this space is never used. This could be fixed later, remind me next week after the Lisp Conference. (defclass db-class (standard-class) ()) As soon as the instances are allocated, we have to set their object-id. (defmethod allocate-instance ((class db-class)) (let ((instance (call-next-method))) (setf (slot-value instance 'object-id) (allocate-object-id)) instance)) We need to add the special slot object-id slot to all db-classes. This just arranges to tack the slot onto all the other slots a given db-class inherits. (defmethod collect-slotds ((class db-class) local-slots cpl) (cons (make-slotd (find-class 'standard-slot-description) :name 'object-id :allocation :instance) (call-next-method))) Now we need to teach slot-value for the class to use the value stored in the database. Of course the object-id slot is special as it is stored in core. (defmethod slot-value-using-class ((class db-class) object slot-name) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (class-slots class) :key #'slotd-name) (GET-VALUE-FROM-DB (slot-value object 'object-id) slot-name) (slot-missing object slot-name)))) (defmethod put-slot-using-class ((class db-class) object slot-name new-value) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (class-slots class) :key #'slotd-name) (PUT-VALUE-IN-DB (slot-value object 'object-id) slot-name new-value) (slot-missing object slot-name)))) We also want to be able to use automatically generated accessor methods to access the slots. We need to make sure PCL uses the right code for getting at these slots. (defmethod make-reader-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object) (slot-value object slot-name)))) (defmethod make-writer-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object new-value) (setf (slot-value object slot-name) new-value)))) We need to make sure that any optimized calls to slot-value we inherit get deoptimized appropriately. We also need to have optimized accessor methods get deoptimized appropriately. De-optimization means having any calls to these trap out to calling slot-value-using-class or put-slot-using-class. This code takes advantage of undocumented PCL functionality. Well, its documented now because I just told you about it. There will be a more elegant mechanism for doing this in future versions of PCL, as well as in the CLOS spec. This method arranges for all optimized accesses to any slot of a db-class to trap through slot-value-using-class. (defmethod lookup-pv-miss-1 ((class db-class) slots pv) (dolist (slot slots) (push nil pv)) pv) This method arranges for all inherited reader and writer methods to trap through slot-value-using-class. (defmethod all-std-class-readers-miss-1 ((class db-class) slot-name) ()) Given this, the proper method for check-super-metaclass-compatibility is. (defmethod check-super-metaclass-compatibility ((class db-class) (new-super standard-class)) t) It doesn't seem worth doing slot-value optimization because of the time required to go to the database. We have to disable the optimization method we would otherwise inherit. (defmethod optimize-slot-value ((class db-class) form) form) (defmethod optimize-set-slot-value ((class db-class) form) form) Here are some stubs for the Database stuff. This just arranges to store the values in a different place so that we can show that the values aren't being stored in the instance. Note that the way I have this setup, the database doesn't get any advance warning about the existence of a new object id. That would be easy to fix by having allocate-object-id inform the database it just made a new id. (defvar *db* ()) (defun get-value-from-db (object-id slot-name) (getf (cdr (get-db-internal object-id)) slot-name)) (defun put-value-in-db (object-id slot-name new-value) (setf (getf (cdr (get-db-internal object-id)) slot-name) new-value)) (defun get-db-internal (object-id) (let ((instance (assq object-id *db*))) (unless instance (setq instance (list object-id)) (push instance *db*)) instance)) (defun allocate-object-id () (gensym)) ;;; ;;; Here is some code that tries it all out. ;;; (defclass pos () ((x :initform 0 :accessor pos-x) (y :initform 0 :accessor pos-y))) (defmethod describe-object ((p pos) stream) (format stream "~&~S is a position, stored in the database.~@ Its x coordinate is ~D, its y coordinate is ~D." p (pos-x p) (pos-y p))) (defmethod move ((p pos) dx dy) (with-slots (x y) p (incf x dx) (incf y dy))) (defclass db-pos (pos) () (:metaclass db-class)) (setq p1 (mki 'db-pos)) # (move p1 -3 5) (describe-object p1 *standard-output*) # is a position, stored in the database. Its x coordinate is -3, its y coordinate is 5. ;;; ;;; The following patches must be made to the 7/20 version of PCL for ;;; the strategy outlined above to work. The nature of these changes ;;; is such that you will have to make them, use compile-pcl to compile ;;; them, load a fresh pcl, and load your code. You do not have to ;;; recompile your code. ;;; ;from vector.lisp, replace lookup-pv-miss with these two definitions (defun lookup-pv-miss (isl &rest wrappers) (let ((pv ()) (class-slots nil)) (dolist (slots (cdr isl)) (when slots (when (null wrappers) (error "Fewer classes than indicated by the isl.")) (let ((class (class-wrapper-class (pop wrappers)))) (setq pv (lookup-pv-miss-1 class slots pv))))) (when wrappers (error "More classes than indicated by the isl.")) (intern-pv (reverse pv)))) (defmethod lookup-pv-miss-1 ((class standard-class) slots pv) ;; *** Later this wants to fetch the cached info from ;; *** the class wrapper. (let ((class-slots (class-instance-slots class))) (dolist (slot slots) (push (position slot class-slots :key #'slotd-name) pv)) pv)) ;from vector.lisp, replace pv-access-trap with this definition. (defun pv-access-trap (instance offset isl &optional (new-value nil nvp)) (let ((slot-name nil) (i 0)) (dolist (per-class-slots (cdr isl)) (dolist (slot per-class-slots) (when (= i offset) (return (setq slot-name slot))) (incf i))) (when (null slot-name) (error "Internal Error:~@ Unable to determine the name of the slot from the PV-OFFSET~@ and the ISL. This results from inconsistency between the~@ PV-OFFSET this access was told to use and the ISL for the~@ method.")) (if nvp (put-slot-using-class (class-of instance) instance slot-name new-value) (slot-value-using-class (class-of instance) instance slot-name)))) ;from dcode.lisp replace the definition of all-std-class-readers-miss ;with the following definition (defun all-std-class-readers-miss (arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn ;; This is an instance slot. Convert it's position to its ;; index, then cache the index. Return the value of the slot. (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (get-static-slot--class arg slot-pos)) (slot-value-using-class class arg slot-name)))))) ;from dcode.lisp, add this definition (defmethod all-std-class-readers-miss-1 ((class standard-class) slot-name) (slotd-position slot-name (class-instance-slots class))) ;from dcode.lisp replace the definition of all-std-class-writers-miss ;with the following definition (defun all-std-class-writers-miss (new-value arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (setf (get-static-slot--class arg slot-pos) new-value)) (put-slot-using-class class arg slot-name new-value)))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jul 88 19:18:29 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUL 88 15:58:29 PDT Date: Fri, 22 Jul 88 15:55 PDT From: Gregor.pa@Xerox.COM Subject: Re: method discrimination on persistent objects To: Larry Rowe cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807061906.AA13139@postgres.Berkeley.EDU> Supersedes: <19880722013224.5.GREGOR@PORTNOY.parc.xerox.com>, <19880722164004.9.GREGOR@PORTNOY.parc.xerox.com> Comments: version 3 version 3 Message-ID: <19880722225535.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Ken pointed out a couple more typos in my previous message. This message is a version of the db-class stuff with all the changes incorporated. Typos are fixed, and the stuff which makes inherited slot accesses be deoptimized is included. I have spent a little time thinking about the question you asked. I haven't answered sooner because I have been to busy to type in a long reply. I am still too busy so this will be a short reply. Once I get back from the Lisp conference I will be able to send more. It seems to me that having make-instance return an object-id rather than an object itself is causing problems. I think a form of your third solution is the way to go. Here are some ideas about how to do it in PCL. Some of this is undocumented PCL, and will change in the next few months. But there is a corresponding part to all of this in the Chapter 3 we are working on. We will define a new metaclass called db-class. The feature of this metaclass is that it will store the values of the slots for its metainstances in the database. The only thing stored in core will be the object-id of the instance. This implementation has an important problem which could be fixed later. It allocates space for the database slots in core even though this space is never used. This could be fixed later, remind me next week after the Lisp Conference. (defclass db-class (standard-class) ()) As soon as the instances are allocated, we have to set their object-id. (defmethod allocate-instance ((class db-class)) (let ((instance (call-next-method))) (setf (slot-value instance 'object-id) (allocate-object-id)) instance)) We need to add the special slot object-id slot to all db-classes. This just arranges to tack the slot onto all the other slots a given db-class inherits. (defmethod collect-slotds ((class db-class) local-slots cpl) (cons (make-slotd (find-class 'standard-slot-description) :name 'object-id :allocation :instance) (call-next-method))) Now we need to teach slot-value for the class to use the value stored in the database. Of course the object-id slot is special as it is stored in core. (defmethod slot-value-using-class ((class db-class) object slot-name) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (class-slots class) :key #'slotd-name) (GET-VALUE-FROM-DB (slot-value object 'object-id) slot-name) (slot-missing object slot-name)))) (defmethod put-slot-using-class ((class db-class) object slot-name new-value) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (class-slots class) :key #'slotd-name) (PUT-VALUE-IN-DB (slot-value object 'object-id) slot-name new-value) (slot-missing object slot-name)))) We also want to be able to use automatically generated accessor methods to access the slots. We need to make sure PCL uses the right code for getting at these slots. (defmethod make-reader-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object) (slot-value object slot-name)))) (defmethod make-writer-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object new-value) (setf (slot-value object slot-name) new-value)))) We need to make sure that any optimized calls to slot-value we inherit get deoptimized appropriately. We also need to have optimized accessor methods get deoptimized appropriately. De-optimization means having any calls to these trap out to calling slot-value-using-class or put-slot-using-class. This code takes advantage of undocumented PCL functionality. Well, its documented now because I just told you about it. There will be a more elegant mechanism for doing this in future versions of PCL, as well as in the CLOS spec. This method arranges for all optimized accesses to any slot of a db-class to trap through slot-value-using-class. (defmethod lookup-pv-miss-1 ((class db-class) slots pv) (dolist (slot slots) (push nil pv)) pv) This method arranges for all inherited reader and writer methods to trap through slot-value-using-class. (defmethod all-std-class-readers-miss-1 ((class db-class) slot-name) ()) Given this, the proper method for check-super-metaclass-compatibility is. (defmethod check-super-metaclass-compatibility ((class db-class) (new-super standard-class)) t) It doesn't seem worth doing slot-value optimization because of the time required to go to the database. We have to disable the optimization method we would otherwise inherit. (defmethod optimize-slot-value ((class db-class) form) form) (defmethod optimize-set-slot-value ((class db-class) form) form) Here are some stubs for the Database stuff. This just arranges to store the values in a different place so that we can show that the values aren't being stored in the instance. Note that the way I have this setup, the database doesn't get any advance warning about the existence of a new object id. That would be easy to fix by having allocate-object-id inform the database it just made a new id. (defvar *db* ()) (defun get-value-from-db (object-id slot-name) (getf (cdr (get-db-internal object-id)) slot-name)) (defun put-value-in-db (object-id slot-name new-value) (setf (getf (cdr (get-db-internal object-id)) slot-name) new-value)) (defun get-db-internal (object-id) (let ((instance (assq object-id *db*))) (unless instance (setq instance (list object-id)) (push instance *db*)) instance)) (defun allocate-object-id () (gensym)) ;;; ;;; Here is some code that tries it all out. ;;; (defclass pos () ((x :initform 0 :accessor pos-x) (y :initform 0 :accessor pos-y))) (defmethod describe-object ((p pos) stream) (format stream "~&~S is a position, stored in the database.~@ Its x coordinate is ~D, its y coordinate is ~D." p (pos-x p) (pos-y p))) (defmethod move ((p pos) dx dy) (with-slots (x y) p (incf x dx) (incf y dy))) (defclass db-pos (pos) () (:metaclass db-class)) (setq p1 (mki 'db-pos)) # (move p1 -3 5) (describe-object p1 *standard-output*) # is a position, stored in the database. Its x coordinate is -3, its y coordinate is 5. ;;; ;;; The following patches must be made to the 7/20 version of PCL for ;;; the strategy outlined above to work. The nature of these changes ;;; is such that you will have to make them, use compile-pcl to compile ;;; them, load a fresh pcl, and load your code. You do not have to ;;; recompile your code. ;;; ;from vector.lisp, replace lookup-pv-miss with these two definitions (defun lookup-pv-miss (isl &rest wrappers) (let ((pv ()) (class-slots nil)) (dolist (slots (cdr isl)) (when slots (when (null wrappers) (error "Fewer classes than indicated by the isl.")) (let ((class (class-wrapper-class (pop wrappers)))) (setq pv (lookup-pv-miss-1 class slots pv))))) (when wrappers (error "More classes than indicated by the isl.")) (intern-pv (reverse pv)))) (defmethod lookup-pv-miss-1 ((class standard-class) slots pv) ;; *** Later this wants to fetch the cached info from ;; *** the class wrapper. (let ((class-slots (class-instance-slots class))) (dolist (slot slots) (push (position slot class-slots :key #'slotd-name) pv)) pv)) ;from vector.lisp, replace pv-access-trap with this definition. (defun pv-access-trap (instance offset isl &optional (new-value nil nvp)) (let ((slot-name nil) (i 0)) (dolist (per-class-slots (cdr isl)) (dolist (slot per-class-slots) (when (= i offset) (return (setq slot-name slot))))) (when (null slot-name) (error "Internal Error:~@ Unable to determine the name of the slot from the PV-OFFSET~@ and the ISL. This results from inconsistency between the~@ PV-OFFSET this access was told to use and the ISL for the~@ method.")) (if nvp (put-slot-using-class (class-of instance) instance slot-name new-value) (slot-value-using-class (class-of instance) instance slot-name)))) ;from dcode.lisp replace the definition of all-std-class-readers-miss ;with the following definition (defun all-std-class-readers-miss (arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn ;; This is an instance slot. Convert it's position to its ;; index, then cache the index. Return the value of the slot. (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (get-static-slot--class arg slot-pos)) (slot-value-using-class class arg slot-name)))))) ;from dcode.lisp, add this definition (defmethod all-std-class-readers-miss-1 ((class standard-class) slot-name) (slotd-position slot-name (class-instance-slots class))) ;from dcode.lisp replace the definition of all-std-class-writers-miss ;with the following definition (defun all-std-class-writers-miss (new-value arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (setf (get-static-slot--class arg slot-pos) new-value)) (put-slot-using-class class arg slot-name new-value)))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jul 88 17:49:23 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 22 JUL 88 14:39:55 PDT Return-Path: Redistributed: CommonLoops.pa Received: from postgres.Berkeley.EDU ([128.32.149.1]) by Xerox.COM ; 22 JUL 88 14:37:09 PDT Received: by postgres.Berkeley.EDU (5.57/1.26) id AA24354; Fri, 22 Jul 88 14:36:28 PDT Message-Id: <8807222136.AA24354@postgres.Berkeley.EDU> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: CommonLoops.pa@Xerox.COM Precedence: special-delivery In-Reply-To: Your message of Fri, 22 Jul 88 11:26 PDT <19880722182607.1.GREGOR@PORTNOY.parc.xerox.com> Subject: Re: Persistent objects Date: Fri, 22 Jul 88 14:36:27 PDT Sender: dcmartin%postgres.Berkeley.EDU@Berkeley.EDU I reimplemented the Shared Object Hierarchy under the 3/17/88 PCL and made use of the iwmc-class structure to reference through a handle to get the shared semantics. Basically, I make two iwmc-class structs and set the same class-wrapper pointer for both. The handle instance has a simple-vector off the iwmc-class-static-slots which contains the object-id and a cache reference to the storage instance. The storage instance is a standard instance and has the standard simple-vector for storing the instance values. I then make use of a hash-table to allow an object-manager to flush arbitrary shared-objects (the storage instance) to the dbms and invalidate the handle's cache reference (via a backward pointer to the handle from the hash-table). I have extended this design to include both shared-objects and shared-classes. dcm ps. code on demand. -------- Your message: Date: Fri, 22 Jul 88 09:24:47 PDT From: Andreas Paepcke The PCLOS imlementation is similar to what Gregor outlines. The object id, however, doesn't show up as a slot which would be seen by the user thro ugh 'describe'. Information like the object id is instead hidden in some fi elds at the beginning of the slot value vector. This is one of the tricks t hat are easy to do through a new metaclass and it adds to the transparency of persistence. This trick is undocumented, and will not be supported as such by CLOS or in any documented way by PCL. The really proper way to do this is to use a slot. To hide this slot from describe, you should define your own describe method which doesn't show it. This is good style for using describe anyways. The problem with slot access optimization by methods of superclasses of a different metaclass is insidious. It has caused me grief until I unders tood it. Unfortunately the solution Gregor suggests - of simply not allowing such inheritance - is problematic in the real world. We have encountere d several cases where we needed to inherit in this way and the superclass es could not be touched because we get them canned. There was originally t alk about an "unoptimize" capability which would presumably go through a me thod and turn all the optimized slot accesses into calls to slot-value. I am not sure how that could possibly be done on binaries, but I refuse to give up my believe in magic. So I am looking for that as a way out of the dilem ma. Future versions of PCL will support a documented mechanism for deoptimizing inherited slot accesses. This rest of this message describes an undocumented PCL mechanism for achieving the same effect. This example code is a supplement to the db-class I sent out yesterday. For the code presented here to work, there are a couple patches at the end of this message that you will have to make to your PCL. ;;; ;;; This method arranges for all optimized accesses to any slot of a ;;; db-class to trap through slot-value-using-class. ;;; (defmethod lookup-pv-miss-1 ((class db-class) slots pv) (dolist (slot slots) (push nil pv)) pv) ;;; ;;; This method arranges for all inherited reader and writer methods to ;;; trap through slot-value-using-class. ;;; (defmethod all-std-class-readers-miss-1 ((class db-class) slot-name) ()) ;;; ;;; Given this, the proper method for check-super-metaclass-compatibility ;;; is. ;;; (defmethod check-super-metaclass-compatibility ((class db-class) (new-super standard-class)) t) ;;; Here is a demo. ;;; (defclass bazola-1 () ((bazola-1 :initform 0 :accessor boof))) (defclass bazola-2 (bazola-1) () (:metaclass db-class)) (defmethod bazola-1 ((b bazola-1)) (slot-value b 'bazola-1)) (setq b2 (mki 'bazola-2)) ;;; ;;; Here are some tests. ;;; (boof b2) ;0 (setf (boof b2) 3) ;3 (bazola-1 b2) ;3 ;;; ;;; The following patches must be made to the 7/20 version of PCL for ;;; the strategy outlined above to work. The nature of these changes ;;; is such that you will have to make them, use compile-pcl to compile ;;; them, load a fresh pcl, and load your code. You do not have to ;;; recompile your code. ;;; ;from vector.lisp, replace lookup-pv-miss with these two definitions (defun lookup-pv-miss (isl &rest wrappers) (let ((pv ()) (class-slots nil)) (dolist (slots (cdr isl)) (when slots (when (null wrappers) (error "Fewer classes than indicated by the isl.")) (let ((class (class-wrapper-class (pop wrappers)))) (setq pv (lookup-pv-miss-1 class slots pv))))) (when wrappers (error "More classes than indicated by the isl.")) (intern-pv (reverse pv)))) (defmethod lookup-pv-miss-1 ((class standard-class) slots pv) ;; *** Later this wants to fetch the cached info from ;; *** the class wrapper. (let ((class-slots (class-instance-slots class))) (dolist (slot slots) (push (position slot class-slots :key #'slotd-name) pv)) pv)) ;from vector.lisp, replace pv-access-trap with this definition. (defun pv-access-trap (instance offset isl &optional (new-value nil nvp)) (let ((slot-name nil) (i 0)) (dolist (per-class-slots (cdr isl)) (dolist (slot per-class-slots) (when (= i offset) (return (setq slot-name slot))))) (when (null slot-name) (error "Internal Error:~@ Unable to determine the name of the slot from the PV-OFFSET~@ and the ISL. This results from inconsistency between the~@ PV-OFFSET this access was told to use and the ISL for the~@ method.")) (if nvp (put-slot-using-class (class-of instance) instance slot-name new-value) (slot-value-using-class (class-of instance) instance slot-name)))) ;from dcode.lisp replace the definition of all-std-class-readers-miss ;with the following definition (defun all-std-class-readers-miss (arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn ;; This is an instance slot. Convert it's position to its ;; index, then cache the index. Return the value of the slot. (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (get-static-slot--class arg slot-pos)) (slot-value-using-class class arg slot-name)))))) ;from dcode.lisp, add this definition (defmethod all-std-class-readers-miss-1 ((class standard-class) slot-name) (slotd-position slot-name (class-instance-slots class))) ;from dcode.lisp replace the definition of all-std-class-writers-miss ;with the following definition (defun all-std-class-writers-miss (new-value arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (setf (get-static-slot--class arg slot-pos) new-value)) (put-slot-using-class class arg slot-name new-value)))))) ------- --------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jul 88 14:39:53 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUL 88 11:30:04 PDT Date: Fri, 22 Jul 88 11:26 PDT From: Gregor.pa@Xerox.COM Subject: Re: Persistent objects To: Andreas Paepcke cc: CommonLoops.pa@Xerox.COM, larry@postgres.berkeley.edu Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8681.585591887@hplap> Message-ID: <19880722182607.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 22 Jul 88 09:24:47 PDT From: Andreas Paepcke The PCLOS imlementation is similar to what Gregor outlines. The object id, however, doesn't show up as a slot which would be seen by the user through 'describe'. Information like the object id is instead hidden in some fields at the beginning of the slot value vector. This is one of the tricks that are easy to do through a new metaclass and it adds to the transparency of persistence. This trick is undocumented, and will not be supported as such by CLOS or in any documented way by PCL. The really proper way to do this is to use a slot. To hide this slot from describe, you should define your own describe method which doesn't show it. This is good style for using describe anyways. The problem with slot access optimization by methods of superclasses of a different metaclass is insidious. It has caused me grief until I understood it. Unfortunately the solution Gregor suggests - of simply not allowing such inheritance - is problematic in the real world. We have encountered several cases where we needed to inherit in this way and the superclasses could not be touched because we get them canned. There was originally talk about an "unoptimize" capability which would presumably go through a method and turn all the optimized slot accesses into calls to slot-value. I am not sure how that could possibly be done on binaries, but I refuse to give up my believe in magic. So I am looking for that as a way out of the dilemma. Future versions of PCL will support a documented mechanism for deoptimizing inherited slot accesses. This rest of this message describes an undocumented PCL mechanism for achieving the same effect. This example code is a supplement to the db-class I sent out yesterday. For the code presented here to work, there are a couple patches at the end of this message that you will have to make to your PCL. ;;; ;;; This method arranges for all optimized accesses to any slot of a ;;; db-class to trap through slot-value-using-class. ;;; (defmethod lookup-pv-miss-1 ((class db-class) slots pv) (dolist (slot slots) (push nil pv)) pv) ;;; ;;; This method arranges for all inherited reader and writer methods to ;;; trap through slot-value-using-class. ;;; (defmethod all-std-class-readers-miss-1 ((class db-class) slot-name) ()) ;;; ;;; Given this, the proper method for check-super-metaclass-compatibility ;;; is. ;;; (defmethod check-super-metaclass-compatibility ((class db-class) (new-super standard-class)) t) ;;; Here is a demo. ;;; (defclass bazola-1 () ((bazola-1 :initform 0 :accessor boof))) (defclass bazola-2 (bazola-1) () (:metaclass db-class)) (defmethod bazola-1 ((b bazola-1)) (slot-value b 'bazola-1)) (setq b2 (mki 'bazola-2)) ;;; ;;; Here are some tests. ;;; (boof b2) ;0 (setf (boof b2) 3) ;3 (bazola-1 b2) ;3 ;;; ;;; The following patches must be made to the 7/20 version of PCL for ;;; the strategy outlined above to work. The nature of these changes ;;; is such that you will have to make them, use compile-pcl to compile ;;; them, load a fresh pcl, and load your code. You do not have to ;;; recompile your code. ;;; ;from vector.lisp, replace lookup-pv-miss with these two definitions (defun lookup-pv-miss (isl &rest wrappers) (let ((pv ()) (class-slots nil)) (dolist (slots (cdr isl)) (when slots (when (null wrappers) (error "Fewer classes than indicated by the isl.")) (let ((class (class-wrapper-class (pop wrappers)))) (setq pv (lookup-pv-miss-1 class slots pv))))) (when wrappers (error "More classes than indicated by the isl.")) (intern-pv (reverse pv)))) (defmethod lookup-pv-miss-1 ((class standard-class) slots pv) ;; *** Later this wants to fetch the cached info from ;; *** the class wrapper. (let ((class-slots (class-instance-slots class))) (dolist (slot slots) (push (position slot class-slots :key #'slotd-name) pv)) pv)) ;from vector.lisp, replace pv-access-trap with this definition. (defun pv-access-trap (instance offset isl &optional (new-value nil nvp)) (let ((slot-name nil) (i 0)) (dolist (per-class-slots (cdr isl)) (dolist (slot per-class-slots) (when (= i offset) (return (setq slot-name slot))))) (when (null slot-name) (error "Internal Error:~@ Unable to determine the name of the slot from the PV-OFFSET~@ and the ISL. This results from inconsistency between the~@ PV-OFFSET this access was told to use and the ISL for the~@ method.")) (if nvp (put-slot-using-class (class-of instance) instance slot-name new-value) (slot-value-using-class (class-of instance) instance slot-name)))) ;from dcode.lisp replace the definition of all-std-class-readers-miss ;with the following definition (defun all-std-class-readers-miss (arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn ;; This is an instance slot. Convert it's position to its ;; index, then cache the index. Return the value of the slot. (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (get-static-slot--class arg slot-pos)) (slot-value-using-class class arg slot-name)))))) ;from dcode.lisp, add this definition (defmethod all-std-class-readers-miss-1 ((class standard-class) slot-name) (slotd-position slot-name (class-instance-slots class))) ;from dcode.lisp replace the definition of all-std-class-writers-miss ;with the following definition (defun all-std-class-writers-miss (new-value arg wrapper .cache. offset generic-function) (let ((class (class-wrapper-class wrapper)) (method (lookup-method-1 generic-function arg))) (if (null method) (no-matching-method generic-function) (let* ((slot-name (reader/writer-method-slot-name method)) (slot-pos (all-std-class-readers-miss-1 class slot-name))) (if (not (null slot-pos)) (progn (setq slot-pos (%convert-slotd-position-to-slot-index slot-pos)) (without-interrupts (setf (r/w-cache-key) wrapper) (setf (r/w-cache-val) slot-pos)) (setf (get-static-slot--class arg slot-pos) new-value)) (put-slot-using-class class arg slot-name new-value)))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jul 88 12:53:43 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUL 88 09:43:03 PDT Date: Fri, 22 Jul 88 09:40 PDT From: Gregor.pa@Xerox.COM Subject: Re: method discrimination on persistent objects To: Larry Rowe cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807061906.AA13139@postgres.Berkeley.EDU> Supersedes: <19880722013224.5.GREGOR@PORTNOY.parc.xerox.com> Comments: fix braino in code Message-ID: <19880722164004.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There was a braino in the previous mailing of this which came from making one last edit before sending it out. This code should work. The key difference is that any mention of the real-slots slot of db-classes is now gone. I have spent a little time thinking about the question you asked. I haven't answered sooner because I have been to busy to type in a long reply. I am still too busy so this will be a short reply. Once I get back from the Lisp conference I will be able to send more. It seems to me that having make-instance return an object-id rather than an object itself is causing problems. I think a form of your third solution is the way to go. Here are some ideas about how to do it in PCL. Some of this is undocumented PCL, and will change in the next few months. But there is a corresponding part to all of this in the Chapter 3 we are working on. We will define a new metaclass called db-class. The feature of this metaclass is that it will store the values of the slots for its metainstances in the database. The only thing stored in core will be the object-id of the instance. This implementation has an important problem which could be fixed later. It allocates space for the database slots in core even though this space is never used. This could be fixed later, remind me next week after the Lisp Conference. (defclass db-class (standard-class) ()) As soon as the instances are allocated, we have to set their object-id. (defmethod allocate-instance ((class db-class)) (let ((instance (call-next-method))) (setf (slot-value instance 'object-id) (allocate-object-id)) instance)) We need to add the special slot object-id slot to all db-classes. This just arranges to tack the slot onto all the other slots a given db-class inherits. (defmethod collect-slotds ((class db-class) local-slots cpl) (cons (make-slotd (find-class 'standard-slot-description) :name 'object-id :allocation :instance) (call-next-method))) Now we need to teach slot-value for the class to use the value stored in the database. Of course the object-id slot is special as it is stored in core. (defmethod slot-value-using-class ((class db-class) object slot-name) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (class-slots class) :key #'slotd-name) (GET-VALUE-FROM-DB (slot-value object 'object-id) slot-name) (slot-missing object slot-name)))) (defmethod put-slot-using-class ((class db-class) object slot-name new-value) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (class-slots class) :key #'slotd-name) (PUT-VALUE-IN-DB (slot-value object 'object-id) slot-name new-value) (slot-missing object slot-name)))) We also want to be able to use automatically generated accessor methods to access the slots. We need to make sure PCL uses the right code for getting at these slots. (defmethod make-reader-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object) (slot-value object slot-name)))) (defmethod make-writer-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object new-value) (setf (slot-value object slot-name) new-value)))) We need to make sure that we don't inherit any methods which have optimized calls to slot-value in them. This is because those methods will be expecting the instance to have all its storage in core. The simple way to do this is to say that we can't be a subclass of a non db-class class that has slots. (defmethod check-super-metaclass-compatibility ((class db-class) (new-super t)) (or (eq (class-of class) (class-of new-super)) (null (class-slots new-super)))) It doesn't seem worth doing slot-value optimization because of the time required to go to the database. We have to disable the optimization method we would otherwise inherit. (defmethod optimize-slot-value ((class db-class) form) form) (defmethod optimize-set-slot-value ((class standard-class) form) form) Here are some stubs for the Database stuff. This just arranges to store the values in a different place so that we can show that the values aren't being stored in the instance. Note that the way I have this setup, the database doesn't get any advance warning about the existence of a new object id. That would be easy to fix by having allocate-object-id inform the database it just made a new id. (defvar *db* ()) (defun get-value-from-db (object-id slot-name) (getf (cdr (get-db-internal object-id)) slot-name)) (defun put-value-in-db (object-id slot-name new-value) (setf (getf (cdr (get-db-internal object-id)) slot-name) new-value)) (defun get-db-internal (object-id) (let ((instance (assq object-id *db*))) (unless instance (setq instance (list object-id)) (push instance *db*)) instance)) (defun allocate-object-id () (gensym)) ;;; ;;; Here is some code that tries it all out. ;;; (defclass pos () ((x :initform 0 :accessor pos-x) (y :initform 0 :accessor pos-y)) (:metaclass db-class)) (defmethod describe-object ((p pos) stream) (format stream "~&~S is a position, stored in the database.~@ Its x coordinate is ~D, its y coordinate is ~D." p (pos-x p) (pos-y p))) (setq p1 (mki 'pos)) # (setf (pos-x p1) 10 (pos-y p1) 10) 10 (describe-object p1 *standard-output*) # is a position, stored in the database. Its x coordinate is 10, its y coordinate is 10. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jul 88 12:38:27 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUL 88 09:27:54 PDT Return-Path: Redistributed: CommonLoops.pa Received: from hplabs.HP.COM ([15.255.16.7]) by Xerox.COM ; 22 JUL 88 09:25:54 PDT Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Fri, 22 Jul 88 08:26:08 PST Received: from hplap.HPL.HP.COM (hplap.hpl.hp.com) by hplms2.HP.COM; Fri, 22 Jul 88 09:25:25 pdt Received: from hplap by hplap.HPL.HP.COM; Fri, 22 Jul 88 09:24:50 pdt To: CommonLoops.pa@Xerox.COM Cc: larry@postgres.berkeley.edu Subject: Persistent objects X-Mailer: mh6.5 Date: Fri, 22 Jul 88 09:24:47 PDT Message-Id: <8681.585591887@hplap> From: Andreas Paepcke We have developed PCLOS which makes CLOS objects persistent on multiple databases. The system may have instances that are transient, or that are stored in a variety of databases, all in one session. Of Larry's choices we have picked the metaclass solution and have been very happy with it. Once you have gone through somewhat difficult-to-read code to understand how the metaclass works, this mechanism is marvelously powerful and allows for elegant, integrated solutions. The PCLOS imlementation is similar to what Gregor outlines. The object id, however, doesn't show up as a slot which would be seen by the user through 'describe'. Information like the object id is instead hidden in some fields at the beginning of the slot value vector. This is one of the tricks that are easy to do through a new metaclass and it adds to the transparency of persistence. DB-specific functional capabilities are furthermore added by having the metaclass slip a superclass into the cpl of all classes. PCLOS turns the allocation of space for slot values in memory to its advantage: That place is used whenever an object is cached in from the database. Slot-value-using-class and its value-setting partner then either go to the database for slot access to non-cached objects, or they access slots the same general way the standard metaclass does when operating on cached or transient objects. We call the in-memory object representations "husks". One advantage of this scheme beyond caching convenience is that it is real simple and natural to mix transient and persistent objects in one session because they look so similar. The problem with slot access optimization by methods of superclasses of a different metaclass is insidious. It has caused me grief until I understood it. Unfortunately the solution Gregor suggests - of simply not allowing such inheritance - is problematic in the real world. We have encountered several cases where we needed to inherit in this way and the superclasses could not be touched because we get them canned. There was originally talk about an "unoptimize" capability which would presumably go through a method and turn all the optimized slot accesses into calls to slot-value. I am not sure how that could possibly be done on binaries, but I refuse to give up my believe in magic. So I am looking for that as a way out of the dilemma. Another advantage to using the metaclass is the fact that you can begin to keep information in the class objects. This is needed for various reasons, support for persistence of class-allocated slots, among others. Andreas  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Jul 88 21:45:13 EDT Received: from Semillon.ms by ArpaGateway.ms ; 21 JUL 88 18:34:39 PDT Date: Thu, 21 Jul 88 18:32 PDT From: Gregor.pa@Xerox.COM Subject: Re: method discrimination on persistent objects To: Larry Rowe cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807061906.AA13139@postgres.Berkeley.EDU> Message-ID: <19880722013224.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no I have spent a little time thinking about the question you asked. I haven't answered sooner because I have been to busy to type in a long reply. I am still too busy so this will be a short reply. Once I get back from the Lisp conference I will be able to send more. It seems to me that having make-instance return an object-id rather than an object itself is causing problems. I think a form of your third solution is the way to go. Here are some ideas about how to do it in PCL. Some of this is undocumented PCL, and will change in the next few months. But there is a corresponding part to all of this in the Chapter 3 we are working on. We will define a new metaclass called db-class. The feature of this metaclass is that it will store the values of the slots for its metainstances in the database. The only thing stored in core will be the object-id of the instance. This implementation has an important problem which could be fixed later. It allocates space for the database slots in core even though this space is never used. This could be fixed later, remind me next week after the Lisp Conference. (defclass db-class (standard-class) ((real-slots))) As soon as the instances are allocated, we have to set their object-id. (defmethod allocate-instance ((class db-class)) (let ((instance (call-next-method))) (setf (slot-value instance 'object-id) (allocate-object-id)) instance)) We need to add the special slot object-id slot to all db-classes. This just arranges to tack the slot onto all the other slots a given db-class inherits. (defmethod collect-slotds ((class db-class) local-slots cpl) (cons (make-slotd (find-class 'standard-slot-description) :name 'object-id :allocation :instance) (call-next-method))) Now we need to teach slot-value for the class to use the value stored in the database. Of course the object-id slot is special as it is stored in core. (defmethod slot-value-using-class ((class db-class) object slot-name) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (slot-value class 'real-slots) :key #'slotd-name) (GET-VALUE-FROM-DB (slot-value object 'object-id) slot-name) (slot-missing object slot-name)))) (defmethod put-slot-using-class ((class db-class) object slot-name new-value) (if (eq slot-name 'object-id) (call-next-method) (if (find slot-name (slot-value class 'real-slots) :key #'slotd-name) (PUT-VALUE-IN-DB (slot-value object 'object-id) slot-name new-value) (slot-missing object slot-name)))) We also want to be able to use automatically generated accessor methods to access the slots. We need to make sure PCL uses the right code for getting at these slots. (defmethod make-reader-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object) (slot-value object slot-name)))) (defmethod make-writer-method-function ((class db-class) slotd) (let ((slot-name (slotd-name slotd))) #'(lambda (object new-value) (setf (slot-value object slot-name) new-value)))) We need to make sure that we don't inherit any methods which have optimized calls to slot-value in them. This is because those methods will be expecting the instance to have all its storage in core. The simple way to do this is to say that we can't be a subclass of a non db-class class that has slots. (defmethod check-super-metaclass-compatibility ((class db-class) (new-super t)) (or (eq (class-of class) (class-of new-super)) (null (class-slots new-super)))) It doesn't seem worth doing slot-value optimization because of the time required to go to the database. We have to disable the optimization method we would otherwise inherit. (defmethod optimize-slot-value ((class db-class) form) form) (defmethod optimize-set-slot-value ((class standard-class) form) form) Here are some stubs for the Database stuff. This just arranges to store the values in a different place so that we can show that the values aren't being stored in the instance. Note that the way I have this setup, the database doesn't get any advance warning about the existence of a new object id. That would be easy to fix by having allocate-object-id inform the database it just made a new id. (defvar *db* ()) (defun get-value-from-db (object-id slot-name) (getf (cdr (get-db-internal object-id)) slot-name)) (defun put-value-in-db (object-id slot-name new-value) (setf (getf (cdr (get-db-internal object-id)) slot-name) new-value)) (defun get-db-internal (object-id) (let ((instance (assq object-id *db*))) (unless instance (setq instance (list object-id)) (push instance *db*)) instance)) (defun allocate-object-id () (gensym)) ;;; ;;; Here is some code that tries it all out. ;;; (defclass pos () ((x :initform 0 :accessor pos-x) (y :initform 0 :accessor pos-y)) (:metaclass db-class)) (defmethod describe-object ((p pos) stream) (format stream "~&~S is a position, stored in the database.~@ Its x coordinate is ~D, its y coordinate is ~D." p (pos-x p) (pos-y p))) (setq p1 (mki 'pos)) # (setf (pos-x p1) 10 (pos-y p1) 10) 10 (describe-object p1 *standard-output*) # is a position, stored in the database. Its x coordinate is 10, its y coordinate is 10. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Jul 88 18:20:13 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 21 JUL 88 14:46:35 PDT Return-Path: Redistributed: CommonLoops.pa Received: from neptune.CS.UCLA.EDU ([128.97.28.9]) by Xerox.COM ; 21 JUL 88 14:45:20 PDT Return-Path: Received: by neptune.CS.UCLA.EDU (Sendmail 5.54/2.07) id AA04437; Thu, 21 Jul 88 14:44:27 PDT Date: Thu, 21 Jul 88 14:44:27 PDT From: mujica@CS.UCLA.EDU (S Mujica) Message-Id: <8807212144.AA04437@neptune.CS.UCLA.EDU> To: CommonLoops.pa@Xerox.COM Subject: pcl the current version (in pub/pcl @parcvax) fails in the compilation of fixup.lisp under kcl, in a sun 3/280 machine running SunOs 3.5. will there be a fix for this? Sergio Mujica, mujica@cs.ucla.edu (213) 825-7276  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Jul 88 13:31:33 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 21 JUL 88 10:21:41 PDT Sender: "Timothy_Koschmann.DPMW4000"@Xerox.COM Date: 21 Jul 88 09:42:18 PDT (Thursday) Subject: Re: Making System Functions Specializable From: "Timothy_Koschmann.DPMW4000"@Xerox.COM To: kanderso@WILMA.BBN.COM cc: "Timothy_Koschmann.DPMW4000"@Xerox.COM, CommonLoops.PA@Xerox.COM In-Reply-to: kanderso%WILMA.BBN:COM:Xerox's message of 20 Jul 88 12:57 Message-ID: <880721-102141-3947@Xerox> > The function MAKE-SPECIALIZABLE should do it. Are you using the Xerox version of PCL? I didn't realize that MAKE-SPECIALIZABLE was distributed for other CL implementations. The problem is that MAKE-SPECIALIZABLE is not documented in the spec. I was wondering why the drafters of the specification have not included provisions for redefining system forms as generic functions. It seems to me that that will prove to impose a serious limitation on the usefulness of generic functions. Tim  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jul 88 22:18:21 EDT Received: from Salvador.ms by ArpaGateway.ms ; 20 JUL 88 19:11:06 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 20 JUL 88 19:09:30 PDT Received: by ti.com id AA06889; Wed, 20 Jul 88 21:09:22 CDT Received: from dsg by tilde id AA27995; Wed, 20 Jul 88 20:49:00 CDT Received: From Sierra By dsg Via CHAOS-NET With CHAOS-MAIL; Wed, 20 Jul 88 18:31:56 CDT Message-Id: <2794433498-10439973@Sierra> Sender: KK@Sierra.csc.ti.com Date: Wed, 20 Jul 88 18:31:38 CDT From: Kerry Kimbrough To: CommonLoops.pa@Xerox.COM Subject: (defmethod (setf ) ... ) Does PCL 7/7/88 implement this? My initial evidence suggests not.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jul 88 22:18:10 EDT Received: from Riesling.ms by ArpaGateway.ms ; 20 JUL 88 19:11:01 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 20 JUL 88 19:09:24 PDT Received: by ti.com id AA06885; Wed, 20 Jul 88 21:09:18 CDT Received: from dsg by tilde id AA27974; Wed, 20 Jul 88 20:48:28 CDT Received: From Sierra By dsg Via CHAOS-NET With CHAOS-MAIL; Wed, 20 Jul 88 18:06:12 CDT Message-Id: <2794431966-10347891@Sierra> Sender: KK@Sierra.csc.ti.com Date: Wed, 20 Jul 88 18:06:06 CDT From: Kerry Kimbrough To: CommonLoops.pa@Xerox.COM Subject: eql specializers Is PCL 7/7/88 supposed to implement these? My initial evidence suggests not.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jul 88 21:22:22 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 JUL 88 18:09:28 PDT Return-Path: Redistributed: Commonloops.pa Received: from VAX.BBN.COM ([128.89.0.91]) by Xerox.COM ; 20 JUL 88 18:07:37 PDT To: Commonloops.pa@Xerox.COM Subject: UncommonWindows Date: Wed, 20 Jul 88 20:58:49 -0400 From: Mike Thome Message-ID: <880720-180928-2818@Xerox> Well, it appears that there is, indeed, some interest in UW. I have started the ball rolling towards getting it out to you, and I'll try to keep you updated (non-trivial problem: UW was paid for by a governemnt office that wants to have all distribution requests pass through IT's hands.. I'll have to try to get some sort of exemption, or you'll all have to send requests to The Right Person In Washington). Enough administrivia... 'fraid I dont have any real documentation other than examples in the code (and we all know about the availability of THAT, now) - but to give you a flavor, you can track down a copy of The Kee Manual Set (preferrably version 3.1) and look up Common Windows. The core of uncommon windows is exactly the content of that manual, except that all the main interface functions are CLOS methods and windows are CLOS UnCommonWindow classes, with all that this implies. There are plenty of tools built on top of this core, but enumeration is silly at this point - if the style of Common Windows seems useful, perhaps UnCommonWindows is for you. Currently the only machine it runs on is symbolix 7.1 (intellicorp hasn't said much about getting kee to run under 7.2, although CW may or may not be a seperate product at some point). Porting to another machine ought to require little more than some time from a minor CLOS magician... and *NO* black magic with window systems. A few of the tools also use symbolics process control stuff that should be trivially replaced with whatever your system uses to coordinate processes (I only use 'em to wait for something to happen). -mik (mthome@bbn.com)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jul 88 18:05:55 EDT Received: from Salvador.ms by ArpaGateway.ms ; 20 JUL 88 14:52:31 PDT Return-Path: Redistributed: CommonLoops.pa Received: from oahu.cs.ucla.edu ([128.97.28.25]) by Xerox.COM ; 20 JUL 88 14:50:21 PDT Return-Path: Received: by oahu.cs.ucla.edu (Sendmail 5.58.2/2.09) id AA04816; Wed, 20 Jul 88 14:49:33 PDT Date: Wed, 20 Jul 88 14:49:33 PDT From: mujica@CS.UCLA.EDU (s. mujica) Message-Id: <8807202149.AA04816@oahu.cs.ucla.edu> To: CommonLoops.pa@Xerox.COM Subject: pcl does not compile in KCL i am trying to compile pcl using KCL in a SUN 3/110 runing SunOs 3.5, and it breaks with a segmentation fault while compilling fixup.lisp. any advise for solving this will be appreciated. Sergio Mujica, mujica@cs.ucla.edu  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jul 88 17:42:02 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 JUL 88 14:10:17 PDT Date: Wed, 20 Jul 88 14:07 PDT From: Gregor.pa@Xerox.COM Subject: Re: Problems with KCL version of 7/7/88 PCL ... To: Leonid V. Belyaev cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807200241.AA11910@maui.cs.ucla.edu> Message-ID: <19880720210713.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Tue, 19 Jul 88 19:41:15 PDT From: Leonid V. Belyaev I am not sure if anyone out there is actually using the KCL version, but I haven't heard anyone complain about the following: 2. PCL will not compile under KCL: when compiling FIXUP, the following se- ries of errors is generated: Compiling FIXUP... Error: LOAD-TIME-EVAL is invalid as a function. Well, even once this bug is properly fixed, there are problems with running the new version of PCL in the version of IBCL I am using. It seems that there is a bug involving dumping non-interned symbols and having them come back as EQ. Following are two test cases. The first one doesn't work in the version of IBCL I am using. The second one does work in the version of IBCL I am using. Please test these in the version of KCL you are using. If the second case works for you, then I may be able to come up with a workaround for PCL and we will be all set. Of course if either case loses, you should report it as a bug to the people who maintain the version of KCL you are using. Put the following code in a file, compile that file and then load it. if both cases work, loading the file should print 1 and 2 on separate lines. If either case doesn't work, it will print something random (probably #) instead. ;;; ;;; This version doesn't work. ;;; (defmacro case-1 () (let ((gensym (gensym))) `(setq foo (list '(a b ,gensym) #'(lambda (x) ,gensym))))) (case-1) (eval-when (load) (set (car (last (car foo))) 1) ;set the gensym to 1 (print (funcall (cadr foo) ()))) ;should print 1 ;;; ;;; This version does work. ;;; (defmacro case-2 () (let ((gensym (gensym))) `(setq bar (list ',gensym #'(lambda (x) ,gensym))))) (case-2) (eval-when (load) (set (car bar) 2) ;set the gensym to 2 (print (funcall (cadr bar) ()))) ;should print 2 -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jul 88 17:08:44 EDT Received: from Salvador.ms by ArpaGateway.ms ; 20 JUL 88 13:57:37 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 20 JUL 88 13:49:00 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: 2 loading performance problems Date: Wed, 20 Jul 88 16:48:58 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880720-135737-2400@Xerox> ;;;-*-Mode: LISP; Package:(PCL Lisp 1000); Base:10; Syntax:Common-lisp -*- #|| Two problems in 3/17/88 PCL that seem to effect compiling and loading performance: PROBLEM 1: When you define a new class, you go through the following functions: LOAD-DEFCLASS -> ADD-NAMED-CLASS -> UPDATE-CLASS -> PROPAGATE-CLASS-UPDATE -> UPDATE-METHOD-INHERITANCE: ;;; from std-class.lisp (defmethod update-method-inheritance ((class standard-class) old-cpl new-cpl) (unless (eq old-cpl new-cpl) (dolist (old old-cpl) (unless (member old new-cpl) (dolist (old-gf (class-direct-generic-functions old)) (invalidate-generic-function old-gf)))) (dolist (new new-cpl) (unless (member new old-cpl) (dolist (new-gf (class-direct-generic-functions new)) (invalidate-generic-function new-gf)))))) For example, in my case OLD-CPL is NIL and NEW-CPL is (# # # # #) What UPDATE-METHOD-INHERITANCE does is invalidate all the direct generic functions of each class on the NEW-CPL, 615 of them. There are 557 generic functions on (CLASS-NAMED 'T), including many irrelevent setf methods that have T as their second specializer, and almost all of PCL. So, as PCL continues to run it finds itself invalid and has to recompute lots of its generic functions unnecessarily. This happens over and over. Do we really need to invalidate all of these methods? PROBLEM 2: When definining a method, LOAD-DEFMETHOD -> LOAD-DEFMETHOD-INTERNAL -> ADD-NAMED-METHOD = REAL-ADD-NAMED-METHOD -> ADD-METHOD = REAL-ADD-METHOD -> ADD-METHOD-ON-SPECIALIZER -> SPECIALIZER-METHODS -> (SETF CLASS-DIRECT-METHODS): ;;; From std-class.lisp (defmethod-setf class-direct-methods ((class standard-class)) (nv) (let ((direct-generic-functions ())) (dolist (m nv) (pushnew (method-generic-function m) direct-generic-functions :test #'eq)) (put-slot--class class 'direct-generic-functions direct-generic-functions) (put-slot--class class 'direct-methods nv))) Thus for each method defined, the CLASS-DIRECT-GENERIC-FUNCTIONS of each specializer is needlessly CONSed up from scratch! The patch i use simply ignores the direct-generic-functions slot, this elimiantes about half a megacons when loading one of our applications. ;;; ;;; Patch std-class.lisp ;;; KRA: Eliminate need for class-direct-generic-functions. (defmethod update-method-inheritance ((class standard-class) old-cpl new-cpl) (declare (ignore class)) (unless (eq old-cpl new-cpl) (dolist (old old-cpl) (unless (member old new-cpl) (dolist (old-gf (class-direct-methods old)) (invalidate-generic-function (method-generic-function old-gf))))) (dolist (new new-cpl) (unless (member new old-cpl) (dolist (new-gf (class-direct-methods new)) (if (null (method-generic-function new-gf)) ;; There are occasional methods with null generic-function ;; slots. Report if you find one. (print (list 'REPORT-BUG-TO-KEN new-gf)) (invalidate-generic-function (method-generic-function new-gf)))))))) ;;; For anyone that needs it. (defmethod class-direct-generic-functions ((class standard-class)) (map 'list #'method-generic-function (class-direct-methods class))) ;;; This is what i want, but i can't pull it through the metabraid, without ;;; Gregor's help. #+not-yet (defmethod-setf class-direct-methods ((class standard-class)) (nv) (put-slot--class class 'direct-methods nv)) ;;; But this will do for now. (defun |setf CLASS-DIRECT-METHODS| (class nv) (put-slot--class class 'direct-methods nv))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jul 88 14:39:22 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 JUL 88 11:10:52 PDT Return-Path: Redistributed: commonloops.PA Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 20 JUL 88 10:57:50 PDT To: "Timothy_Koschmann.DPMW4000"@Xerox.COM cc: commonloops.PA@Xerox.COM Subject: Re: Making System Functions Specializable In-reply-to: Your message of Mon, 18 Jul 88 13:10:46 -0700. <880718-131347-3707@Xerox> Date: Wed, 20 Jul 88 14:01:30 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880720-111052-2025@Xerox> The function MAKE-SPECIALIZABLE should do it.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 Jul 88 22:52:30 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 19 JUL 88 19:43:33 PDT Return-Path: Redistributed: commonloops.pa Received: from maui.cs.ucla.edu ([128.97.28.26]) by Xerox.COM ; 19 JUL 88 19:42:12 PDT Return-Path: Received: from LocalHost by maui.cs.ucla.edu (Sendmail 5.58.2/2.09) id AA11910; Tue, 19 Jul 88 19:41:18 PDT Message-Id: <8807200241.AA11910@maui.cs.ucla.edu> To: CommonLoops.pa@Xerox.COM Subject: Problems with KCL version of 7/7/88 PCL ... Date: Tue, 19 Jul 88 19:41:15 PDT From: Leonid V. Belyaev I am not sure if anyone out there is actually using the KCL version, but I haven't heard anyone complain about the following: 1. In kcl-patches, the line that looks like (unless (and (boundp '*defmacro*) *defmacro) generates an error about *DEFMACRO being undefined. I chenged it to (unless (and (boundp '*defmacro*) *defmacro*) 2. PCL will not compile under KCL: when compiling FIXUP, the following se- ries of errors is generated: Compiling FIXUP... Compiling /s/local3/pcl/fixup.lsp. INVALIDATE-GENERIC-FUNCTION...trampoline...fixed... Error: LOAD-TIME-EVAL is invalid as a function. Error signalled by |(SETF CLASS-DIRECT-METHODS)|. Backtrace: > eval > fix-early-generic-functions > add-method-on-specializer > | (SETF CLASS-DIRECT-METHODS)| . ; (FIX-EARLY-GENERIC-FUNCTIONS T) is being compiled. ;;; The form (FIX-EARLY-GENERIC-FUNCTIONS T) was not evaluated success- fully. ;;; You are recommended to compile again. No FASL generated. Loading binary of FIXUP... Error: Cannot open the file /s/local3/pcl/fixup.o. Error signalled by LOAD. I had de-commented the definition for LOAD-TIME-EVAL in KCL-LOW, since the error before this was done was that LOAD-TIME-EVAL was undefined. This needs either a workaround for how to compile FIXUP.LSP without LOAD-TIME-EVAL, or LOAD-TIME-EVAL needs to be "done right", as speci- fied in the file. Just out of curiosity, has no one run into these two problems? Leo.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 Jul 88 19:54:04 EDT Received: from Riesling.ms by ArpaGateway.ms ; 19 JUL 88 16:48:29 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 19 JUL 88 16:47:15 PDT Received: by ti.com id AA03418; Tue, 19 Jul 88 18:46:41 CDT Received: from dsg by tilde id AA26520; Tue, 19 Jul 88 18:45:52 CDT Received: From Sierra By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 19 Jul 88 18:39:03 CDT Message-Id: <2794347542-5275574@Sierra> Sender: KK@Sierra.csc.ti.com Date: Tue, 19 Jul 88 18:39:02 CDT From: Kerry Kimbrough To: CommonLoops.pa@Xerox.COM Subject: Re: with-slots problem In-Reply-To: Msg of Tue, 19 Jul 88 18:34:46 CDT from Kerry Kimbrough > In this > case, title, font, and inside-border-width are direct slots of the > virtual-button class, while height and width are slots in a (non-local) > superclass of virtual-button. Oops, I mean virtual-label, as the example shows (not virtual-button).  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 Jul 88 19:53:52 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 19 JUL 88 16:48:19 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 19 JUL 88 16:46:35 PDT Received: by ti.com id AA03406; Tue, 19 Jul 88 18:46:23 CDT Received: from dsg by tilde id AA26411; Tue, 19 Jul 88 18:41:53 CDT Received: From DRACO By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 19 Jul 88 18:35:00 CDT Message-Id: <2794347286-4864165@DRACO> Sender: KK@DRACO.csc.ti.com Date: Tue, 19 Jul 88 18:34:46 CDT From: Kerry Kimbrough To: CommonLoops.pa@Xerox.COM Subject: with-slots problem I'm running PCL 7/7/88 on a TI Explorer. When I compile some defmethod forms containing a with-slots, the with-slots is not expanded correctly, with the result that slot names are not bound. For example, when I compile: (defmethod initialize-instance :after ((self virtual-label) &rest init-plist) (declare (ignore init-plist)) (with-slots (title font height width inside-border-width) self (when (symbolp title) ;; NIL is a symbol (setf title (string-capitalize (string (or title (contact-name self)))))) (let ((label-font font)) (setf height (+ (max-char-ascent label-font) (max-char-descent label-font) (* 2 inside-border-width) 2)) (setf width (+ 2 (text-width label-font title)))))) I get the warning "TITLE and INSIDE-BORDER-WIDTH used free". In this case, title, font, and inside-border-width are direct slots of the virtual-button class, while height and width are slots in a (non-local) superclass of virtual-button. However, in other apparently similar defmethods, the problem does not occur. When with-slots is given several slot name, only some may be reported unbound. Either local or non-local slot names may be left unbound. What's going on? Here's the result of macro-expanding the above example. (PROGN (EVAL-WHEN (COMPILE LOAD EVAL) (PROGN (PROGN (PCL::LOAD-DEFMETHOD 'PCL::STANDARD-METHOD 'INITIALIZE-INSTANCE '(:AFTER) '(VIRTUAL-LABEL) '(SELF &REST INIT-PLIST) (QUOTE NIL) '(:ISL ((FONT HEIGHT TITLE TITLE WIDTH)) :ISL-CACHE-SYMBOL #:|isl-cache|) #'(LAMBDA (SELF &REST INIT-PLIST) (DECLARE (IGNORE INIT-PLIST) (PCL::CLASS SELF VIRTUAL-LABEL)) (LET ((PCL::.ISL. (LET () (DECLARE (SPECIAL #:|isl-cache|)) #:|isl-cache|)) (PCL::.PV. NIL)) (SETQ PCL::.PV. (LET* ((PCL::.CACHE. (CAR PCL::.ISL.)) (PCL::W1 (AREF SELF 0)) (PCL::.OFFSET. (LOGAND 14 (LOGXOR (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR PCL::W1) (THE FIXNUM 0))))))) (IF (AND (EQ PCL::W1 (AREF PCL::.CACHE. PCL::.OFFSET.))) (AREF PCL::.CACHE. (1+ PCL::.OFFSET.)) (PCL::PRIMARY-PV-CACHE-MISS PCL::.ISL. PCL::.OFFSET. PCL::W1 SELF)))) (PROGN SELF) (BLOCK INITIALIZE-INSTANCE (LET ((#:G5018 SELF)) (DECLARE (PCL::VARIABLE-REBINDING #:G5018 SELF)) (AND (SYMBOLP (LET ((PCL::.INDEX. (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR PCL::.PV.) (THE FIXNUM '3))))) (IF (NULL PCL::.INDEX.) (PCL::PV-ACCESS-TRAP #:G5018 '3 PCL::.ISL.) (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR (AREF #:G5018 1)) (THE FIXNUM PCL::.INDEX.)))))) (PROGN (LET ((#:G5019 (STRING-CAPITALIZE (STRING (OR TITLE (CONTACT-NAME SELF)))))) (LET ((PCL::.INDEX. (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR PCL::.PV.) (THE FIXNUM '2))))) (IF (NULL PCL::.INDEX.) (PCL::PV-ACCESS-TRAP #:G5018 '2 PCL::.ISL. #:G5019) (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0))) (SYS:SET-AREF (THE SIMPLE-VECTOR (PROGN (AREF #:G5018 1))) (THE FIXNUM (PROGN PCL::.INDEX.)) (PROGN #:G5019)))))))) (LET ((LABEL-FONT (LET ((PCL::.INDEX. (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR PCL::.PV.) (THE FIXNUM '0))))) (IF (NULL PCL::.INDEX.) (PCL::PV-ACCESS-TRAP #:G5018 '0 PCL::.ISL.) (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR (AREF #:G5018 1)) (THE FIXNUM PCL::.INDEX.))))))) (LET ((#:G5023 (+ (MAX-CHAR-ASCENT LABEL-FONT) (MAX-CHAR-DESCENT LABEL-FONT) (* 2 INSIDE-BORDER-WIDTH) 2))) (LET ((PCL::.INDEX. (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR PCL::.PV.) (THE FIXNUM '1))))) (IF (NULL PCL::.INDEX.) (PCL::PV-ACCESS-TRAP #:G5018 '1 PCL::.ISL. #:G5023) (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0))) (SYS:SET-AREF (THE SIMPLE-VECTOR (PROGN (AREF #:G5018 1))) (THE FIXNUM (PROGN PCL::.INDEX.)) (PROGN #:G5023)))))) (LET ((#:G5027 (+ 2 (TEXT-WIDTH LABEL-FONT TITLE)))) (LET ((PCL::.INDEX. (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0)) (INLINE SVREF)) (AREF (THE SIMPLE-VECTOR PCL::.PV.) (THE FIXNUM '4))))) (IF (NULL PCL::.INDEX.) (PCL::PV-ACCESS-TRAP #:G5018 '4 PCL::.ISL. #:G5027) (LET () (DECLARE (OPTIMIZE (SPEED 3) (SAFETY 0))) (SYS:SET-AREF (THE SIMPLE-VECTOR (PROGN (AREF #:G5018 1))) (THE FIXNUM (PROGN PCL::.INDEX.)) (PROGN #:G5027))))))))))))))) (EVAL-WHEN NIL))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 Jul 88 16:06:26 EDT Received: from Salvador.ms by ArpaGateway.ms ; 19 JUL 88 13:03:32 PDT Return-Path: Redistributed: commonloops.pa Received: from ti.com ([10.7.0.46]) by Xerox.COM ; 19 JUL 88 13:02:11 PDT Received: by ti.com id AA01968; Tue, 19 Jul 88 15:01:38 CDT Received: from dsg by tilde id AA21905; Tue, 19 Jul 88 14:55:37 CDT Received: From Sierra By dsg Via CHAOS-NET With CHAOS-MAIL; Tue, 19 Jul 88 14:46:48 CDT Message-Id: <2794333604-4438198@Sierra> Sender: KK@Sierra.csc.ti.com Date: Tue, 19 Jul 88 14:46:44 CDT From: Kerry Kimbrough To: Mike Thome Cc: CommonLoops.pa@Xerox.COM Subject: Re: Object-oriented window systems. In-Reply-To: Msg of Tue, 19 Jul 88 11:29:08 -0400 from Mike Thome On the same topic: here at TI we've developed a system called CLUE (Common Lisp User Interface Environment), which is an OOPS for user interface programming in Common Lisp, based on CLOS and the X Window System (i.e. CLX). CLUE is a way to create X applications using CLOS. CLUE is also modelled on the Xt toolkit used by C programmers and offers the same kind of features. A portable implementation of CLUE is now available in the public domain. Anyone interested may receive source code and documentation via anonymous ftp from CSC.TI.COM, (internet address 10.7.0.46) in pub/clue.tar.Z We encourage comments from anyone interested in Lisp user interface programming. General comments and CLUE issue discussion should be addressed to clue-review@dsg.csc.ti.com. I'm a newcomer to this mailing list, having just begun the job of getting CLUE working with PCL. I'm interested in anybody's thoughts on standard (or portable) systems for UI programming in CLOS.  Received: from REAGAN.AI.MIT.EDU (CHAOS 13065) by AI.AI.MIT.EDU 19 Jul 88 12:25:39 EDT Received: from XEROX.COM by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 125635; 19 Jul 88 10:39:10 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 19 JUL 88 07:00:22 PDT Return-Path: Redistributed: commonloops.PA Received: from media-lab.media.mit.edu ([18.85.0.2]) by Xerox.COM ; 19 JUL 88 06:59:05 PDT Received: from waterloo.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA10800; Tue, 19 Jul 88 09:58:44 EDT Received: by waterloo (3.2/4.8) id AA15822; Tue, 19 Jul 88 09:55:21 EDT Date: Tue, 19 Jul 88 09:55:21 EDT From: Michael Sokolov Message-Id: <8807191355.AA15822@waterloo> To: "Timothy_Koschmann.DPMW4000"@Xerox.COM Cc: commonloops.PA@Xerox.COM, "Timothy_Koschmann.DPMW4000"@Xerox.COM In-Reply-To: "Timothy_Koschmann.DPMW4000"@xerox.com's message of 18 Jul 88 13:10:46 PDT (Monday) <880718-131347-3707@Xerox> Subject: Making System Functions Specializable Here's one thing to try. Say you have want to define + on arrays. (setq num-plus (function #'+)) (fmakunbound #'+) (defmethod + ((a array) (b array)) ....) (defmethod + ((x number) (y number)) (num-plus x y)) Then, after you compile this, you could even get rid of num-plus' function binding. Mike S.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 Jul 88 12:15:29 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 19 JUL 88 08:38:21 PDT Return-Path: Redistributed: CommonLoops.pa Received: from VAX.BBN.COM ([128.89.0.91]) by Xerox.COM ; 19 JUL 88 08:36:43 PDT To: CommonLoops.pa@Xerox.COM Subject: Object-oriented window systems. Date: Tue, 19 Jul 88 11:29:08 -0400 From: Mike Thome Message-ID: <880719-083821-4881@Xerox> In reply to the question of clos-based window systems, I've been working on something that may be of some interest. What: we usually call it Uncommon-windows - a version of the Intellicorp-proposed (I think) window system standard ("Common-Windows") based on CLOS/PCL rather than the pseudo-object-hackery that CW comes with. UW provides a superset of the functionality of CW to the extent that UW and CW may non-destructively inhabit the same machine... even cooperate. How: well, in order not to lose the single biggest benefit of CW (that is, portability), rather than porting CW, we added a layer of CLOS functionality on top. Unfortunately, this sort of scheme, while nice and portable, doesnt solve a number of important issues involving integration with the native window system (whatever is behind CW) - when you mouse-right-2 on a Uncommon-Window to reshape it, you want your CLOS reshape methods to get called, rather than the default CW method(s). Sooo... we get UW to dig itself into CW, replacing the top layer with all generic functions with default methods for a number of different sorts/implementations of windows which all do The Right Thing. Performance: The system does not seem to cause much of a slowdown over vanilla common windows- in several cases, things have become faster because of smarter methods. What it can do: A sampling of what we've done: a constraint-frame system, speed-panning graphics (dragging of window contents a la Mac), numerous symbolics-window-system-function-clones (i.e. choose-variable- values)), text-filling format/windows/hotspot-texts, and presentation-like objects. How to get it: not quite sure yet - there are a few potential problems, but I'm sure they can be "fixed" if there is any interest out there. Questions? Comments? - Mike Thome (mthome@bbn.com)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Jul 88 20:18:19 EDT Received: from Semillon.ms by ArpaGateway.ms ; 18 JUL 88 17:05:41 PDT Date: Mon, 18 Jul 88 17:02 PDT From: Gregor.pa@Xerox.COM Subject: CLOS specification To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest Message-ID: <19880719000207.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no The TeX sources for chapters 1 and 2 of the CLOS specification as voted on by X3J13 are now on parcvax.xerox.com. They are in the /pub/pcl/doc directory. You can copy them by logging in as username "anonymous" and password "anonymous". There are instructions for using TeX to format them in the README file in that same directory. For sites which do not have TeX access, or which do not have Arpanet access, other distribution mechanisms are in the works. Stay tuned for announcements about this. Chapter 1 and 2 of the CLOS specification will also be published in a a future issue of the Journal of Lisp and Symbolic Computing, and in SIGPLAN notices. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Jul 88 16:27:35 EDT Received: from Burger.ms by ArpaGateway.ms ; 18 JUL 88 13:13:47 PDT Sender: "Timothy_Koschmann.DPMW4000"@Xerox.COM Date: 18 Jul 88 13:10:46 PDT (Monday) Subject: Making System Functions Specializable From: "Timothy_Koschmann.DPMW4000"@Xerox.COM To: commonloops.PA@Xerox.COM cc: "Timothy_Koschmann.DPMW4000"@Xerox.COM Message-ID: <880718-131347-3707@Xerox> How does one make existing CL forms specializable? I know that with-added-methods allows you to create lexically scoped generic functions on defined forms, but I am interested in defining dynamically scoped generic functions on existing CL forms. Is there no way to do this within the CLOS spec? Tim  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Jul 88 16:17:09 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 18 Jul 88 13:07:13 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA29734; Mon, 18 Jul 88 13:04:21 PDT Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-4.0) id AA29199; Mon, 18 Jul 88 13:04:51 PDT Received: by lukasiewicz.sun.com (4.0/SMI-4.0) id AA18995; Mon, 18 Jul 88 13:06:16 PDT Date: Mon, 18 Jul 88 13:06:16 PDT From: jrose@Sun.COM (John Rose) Message-Id: <8807182006.AA18995@lukasiewicz.sun.com> To: Moon@STONY-BROOK.SCRC.Symbolics.COM, Bobrow.pa@Xerox.COM Cc: common-lisp-object-system@SAIL.STANFORD.EDU Cc: jrose@Sun.COM In-Reply-To: David A. Moon's message of Fri, 15 Jul 88 17:07 EDT <19880715210732.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Subject: putting CLOS objects in binfiles Date: Fri, 15 Jul 88 17:07 EDT From: David A. Moon Date: Fri, 15 Jul 88 12:42:03 PDT From: jrose@Sun.COM (John Rose) It's a shame that there's no provision in CLOS for saving objects in binfiles. ... Here's essentially what's needed: A generic function (called, say, RECONSTRUCTOR-FORM) which returns a Lisp form to evaluate to reconstruct any given object. This is fine. It's how Flavors does it, so there is some precedent. The only problem with this technique is that it doesn't cope well with circular structures, which can only be handled by separating creation of the objects from filling them in (and even that doesn't work in general, for reasons too complicated to get into here). ... OK, I'd like to create a proposal. I understand my hallmate Cris Perdue is thinking about binfiles, so I'll talk with him some first. To deal with circularities, one can separate the object creation protocol into two passes, one to create a reference to an uninitialized object (which can be used to plug into other structures), and a second pass to initialize the object itself. You say there are in general problems here, and I imagine you are referring to the window between the two passes, when the object can be referenced, but might not yet contain valid data. Do you think this problem can be addressed adequately as follows: At dump time, if circularities are detected, the target of a back-arc (which will need to be created in two passes at load time) is passed to a generic function (named, e.g., CIRCULAR-RECONSTRUCTOR-FORMS) which either generates parameters for the two load time passes, or signals an error at dump time. This would allow a class to disallow all or some circularities, or handle them in a class-specific manner, by gaining some control over the window between the two load time passes. An object in the inter-pass window could even have a different class; pass 2 could perform a CHANGE-CLASS. Also, let me make another stab at a default behavior for dumping: Use the PRINT-OBJECT printer, and save the string the binary file. Proper use of a *PRINT-READABLY* flag would be required to detect errors, and recursive calls to PRINT-OBJECT would have to transfer control to the binary dumper (leaving a ## or similar notation in the object's string). The advantage of this default is that the class writer need only code a readable PRINT-OBJECT representation, and not worry about binary files explicitly. Here's my immediate problem: I want to build objects which represent predicates in a special purpose query language, and I want them to be uniquified, like pathnames on the Lisp Machine. (They cache things like compiled Lisp code, so it's expensive to build new copies.) Such things do not dump properly, and even if a simple patch were to be applied (say, to dump a class symbol instead of a class), a simple-minded load routine would not uniquify them. I'm not sure that anything in Common Lisp requires that multiple references to a single object, in a file being compiled, do not turn into multiple objects when the file is loaded. Symbols load as single objects. And on the Lisp Machine (last time I looked) pathnames were interned in the same way. I think this is done because symbols and pathnames are used as names, or references for other objects, and making them EQ makes for fast comparison, and allows referencing parties to make shared annotations on the name object. You might have to address this in an implementation-dependent way unless the definition of Common Lisp were changed to require this explicitly. I think most implementations do guarantee object identity within a single COMPILE-FILE, even though they're not required to. This is not a CLOS issue, it applies to all objects for which EQ is defined. I'm willing to guarantee object identity myself, if I can only get control whenever the system thinks it wants to cons one of my objects, and intern it. Something like this: (LET ((TABLE (MAKE-HASH-TABLE :TEST 'EQUAL))) (DEFMETHOD MAKE-INSTANCE ((EQL 'MYCLASS) &KEY X Y) (LET ((PARAMS (LIST X Y))) (OR (GETHASH PARAMS TABLE) (SETF (GETHASH PARAMS TABLE) (CALL-NEXT-METHOD)))))) Date: 15 Jul 88 17:08 PDT From: Bobrow.pa@Xerox.COM In Loops, the way we solved this problem was to provide each savable object a unique identifier. This UID was constructed from some representation of the machine of ceation and the time of creation. An object knows its UID, and from the UID one can find the object. For any object, the form that was dumped includes its UID, as well as its contents. References from a dumped object to another object contain a form which reconstructs the pointer to object referred to, but does not try to reconstruct its contents. Wow! That's neat stuff. It shows how far we've come that solutions to the problem of object identity within a single Lisp session are taken for granted (reread the CLtL chapter on packages if you think it's no problem) and the current research is into defining and maintaining uniqueness across much wider domains, such as all machines and times in some space. But all I wanted (this time) was uniqueness across a session, and some sort of transportable printed representation, like symbols or LispM pathnames. -- John  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Jul 88 16:04:18 EDT Received: from Semillon.ms by ArpaGateway.ms ; 18 JUL 88 12:52:34 PDT Return-Path: Redistributed: CommonLoops.pa Received: from media-lab.media.mit.edu ([18.85.0.2]) by Xerox.COM ; 18 JUL 88 12:50:53 PDT Received: from victoria.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA02502; Mon, 18 Jul 88 15:50:40 EDT Received: by victoria (3.2/4.8) id AA01220; Mon, 18 Jul 88 15:50:33 EDT Date: Mon, 18 Jul 88 15:50:33 EDT Message-Id: <8807181950.AA01220@victoria> From: Michael Sokolov Sender: sokolov@victoria.media.mit.edu To: CommonLoops.pa@Xerox.COM Subject: Iterate macro on Symbolics I got the following error during (pcl::compile-pcl) on a Symbolics running 7.1: For function optimize-iterate-form, Error: The second argument (value) to sys:signed-immediate-operand, 231, was of the wrong type. The function expected a small signed operand. Arg 0 (compiler:opcode): 67 Arg 1 (compiler:value): 231 This is a little beyond me, but I was just wondering if anyone had had any success compiling the new (7/7/88) PCL in Symbolics 7.1? -Mike S.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 18 Jul 88 15:15:47 EDT Received: from Salvador.ms by ArpaGateway.ms ; 18 JUL 88 12:01:19 PDT Return-Path: Redistributed: commonloops.pa Received: from cu-arpa.cs.cornell.edu ([10.3.0.96]) by Xerox.COM ; 18 JUL 88 11:59:04 PDT Received: from WRATH.CS.CORNELL.EDU by cu-arpa.cs.cornell.edu (5.59/4.30) id AA26445; Mon, 18 Jul 88 14:58:21 EDT From: oravax!polites.UUCP!hook@cu-arpa.cs.cornell.edu Received: by wrath.cs.cornell.edu (5.54/4.30) id AA02911; Mon, 18 Jul 88 14:58:13 EDT Received: by oravax.UUCP (5.51/5.17) id AA05476; Mon, 18 Jul 88 14:54:22 EDT Received: by polites.UUCP (3.2/SMI-3.2) id AA19419; Mon, 18 Jul 88 14:51:14 EDT Date: Mon, 18 Jul 88 14:51:14 EDT Message-Id: <8807181851.AA19419@polites.UUCP> To: commonloops.pa@Xerox.COM Subject: Recursive slot specialization proposal This note proposes an extension to the defmethod mechanism of CLOS to allow method specialization to refer (recursively) to the structure of slot values. This idiom has arisen in the course of translating an ML program into a dialect of lisp which exploits the "HOPE-style" pattern matching facilities of ML. In ML, a concrete type is given by specifying functions which construct its elements. For example, to say that the new type "my_boolean" is built from the two constants "my_true" and "my_false" one would write type my_bool = my_true | my_false;; [People familiar with ML will note that this is non-standard syntax. It comes from the Formel implementation, which is not the same as standard ML. Standard ML is better!] Similarly, to say that lists are built out of my_nil and my_cons one writes: rectype * my_list = my_nil | my_cons of * # * my_list ;; [The * is a prefix "type argument" indicating that my_list is a polymorphic type.] When types are defined in this manner it is possible to define functions by cases on the constructors used. For example, is_empty = fun my_nil . my_true | my_cons (_) . my_false ;; and hd_is_true = fun my_cons (my_true,_) . my_true | _ . my_false ;; [The _ character is a "wildcard" pattern---it matches anything.] In our translation into CLOS we have used classes for the "concrete types" and subclasses with appropriate slot arguments to represent the constructors and their arguments. In this idiom it is easy to use the defmethod construct to define functions such as "is_empty" above, but it is less natural to define functions which exploit the recursive structure of patterns such as "head_is_true". Our response to this problem has been to provide a quick and temporary interpreted solution. We introduce a few new constructs which we think make the code easy to read. Then we expand them at load time into if-then-else chains, and don't use defmethod at all. There are a few simple things we could do to shorten the if-then-else chains, and we could produce defmethods to do the split on top-level structure. But the most efficient, clean, and compatible solution would be to reach in and change defmethod so it can handle arbitrarily deep trees of patterns to be matched against actual parameter instances. Since we don't have the time to do that ourselves, we are advertising this idea to see what comments we get. The defmethod construct has the following structure (and more): (defmethod ( ) ) where ::= | . The existing pattern grammar is: ::= | ( ) | ( (eql
)) Here is the pattern grammar we have in mind: ::= | (eql ) | (as ) | ( { }* ) The meaning of a is: 1. matches any object. As a result of the match, will be bound to the object. 2. (Eql ) matches only those objects which are "eql" in the sense of Common LISP to the value of , evaluated in the context of any bindings established by an enclosing level of pattern matching. 3. (As ) matches any object which matches . In case of success, will be bound to the matching object. 4. ( { }* ) matches any object of class , as determined by the standard predicate for , as long as that object, in each slot specified as , has a value matching the corresponding . In case of a match, the bindings established by the subpatterns will hold for the whole pattern. The main feature of this grammar is the recursion. A secondary feature is the role of the class name, which we put first because we treat the class name as a type constructor. In fact, to improve on the make-instance syntax we add ::= ( ( { ( ) }* )) to the grammar for forms so that the class of the constructed instance is more prominent and instance construction is less obtrusive. Here are two code enclosures, an ML function and its Lisp translation. The function takes a term of a version of the lambda calculus and returns its string representation. Since we don't have a modified defmethod, in the Lisp code we use the following idiom: (defun-pattern ( ) (pattern-let (( ) ... ))). This is interpreted to mean 1. Compute , then match it against s from first to last, taking the first match that succeeds. 2. Evaluate the corresponding in an environment having the bindings established during the match. [disclaimer: this code was somewhat "simplified" by hand. It was derived from running code...] let unparse environment bind preterm = rec_unparse bind preterm whererec rec_unparse bind = fun free_var s . Id_to_string s | context_var s . Id_to_string s | bound_var y . nth_boundvar y bind | primitive_constant X . (Primitive_constant_to_string X) | ap (X, Y) . (Ap_to_string (rec_unparse bind X) (rec_unparse bind Y)) | ap (ap ( (primitive_constant phi), X), lambda(binder_name,Y)) . % \binder_name:X.Y % let name = new_name (Id_or_int_to_string binder_name) bind in (Lambda_form_to_string name (rec_unparse bind X) (rec_unparse (name.bind) Y)) | ap (ap ( (primitive_constant all), X), lambda(binder_name,Y)) . % forall binder_name:X.Y % let name = new_name (Id_or_int_to_string binder_name) bind in (Generalization_to_string name (rec_unparse bind X) (rec_unparse (name . bind) Y)) | ap (ap (ap (primitive_constant either, X), lambda(binder_name,Y)), Z) . % (either binder_name:X.Y) Z % (Ap_of_fn_or_gen_to_string (rec_unparse bind (ap (ap (primitive_constant either, X), lambda (binder_name, Y))) ) (rec_unparse bind Z)) | lambda(binder_name,X) . let name = new_name (Id_or_int_to_string binder_name) bind in (Untyped_lambda_form_to_string name (rec_unparse (name.bind) X)) | abbrev_instance(id,ilist,prelist) . error `action omitted` | abbrev_arg n . Abbrev_arg_to_string n | match_var s . Match_var_to_string s ;; ;;; unparse ;;; Return string representation of a preterm. ;;; (defun-pattern unparse (env bind preT) (pattern-let preT (((free_var id s) (Id_to_string s)) ((context_var id s) (Id_to_string s)) ((bound_var deBruijn_index y) (nth_boundvar y bind)) ((primitive_constant p_constant c) (Primitive_constant_to_string c)) ((ap fn M arg N) (Ap-to-string (unparse env bind M) (unparse env bind N)) ) ((ap fn (ap fn (primitive_constant p_constant phi) arg A) arg (lambda_form binder x body b)) ; \ x : A . b (let ((name (new_name (Id_or_int_to_string x) bind))) (Lambda_form-to-string name (unparse env bind A) (unparse env (name . bind) b) ))) ((ap fn (ap fn (primitive_constant p_constant all) arg A) arg (lambda_form binder x body b)) ; forall x : A . b (let ((name (new_name (Id_or_int_to_string x) bind))) (Generalization-to-string name (unparse env bind A) (unparse env (name . bind) b) ))) ((ap fn (ap fn (ap fn (primitive_constant p_constant either) arg A) arg (lambda_form binder x body b)) arg N) ; (either x : A . b) N (Ap_of_fn_or_gen-to-string x A b N)) ((lambda_form binder x body b) (Untyped_lambda_form-to-string x b)) ((abbrev_instance id name binding_vars vars actuals terms) ;; [ name < vars > terms ] (Abbrev_instance-to-string env bind name vars terms)) ((abbrev_arg arg_num n_minus_one) (Abbrev_arg-to-string (princ-to-string n_minus_one))) ((match_var id s) (Match_var-to-string s)) )) ) We have been using the recursive CLOS patterns in our code and have been finding them quite useful. We would like to know how much interest there is in this kind of extension. We should also add that we are new to the commonloops/CLOS community. If these issues have been discussed before please let us know politely. Thanks, Bruce Esrig & Jim Hook esrig%oravax.uucp@svax.cs.cornell.edu  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Jul 88 11:16:03 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 18 Jul 88 08:08:54 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA22842; Mon, 18 Jul 88 08:06:28 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-4.0) id AA15584; Mon, 18 Jul 88 08:07:04 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA18158; Mon, 18 Jul 88 08:06:20 PDT Message-Id: <8807181506.AA18158@suntana.sun.com> To: David A. Moon Cc: John Rose , common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: putting CLOS objects in binfiles In-Reply-To: Your message of Fri, 15 Jul 88 17:07:00 -0400. <19880715210732.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 18 Jul 88 08:06:17 -0700 From: kempf@Sun.COM >I'm not sure that anything in Common Lisp requires that multiple >references to a single object, in a file being compiled, do not >turn into multiple objects when the file is loaded. You might have Yes, in fact, there is one Common Lisp implementation in which references to vectors are not EQ after loading. After looking through selected sections of CLtL, no guarantees seem to be made about preserving EQness between compile time and run time. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 17 Jul 88 23:34:47 EDT Received: from Salvador.ms by ArpaGateway.ms ; 17 JUL 88 20:22:27 PDT Return-Path: Redistributed: CommonLoops.pa Received: from ads.com ([128.229.30.16]) by Xerox.COM ; 17 JUL 88 20:20:30 PDT Received: by ads.com (5.59/1.17) id AA10851; Sun, 17 Jul 88 20:23:24 PDT Date: Sun, 17 Jul 88 20:23:24 PDT From: John W. Dye Jr. Message-Id: <8807180323.AA10851@ads.com> To: CommonLoops.pa@Xerox.COM Subject: Clos for Symbolics version7.2 Cc: jdye@ads.com Will you be supporting version 7.2 of the Symbolics Software in forthcoming releases of the Clos software? JD jdye@ads.com  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Jul 88 20:26:00 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Jul 88 17:19:05 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 15 JUL 88 17:08:30 PDT Date: 15 Jul 88 17:08 PDT From: Bobrow.pa@Xerox.COM Subject: Re: putting CLOS objects in binfiles In-reply-to: David A. Moon 's message of Fri, 15 Jul 88 17:07 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: jrose@Sun.COM, common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <880715-170830-1592@Xerox> Here's my immediate problem: I want to build objects which represent predicates in a special purpose query language, and I want them to be uniquified, like pathnames on the Lisp Machine. (They cache things like compiled Lisp code, so it's expensive to build new copies.) Such things do not dump properly, and even if a simple patch were to be applied (say, to dump a class symbol instead of a class), a simple-minded load routine would not uniquify them. "I'm not sure that anything in Common Lisp requires that multiple references to a single object, in a file being compiled, do not turn into multiple objects when the file is loaded. You might have to address this in an implementation-dependent way unless the definition of Common Lisp were changed to require this explicitly." In Loops, the way we solved this problem was to provide each savable object a unique identifier. This UID was constructed from some representation of the machine of ceation and the time of creation. An object knows its UID, and from the UID one can find the object. For any object, the form that was dumped includes its UID, as well as its contents. References from a dumped object to another object contain a form which reconstructs the pointer to object referred to, but does not try to reconstruct its contents. Suppose we had an objects O1 and O2, of classes FOO and FIE respectively, each with one slot named OTHER pointing to the other object. Then dumping them to a file might create expressions like: #,(reconstruct-object uid1 FOO OTHER #.(pointer-to-object uid2 FIE)) #,(reconstruct-object uid2 FOO OTHER #.(pointer-to-object uid1 FOO)) The result of evaluating (pointer-to-object uid2 FIE) is to create an uninitialized object of class FIE, and make it be the value of the slot OTHER of O1. O1 is the object created by the first reconstruct-object form, with UID uid1. Evaluating the second reconstruct-object form changes the contents of the uninititialized object. Evaluating the form (pointer-to-object uid1 FOO) finds the first object created. As far as tracing through objects, we found it was better to separate out the process of finding all objects that you want dumped (a user defined trace that creates a list). One then dumps each of the listed objects. Stan Lanning implemented a preliminary CLOS version that we have been experimenting with.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Jul 88 17:16:25 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Jul 88 14:08:45 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 434003; Fri 15-Jul-88 17:07:46 EDT Date: Fri, 15 Jul 88 17:07 EDT From: David A. Moon Subject: putting CLOS objects in binfiles To: John Rose cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8807151942.AA07423@lukasiewicz.sun.com> Message-ID: <19880715210732.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 15 Jul 88 12:42:03 PDT From: jrose@Sun.COM (John Rose) It's a shame that there's no provision in CLOS for saving objects in binfiles. CLOS doesn't address this because Common Lisp doesn't. Note that CL provides no way to write a "binfile" other than COMPILE-FILE. Of course you can trick COMPILE-FILE into doing anything, using macros, so that's no real limitation. The reason is that the default object fasdumper does a GC-style walk over the object, dumping not only the object but also its class hierarchy. That's a statement about some particular implementation, not about Common Lisp. Can a fix for this get sneaked into Chapter 3 of the CLOS spec? Chapter 3 would be the wrong place. This is logically a Chapter 2 facility, in the same vein as PRINT-OBJECT. The status of CLOS is that it has been accepted by X3J13 into the same status as CLtL. This means that it is open to cleaning up and improvement through the normal X3J13 mechanisms, and I think your suggestion makes a great deal of sense and should be done through those mechanisms. Do you want to make the proposal (I don't know if you're familiar with X3J13), or do want to ask someone on the CLOS committee to do it? Here's essentially what's needed: A generic function (called, say, RECONSTRUCTOR-FORM) which returns a Lisp form to evaluate to reconstruct any given object. This is fine. It's how Flavors does it, so there is some precedent. The only problem with this technique is that it doesn't cope well with circular structures, which can only be handled by separating creation of the objects from filling them in (and even that doesn't work in general, for reasons too complicated to get into here). It can return NIL, which means to do some system default, like a GC-style walk. I think this is a really bad idea. My experience is that there is no default that is right for all objects and any attempt to offer a default does users more harm than good, because the default gets used for cases where it can't work any causes hard to understand problems. Furthermore, if there was a default, it should be implemented by a default method for the generic function, not by special-casing NIL. I'd prefer that there be no default and hence if the user has not defined a method, an error is signalled. Here's my immediate problem: I want to build objects which represent predicates in a special purpose query language, and I want them to be uniquified, like pathnames on the Lisp Machine. (They cache things like compiled Lisp code, so it's expensive to build new copies.) Such things do not dump properly, and even if a simple patch were to be applied (say, to dump a class symbol instead of a class), a simple-minded load routine would not uniquify them. I'm not sure that anything in Common Lisp requires that multiple references to a single object, in a file being compiled, do not turn into multiple objects when the file is loaded. You might have to address this in an implementation-dependent way unless the definition of Common Lisp were changed to require this explicitly. I think most implementations do guarantee object identity within a single COMPILE-FILE, even though they're not required to. This is not a CLOS issue, it applies to all objects for which EQ is defined.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 16:27:05 EDT Received: from Semillon.ms by ArpaGateway.ms ; 15 JUL 88 12:48:59 PDT Return-Path: Redistributed: commonloops.pa Received: from MCC.COM ([10.3.0.62]) by Xerox.COM ; 15 JUL 88 12:47:07 PDT Date: Fri, 15 Jul 88 14:46:51 CDT From: Nat Ballou Subject: KCL PCL version 7/7/88 To: commonloops.pa@Xerox.COM Message-ID: <12414569467.53.AI.BALLOU@MCC.COM> There seems to be an error in the file KCL-Patches - the special variable is misspelled *defmacro (should be *defmacro*). Also, I have been unable to compile this version of PCL in KCL. Has anyone out there succeeded? Nat Ballou MCC -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Jul 88 16:11:48 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 15 Jul 88 13:04:09 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA27189; Fri, 15 Jul 88 13:02:05 PDT Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2) id AA05872; Fri, 15 Jul 88 13:02:42 PDT Received: by lukasiewicz.sun.com (4.0/SMI-4.0) id AA07423; Fri, 15 Jul 88 12:42:03 PDT Date: Fri, 15 Jul 88 12:42:03 PDT From: jrose@Sun.COM (John Rose) Message-Id: <8807151942.AA07423@lukasiewicz.sun.com> To: common-lisp-object-system@sail.stanford.edu Subject: putting CLOS objects in binfiles It's a shame that there's no provision in CLOS for saving objects in binfiles. It's going to blow up in our faces when CLOS gets ubiquitous enough for people to use CLOS objects without being aware of it. (I.e., when lower layers of layered products use CLOS without advertising the fact.) The reason is that the default object fasdumper does a GC-style walk over the object, dumping not only the object but also its class hierarchy. Saving one object got me a binary file of over 100Kb. (In Lucid 3.0.) People expect to use binary files to store data in! If CLOS objects can't be dumped, it will effectively mean that you can't store data in Common Lisp binary files. It's like that ancient MIT story about Lisp packages: The first time they tried to fasdump a package object, much of the Lisp world went along with it. This kind of behavior has to be fixed in real systems. (As with our future unaware user of CLOS, the MIT package fasdump meltdown happened unexpectedly. A bare "FOO:" used to mean the FOO package object, instead of its present meaning.) Can a fix for this get sneaked into Chapter 3 of the CLOS spec? Here's essentially what's needed: A generic function (called, say, RECONSTRUCTOR-FORM) which returns a Lisp form to evaluate to reconstruct any given object. It can return NIL, which means to do some system default, like a GC-style walk. The reconstructor form would be stored in lieu of the real object into the binary file, adorned with #, for evaluation at load time. A different way to factor things would be to have a function RECONSTRUCTOR-INITS which computes at dump time a class name and keyword/value plist, and a function RECONSTRUCT-INSTANCE analogous to and equivalent by default to MAKE-INSTANCE, which is called at load time on the saved data. The fasdumper (and other utilities, like an object migrator) could use protocols like these to handle user-defined types correctly. Using #, is not a solution: A fasdumper needs to correctly handle CLOS objects wherever they occur in the data structures being dumped. Here's my immediate problem: I want to build objects which represent predicates in a special purpose query language, and I want them to be uniquified, like pathnames on the Lisp Machine. (They cache things like compiled Lisp code, so it's expensive to build new copies.) Such things do not dump properly, and even if a simple patch were to be applied (say, to dump a class symbol instead of a class), a simple-minded load routine would not uniquify them. -- John  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 15:30:14 EDT Received: from Riesling.ms by ArpaGateway.ms ; 15 JUL 88 12:06:55 PDT Return-Path: Redistributed: CommonLoops.pa Received: from avalon.berkeley.edu ([128.32.149.8]) by Xerox.COM ; 15 JUL 88 11:59:05 PDT Received: by avalon.berkeley.edu (5.57/1.26) id AA01249; Fri, 15 Jul 88 11:58:36 PDT Message-Id: <8807151858.AA01249@avalon.berkeley.edu> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: David C. Martin Cc: CommonLoops.pa@Xerox.COM Precedence: special-delivery In-Reply-To: Your message of Fri, 15 Jul 88 09:58:32 PDT <8807151658.AA20063@limbo.berkeley.edu> Subject: Re: object-oriented Lisp user interfaces Date: Fri, 15 Jul 88 11:58:31 PDT Sender: dcmartin%avalon.Berkeley.EDU@Berkeley.EDU I put the version I have on camelot.Berkeley.EDU. I don't know if it is the most current, but you're welcome to it. dcm  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 15:30:04 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 15 JUL 88 12:01:18 PDT Return-Path: Redistributed: CommonLoops.pa Received: from avalon.berkeley.edu ([128.32.149.8]) by Xerox.COM ; 15 JUL 88 12:00:24 PDT Received: by avalon.berkeley.edu (5.57/1.26) id AA01260; Fri, 15 Jul 88 11:59:46 PDT Message-Id: <8807151859.AA01260@avalon.berkeley.edu> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: Charles R. Martin Cc: CommonLoops.pa@Xerox.COM Precedence: special-delivery In-Reply-To: Your message of Fri, 15 Jul 88 14:39:40 EDT <8807151839.AA00313@summanulla.mc.duke.edu> Subject: Re: object-oriented Lisp user interfaces Date: Fri, 15 Jul 88 11:59:43 PDT Sender: dcmartin%avalon.Berkeley.EDU@Berkeley.EDU I put the version I have on camelot.Berkeley.EDU (128.32.149.18). dcm -------- Your message: If anyone finds out where to get CLUE, I'd like to know. --------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 15:02:52 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 15 JUL 88 11:43:51 PDT Return-Path: Redistributed: CommonLoops.pa Received: from duke.cs.duke.edu ([128.109.140.1]) by Xerox.COM ; 15 JUL 88 11:41:37 PDT Received: from summanulla.mc.duke.edu by duke.cs.duke.edu (5.59/DUKE/7-8-88) id AA26486; Fri, 15 Jul 88 14:42:05 EDT Received: by summanulla.mc.duke.edu (3.2/DUKE/3-1-88) id AA00313; Fri, 15 Jul 88 14:39:40 EDT Date: Fri, 15 Jul 88 14:39:40 EDT From: Charles R. Martin Message-Id: <8807151839.AA00313@summanulla.mc.duke.edu> To: dcmartin@postgres.berkeley.edu Cc: sokolov@waterloo.media.mit.edu, CommonLoops.pa@Xerox.COM In-Reply-To: David C. Martin's message of Fri, 15 Jul 88 09:58:32 PDT <8807151658.AA20063@limbo.berkeley.edu> Subject: object-oriented Lisp user interfaces If anyone finds out where to get CLUE, I'd like to know.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 15:02:39 EDT Received: from Salvador.ms by ArpaGateway.ms ; 15 JUL 88 11:35:50 PDT Return-Path: Redistributed: CommonLoops.pa Received: from VAX.BBN.COM ([128.89.0.91]) by Xerox.COM ; 15 JUL 88 11:34:15 PDT From: Dan Cerys Sender: cerys@bbn.com To: oravax!dean@CU-ARPA.CS.CORNELL.EDU CC: CommonLoops.pa@Xerox.COM In-reply-to: William Dean's message of Wed, 13 Jul 88 12:29:22 EDT <8807131629.AA20958@oravax.UUCP> Subject: object-oriented Lisp user interfaces Date: Fri, 15 Jul 88 14:25:23 EDT Message-ID: <880715-113550-7988@Xerox> Does anyone know of any good user interface development tools or environments written in Lisp, preferably Common Lisp or CLOS? There are two systems that are built on top of X Windows. The first is CLX, a Common Lisp binding to the X protocol. This allows a Common Lisp application to use windows on an X server. There is a freely available implementation of this written by folks at TI and MIT that is available as part of the X11 distribution (on expo.lcs.mit.edu). This is written in vanilla Common Lisp and has been ported to most common CL implementations. Again, if you use this, you'll need a display server. These are widely available for UNIX boxes, and will someday soon be available on one or more of the Lisp machines. CLX is a low-level interface. One attempt at providing a higher-level interface built on top of CLX is CLUE (Common Lisp User-interface Environment), a system being proposed by TI. By higher-level, I mean dealing in Lisp-Listeners, menus and scroll bars, instead of lines, windows and fonts. This system is based on both CLX and CLOS. It is available on both EXPO.LCS.MIT.EDU (/contrib/clue/) and TI.COM. Although CLX is a fairly stable specification and implementation, CLUE is still evolving. A useful mailing list for those interested in window systems and user interfaces in CL is cl-window@sail.stanford.edu. Dan  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 13:26:12 EDT Received: from Semillon.ms by ArpaGateway.ms ; 15 JUL 88 10:05:14 PDT Return-Path: Redistributed: CommonLoops.pa Received: from limbo.berkeley.edu ([128.32.149.9]) by Xerox.COM ; 15 JUL 88 10:01:28 PDT Received: by limbo.berkeley.edu (5.57/1.26) id AA20063; Fri, 15 Jul 88 09:58:35 PDT Message-Id: <8807151658.AA20063@limbo.berkeley.edu> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: Michael Sokolov Cc: CommonLoops.pa@Xerox.COM Precedence: special-delivery In-Reply-To: Your message of Thu, 14 Jul 88 21:13:07 EDT <8807150113.AA13183@waterloo> Subject: Re: object-oriented Lisp user interfaces Date: Fri, 15 Jul 88 09:58:32 PDT Sender: dcmartin%limbo.Berkeley.EDU@Berkeley.EDU Starting from the oldest to the newest... From UCB Picasso Group - public ftp camelot.Berkeley.EDU (128.32.149.18): XCL = Common LISP Interface for X version 10.4 using foreign functions to Xlib and XMenu C libraries. XCLOS = Object-oriented toolkit using XCL and PCL/CLOS. From MIT X Consortium - public ftp expo.lcs.mit.edu: CLX = Common LISP Interface for X version 11.2 reimplementing Xlib in LISP and using foreign functions for network connections. From TI - don't know where - but I have an old copy: CLUE = Common LISP User Environment - object-oriented toolkit-like extension to CLX using PCL/CLOS. dcm  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 13:06:27 EDT Received: from Semillon.ms by ArpaGateway.ms ; 15 JUL 88 09:53:08 PDT Date: Fri, 15 Jul 88 09:50 PDT From: Gregor.pa@Xerox.COM Subject: Re: problem with 7-7 version: setfs inside with-slots To: duff@eraserhead.steinmetz.ge.com cc: CommonLoops.PA@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest In-Reply-To: <8807141443.AA23043@eraserhead.steinmetz.ge.com> Message-ID: <19880715165029.2.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Thu, 14 Jul 88 10:43:51 EDT From: steinmetz!eraserhead!duff@uunet.UU.NET (David A Duff) I came across the following bug in testing the new (7-7) version of pcl in lucid common lisp 3.0: When using the with slots macro, setf's don't seem to get handled right. This is the most interesting PCL bug I have worked on in a long time. Read "interesting" as a euphemism for I am still confused about this. Here is a temporary patch which should fix the problem. It doesn't fix it the way I would really like. I hope to release a better fix later today. But this is pretty interesting after all so it may take longer. ;from boot.lisp (defun expand-with-slots (whole specs body env gensym instance translate-fn) (walk-form `(let ((,gensym ,instance)) ,@(and (symbolp instance) `((declare (variable-rebinding ,gensym ,instance)))) ,@body) env #'(lambda (f c e) (declare (ignore e)) (expand-with-slots-internal specs f c translate-fn)))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 15 Jul 88 09:20:44 EDT Received: from Riesling.ms by ArpaGateway.ms ; 15 JUL 88 06:12:29 PDT Return-Path: <@EN-C06.Prime.COM:doug@zaphod.prime.com> Redistributed: CommonLoops.pa Received: from EN-C06.Prime.COM ([192.5.58.32]) by Xerox.COM ; 15 JUL 88 06:11:28 PDT Received: from primerd.prime.com by EN-C06.Prime.COM; 13 Jul 88 10:48:09 EDT Received: from zaphod.prime.com by primerd.prime.com (3.2/SMI-3.0DEV3/smail) id AA25811; Wed, 13 Jul 88 11:37:05 EDT Received: by zaphod.prime.com (4.0/SMI-4.0) id AA02176; Wed, 13 Jul 88 10:37:06 EST Date: Wed, 13 Jul 88 10:37:06 EST From: doug@zaphod.prime.com (Douglas Rand) Message-Id: <8807131537.AA02176@zaphod.prime.com> To: gregor.pa@Xerox.COM Subject: Problem in yesterday's new PCL Cc: CommonLoops.pa@Xerox.COM In defs.lisp there should be a line: (defvar *variable-declarations* nil) Also the line: #+:Lucid (system::define-macro `(deftype ,name) expand-fn nil) should be modified for Prime's Common LISP: #+(and :Lucid (not prime)) (system::define-macro `(deftype ,name) expand-fn nil) #+(and :Lucid Prime) (eval `(deftype ,name () '(satisfies ,predicate))) Cheers, Doug  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Jul 88 21:31:27 EDT Received: from Semillon.ms by ArpaGateway.ms ; 14 JUL 88 18:18:16 PDT Return-Path: Redistributed: CommonLoops.pa Received: from media-lab.media.mit.edu ([18.85.0.2]) by Xerox.COM ; 14 JUL 88 18:16:33 PDT Received: from waterloo.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA11873; Thu, 14 Jul 88 21:16:23 EDT Received: by waterloo (3.2/4.8) id AA13183; Thu, 14 Jul 88 21:13:07 EDT Date: Thu, 14 Jul 88 21:13:07 EDT From: Michael Sokolov Message-Id: <8807150113.AA13183@waterloo> To: oravax!dean@cu-arpa.cs.cornell.edu Cc: CommonLoops.pa@Xerox.COM Subject: object-oriented Lisp user interfaces My group (the Vision Sciences group) is currently developing an image proccessing package based on CLOS. In the process of doing this, we have developed a fairly flexible and easy-to-use (I believe) user interface; we define a class of panes, which are our window abstractions, and which respond to events (messages) from the window system in which they reside. The system has been developed on Suns, but with an eye to porting (especially to Symbolics). I don't think this is exactly what you want; our system relies on some sort of native window system; SunView, Symbolics windows, I'd like to make an X-windows port some time too...). But the basic notion we used was to make a system-independent (read portable) pane class, and then, on each type of machine, to define a subclass (like sun-pane, or X-pane) which contains all of the system-dependent information and methods. Then the user-interface can be manipulated at a purely portable level. Sorry to take up so much space for so much blather, but please let me know if you find anything else out about this - Mike Sokolov P.S. I believe there exists something called CLX (or is it XCL?) which is a lisp-based object-oriented interface to X Windows. Please correct me if I am wrong, all you out there!  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Jul 88 20:18:54 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 14 JUL 88 17:12:46 PDT Return-Path: Redistributed: CommonLoops.pa Received: from ECLA.USC.EDU ([26.21.0.65]) by Xerox.COM ; 14 JUL 88 17:11:25 PDT Date: Thu, 14 Jul 88 15:00:28 PDT From: IIM@ECLA.USC.EDU Subject: Re: defmethod does not eval eql-specializer-forms To: IDH@AI.AI.MIT.EDU cc: IIM@ECLA.USC.EDU, CommonLoops.pa@Xerox.COM In-Reply-To: <410986.880712.IDH@AI.AI.MIT.EDU> Message-ID: <12414331647.28.IIM@ECLA.USC.EDU> Actually, the problem with EQL specifiers not being evaluated seems to have been introduced in the St. Patricks day release. There was a change in how the specializers argument to load-defmethod was being generated between the Valentines and St. Patricks day releases that broke things. Since I don't have my sources handy right now I can't give you a precise fix, but roughly: (defmethod foo ((a (eql 'x))) ...) Valentines day release, expands to (load-defmethod ...args... (list (list 'eql 'x)) ;specializers ...more args...) St. Patricks day release, expands to (load-defmethod ...args... '((eql 'x)) ;specializers ...more args...) kab -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Jul 88 12:05:25 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 14 JUL 88 08:54:20 PDT Return-Path: Redistributed: commonloops.PA Received: from uunet.UU.NET ([192.12.141.129]) by Xerox.COM ; 14 JUL 88 08:47:44 PDT Received: from steinmetz.UUCP by uunet.UU.NET (5.59/1.14) with UUCP id AA04737; Thu, 14 Jul 88 11:47:17 EDT Received: from eraserhead.steinmetz.ge.com (eraserhead.ARPA) by kbsvax.steinmetz (1.2/1.1x Steinmetz) id AA21100; Thu, 14 Jul 88 10:45:56 edt Received: by eraserhead.steinmetz.ge.com 3.2/GE-CRD (%W% %D% %T%)) id AA23043; Thu, 14 Jul 88 10:43:51 EDT Date: Thu, 14 Jul 88 10:43:51 EDT From: steinmetz!eraserhead!duff@uunet.UU.NET (David A Duff) Message-Id: <8807141443.AA23043@eraserhead.steinmetz.ge.com> To: CommonLoops.PA@Xerox.COM Subject: problem with 7-7 version: setfs inside with-slots Reply-To: duff@eraserhead.steinmetz.ge.com I came across the following bug in testing the new (7-7) version of pcl in lucid common lisp 3.0: When using the with slots macro, setf's don't seem to get handled right. When I try to setf one slot to a forms which has a symbol which should be bound to another slot, I get an error. Similar code worked ok on the 3-17 version, so my guess is that something must have broken in with-slots or in the walker. Examples: (defclass my-class () (slot1 slot2)) (defmethod broken ((x my-class)) (with-slots (slot1 slot2) x (setf slot1 slot2))) (defmethod works ((x my-class)) (with-slots (slot1 slot2) x (let ((v2 slot2)) (setf slot1 v2)))) Dave Duff GE Research and Development Center Schenectady, New York 518-387-5649 duff@eraserhead.steinmetz.ge.com  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 13 Jul 88 13:50:11 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 13 JUL 88 10:34:26 PDT Return-Path: Redistributed: CommonLoops.pa Received: from cu-arpa.cs.cornell.edu ([10.3.0.96]) by Xerox.COM ; 13 JUL 88 10:24:51 PDT Received: from WRATH.CS.CORNELL.EDU by cu-arpa.cs.cornell.edu (5.59/4.30) id AA07106; Wed, 13 Jul 88 13:01:51 EDT Received: by wrath.cs.cornell.edu (5.54/4.30) id AA27576; Wed, 13 Jul 88 13:01:45 EDT Received: by oravax.UUCP (5.51/5.17) id AA20958; Wed, 13 Jul 88 12:29:22 EDT Date: Wed, 13 Jul 88 12:29:22 EDT From: oravax!dean@cu-arpa.cs.cornell.edu (William Dean) Message-Id: <8807131629.AA20958@oravax.UUCP> To: CommonLoops.pa@Xerox.COM Subject: object-oriented Lisp user interfaces Does anyone know of any good user interface development tools or environments written in Lisp, preferably Common Lisp or CLOS? We are trying to select some software on which to develop portable user interfaces for multiple workstations (Symbolics, Suns). We're especially interested in flexible, extensible tools written with object-oriented programming in mind. Something like X-Windows, with client objects (not necessarily windows) responding to messages from servers. Thanks, Bill  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 12 Jul 88 17:59:22 EDT Received: from Semillon.ms by ArpaGateway.ms ; 12 JUL 88 14:36:52 PDT Date: Tue, 12 Jul 88 14:28 PDT From: Gregor.pa@Xerox.COM Subject: Re: defmethod does not eval eql-specializer-forms To: Ian Horswill cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <410986.880712.IDH@AI.AI.MIT.EDU> Message-ID: <19880712212822.3.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Tue, 12 Jul 88 13:12:37 EDT From: Ian Horswill I don't know what the right fix is for this. I patched it by putting a call to eval into parse-specializer in boot.lisp. This is probably wrong because it seems wrong for the "parser" to be eval'ing things and is definitely wrong because it evaluates the form in a null lexical environment whereas the spec says it should be evaled in the environment ofr the defmethod. It's sufficient for my purposes however. What version of PCL are you using? The newest version just put out there yesterday doesn't have this problem, and I thought St. Patricks days was OK too. What is true is that eql methods and method combination don't interact that well in either St. Patricks Day or 7/11/88. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 12 Jul 88 16:15:24 EDT Received: from Salvador.ms by ArpaGateway.ms ; 12 JUL 88 12:53:07 PDT Return-Path: Redistributed: CommonLoops.pa Received: from AI.AI.MIT.EDU ([10.2.0.6]) by Xerox.COM ; 12 JUL 88 10:09:55 PDT Date: Tue, 12 Jul 88 13:12:37 EDT From: Ian Horswill Subject: defmethod does not eval eql-specializer-forms To: CommonLoops.pa@Xerox.COM cc: IDH@AI.AI.MIT.EDU Message-ID: <410986.880712.IDH@AI.AI.MIT.EDU> I don't know what the right fix is for this. I patched it by putting a call to eval into parse-specializer in boot.lisp. This is probably wrong because it seems wrong for the "parser" to be eval'ing things and is definitely wrong because it evaluates the form in a null lexical environment whereas the spec says it should be evaled in the environment ofr the defmethod. It's sufficient for my purposes however. -ian  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Jul 88 18:48:02 EDT Received: from Semillon.ms by ArpaGateway.ms ; 11 JUL 88 15:34:01 PDT Date: Mon, 11 Jul 88 15:28 PDT From: Gregor.pa@Xerox.COM Subject: new version of PCL To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880711222847.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There is a new version of PCL on parcvax.xerox.com. The *pcl-system-date* of this version is 7/7/88 beta. This is a beta test version. I have only tried this version in Genera 7.2, Lucid 2.1 and 3.0 and ExCL 3.0 Lisps. I encourage the brave to get this version and try it out. Less brave users may want to wait a week or two. As usual, see the notes.text file for more details about what has changed in this release. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Jul 88 16:15:15 EDT Received: from Semillon.ms by ArpaGateway.ms ; 11 JUL 88 11:18:46 PDT Date: Mon, 11 Jul 88 11:12 PDT From: Gregor.pa@Xerox.COM Subject: Re: bug fix To: Ian Horswill cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <410346.880711.IDH@AI.AI.MIT.EDU> Message-ID: <19880711181236.9.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Mon, 11 Jul 88 12:35:58 EDT From: Ian Horswill In the pcl beta release of 17 March 1988, there seems to be a bug in update-slot-accessors--class-1 in std-class.lisp. The occurance of: (neq (slotd-type old-slotd) (slotd-type slotd)) should be changed to: (not (equal (slotd-type ... Fixed, and will be in the next release. It's also not clear to me why update-slot-accessors--class-2 deletes the old method after adding the new since it would seem to cause the accessor to be removed entierly if, say, only the type changed and not the name (this is how the problem above kills accessors with non-symbol types). Also fixed and will be in the next release. Thanks for this report. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Jul 88 14:55:52 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Jul 88 11:11:23 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 JUL 88 11:06:55 PDT Date: Mon, 11 Jul 88 11:02 PDT From: Gregor.pa@Xerox.COM Reply-To: Gregor@GRAPEVINE.parc.xerox.com Subject: CLOS Workshop To: Common-Lisp@Sail.Stanford.edu, common-lisp-object-system@sail.stanford.edu, CL-Object-Oriented-Programming@Sail.Stanford.edu, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880711180221.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Workshop for CLOS Users and Implementors October 3rd and 4th Xerox PARC Palo Alto, California We have been excited by the extent to which CLOS is already being used, and the ways in which it is being extended. The purpose of this workshop is to provide an opportunity for the members of the CLOS community to get together and share their experience. To provide a good start for the interchange, we are requesting that participants supply a short position paper (1-3 pages) describing work related to CLOS. Some topics of interest are: Applications Programming Techniques Implementation Programming Environment Tools Extensions of CLOS Techniques for Converting to CLOS Meta Object Techniques and Theory Critiques We will try to support demonstrations or videotapes of applications, programming environments, implementations or other relevant systems. If you are planning to attend, please let us know by August 15th. This will help us with planning and allow us to arrange a discount rate at a local hotel. Position papers should reach us by September 9th so that we can organize a program and arrange for duplication of the papers. Position papers, notice to attend, and other correspondence should be sent to: Gregor Kiczales 3333 Coyote Hill Rd. Palo Alto, CA 94304 or by Internet mail to: Gregor.pa@Xerox.com -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Jul 88 14:16:04 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 JUL 88 11:06:55 PDT Date: Mon, 11 Jul 88 11:02 PDT From: Gregor.pa@Xerox.COM Reply-To: Gregor@GRAPEVINE.parc.xerox.com Subject: CLOS Workshop To: Common-Lisp@Sail.Stanford.edu, common-lisp-object-system@sail.stanford.edu, CL-Object-Oriented-Programming@Sail.Stanford.edu, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880711180221.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Workshop for CLOS Users and Implementors October 3rd and 4th Xerox PARC Palo Alto, California We have been excited by the extent to which CLOS is already being used, and the ways in which it is being extended. The purpose of this workshop is to provide an opportunity for the members of the CLOS community to get together and share their experience. To provide a good start for the interchange, we are requesting that participants supply a short position paper (1-3 pages) describing work related to CLOS. Some topics of interest are: Applications Programming Techniques Implementation Programming Environment Tools Extensions of CLOS Techniques for Converting to CLOS Meta Object Techniques and Theory Critiques We will try to support demonstrations or videotapes of applications, programming environments, implementations or other relevant systems. If you are planning to attend, please let us know by August 15th. This will help us with planning and allow us to arrange a discount rate at a local hotel. Position papers should reach us by September 9th so that we can organize a program and arrange for duplication of the papers. Position papers, notice to attend, and other correspondence should be sent to: Gregor Kiczales 3333 Coyote Hill Rd. Palo Alto, CA 94304 or by Internet mail to: Gregor.pa@Xerox.com -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 11 Jul 88 12:54:02 EDT Received: from Salvador.ms by ArpaGateway.ms ; 11 JUL 88 09:38:39 PDT Return-Path: Redistributed: CommonLoops.pa Received: from AI.AI.MIT.EDU ([10.2.0.6]) by Xerox.COM ; 11 JUL 88 09:33:23 PDT Date: Mon, 11 Jul 88 12:35:58 EDT From: Ian Horswill Subject: bug fix To: CommonLoops.pa@Xerox.COM cc: IDH@AI.AI.MIT.EDU Message-ID: <410346.880711.IDH@AI.AI.MIT.EDU> In the pcl beta release of 17 March 1988, there seems to be a bug in update-slot-accessors--class-1 in std-class.lisp. The occurance of: (neq (slotd-type old-slotd) (slotd-type slotd)) should be changed to: (not (equal (slotd-type ... The bug manifests itself by quietly deleting readers and accessors for slots whose types are not symbols. In particular, CLUE and CLX (X window system interfaces for CommonLisp) break without the change. It's also not clear to me why update-slot-accessors--class-2 deletes the old method after adding the new since it would seem to cause the accessor to be removed entierly if, say, only the type changed and not the name (this is how the problem above kills accessors with non-symbol types). If the old methods were removed before adding the new it would survive the case where the old and new names were the same but the forcep flag was still set. Thanks, -ian  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 8 Jul 88 17:44:55 EDT Received: from Salvador.ms by ArpaGateway.ms ; 08 JUL 88 14:39:39 PDT Return-Path: <@EN-C06.Prime.COM,@S51.Prime.COM:SOBO@S66.Prime.COM> Redistributed: commonloops.pa Received: from EN-C06.Prime.COM ([192.5.58.32]) by Xerox.COM ; 08 JUL 88 14:37:45 PDT Received: from S51.Prime.COM by EN-C06.Prime.COM; 08 Jul 88 17:36:58 EDT Received: from S66.Prime.COM by S51.Prime.COM; 08 Jul 88 17:37:55 EDT Received: (from user SOBO) by S66.Prime.COM; 08 Jul 88 17:36:19 EDT To: commonloops.pa@Xerox.COM From: SOBO@S66.Prime.COM Date: 08 Jul 88 17:36:20 EDT Message-ID: <880708-143939-4883@Xerox> To: (commonloops.pa@xerox.com) From: Nadine Sobolevitch (sobo@s66) Date: 08 Jul 88 5:21 PM Subject: PCL and Symbolics ZMACS I have been having some problems editing PCL methods in ZMACS. 1. The function record-definition in the file 3600-low is mostly commented out, so that the method definition does not get linked to its source file. Was there a reason for this? It seems to work once I uncommented it. 2. I have a method-defining macro which uses the declaration sys:function-parent in order to tell the editor that the method is defined within the textual body of the macro call. This stopped working in St. Patrick's day PCL. Here is a sample of code which (I believe) should work but does not: (scl:defprop deffoo "foo maker" si:definition-type-name) (defmacro deffoo (name) `(defmethod ,name ((self pcl:object)) (declare (sys:function-parent ,name deffoo)) (format t "~&~s" self)) ) (deffoo smurf) Any attempt to edit smurf breaks with ZMACS unable to find (PCL:METHOD SMURF (PCL:OBJECT)) in the (correct) source-file; ZMACS then tries a textual search, which, of course, fails.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 7 Jul 88 13:05:40 EDT Received: from Semillon.ms by ArpaGateway.ms ; 07 JUL 88 09:51:29 PDT Return-Path: Redistributed: commonloops.pa Received: from RELAY.CS.NET ([10.4.0.5]) by Xerox.COM ; 07 JUL 88 09:46:57 PDT Received: from cs.brown.edu by RELAY.CS.NET id aa07010; 7 Jul 88 10:40 EDT Received: from thayer.sun (thayer.ARPA) by cs.brown.edu (1.2/1.00) id AA27635; Thu, 7 Jul 88 10:39:55 edt Date: Thu, 7 Jul 88 10:39:39 EDT From: kgk@cs.brown.edu Message-Id: <8807071439.AA26393@thayer.sun> To: commonloops.pa@Xerox.COM Subject: test 1 2 3 4  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 7 Jul 88 06:42:14 EDT Received: from Semillon.ms by ArpaGateway.ms ; 07 JUL 88 03:32:41 PDT Return-Path: Redistributed: commonloops.pa Received: from uunet.UU.NET ([192.12.141.129]) by Xerox.COM ; 07 JUL 88 03:30:35 PDT Received: from unido.UUCP by uunet.UU.NET (5.59/1.14) with UUCP id AA15314; Thu, 7 Jul 88 06:30:17 EDT Received: by unido.uucp with uucp; Thu, 7 Jul 88 11:22:38 +0100 From: unido!ztivax!adf@uunet.UU.NET (Angela Dappert-Farquhar) Date: Thu, 7 Jul 88 12:12:44 -0200 Message-Id: <8807071012.AA16043@ztivax.uucp> Received: by ztivax.uucp; Thu, 7 Jul 88 12:12:44 -0200 To: commonloops.pa@Xerox.COM Subject: patch for slot-value Cc: adf@uunet.UU.NET The option "default" in slot-value-using-class doesn't work: (slot-value-using-class class object slot-name dont-call-slot-missing-p default) ==> ... (slot-value-using-class--class class object ... default) ==> ... (slot-value-using-class--class-internal ,class ,object .. ,default) ==> Now slot-value-using-class--class-internal never passes "default" to "with-slot-internal", and if it would pass it "with-slot-internal" would not return it. Here is our patch: (defun slot-value-using-class--class-internal (class object slot-name dont-call-slot-missing-p default) (with-slot-internal--class (class object slot-name nil) (:instance ...) (:dynamic ...) (:class ...) (nil () (progn (unless dont-call-slot-missing-p (slot-missing object slot-name)) default)))) (defmacro with-slot-internal--class ((class object slot-name createp) &body cases) .... nil-case (let ,(and (car nil-case) '((,(caar nil-case) ,temp1))) ;;^ backquote (return . ,(cdr nil-case)))))) Now slot-exists-p also works. --------------- Something else: We need to redefine classes that have been created with a certain metaclass with an other metaclass. This is not possible in the current version of PCL. There should be a (when new-metaclass-p ... with (class-change old-class new-metaclass) in "update-class". (defclass a () (s1) (:metaclass standard-class)) (defclass my-meta-class (standard-class) (...)) (defclass a () (s1) (:metaclass standard-class)) Angela adf%ztivax.siemens.com@siemens.com  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 6 Jul 88 20:14:08 EDT Received: from Salvador.ms by ArpaGateway.ms ; 06 JUL 88 17:04:05 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM ([10.7.0.2]) by Xerox.COM ; 06 JUL 88 17:01:56 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA13341; Wed, 6 Jul 88 17:00:30 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA03161; Wed, 6 Jul 88 16:55:52 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA08730; Wed, 6 Jul 88 17:00:34 PDT Message-Id: <8807070000.AA08730@suntana.sun.com> To: commonloops.pa@Xerox.COM Subject: *slotd-unsupplied* Date: Wed, 06 Jul 88 17:00:29 -0700 From: kempf@Sun.COM The method PARSE-CLASS-SLOT in defclass.lisp initializes the type and initfunction slots of a standard-slot-description object to *slotd-unsupplied*. This is OK, except *slotd-unsupplied* is not a valid type specifier nor is it a valid function. As a result, when, for example, initialize-from-defaults in slots.lisp checks to see if the initfunction is NIL, it is not, but it is not a valid function either. Result: initialize-from-defaults trys to funcall *slotd-unsupplied*. Something similar happens in COMPUTE-EFFECTIVE-SLOTD, where an eq test of (slotd-type slotd) against *slotd-unsupplied* fails, presumably because the slot contents is initialized to a copy somewhere. Anyway, I'd suggest making the initfunction something like: (function (lambda () *slotd-unsupplied*) and the type be nil. This is all happening in the St. Patrick's Day release, in Sun Common Lisp 2.1. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 6 Jul 88 18:48:34 EDT Received: from Semillon.ms by ArpaGateway.ms ; 06 JUL 88 15:36:07 PDT Date: Wed, 6 Jul 88 15:34 PDT From: Gregor.pa@Xerox.COM Reply-To: Gregor.pa@GRAPEVINE.parc.xerox.com Subject: the weather is here, wish you were beautiful To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880706223453.4.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Well its summer time again. Has been for a while actually, but out here on the west coast things move more slowly. At this time of year, it is traditional for many people to seek rest from their day to day worries and obligations. Lots of people go on vacation. Which brings me to the real subject of my message, the vacation program. If you don't receive your mail on a Unix machine, read no further. I don't know much about Unix, but from what people tell me, the vacation programs seems to be like most other Unix facilities. It seems that it has a switch which will make it behave reasonably, but it doesn't do this by default. It seems that when someone on the CommonLoops list goes on vacation, and uses the default mode of the vacation program, an annoying thing happens. Specifically, everytime a message gets sent to the CommonLoops list, I get a message from that person's machine telling me they are on vacation. So, if five people go on vacation for a week, and if there are 5 messages to the CommonLoops list a day that week, I get 125 messages telling me about what a wonderful time people are having on vacation. To make maintaining the CommonLoops list easier, and to reduce my level of envy about other people's vacations, please be sure to use the mode of the vacation program that arranges for it to send me only one notification that you have gone on vacation. I don't know, but I've heard it said that this has something to do with the -I option. Thanks, and have a nice vacation. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 6 Jul 88 15:24:57 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 06 JUL 88 12:07:45 PDT Return-Path: Redistributed: commonloops.pa Received: from postgres.Berkeley.EDU ([128.32.149.1]) by Xerox.COM ; 06 JUL 88 12:06:43 PDT Received: by postgres.Berkeley.EDU (5.57/1.26) id AA13139; Wed, 6 Jul 88 12:06:20 PDT Date: Wed, 6 Jul 88 12:06:20 PDT From: larry%postgres.Berkeley.EDU@berkeley.edu (Larry Rowe) Message-Id: <8807061906.AA13139@postgres.Berkeley.EDU> To: commonloops.pa@Xerox.COM Subject: method discrimination on persistent objects Cc: Gregor.pa@Xerox.COM We are implementing a persistent object system that stores CLOS objects in an extensible database system (POSTGRES). Since pointers have to be stored symbolically in the database, each persistent object is represented by a unique object identifier, called an objid. We would like to make all references to persistent objects, whether they are in main memory or in the database, an objid. We have implemented a main memory cache for persistent objects to improve performance. The cache maps objid's to objects. Currently, the cache contains a lisp pointer to the object. We have modified the make-instance function so that it returns the objid for the new object. In addition, slot-value has been modified to accept an objid and to lookup the object in the cache. However, we have had a difficult time modifying the PCL code to support method invocation on persistent objects. The problem arises because the objid's are not instances of the represented class. We have explored three approaches to fix this problem and thus far we have not been able to make any one work: 1. change the behavior of the class-of function to return a pointer to the class object when given an objid. note that the class object will also be a persistent object so the return value should be an objid or, to optimize method lookup, a lisp pointer. (this failed because we couldn't figure out where to make this change. we looked at class-of-1 and get-class-1 but couldn't figure out where the change should be made.) 2. change the discriminating-function for the generic-function. (this also failed because we couldn't figure out how to make the change. moreover, it was clear that this approach would not survive future enhancements to the PCL/CLOS implementation.) 3. change the main memory representation for an object to be a handle that contains the following slots: a class reference, an objid, lisp pointer to the actual object. (we haven't tried to implement this approach yet because it requires changes to the low-level implementation of PCL.) Before we embark on this third approach we thought we'd query the community to see if anyone else has an idea how we can solve this problem without having to muck with the low-level implementation. It seems like the CLOS metaclass protocol ought to support this kind of extension. larry rowe  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 5 Jul 88 22:08:58 EDT Received: from Semillon.ms by ArpaGateway.ms ; 05 JUL 88 18:56:06 PDT Date: Tue, 5 Jul 88 18:55 PDT From: Gregor.pa@Xerox.COM Subject: typep and defclass vs. ExCL To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880706015500.7.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Jim Larus' message last week pointed out a significant PCL performance problem I was previously unaware of. Specifically, there was a performance problem which I thought was a compile time issue, which is in fact a runtime issue in ExCL. This only affects people who use typep to test if an object is an instance of a PCL defined class. Anyone using the St. Patrick's day version of PCL in Franz Lisp should make this patch. People using other ports of PCL can ignore this message. The change involves installing three new definitions in your PCL. You can avoid a lot of wasted PCL recompilation time by doing the following. 1) Edit the files to install these changes. 2) In the PCL you already have loaded, manually recompile each file of the changed files. First recompile defs, then load it. Then recompile defclass. 3) Get a new lisp, load pcl with the recompiled files, and load your system. You do not need to recompile your code. If you use (compile-pcl), it will probably recompile all of PCL which is unnecessary. ;in defs.lisp, replace do-deftype with this (defun do-satisfies-deftype (name predicate) (let* ((specifier `(satisfies ,predicate)) (expand-fn #'(lambda (&rest ignore) (declare (ignore ignore)) specifier))) ;; Specific ports can insert their own way of doing this. Many ;; ports may find the expand-fn defined above useful. ;; the right place is. (or #+:Genera (setf (get name 'deftype) expand-fn) #+:Lucid (system:define-macro `(deftype ,name) expand-fn nil) #+ExCL (setf (get name 'excl::deftype-expander) expand-fn) #+:coral (setf (get name 'ccl::deftype-expander) expand-fn) ;; This is the default for ports for which we don't know any ;; better. Note that for most ports, providing this definition ;; should just speed up class definition. It shouldn't have an ;; effect on performance of most user code. (eval `(deftype ,name () `'(satisfies ,predicate)))))) ;in defs.lisp, replace existing definition with this one (defun define-early-setfs-and-type-predicates () (dolist (forms-var '(*early-defclass-forms* *fsc-defclass-forms* *methods-defclass-forms*)) (dolist (defclass (eval forms-var)) (destructuring-bind (ignore name supers slots . options) defclass (unless (eq name 't) (do-satisfies-deftype name (make-type-predicate-name name))) (dolist (slot slots) (let ((slot-options (cdr slot))) (loop (when (null slot-options) (return t)) (when (eq (car slot-options) ':accessor) (do-defmethod-setf-defsetf (cadr slot-options) (list name))) (setq slot-options (cddr slot-options))))) (dolist (option options) (when (and (listp option) (eq (car option) :accessor-prefix)) (setq option (cadr option)) (dolist (slot slots) (if (null option) (do-defmethod-setf-defsetf (car slot) (list name)) (do-defmethod-setf-defsetf (symbol-append (symbol-name option) (symbol-name (car slot))) (list name)))))))))) ;in defclass.lisp, replace existing definition with this one (defmethod inform-type-system-about-class ((class standard-class) name) (let ((predicate-name (make-type-predicate-name name))) (setf (symbol-function predicate-name) (make-type-predicate class)) (do-satisfies-deftype name predicate-name))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 30 Jun 88 15:22:48 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 30 JUN 88 12:05:31 PDT Return-Path: Redistributed: commonloops.pa Received: from uunet.UU.NET ([192.12.141.129]) by Xerox.COM ; 30 JUN 88 12:04:06 PDT Received: from unido.UUCP by uunet.UU.NET (5.59/1.14) with UUCP id AA14383; Thu, 30 Jun 88 15:03:43 EDT Received: by unido.uucp with uucp; Thu, 30 Jun 88 15:57:55 +0100 From: unido!ztivax!adf@uunet.UU.NET (Angela Dappert-Farquhar) Date: Thu, 30 Jun 88 16:56:06 -0200 Message-Id: <8806301456.AA06326@ztivax.uucp> Received: by ztivax.uucp; Thu, 30 Jun 88 16:56:06 -0200 To: commonloops.pa@Xerox.COM Subject: shared slots, obsolete classes, dynamic slots Cc: adf@uunet.UU.NET 1. Are shared slots supposed to have initforms? If yes, when should they be evaluated? 2. The description of shared slots in CLOS looks as if there should be only one cell for all instances of a class that defines this slot and also for all instances of its subclasses. PCL defines a cell for the class and one for every subclass. Which is the correct interpretation? (defclass a() ((s1 :allocation :class))) (defclass b (a) ()) (setq i (make-instance 'a)) (setq j (make-instance 'a)) (setq k (make-instance 'b)) (setf (slot-value i 's1) 1) (slot-value j 's1) ;;; -> 1 (slot-value k 's1) ;;; -> (*slotd-unsupplied*) 3. The patch that should fix the bug using slot-value of an instance of class obsolete-class doesn't work. (Mail 29. April). It just solves the problem with the infinite loop but still leaves the changed instance incorrect. Obsolete class is a copy of the new class instead of the old one. Information of the old class isn't accessible anymore. As soon as you don't just add new slots to the old class (i.e. you insert, delete, exchange the order of some slots) it can not work anymore. (defclass c () (s1 s2)) (setq x (make-instance 'c :s1 1 :s2 2)) (defclass c () (s2 s1)) (slot-value x 's1) ;;; ->2 (slot-value x 's2) ;;; ->1 4. Last years Meta Object Protocol mentions operations on dynamic slots. The new chapter 2 doesn't. Does that mean that dynamic slots won't be supported in CLOS? Angela adf%ztivax.siemens.com@siemens.com  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 30 Jun 88 13:23:03 EDT Received: from Semillon.ms by ArpaGateway.ms ; 30 JUN 88 10:11:35 PDT Return-Path: Redistributed: commonloops.pa Received: from cu-arpa.cs.cornell.edu ([10.3.0.96]) by Xerox.COM ; 30 JUN 88 10:03:57 PDT Received: from WRATH.CS.CORNELL.EDU by cu-arpa.cs.cornell.edu (5.59/4.30) id AA25261; Thu, 30 Jun 88 12:54:27 EDT Received: by wrath.cs.cornell.edu (5.54/4.30) id AA10304; Thu, 30 Jun 88 12:54:21 EDT Received: by oravax.UUCP (5.51/5.17) id AA22913; Thu, 30 Jun 88 12:06:41 EDT Date: Thu, 30 Jun 88 12:06:41 EDT From: oravax!cde@cu-arpa.cs.cornell.edu (Carl Eichenlaub) Message-Id: <8806301606.AA22913@oravax.UUCP> To: commonloops.pa@Xerox.COM Subject: Request for Flavors -> CLOS We have an application that is largely written using Symbolics Flavors that we would like to make portable to Common Lisp via CLOS. Does anyone have an implementation of Flavors in CLOS (i.e. a Flavors -> CLOS translation)? It needn't be for all the bells and whistles of Flavors. We have used a fairly restricted subset of the full functionality of Flavors. Carl D. Eichenlaub oravax!cde@cu-arpa.cs.cornell.edu (ARPANET) ...{rochester,allegra}!cornell!oravax!cde (UUCP)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jun 88 19:33:17 EDT Received: from Semillon.ms by ArpaGateway.ms ; 29 JUN 88 16:22:32 PDT Date: Wed, 29 Jun 88 16:20 PDT From: Gregor.pa@Xerox.COM Subject: Re: CLOS Speed To: larus@ginger.Berkeley.EDU cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8806292200.AA08497@paris.Berkeley.EDU> Message-ID: <19880629232026.2.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 29 Jun 88 15:00:13 PDT From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus) The reason that this function speeds up execution of my program is that the body (BODY) passed to DO-DEFTYPE is *interpreted* everytime that TYPEP is applied to a PCL object. In fact, since TYPEP must apply many, if not most, of the predicates, these simple code fragements are interpreted frequently. I had assumed that all implementations did the optimization that prevented this interpreted code from being called at runtime. It goes to show that you don't ever know. I will include your change in the next release of PCL. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jun 88 18:15:59 EDT Received: from Salvador.ms by ArpaGateway.ms ; 29 JUN 88 15:02:42 PDT Return-Path: Redistributed: commonloops.pa Received: from paris.Berkeley.EDU ([128.32.150.46]) by Xerox.COM ; 29 JUN 88 15:01:24 PDT Received: by paris.Berkeley.EDU (5.57/1.25) id AA08497; Wed, 29 Jun 88 15:00:18 PDT From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus) Message-Id: <8806292200.AA08497@paris.Berkeley.EDU> To: Gregor.pa@Xerox.COM Cc: commonloops.pa@Xerox.COM Subject: Re: CLOS Speed In-Reply-To: Your message of Wed, 29 Jun 88 13:29:00 PDT. <19880629202919.1.GREGOR@PORTNOY.parc.xerox.com> Reply-To: larus@ginger.Berkeley.EDU Date: Wed, 29 Jun 88 15:00:13 PDT The reason that this function speeds up execution of my program is that the body (BODY) passed to DO-DEFTYPE is *interpreted* everytime that TYPEP is applied to a PCL object. In fact, since TYPEP must apply many, if not most, of the predicates, these simple code fragements are interpreted frequently. This interpretation is expensive. Compiling the body reduces the cost of these predicates to a trivial amount. /Jim  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jun 88 16:46:51 EDT Received: from Semillon.ms by ArpaGateway.ms ; 29 JUN 88 13:32:07 PDT Date: Wed, 29 Jun 88 13:29 PDT From: Gregor.pa@Xerox.COM Subject: Re: CLOS Speed To: larus@ginger.Berkeley.EDU cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8806291650.AA08198@paris.Berkeley.EDU> Message-ID: <19880629202919.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 29 Jun 88 09:50:54 PDT From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus) The change for Allegro CL is below. I don't know of a portable way to compile this special form declaration (which is clearly a shortcomming in CL). (defun do-deftype (name lambda-list &rest body) (let #+Symbolics ((si:inhibit-fdefine-warnings t)) #-Symbolics () #+Lispm (setq body (copy-list body)) (eval `(deftype ,name ,lambda-list ,@body)) #+excl (compile `(:property ,name excl::deftype-expander)))) Thanks for this change. I have actually been planning to look at doing special port-specific code for this and for do-defmethod-setf-defsetf. But I don't understand why this change speeds up the execution of your program. I would have thought it would make it compile faster, but that was all. To help me understand this, could you send me two things please: A small code fragment which runs faster after you make this change, and the result of calling walker::walk-form on that code fragment. Thanks for the help. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jun 88 14:18:00 EDT Received: from Semillon.ms by ArpaGateway.ms ; 29 JUN 88 11:15:32 PDT Date: Wed, 29 Jun 88 11:12 PDT From: Gregor.pa@Xerox.COM Subject: Re: CLOS slot access To: Brad.Myers@a.gp.cs.cmu.edu cc: commonloops.pa@Xerox.COM, bam@a.gp.cs.cmu.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <1988.6.28.16.40.45.Brad.Myers@A.GP.CS.CMU.EDU> Message-ID: <19880629181240.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Tue, 28 Jun 88 12:48:18 EDT From: Brad.Myers@a.gp.cs.cmu.edu What is the fastest way to do slot accesses in CLOS? We are using (defclass foo () (slot1 :initform NIL) .... ) (:accessor-prefix)) (defmethod bar ((f foo)) (clos::with-slots* (slot1) f (setf slot1 3) ; setting (+ 6 slot1) ; access This is the fastest way to do slot access in PCL, and will remain so. But, one of the key points of my message is that you shouldn't decide which interface to use based soley on performance, you should look at whether the functionality is what you really want. Two other comments: - there will be a new version shortly which should provide somewhat better slot access performance. - the :accessor-prefix option is now obsolete and should not be used in new code. Final question. It is possible that there is a problem with slot access optimization in your lisp. Could you please send me the results of: (pprint (walker::walk-form '(defmethod bar ((f foo)) (clos::with-slots* (slot1) f (setf slot1 3) (+ 6 slot1))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jun 88 13:22:41 EDT Received: from Salvador.ms by ArpaGateway.ms ; 29 JUN 88 10:19:27 PDT Return-Path: <@HELIOS.NORTHEASTERN.EDU:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET ([10.4.0.5]) by Xerox.COM ; 29 JUN 88 10:16:22 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id ac07416; 29 Jun 88 11:12 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa09478; 29 Jun 88 10:53 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA14260; Wed, 29 Jun 88 09:37:42 EDT Date: Wed, 29 Jun 88 09:37:42 EDT From: karl lieberherr Message-Id: <8806291337.AA14260@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Let's take a break. Based on Richard Gabriel's feedback: Your poem is fun. I liked your reference to mountains: I did grow up in them, in a small valley in Switzerland. You recommend that our OOPSLA paper not discuss the application of the Law of Demeter to CLOS at all. I am sorry but I cannot follow this recommendation. We (the Demter team) believe in what we are doing, we stand to it and we don't hesitate to publish it. CLOS has given us the unique opportunity to generalize our original message passing Law from one dynamic method selection argument to several dynamic method selection arguments. This generalization has given us further insight into the role of the Law and we can get the old formulation back by specializing the number of dynamic method selection arguments to one. ---------------------------------------- Based on Lanning's message from Xerox: You made an important point which was also acknowledged by Gabriel. Here is our point of view which makes clear where we disagree. Let's assume we have a (non-generic) function op-res which takes as first argument an operator of type Operator : AddSym | MulSym. plus two other arguments which are numbers. Function op-res returns the value of applying the operator to the two numbers. We have provided this function to our users and given them the interface for the function. Some time later, we decide to make the function generic in its first argument. Should we inform the users about this change? (By the way, in CLOS we are forced to make it generic in all three arguments since all three are required.) The users might have used this function op-res inside other methods and if we make now the first argument generic the user's code might suddenly violate the Law. Why should the user know about the fact that the first argument is generic now? The reason is extensibility! The user has now an easy way to extend the op-res function to other types and that is very useful knowledge for the future modification of the user's program. When the function is generic in its first argument, its implementation must look like: (pardon the new Flavors notation; this discussion is relevant not only to CLOS but also to generic function systems with only one dynamic method-selection argument (such as new Flavors)): (defmethod (AddSym op-res) (e1 e2) ... ) (defmethod (MulSym op-res) (e1 e2) ... ) If the user wants to extend the domain of op-res, he/she just adds another method. If the function is not generic, this won't work. Therefore, we view the number of method selection arguments of a function as part of the interface of that function along with the typing information and a formal or informal specification. HERE WE CLASH WITH THE VIEW OF THE CLOS INVENTORS. They view the syntactic non-distinction as a contribution of CLOS, while we view the fact that we can have several method selection arguments as one (among many) contributions of CLOS. What about the violation of the Law when we go from non-generic to generic? Lets consider the following classes: (Pardon the Demeter notation which is explained in IEEE Computer, June 88) A = Compound. Compound = "(" Operator List(PrefixExp) ")". Consider the method: (defmethod (A bad-style) (e1 e2) (op-res (op x) e1 e2)) which is identical before and after the transition from non-generic to generic. Why is method "bad-style" in bad-style after the transition? Since it is attached to A AND since it contains a dependency on the subparts of the Compound class. If Compound changes to Compound = "(" Operator List(PrefixExp) ")". we have to modify the semantics of class A, although class A did not change: (defmethod (A :bad-style) (e1 e2) (op-res (additive-op x) e1 e2)) This violates the principle of modularity. Why is "bad-style" in good-style before the transition? It is the prerogative of the Law that it can accept certain constructs which are in bad shape. We want to have a Law without exceptions which is easy to remember and to follow. We don't want to restrict non generic function calls since we don't want to upset the Lisp or C programmers. ------------------------------------------------- Based on Gregor Kiczales' feedback: CLOS and C++: There is certainly a huge difference between CLOS and C++ but with respect to the Law, CLOS and C++ are not that far apart: In C++ also all arguments are used to determine which method (called a member function) to execute. The difference is that in C++ the argument types (after the first) are used to determine the member function at compile-time. I.e., C++ uses static method selection. The first argument in a method of a derived class is used for implicit case analysis at run-time. In other words: CLOS supports implicit case analysis on all required arguments, while C++ supports implicit case analysis only on the first argument. Both C++ and CLOS support function overloading on all required arguments. For C++ the message passing formulation of the Law is appropriate. We view the compile-time method selection of C++ due to overloading as syntactic sugar. We could always rename the methods by prefixing their names with argument types to avoid the need of overloading. But CLOS is inherently more powerful: it does true implicit case analysis on all the method selection arguments. Therefore we need for CLOS the generalization of the Law as proposed. >Since it seems to be difficult to explain the law in netmail, I look >forward to the presentation at OOPSLA. Until then, I will wait and >wonder. I agree! Let's pick up the discussion again at or after OOPSLA '88 and I am convinced that most of you will be converted to faithful followers of the Law. Thank you very much for your contributions of technical ideas and poems. The Demeter team looks forward to seeing you at OOPSLA '88. -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jun 88 13:22:16 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 29 JUN 88 10:15:36 PDT Return-Path: Redistributed: commonloops.pa Received: from ucsd.edu ([128.54.16.1]) by Xerox.COM ; 29 JUN 88 10:09:32 PDT Received: from sdics.ucsd.edu by ucsd.edu (5.58/UCSD-1.0); Wed, 29 Jun 88 10:03:20 PDT id AA12636 for commonloops.pa@xerox.com From: hartung%ics@ucsd.edu (Jeff Hartung) Message-Id: <8806291706.AA07185@sdics.ICS> Received: by sdics.ICS scf2.7vax; Wed, 29 Jun 88 10:06:29 PDT Date: 29 Jun 88 10:05 PDT (Wednesday) To: Brad.Myers@a.gp.cs.cmu.edu Subject: Re: CLOS slot access Cc: commonloops.pa@Xerox.COM, bam@a.gp.cs.cmu.edu >What is the fastest way to do slot accesses in CLOS? >We are using > (defclass foo () > (slot1 :initform NIL) > .... > ) >(:accessor-prefix)) >(defmethod bar ((f foo)) > (clos::with-slots* (slot1) f > (setf slot1 3) ; setting > (+ 6 slot1) ; access ... The latest CLOS specs no longer have an :accessor-prefix class-option and now include :accessor as a slot option, as well as :reader, :writer and other slot related stuff. Therefore, you would use: (defclass foo () ((slot1 :accessor slot1 :initform NIL) ... )) (defmethod bar ((f foo)) ... --Jeff Hartung-- ARPA - hartung@sdics.ucsd.edu UUCP - !ucsd!sdics!hartung  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 Jun 88 13:22:06 EDT Received: from Semillon.ms by ArpaGateway.ms ; 29 JUN 88 10:02:06 PDT Return-Path: Redistributed: commonloops.pa Received: from paris.Berkeley.EDU ([128.32.150.46]) by Xerox.COM ; 29 JUN 88 09:52:05 PDT Received: by paris.Berkeley.EDU (5.57/1.25) id AA08198; Wed, 29 Jun 88 09:50:59 PDT From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus) Message-Id: <8806291650.AA08198@paris.Berkeley.EDU> Cc: commonloops.pa@Xerox.COM Subject: Re: CLOS Speed Reply-To: larus@ginger.Berkeley.EDU Date: Wed, 29 Jun 88 09:50:54 PDT Depending on your programming style, there is another place in PCL that can be changed to significantly speed up execution of a programming. If your program applies TYPEP to PCL objects, then you should look at redefining DO-DEFTYPE (in defs.lisp) to compile the DEFTYPE body. The problem is that DO-DEFTYPE eval's a DEFTYPE special from to define new type predicates for each class. These predicates are stored as lists and are evaluated (at least in Allegro CL). This evaluation consumed around 25% of the execution type in Curare. The change for Allegro CL is below. I don't know of a portable way to compile this special form declaration (which is clearly a shortcomming in CL). (defun do-deftype (name lambda-list &rest body) (let #+Symbolics ((si:inhibit-fdefine-warnings t)) #-Symbolics () #+Lispm (setq body (copy-list body)) (eval `(deftype ,name ,lambda-list ,@body)) #+excl (compile `(:property ,name excl::deftype-expander)))) /Jim  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 23:15:26 EDT Received: from Salvador.ms by ArpaGateway.ms ; 28 JUN 88 20:07:53 PDT Return-Path: Redistributed: commonloops.pa Received: from SAIL.Stanford.EDU ([10.0.0.11]) by Xerox.COM ; 28 JUN 88 20:06:52 PDT Message-ID: Date: 28 Jun 88 20:06 PDT From: Dick Gabriel Subject: The Law of Demeter To: commonloops.pa@Xerox.COM I just wrote a poem that helps explain the Law of Demeter (apologies to Wallace Stevens): Thirteen Ways of Looking at the Law of Demeter I Among twenty snowy mountains, The only moving thing Was the Speaker of the Law. II I was of three minds, Like a program In which there are three violations. III The Sheet of the Law whirled in the autumn winds. It was a small part of the pantomime. IV A message and an argument Are one. A message and an argument and the Law Are one. V I do not know which to prefer, The beauty of inflections Or the beauty of innuendos, The Law speaking Or just after. VI Icicles filled the long window With barbaric glass. The shadow of the Speaker Crossed it to and fro. The mood Traced in the shadow An indecipherable cause. VII O thin men of Haddam, Why do you imagine golden birds? Do you not see how the Law Walks around the feet Of the programs about you? VIII I know noble accents And lucid, inescapable rhythms; But I know, too, That the Law is involved In what I know. IX When the Law disappeared from sight, It marked the edge Of one of many circles. X At the sight of the Law Working in green light, Even the bawds of euphony Would cry out sharply. XI He rode over Connecticut In a glass coach. Once, a fear pierced him, In that he mistook The shadow of his equipage For a violation. XII The river is moving. The Law must be working. XIII It was evening all afternoon. It was snowing. And it was going to snow. The Law sat On a sheet of paper.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 20:56:22 EDT Received: from Salvador.ms by ArpaGateway.ms ; 28 JUN 88 17:03:55 PDT Return-Path: Redistributed: commonloops.pa Received: from ECLA.USC.EDU ([26.21.0.65]) by Xerox.COM ; 28 JUN 88 17:00:10 PDT Date: Tue, 28 Jun 88 15:46:11 PDT From: Kim A. Barrett Subject: intern-function-name To: commonloops.pa@Xerox.COM cc: iim@ECLA.USC.EDU Message-ID: <12410145665.34.IIM@ECLA.USC.EDU> I more or less agree with Gregor about what the definition of intern-function-name should be. The problem with the current definition is that it doesn't go quite far enough in including package qualifiers in the names, and isn't necessarily very consistent about what package the symbol is interned into. Back before I had fixed the couple of known places in our system which required that function names be symbols, I was using the following definition of intern-function-name. kab (defvar *intern-function-name-package* (make-package "Package for PCL::INTERN-FUNCTION-NAME -- Hands off" :use ())) ;don't use anybody, even LISP (defun intern-function-name (name) (etypecase name (symbol name) (list (let ((*package* *intern-function-name-package*)) (intern (write-to-string name :escape t ;to include package specifiers :level nil ;avoid cuttoff of long or :length nil ; deeply nested names ;; the rest of these are specified to ensure ;; consistency from one call to the next, ;; making this function insensitive to current ;; bindings of the corresponding printer vars :radix nil :base 10 :circle nil :pretty nil :case :upcase :gensym t :array t ;for completeness, why not )))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 13:07:06 EDT Received: from Semillon.ms by ArpaGateway.ms ; 28 JUN 88 09:53:14 PDT Date: Tue, 28 Jun 88 09:50 PDT From: Gregor.pa@Xerox.COM Subject: Re: A Law is a Law, Guffaw, Guffaw To: Dick Gabriel cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: Message-ID: <19880628165000.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: 27 Jun 88 23:57 PDT From: Dick Gabriel The point my Debunker team came up with is that the purpose of a law - such as the law from Demeter - should be clearly stated. Inlining as a means of defeating the law is only interesting because it introduces a way to meet the letter of the law without meeting the spirit of it - by out-of-lining. That is, wherever there is a violation of the law, one can repair it by introducing local methods. Therefore, I ask: What does the law buy you, for stating law only gives no clue about objectives. I actually asked this question in my first reply to the proposed law. Based on the fact that I got no real reply, and the other mail I saw, I concluded that this law was not really applicable to CLOS. CLOS is a different language than Smalltalk, and certainly a different language than C++. I would still like to see an explanation of exactly what this law is really trying to provide in terms of helping programmers understand what their code is doing, or helping compilers or helping whatever. Since it seems to be difficult to explain the law in netmail, I look forward to the presentation at OOPSLA. Until then, I will wait and wonder. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 13:06:52 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 28 JUN 88 09:50:05 PDT Return-Path: Redistributed: commonloops.pa Received: from A.GP.CS.CMU.EDU ([128.2.242.7]) by Xerox.COM ; 28 JUN 88 09:48:23 PDT Date: Tue, 28 Jun 88 12:48:18 EDT From: Brad.Myers@a.gp.cs.cmu.edu To: commonloops.pa@Xerox.COM cc: bam@a.gp.cs.cmu.edu Subject: CLOS slot access Message-ID: <1988.6.28.16.40.45.Brad.Myers@A.GP.CS.CMU.EDU> What is the fastest way to do slot accesses in CLOS? We are using (defclass foo () (slot1 :initform NIL) .... ) (:accessor-prefix)) (defmethod bar ((f foo)) (clos::with-slots* (slot1) f (setf slot1 3) ; setting (+ 6 slot1) ; access >From Gregor's message, I got the impression that this was wrong. Is there a better/faster way to access fields of objects? We are using the February 3, 1988 release of PCL/CLOS. Brad A. Myers Research Computer Scientist Computer Science Department Carnegie Mellon University Pittsburgh, PA 15213 (412) 268-5150 bam@a.gp.cs.cmu.edu  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 12:03:52 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 28 JUN 88 08:52:59 PDT Return-Path: Redistributed: commonloops.pa Received: from fs3.cs.rpi.edu ([128.213.1.14]) by Xerox.COM ; 28 JUN 88 08:50:31 PDT Received: by fs3.cs.rpi.edu (5.54/1.2-RPI-CS-Dept) id AA05790; Tue, 28 Jun 88 11:49:40 EDT Date: Tue, 28 Jun 88 11:50:00 EDT From: harrisr@turing.cs.rpi.edu (Richard Harris) Received: by turing.cs.rpi.edu (3.2/1.2-RPI-CS-Dept) id AA15542; Tue, 28 Jun 88 11:50:00 EDT Message-Id: <8806281550.AA15542@turing.cs.rpi.edu> To: commonloops.pa@Xerox.COM Subject: intern-function-name The result returned by intern-function-name should be independent of the current value of *package* (at least when invoked with names used by the PCL system). (In fact, the result should depend only on the argument to intern-function-name.) Otherwise, operations which depend on intern-function-name returning the same symbol might not work. TRACE-METHOD is an example of a function that depends on the value returned by intern-function-name and that might be called when the value of *package* has changed from its value at method definition time. The form (format nil "~S" name) uses the value of *package*. A better definition of intern-function-name is: ;;; I assume that the function-names used by the PCL system are either symbols, ;;; or lists beginning with METHOD. (defun intern-function-name (name) #+Symbolics name #-Symbolics (cond ((symbolp name) name) ((listp name) (let ((*package* (if (eq (car name) 'method) (symbol-package (if (listp (cadr name)) (cadr (cadr name)) (cadr name))) *package*))) (intern (format nil "~S" name)))))) This still isn't quite right if one wants to prevent symbols from being interned in some package(s) (the LISP package, for example). If this matters, something like the following definition could be used: ;; the assumption mentioned above doesn't matter in this definition. (defvar *name-package* (or (find-package "NAME") (make-package "NAME" :use nil))) (defun intern-function-name (name) #+Symbolics name #-Symbolics (cond ((symbolp name) name) ((listp name) (let ((*package* *name-package*)) (intern (format nil "~S" name))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 11:10:02 EDT Received: from Semillon.ms by ArpaGateway.ms ; 28 JUN 88 08:02:20 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM ([10.7.0.2]) by Xerox.COM ; 28 JUN 88 07:59:55 PDT Received: from snail.sun.com ([129.145.1.3]) by Sun.COM (4.0/SMI-4.0) id AA14120; Tue, 28 Jun 88 07:55:30 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA16945; Tue, 28 Jun 88 07:51:14 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA14555; Tue, 28 Jun 88 07:55:44 PDT Message-Id: <8806281455.AA14555@suntana.sun.com> To: Dick Gabriel Cc: commonloops.pa@Xerox.COM Subject: Re: A Law is a Law, Guffaw, Guffaw In-Reply-To: Your message of 27 Jun 88 23:57:00 -0700. Date: Tue, 28 Jun 88 07:55:41 -0700 From: kempf@Sun.COM >Given that there seems to have been little thought given to method >combination, given that the full implications and use of CLOS has not been >fully understood, and, well, given all of this, I recommend that your >OOPSLA paper not discuss the application of the law from Demeter to CLOS >at all. I agree. There are some legitimate style issues which need to be worked out for CLOS programming, since the user-definable generic function model which it presents is a new one. Unfortunately, I think the "Law" of Demeter contributes only confusion. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 10:17:50 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 28 JUN 88 07:10:12 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 28 JUN 88 07:08:41 PDT To: Gregor.pa@Xerox.COM CC: kanderso@WILMA.BBN.COM, CommonLoops.pa@Xerox.COM, kanderson@WILMA.BBN.COM In-reply-to: Gregor.pa@xerox.com's message of Mon, 27 Jun 88 13:19 PDT <19880627201930.4.GREGOR@PORTNOY.parc.xerox.com> Subject: Problems with 7debug in 7.2 Reply-to: aboulanger@bbn.com Date: Tue, 28 Jun 88 10:10:22 EDT From: aboulang@WILMA.BBN.COM Sender: aboulang@WILMA.BBN.COM Message-ID: <880628-071012-3530@Xerox> Data point: Most machines when doing a Function 1 F at BBN are 7.1. Albert Boulanger  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 Jun 88 03:05:45 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 JUN 88 23:58:59 PDT Return-Path: Redistributed: commonloops.pa Received: from SAIL.Stanford.EDU ([10.0.0.11]) by Xerox.COM ; 27 JUN 88 23:57:40 PDT Message-ID: Date: 27 Jun 88 23:57 PDT From: Dick Gabriel Subject: A Law is a Law, Guffaw, Guffaw To: commonloops.pa@Xerox.COM The point my Debunker team came up with is that the purpose of a law - such as the law from Demeter - should be clearly stated. Inlining as a means of defeating the law is only interesting because it introduces a way to meet the letter of the law without meeting the spirit of it - by out-of-lining. That is, wherever there is a violation of the law, one can repair it by introducing local methods. Therefore, I ask: What does the law buy you, for stating law only gives no clue about objectives. Structured programming, the inquisition of the '70's, introduced ``laws'' that required that only certain programming constructs be used. Unfortunately I had to take exams under such inquisitors, and when asked to render Knuth's Art of Programming algorithms into these constructs, I always used a While loop and a Case statement: The While loop tested whether a PC went negative, and the case statement used the non-negative PC's to select the right statement to execute and to set the next PC. It wasn't that I missed the point of structured programming so much as I resented it being presented as a set of laws that guaranteed something, when all the laws did were encourage it. What is it you encourage? Some bright fellow hit the nail on the head on this issue in a recent message, which I cannot locate, when he remarked that CLOS abstraction practice required that no one know how a function is implemented, but to only know its interface. If you use my function, you have no business knowing whether it's generic, let alone what methods it uses or what method combination it uses. I will publish the interface, and you must use it. Maybe I'll provide a means to extend my function, and then I'll tell more about its implementation. I certainly reserve the right to not tell you which arguments I use for non-trivial method selection, and to possibly change my decision. That is the key difference between CLOS-like object orientedness and Smalltalk-like: In Smalltalk you know that the message gets sent to some method/class while in CLOS you have no idea how the function is implemented: Because of optionals, keywords, and the use of the class named T to ignore required arguments during method computation, there is no guaranteed knowledge by the client of a function about the method computation of that function or even about any aspect of its implementation. Therefore, the law from Demeter might not have any reasonable application to a CLOS-style language. Given that there seems to have been little thought given to method combination, given that the full implications and use of CLOS has not been fully understood, and, well, given all of this, I recommend that your OOPSLA paper not discuss the application of the law from Demeter to CLOS at all. Anyway, OOPSLA seems to be a SmallTalk-and-friends conference, so discussion of CLOS really belongs in the Lisp conferences. -rpg-  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 19:23:38 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 JUN 88 16:07:42 PDT Return-Path: Redistributed: commonloops.pa Received: from mitre-bedford.ARPA ([26.3.0.66]) by Xerox.COM ; 27 JUN 88 16:06:10 PDT Posted-From: The MITRE Corp., Bedford, MA Received: from orbit.sun.uucp by linus.MENET (3.2/4.7) id AA19551; Mon, 27 Jun 88 19:01:32 EDT Posted-Date: Mon, 27 Jun 88 19:01:17 EDT Received: from localhost by orbit.sun.uucp (3.2/SMI-3.0DEV3) id AA29947; Mon, 27 Jun 88 19:01:18 EDT Message-Id: <8806272301.AA29947@orbit.sun.uucp> To: kanderso@wilma.bbn.com Cc: CommonLoops.pa@Xerox.COM Subject: Re: Problems with 7debug in 7.2 Date: Mon, 27 Jun 88 19:01:17 EDT From: rich%linus@mitre-bedford.ARPA Yes, there are additional errors in 7debug, because two functions are no longer around in 7.2. We investigated them, and the following code gets around some of the problems. Seems that in 7.2 they have set up the debugger to handle various languages (not only Lisp!). Therefore, you have to call slightly different functions (as you can see below). Just use these patches to the debugger instead of the old ones. Frankly, the code was too dense to completely debug, especially considering the fact that I never use the features of the debugger (showing source code, or diassembled code) that the bugs pertain to. --------- As for having a clos for 7.1 and 7.2, it is possible. You have to get the minor version and load different files accordingly. There are a few other details, and if you want them, contact me, and I will try to recreate what we did here at MITRE. However, I think you would really rather invest the time converting all of your systems to 7.2. It was a relatively painless process and we have about 4 or 5 major systems. **** code to make things "better" ;===================================== (SYSTEM-INTERNALS:BEGIN-PATCH-SECTION) ; From buffer debugger.lisp >rel-7>debugger BD: (552) (SYSTEM-INTERNALS:PATCH-SECTION-ATTRIBUTES "-*- Mode: LISP; Package: Debugger; Base: 8; Lowercase: Yes -*-") (defun show-all-compiled (&optional show-source-file-p) (let* ((*printing-monitor-message* t) (frame *current-frame*) (function (frame-function frame))) (format t "~V~S~" *emphasis-character-style* (function-name-for-debugger frame)) (when show-source-file-p (print-function-source-file function)) (format t "~2%") ;; Print the arguments, including the rest-arg which is a local (let ((local-start (print-frame-args *current-frame* 1 t))) (cond ((frame-active-p *current-frame*) ;; Print the rest of the locals, if the frame is active (print-frame-locals *current-frame* local-start 1) (format t "~%~VDisassembled code:~" *deemphasis-character-style*) ;; YIKES!! I can't believe I did this! PAUL 6/8/88 ;; (show-all-compiled-1 frame function) was the old call here. ;; now, in 7.2 the debugger has been COMPLETELY rewritten using methods and whatnot. ;; this is apparently because of the support other languages and the new window debugger, etc... ;; lframe-show-code-for-function is what the REAL debugger calls here, so I just threw it in. (lframe-show-code-for-function *current-language* frame function (lframe-show-source-code-p *current-language*) :brief nil) ;; This kludge is to prevent the prompt from triggering a **MORE** ;; when it comes out on the bottom line of the window (if (memq :notice (send standard-output :which-operations)) (send standard-output :notice :input-wait))))))) ;===================================== (SYSTEM-INTERNALS:BEGIN-PATCH-SECTION) ; From buffer debugger.lisp >rel-7>debugger BD: (552) (SYSTEM-INTERNALS:PATCH-SECTION-ATTRIBUTES "-*- Mode: LISP; Package: Debugger; Base: 8; Lowercase: Yes -*-") (cp:define-command (com-show-source-code :command-table "Global" :provide-output-destination-keyword nil :explicit-arglist (&optional (function nil function-supplied-p))) ((function '((sys:function-spec :defined-p t) :partial-completers nil) :default (if (variable-boundp *current-frame*) (function-name-for-debugger *current-frame*) nil))) (let* ((function (if function-supplied-p function (function-name-for-debugger *current-frame*))) (frame (if function-supplied-p nil *current-frame*)) ;; YIKES AGAIN!! As before, the debugger has been changed substantially, ;; so the call to (show-frame-source frame function) that was here no longer compiles. ;; I stole the code below from the rel-7 debugger source. Hope it is correct. PAUL 6/8/88. (language (if frame (find-language-for-frame frame) (find-language-for-function function)))) ;;; Rich: instead of passing on function, you could pass a nil. You get different (maybe better) behavior. (lframe-show-code-for-function language frame function t t t)))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 16:41:03 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 JUN 88 13:21:37 PDT Date: Mon, 27 Jun 88 13:19 PDT From: Gregor.pa@Xerox.COM Subject: Re: Problems with 7debug in 7.2 To: kanderso@WILMA.BBN.COM cc: CommonLoops.pa@Xerox.COM, kanderson@WILMA.BBN.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: The message of 27 Jun 88 10:44 PDT from kanderso@WILMA.BBN.COM Message-ID: <19880627201930.4.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Mon, 27 Jun 88 13:44:47 -0400 From: kanderso@WILMA.BBN.COM I think there are more problems in 7debug when running in 7.2. For example DBG:SHOW-ALL-COMPILED-1 is undefined. It looks like it has been replaced with something else in 7.2. I also suspect (but have not proven yet) that the previous bug fix you sent out (originally from MITRE) will not compile in 7.1. I think it is getting hard to have 1 system that will work in 7.1 and 7.2... We should just get rel-7-debug to work in 7.2. I suspect that most Genera sites have converted to 7.2 by now, and I am willing to say that sites that haven't can't get new versions. Could you take a look at fixing this? I have some separate changes I want to look at making to make combined method names print out better, but I will hold off on these until you have a chance address these other debugger problems. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 14:27:50 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 JUN 88 11:14:42 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM ([10.7.0.2]) by Xerox.COM ; 27 JUN 88 11:12:02 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA28719; Mon, 27 Jun 88 11:09:23 PDT Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2) id AA23240; Mon, 27 Jun 88 11:05:07 PDT Received: by lukasiewicz.sun.com (4.0/SMI-4.0) id AA21675; Mon, 27 Jun 88 11:11:26 PDT Date: Mon, 27 Jun 88 11:11:26 PDT From: jrose@Sun.COM (John Rose) Message-Id: <8806271811.AA21675@lukasiewicz.sun.com> To: lieber@corwin.ccs.northeastern.edu Cc: commonloops.pa@Xerox.COM In-Reply-To: karl lieberherr's message of Thu, 23 Jun 88 07:49:36 EDT <8806231149.AA04866@corwin.CCS.Northeastern.EDU> Subject: Nesting and the Law Redistributed: commonloops.pa Date: Thu, 23 Jun 88 07:49:36 EDT From: karl lieberherr Jim Kempf took strong exception to our ideas in writing: After reading your IEEE Computer article, I must unfortunately take strong exception to your Law of Demeter for CLOS. This is a clear statement and requires a clear answer. We took his message (along with feedback from our students) as an opportunity to make our Law more clear: ----- LAW OF DEMETER (CLOS, object version, revised) ------------- For all methods M, all function calls inside M must use only the following objects as method selection arguments: - M's argument objects or - slot values of method selection argument classes of M. (Objects created by the method, or by functions which it calls, and objects in global variables are viewed as being passed by arguments. A method selection argument is an argument which is used for identifying the applicable methods.) ---------------------------------------------------------- This law is vacuous, except for the clarification below, because function calling is the only mode of computation in Lisp, apart from the evaluation of literal constants and special forms. (Proof: In Lisp, (F X) == (FUNCALL #'F X), except for special forms.) Therefore, this Law prohibits nothing. (Or are you restricting special forms and literals? :-). The important thing to realize is that Lisp supports, as its fundamental concept, functional abstraction. Any rule, guideline, or Law which attempts to differentiate functions according to their nature or contents is not going to integrate well with Lisp. ........... The Law of Demeter has implications for the nesting of function calls. To discuss those implications, we classify functions as follows: A accessor function returns an object which exists before the function was called. A constructor function returns an object which did not exist before the function was called. The Law allows the nesting of constructor functions, as well as the nesting of non-generic functions. >>>>> However, the Law prohibits functional composition of generic accessor functions. >>>>> Finally! A straightforward statement of your Law. As I expected, a negative formulation would be clearest. What this clarifies, perhaps, is a misconception of this Law's proponents concerning the character of Lisp. In some languages, there are linguistic distinctions between accessors, constructors, overloaded functions, and "plain" functions. Checking adherence to your Law requires the ability to make those distinctions, for every function which appears in a method body. In Lisp, such distinctions may be hidden behind functional abstraction boundaries (e.g., inside a lambda). Therefore, adherence to your Law not only requires examination of the source code of a method body, which is reasonable, but also forces the examination of the definitions of all functions used by the method. That's unreasonable, not least because it destroys functional abstraction boundaries. In fact, since Lisp functions can be stored in data structures and computed at runtime, adherence to your Law is a theoretically undecidable proposition. I don't think your Law integrates well with Lisp. I think it depends on linguistic distinctions which Lisp happily avoids. (For the record, I further believe that these distinctions in a language hamper the creation of good abstractions.) Here's an alternative law governing slot variables, which preserves abstraction, instead of destroying it: The function SLOT-VALUE may only be used to access the slots of lexically apparent classes. Clarifications and definitions: * A class is lexically apparent within its defining form, and within the body of any method which uses that class as a selector. * We define all such locations to be the "scope" of the class. That is, a class is lexically apparent within its scope, and nowhere else. * The call to SLOT-VALUE may appear on the scope of a class through macroexpansion and DEFCONSTANT substitution, but not through inline substitution or runtime use of FUNCALL. * The slot accessed by any call to SLOT-VALUE must be determined at compile time. That is, only literal symbol values and DEFCONSTANT values may be used as slot names. * The scope of a class may be extended to include the scopes of other classes, or to include specific functions, by the use of a to-be-defined FRIEND declaration. (This is as in C++, and makes this rule more flexible without detracting from a class's autonomy.) * This rule is made to be broken by debuggers and other system code. -- Karl -- John  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 14:00:57 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 27 JUN 88 10:48:27 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 27 JUN 88 10:46:03 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: Problems with 7debug in 7.2 Date: Mon, 27 Jun 88 13:44:47 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880627-104827-1802@Xerox> I think there are more problems in 7debug when running in 7.2. For example DBG:SHOW-ALL-COMPILED-1 is undefined. It looks like it has been replaced with something else in 7.2. I also suspect (but have not proven yet) that the previous bug fix you sent out (originally from MITRE) will not compile in 7.1. I think it is getting hard to have 1 system that will work in 7.1 and 7.2... k  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 12:15:55 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 27 JUN 88 09:10:41 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM ([10.7.0.2]) by Xerox.COM ; 27 JUN 88 09:09:21 PDT Received: from snail.sun.com ([129.145.1.3]) by Sun.COM (4.0/SMI-4.0) id AA25850; Mon, 27 Jun 88 09:07:42 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA17076; Mon, 27 Jun 88 09:03:26 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA12589; Mon, 27 Jun 88 09:07:54 PDT Message-Id: <8806271607.AA12589@suntana.sun.com> To: Gregor.pa@Xerox.COM Cc: kempf@Sun.COM, David Vinayak Wallace , commonloops.pa@Xerox.COM Subject: Re: Bug in intern-function-name (low.l) In-Reply-To: Your message of Sat, 25 Jun 88 14:55:00 -0700. <19880625215557.6.GREGOR@PORTNOY.parc.xerox.com> Date: Mon, 27 Jun 88 09:07:51 -0700 From: kempf@Sun.COM > This function uses ~S to generate function names instead of ~A. Thus, if > the interning is being done in another package, the package qualification > will be inserted into the name and a different name will be generated. > Below, it is correctly defined. > > . > . > >Actually, I think the function is correctly defined as it stands. In >the code fragment concerned, it is trying to generate a symbol whose >name looks like the printed representation of a list. I wanted any >package qualification that might appear in the printed representation to >appear in that list. The problem comes when the function is used to generate method function names for purposes of identifying methods in environment tools. Since real function specs have not yet been approved much less implemented, the only portable alternative is to use symbols, as PCL does. However, if a method spec is computed in list form during some environmental operation (for example, source code finding using the generic function name) and INTERN-FUNCTION-NAME is called to generate a symbol identifying the method function, the ~S format will cause the symbols in the method spec to be prefixed with the package symbol unless FORMAT happens to be called in the package in which the original symbols in the spec were interned. The result is a symbol name which is not EQUALP to the original, since the original method function spec is formatted in the package where the generic function (and thus the method) was defined. Another alternative, mentioned by Dave Wallace, would be to use SYMBOL-NAME, in which case the package in which the formatting was occuring does not matter. If package qualification within the list is desired, then it should probably be generated explicitly by INTERN-FUNCTION-NAME. This will cause the package name to always appear in the symbol, regardless of what the current state of the user's environment happens to be. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 11:55:03 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 JUN 88 08:38:08 PDT Date: 27 Jun 88 08:37 PDT Sender: Lanning.pa@Xerox.COM From: Stanley's Tool Works Subject: Re: Law and documentation In-reply-to: karl lieberherr 's message of Mon, 27 Jun 88 08:24:23 EDT To: lieber@corwin.ccs.northeastern.edu cc: commonloops.pa@Xerox.COM Message-ID: <880627-083808-1460@Xerox> ...When the programmer writes a function call, he/she has to know how the system will locate the code to execute (otherwise the wrong code might get executed). ...The Law of Demeter promotes information restriction (in a given method you can only call certain other methods). The concepts of information restriction and information hiding are orthogonal to each other and both have been proposed originally by Parnas. It is true that the Law requires you to keep track of certain information, but you need that information anyway to understand the method you are writing. It is excellent documentation to your program. -- Karl So I can't write a piece of code for others to use without telling the user how it is implemented? And if I write version 1 using functions, I can't use generic-functions in version 2 without causing the poor users code to break the (lowercase) "law"? While the developer of a system may need to know the global structure of that program, a user does not. The "information ... you need ... to understand the [code] you are writing" is the structure of that code, the functionality and interfaces to programs that you are using (but not now writing), and the fact that those programs work. You should not need to know the internals of programs that you use. That is one of the features of CLOS -- you don't have a different syntax for method invocation and function call, so you need not know about implementation details of functions you use. And what is this about "the wrong code might get executed"? That will happen only if I violate the input contract (or if I'm using broken code), regardless of whether I follow the "law" or not. With this in mind, I propose "smL's Law": >> If a functional interface requires that its input arguments >> satisfy some property, don't pass it arguments that might violate >> that property. ----- smL P.S. Can we *please* stop calling this a (uppercase) "Law"? How about "The Advice of Demeter"? Or "The Suggestion of Demeter"...  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 10:34:26 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 JUN 88 07:26:59 PDT Return-Path: <@HELIOS.NORTHEASTERN.EDU:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET ([10.4.0.5]) by Xerox.COM ; 27 JUN 88 07:25:36 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id aa01607; 27 Jun 88 10:12 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa12054; 27 Jun 88 10:11 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA02719; Mon, 27 Jun 88 10:10:24 EDT Date: Mon, 27 Jun 88 10:10:24 EDT From: karl lieberherr Message-Id: <8806271410.AA02719@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law/Authorship/Inline Dick Gabriel writes: >I've put my Debunker team on this problem. Here is the latest version of >the law (I wonder: Will the people whose comments on the law alter it be >made co-authors on the OOPSLA paper?): The Law of Demeter for CLOS is the generalization of the Law of Demeter for message passing object-oriented systems. While the text of the Law of Demeter for CLOS has changed based on feedback from the CLOS developers and users, the intent of the Law has not changed. The OOPSLA paper: "Object-oriented programming: An objective sense of style" is about the Law for message passing systems and devotes only one paragraph to the CLOS formulation of the Law. Therefore, we find it appropriate to acknowledge the contributions of the CLOS developers/users in the acknowledgement section of the paper. Dick Gabriel further points out that inline expansion destroys adherence to the Law. Yes, that is expected. What we need is a smart compiler which finds the suitable inline expansions automatically. Nothing is for free: When you follow the Law, you tend to get more methods (see the OOPSLA paper for further discussion). The only way to convince yourself of the benefits of the Law, is to take a 1000 line CLOS program which contains many class definitions and make it satisfy the Law. Some programmers will note that they follow the Law without conscious effort and other will be surprised how their program gets improved. We have done this exercise with a good part of the 14000 line Demeter system. -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 Jun 88 10:28:05 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 JUN 88 07:20:01 PDT Return-Path: <@HELIOS.NORTHEASTERN.EDU:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET ([10.4.0.5]) by Xerox.COM ; 27 JUN 88 07:18:59 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id aa01372; 27 Jun 88 9:53 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa10635; 27 Jun 88 8:25 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA02276; Mon, 27 Jun 88 08:24:23 EDT Date: Mon, 27 Jun 88 08:24:23 EDT From: karl lieberherr Message-Id: <8806271224.AA02276@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law and documentation John Berger has the following comments: >Concerning the Law: You say that function calls inside a method M >should use only certain objects as method selection arguments. >How does the programmer know what arguments a function will use to >dispatch according to type? How does the programmer know that a >function is generic and will do such a dispatch? When the programmer writes a function call, he/she has to know how the system will locate the code to execute (otherwise the wrong code might get executed). >You say the Law prohibits functional composition of accessor functions >which return non-slot objects. >How does the programmer know that a function-call is a slot-access? If you request a reader or accessor, CLOS will generate such a function for you. You can do it also with slot-value. >You say it's okay to use objects that are created by the method in >question, or by a function that it calls. >How does the programmer know that an object returned by a function is >newly-created? It is standard to distinguish between constructors, mutators and observers (see Liskov and Guttag, Abstraction and Spec. in Progr. Dev., page 90). I consider it good practice to consider it as part of the type of a method whether it is a constructor or not. >It seems that in order to use the Law, the programmer must have >knowledge which violates an even older law: That of information-hiding. No. The Law of Demeter promotes information restriction (in a given method you can only call certain other methods). The concepts of information restriction and information hiding are orthogonal to each other and both have been proposed originally by Parnas. It is true that the Law requires you to keep track of certain information, but you need that information anyway to understand the method you are writing. It is excellent documentation to your program. -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jun 88 20:34:55 EDT Received: from Salvador.ms by ArpaGateway.ms ; 25 JUN 88 17:31:24 PDT Return-Path: Redistributed: commonloops.pa Received: from VMSA.CF.UCI.EDU by Xerox.COM ; 25 JUN 88 17:30:23 PDT Return-path: drector@orion.cf.uci.edu Received: from orion.cf.uci.edu by VMSA.CF.UCI.EDU via TCP; Sat Jun 25 17:25 PDT Received: from localhost by orion.cf.uci.edu id a004028; 25 Jun 88 17:25 PDT Date: Sat, 25 Jun 88 17:25:53 -0700 From: David Rector To: commonloops.pa%xerox.com@orion.cf.uci.edu Cc: drector@orion.cf.uci.edu Message-ID: <880625-173124-7271@Xerox> Please remove my address "drector@orion.cf.uci.edu" from the commonloops.pa@xerox.com distribution list. My campus already subscribes. Thanks. David Rector  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jun 88 18:04:27 EDT Received: from Semillon.ms by ArpaGateway.ms ; 25 JUN 88 14:58:35 PDT Date: Sat, 25 Jun 88 14:55 PDT From: Gregor.pa@Xerox.COM Subject: Re: Bug in intern-function-name (low.l) To: kempf@Sun.COM, David Vinayak Wallace cc: commonloops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8806242253.AA07881@suntana.sun.com>, <880624231154.5.GUMBY@BRAHMA.ACA.MCC.COM> Message-ID: <19880625215557.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 24 Jun 88 15:53:51 -0700 From: kempf@Sun.COM This function uses ~S to generate function names instead of ~A. Thus, if the interning is being done in another package, the package qualification will be inserted into the name and a different name will be generated. Below, it is correctly defined. . . Actually, I think the function is correctly defined as it stands. In the code fragment concerned, it is trying to generate a symbol whose name looks like the printed representation of a list. I wanted any package qualification that might appear in the printed representation to appear in that list. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Jun 88 15:08:22 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Jun 88 12:04:03 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 424648; Sat 25-Jun-88 15:01:44 EDT Date: Sat, 25 Jun 88 15:01 EDT From: David A. Moon Subject: Re: which functions should be generic? To: Warren Harris cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <6353.583198623@hplwhh> Message-ID: <19880625190143.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 24 Jun 88 16:37:03 PDT From: Warren Harris > It's difficult to implement COERCE's dispatch in terms of generic > function dispatch since equivalence of type specifiers is not done > in an object-oriented way. This could be handled in the same way as the PRINT-OBJECT generic function. Implementations are required to call it from within their print system. One could supply a COERCE-OBJECT generic function which the COERCE function would ultimately call if the coercion argument named a class. But it's meaningful for COERCE's second argument to be a type specifier that does not name a class. CLtL gives as an example (vector (complex short-float)). It would be inconsistent to do some coercions with classes and others through some other mechanism. I don't think your idea will work without a larger recasting of Common Lisp in object-oriented terms. While that's an interesting project for investigation, I suspect it would quickly go way beyond the proper charter of a standardization effort. It would be nice if CL had facilities for formally specifying the protocols for abstract classes like NUMBER, SEQUENCE, or OBJECT (i.e. first class protocol objects, or an abstract-class metaclass), and allow individual classes to implement a protocol. This way the user can write code that meets a protocol without regard to the specifics of its implementation. While I strongly agree with this, and have thought so for several years, again I feel this is beyond the proper charter of a standardization effort. There does not appear to be any current practice at all, let alone a concensus from which to build a standard. Some of the directions in which I feel Lisp ought to evolve in the 1990s include enormously better tools for modularity and program packaging, like what such languages as Ada have but better conceived and (as always in Lisp) more flexible (the "locales" found in some dialects in Scheme might be a good place to start); formal notions of protocols and machine-understandable interface specifications; complete integration of database concepts into the language; and development tools that "understand" both Lisp programming concepts and the dynamics of large development teams. None of this is X3J13's business, which is to stabilize the Lisp of the 1980s so people can use it.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 Jun 88 00:18:48 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUN 88 21:13:34 PDT Return-Path: <@MCC.COM,@BRAHMA.ACA.MCC.COM:Gumby@MCC.COM> Redistributed: commonloops.pa Received: from MCC.COM by Xerox.COM ; 24 JUN 88 21:12:12 PDT Received: from BRAHMA.ACA.MCC.COM (BRAHMA.ACA.MCC.COM.#Chaos) by MCC.#Chaos with Chaos/SMTP; Fri 24 Jun 88 23:11:58-CDT Date: Fri, 24 Jun 88 23:11 CDT From: David Vinayak Wallace Subject: Bug in intern-function-name (low.l) To: kempf@sun.com cc: commonloops.pa@Xerox.COM In-Reply-To: <8806242253.AA07881@suntana.sun.com> Message-ID: <880624231154.5.GUMBY@BRAHMA.ACA.MCC.COM> Date: Fri, 24 Jun 88 15:53:51 -0700 From: kempf@sun.com This function uses ~S to generate function names instead of ~A... This function probably should call SYMBOL-NAME rather than FORMAT ~A. It would be faster and wouldn't be affected by *print-case*.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 21:13:44 EDT Received: from Semillon.ms by ArpaGateway.ms ; 24 JUN 88 18:10:09 PDT Date: Fri, 24 Jun 88 18:08 PDT From: Gregor.pa@Xerox.COM Subject: Re: CLOS Speed To: kempf@Sun.COM, Brad.Myers@a.gp.cs.cmu.edu cc: commonloops.pa@Xerox.COM, bam@a.gp.cs.cmu.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8806241526.AA07700@suntana.sun.com>, <1988.6.24.14.21.48.Brad.Myers@A.GP.CS.CMU.EDU> Message-ID: <19880625010808.3.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 24 Jun 88 10:36:58 EDT From: Brad.Myers@a.gp.cs.cmu.edu Our project is using the February 3rd, 1988 version of PCL (CLOS). I am trying to convince our group to continue to use CLOS, but the problem is that the speed of slot access and method call is so slow that we are thinking of using a home-brewed object system. Our measurements show that using CLOS is between 3 to 5 times slower than using structs and procedure calls on CMU Common Lisp on an IBM-RT. This message contains some added comments which may be useful for interpreting the performance estimates I gave in my last message. As was the case in my last message, I am speaking primarily about the performance you can expect from PCL. There are many different ways of looking at the difference in performance between using CLOS and using ordinary functions and defstruct. I will only look at three comparisons between the two. * Using a generic function versus using an ordinary function. Generic functions and ordinary functions do different things. While it is interesting to compare the difference in performance of a generic function call (what you call a method call) with an ordinary function call, that number isn't really the interesting number. What we really want to compare is the difference between using a generic function, and an ordinary function and typecase which has the same effect. For example: (defclass c1 () ()) (defclass c2 () ()) (defun test-generic-function (x) (let ((c1 (make-instance 'c1))) (time (dotimes (i x) (test-generic-function-internal c1))))) (defmethod test-generic-function-internal ((c1 c1)) 'c1) (defmethod test-generic-function-internal ((c2 c2)) 'c2) (defstruct (s1 (:constructor make-s1)) dummy) (defstruct (s2 (:constructor make-s2)) dummy) (defun test-typecase (x) (let ((s1 (make-s1))) (time (dotimes (i x) (test-typecase-internal s1))))) (defun test-typecase-internal (x) (typecase x (s1 's1) (s2 's2) (otherwise (error "Don't know what to do with ~S." x)))) In the two implementations that I just tried, test-generic-function is faster than test-typecase. Some numbers were: 100000 tries generic-function typecase Implementation 1 396 2048 Implementation 2 184 180 Implementation 3 560 795 In each of these implementations, I expect that future work will improve the generic function lookup time. I expect the numbers to become: 300 2048 80 180 400 795 (I am quite deliberately ommitting the units or the implementations. What is important here is the ratios.) This shows that by comparing generic function call to what it really corresponds to, you get a much more favorable comparison. But remember, in places where an ordinary function with no typecase is all you really need (now and in the future) you should use that. Don't use generic functions if you don't need them. When you do need a generic function, it is likely to be the fastest way to do what you want. * Using defstruct accessors versus using slot-value. As I said in my previous message, it is reasonable to expect a use of slot-value to take about twice as long as an access using a highly optimized defstruct accessor. A highly optimized defstruct accessor is basically a single memory read (or aref). A slot access is basically two memory reads. The extra memory read corresponds to the indirection required to support multiple inheritance. * Using defstruct accessors versus using accessor methods. As mentioned above, in most implementations of defstruct, the compiler inlines the code for defstruct accessors, so they become a single memory read. This provides high performance, but since the actual call to the accessor has been compiled away it makes it impossible to change the accessor without recompiling all the code that uses it. The defstruct accessors are essentially macros. In CLOS, generic functions which have accessor methods methods generated by defclass are just like other generic functions. That is, the compiler doesn't compile out calls to them. At run time, method lookup happens to get the appropriate method to run. This offers much more flexibility, it makes it possible to define methods which specialize those accessors. But there are some optimizations to make CLOS accessors faster. This is why the projected performance for this is approximately 1.3 function calls. I hope I have made it more clear what some of the real comparisons between CLOS and defun+typecase+defstruct are. Of course the real issues can be much more complex, as are any attempts at real performance benchmark. The point I want to stress is that when you need the functionality CLOS provides, it is likely to be the highest performance mechanism for providing. As Jim mentioned in his message, these projected performance numbers are quite competitive with other object systems. To build a system of your own which provided better performance would probably take a lot work. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 20:01:16 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 24 JUN 88 16:52:57 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 24 JUN 88 16:52:02 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA01950; Fri, 24 Jun 88 16:50:44 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA24838; Fri, 24 Jun 88 16:46:42 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA07881; Fri, 24 Jun 88 15:53:55 PDT Message-Id: <8806242253.AA07881@suntana.sun.com> To: commonloops.pa@Xerox.COM Subject: Bug in intern-function-name (low.l) Date: Fri, 24 Jun 88 15:53:51 -0700 From: kempf@Sun.COM This function uses ~S to generate function names instead of ~A. Thus, if the interning is being done in another package, the package qualification will be inserted into the name and a different name will be generated. Below, it is correctly defined. (defun intern-function-name (name) #+Symbolics name #-Symbolics (cond ((symbolp name) name) ((listp name) (intern (format nil "~A" name) (if (eq (car name) 'method) (symbol-package (if (listp (cadr name)) (cadr (cadr name)) (cadr name))) *package*)))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 20:01:03 EDT Received: from Semillon.ms by ArpaGateway.ms ; 24 JUN 88 16:51:31 PDT Date: Fri, 24 Jun 88 16:49 PDT From: Gregor.pa@Xerox.COM Subject: Re: CLOS Speed To: Brad.Myers@a.gp.cs.cmu.edu cc: commonloops.pa@Xerox.COM, bam@a.gp.cs.cmu.edu Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <1988.6.24.14.21.48.Brad.Myers@A.GP.CS.CMU.EDU> Message-ID: <19880624234907.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 24 Jun 88 10:36:58 EDT From: Brad.Myers@a.gp.cs.cmu.edu Our project is using the February 3rd, 1988 version of PCL (CLOS). I am trying to convince our group to continue to use CLOS, but the problem is that the speed of slot access and method call is so slow that we are thinking of using a home-brewed object system. Our measurements show that using CLOS is between 3 to 5 times slower than using structs and procedure calls on CMU Common Lisp on an IBM-RT. The times we are getting are: Simple CLOS Slot access: 17 microseconds Simple struct access: 4.7 " Method call: 56 " Procedure call: 20 " You can expect to see some improvement in these times. Particularly the time take by slot access. You should expect something like the following: * Ordinary method call will be between 2 and 3 times a corresponding function call. It may well be close to 2, but it is unlikely to go below that. Your time will certainly go down some from where it is now, but how much is unclear. Method call of a method which uses slot-value in its body will be slightly slower. Expect it to be slower by about 25% of a function call time. Method call of a method which uses call-next-method will be slower than ordinary method call. It may be as much as a factor of 1 function call slower. These last two times are additive, so if you have a method which uses both call-next-method and slot-value in its body it will take about 1.25 times a procedure call more than ordinary method call. Ordinary procedure call: 1 Ordinary method call: 2-3 Method with slot-value: 2.25-3.25 Method with call-next-method: 3-4 Method with call-next-method and slot-value 3.25 - 4.25 * Slot access done by calling an accessor method will take about 1.3 times the time take by an ordinary procedure call. * Slot access done by using slot-value inside the body of a method will take time equivalent to that shown by the following code. This is basically the time taken by two memory reads. (defmacro aref* (array dimension) ;; This is a version of aref that runs like the wind. ;; It doesn't have to check that the array is an array, ;; it can count on that. It doesn't have to check that ;; the dimension is within the array bounds. It can ;; count on that. `(locally (declare (optimize (speed 3) (safety 0))) (aref ,array ,dimension))) (defun test (x) (let ((array-1 (make-array 3 :initial-contents '(1 2 0))) (array-2 (make-array 3 :initial-contents '(x y z)))) (time (dotimes (i x) ;; This is the simulated code for the (let ((offset (aref* array-1 0))) (if (null offset) (slot-missing-trap) (aref* array-2 offset))))))) -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jun 88 19:54:53 EDT Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 24 Jun 88 16:48:51 PDT Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Fri 24 Jun 88 16:50:28-PDT Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Fri, 24 Jun 88 15:39:09 PST Received: from hplwhh.HPL.HP.COM (hplwhh.hpl.hp.com) by hplms2.HP.COM; Fri, 24 Jun 88 16:38:46 pdt Received: from hplwhh by hplwhh.HPL.HP.COM; Fri, 24 Jun 88 16:37:05 pdt To: "David A. Moon" Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: which functions should be generic? X-Mailer: mh6.5 In-Reply-To: Your message of Fri, 24 Jun 88 18:43:00 -0400. <19880624224355.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 24 Jun 88 16:37:03 PDT Message-Id: <6353.583198623@hplwhh> From: Warren Harris > It's difficult to implement COERCE's dispatch in terms of generic > function dispatch since equivalence of type specifiers is not done > in an object-oriented way. This could be handled in the same way as the PRINT-OBJECT generic function. Implementations are required to call it from within their print system. One could supply a COERCE-OBJECT generic function which the COERCE function would ultimately call if the coercion argument named a class. I realize that one could probably find a large number of candidates in CLtL to be made generic. Ideally EQUAL should be generic too. It already depends on the type of objects you give it, looking inside of vectors, etc. Why not allow it to look inside of objects in an object dependent way? At some point the argument boils down to an efficiency consideration. I don't think anyone would be happy if EQ was required to be generic. There should be a strong rational for which functions are to be made generic and which are not. (For example: how should the average user know when to use ELT instead of SVREF?) Perhaps a generic layer of CL is in order. CL already kind of does this with its sequence operations. I can think of three generic protocols off hand: - sequences which access subcomponents by position - objects and structures which access subcomponents by name - math functions which operate on generic "numbers" It would be nice if CL had facilities for formally specifying the protocols for abstract classes like NUMBER, SEQUENCE, or OBJECT (i.e. first class protocol objects, or an abstract-class metaclass), and allow individual classes to implement a protocol. This way the user can write code that meets a protocol without regard to the specifics of its implementation.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 19:28:17 EDT Received: from Semillon.ms by ArpaGateway.ms ; 24 JUN 88 16:24:47 PDT Return-Path: <@RELAY.CS.NET:schmolze@cs.tufts.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 24 JUN 88 16:23:56 PDT Received: from relay2.cs.net by RELAY.CS.NET id ab28163; 24 Jun 88 17:19 EDT Received: from cs.tufts.edu by RELAY.CS.NET id ac28811; 24 Jun 88 17:11 EDT Received: from schmolze.cs by summit.cs (3.2/SMI-3.2) id AA00280; Fri, 24 Jun 88 16:34:11 EDT Received: by schmolze.cs (3.2/SMI-3.2) id AA17300; Fri, 24 Jun 88 16:35:02 EDT Date: Fri, 24 Jun 88 16:35:02 EDT From: schmolze@cs.tufts.edu Message-Id: <8806242035.AA17300@schmolze.cs> To: CommonLoops.pa@Xerox.COM Cc: schmolze@cs.tufts.edu Subject: New PCL user I have obtained your PCL code and am begining to use it on a Sun-3 and, soon, a Sun-4. Please add me to your mailing list concerning new releases, etc. Also, are there any examples of using CLOS and/or PCL? It is very difficult to get started from just the documentation. (I have experrience with Lucid's Flavors).  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 18:56:54 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUN 88 15:48:10 PDT Return-Path: Redistributed: commonloops.pa Received: from SAIL.Stanford.EDU by Xerox.COM ; 24 JUN 88 15:47:22 PDT Message-ID: <1#9sgj@SAIL.Stanford.EDU> Date: 24 Jun 88 15:47 PDT From: Dick Gabriel Subject: Law To: commonloops.pa@Xerox.COM DCM found a minor typo, corrected here: (defmethod v ((p1 A) (p2 Z)) (generic-labels ((v1 (:method ((p B)) (v2 (slot-value p 'c)))) (v2 (:method ((p C)) (slot-value p 'd)))) (v1 (slot-value p1 'b)))) -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jun 88 18:50:44 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Jun 88 15:44:57 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 424437; Fri 24-Jun-88 18:44:06 EDT Date: Fri, 24 Jun 88 18:43 EDT From: David A. Moon Subject: which functions should be generic? To: Masinter.pa@Xerox.COM cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: <880624-122008-5902@Xerox> Message-ID: <19880624224355.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Line-fold: No Date: 24 Jun 88 12:19 PDT From: Masinter.pa@Xerox.COM Mr. Ida asks (relative to COERCE-INCOMPLETE): "Will Coerce function be a (standard) generic function ?" It's difficult to implement COERCE's dispatch in terms of generic function dispatch since equivalence of type specifiers is not done in an object-oriented way. There is no way to write a method that is applicable both for (coerce '(#\a) 'string) and for (coerce '(#\a) '(vector string-char)), even though both of those forms mean the same thing. I'd like to generalize this: Now that CLOS is part of the standard, which functions in CL should be generic? I think this is the wrong mailing list to discuss changes that X3J13, or anyone else, might want to make to the language in order to take advantage of CLOS.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 18:40:37 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 24 JUN 88 15:34:11 PDT Return-Path: Redistributed: commonloops.pa Received: from avalon.berkeley.edu by Xerox.COM ; 24 JUN 88 15:33:15 PDT Received: by avalon.berkeley.edu (5.57/1.26) id AA17490; Fri, 24 Jun 88 15:32:20 PDT Message-Id: <8806242232.AA17490@avalon.berkeley.edu> From: David C. Martin Organization: University of California at Berkeley - Dept of EECS/CS Division Email: dcmartin@postgres.Berkeley.EDU or {ihnp4,decvax}!ucbvax!dcmartin Phone: 415/642-9585 (O) To: Dick Gabriel Cc: commonloops.pa@Xerox.COM Precedence: special-delivery In-Reply-To: Your message of 24 Jun 88 13:58 PDT <1O9rBs@SAIL.Stanford.EDU> Subject: Re: Law of Good Style Date: Fri, 24 Jun 88 15:32:17 PDT Sender: dcmartin%avalon.Berkeley.EDU@Berkeley.EDU This one also obeys the law. Let's combine these using generic-labels (defmethod v ((p1 A) (p2 Z)) (generic-labels ((v1 (:method ((p B)) (v2 (slot-value p 'c)))) (v2 (:method ((p C)) (slot-value p 'd)))) (v1 (slot-value p 'b)))) Was this -------------- ^ -- supposed to be p1? dcm  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 17:11:07 EDT Received: from Salvador.ms by ArpaGateway.ms ; 24 JUN 88 14:01:32 PDT Return-Path: Redistributed: commonloops.pa Received: from SAIL.Stanford.EDU by Xerox.COM ; 24 JUN 88 13:59:28 PDT Message-ID: <1O9rBs@SAIL.Stanford.EDU> Date: 24 Jun 88 13:58 PDT From: Dick Gabriel Subject: Law of Good Style To: commonloops.pa@Xerox.COM Laws of good style are like laws of good taste - hard to define and changeable. Also, they are debatable and not everyone will eventually agree with them. I've put my Debunker team on this problem. Here is the latest version of the law (I wonder: Will the people whose comments on the law alter it be made co-authors on the OOPSLA paper?): ----- LAW OF DEMETER (CLOS, object version) ------------- All function calls inside a method M must have one of the following method selection argument objects: - M's argument objects or - slot values of method selection argument classes of M. (Objects created by the method and objects in global variables are viewed as being passed by arguments. A method selection argument is an argument which is used for identifying the applicable methods.) ---------------------------------------------------------- We need some classes, so let's randomly pick the ones Karl suggested: ;;; The slot named B in instances of A contain objects of type B (defclass A () ((B :type B))) ;;; The slot named C in instances of B contain objects of type C (defclass B () ((C :type C))) ;;; The slot named D in instances of C contain objects of type D (defclass C () ((D :type D))) Here is a method that obeys the law: (defmethod v ((p1 A) (p2 Z)) (v1 (slot-value p1 'b))) Let's look at v1: (defmethod v1 ((p B)) (v2 (slot-value p 'c))) That also obeys the law. Let's look at v2: (defmethod v2 ((p C)) (slot-value p 'd)) This one also obeys the law. Let's combine these using generic-labels (defmethod v ((p1 A) (p2 Z)) (generic-labels ((v1 (:method ((p B)) (v2 (slot-value p 'c)))) (v2 (:method ((p C)) (slot-value p 'd)))) (v1 (slot-value p 'b)))) Since this is really the same program as the previous set of methods, it must also obey the law, though the law doesn't seem to clearly treat local functions. Let's assume that we are freezing the classes A, B, and C. Now we can decorate this function with some declarations: (defmethod v ((p1 A) (p2 Z)) (generic-labels ((v1 (:method ((p B)) (v2 (the C (slot-value p 'c))))) (v2 (:method ((p C)) (slot-value p 'd)))) (v1 (the B (slot-value p 'b))))) Now let's inline these procedures: (defmethod v ((p1 A) (p2 Z)) (slot-value (slot-value (slot-value p1 'b) 'c) 'd)) And while we're at it, let's rename the function: (defmethod violation ((p1 A) (p2 Z)) (slot-value (slot-value (slot-value p1 'b) 'c) 'd)) -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jun 88 16:40:37 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 24 Jun 88 13:31:53 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA28747; Fri, 24 Jun 88 13:30:10 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA18466; Fri, 24 Jun 88 13:26:07 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA07800; Fri, 24 Jun 88 13:30:29 PDT Message-Id: <8806242030.AA07800@suntana.sun.com> To: Masinter.pa@Xerox.COM Cc: common-lisp-object-system@sail.stanford.edu Subject: Re: which functions should be generic? In-Reply-To: Your message of 24 Jun 88 12:19:00 -0700. <880624-122008-5902@Xerox> Date: Fri, 24 Jun 88 13:30:26 -0700 From: kempf@Sun.COM 1) All the sequence functions (Chapter 14) 2) Stream functions and output functions which use streams (Chapters 21 & 22). Even though, or perhaps because, extensible streams are not yet part of the CLOS draft, generic output functions would be useful. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Jun 88 15:33:49 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 24 Jun 88 12:25:16 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 24 JUN 88 12:20:08 PDT Date: 24 Jun 88 12:19 PDT From: Masinter.pa@Xerox.COM Subject: which functions should be generic? To: common-lisp-object-system@sail.stanford.edu Message-ID: <880624-122008-5902@Xerox> Mr. Ida asks (relative to COERCE-INCOMPLETE): "Will Coerce function be a (standard) generic function ?" I'd like to generalize this: Now that CLOS is part of the standard, which functions in CL should be generic?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 12:20:21 EDT Received: from Semillon.ms by ArpaGateway.ms ; 24 JUN 88 09:15:05 PDT Return-Path: Redistributed: CommonLoops.pa Received: from mitre-bedford.ARPA by Xerox.COM ; 24 JUN 88 09:12:46 PDT Posted-From: The MITRE Corp., Bedford, MA Received: from tom.sun.uucp by linus.MENET (3.2/4.7) id AA24734; Fri, 24 Jun 88 12:08:48 EDT From: John D. Berger Posted-Date: Fri, 24 Jun 88 11:14:45 EDT Received: by tom.sun.uucp (3.2/SMI-3.0DEV3) id AA26183; Fri, 24 Jun 88 11:14:45 EDT Date: Fri, 24 Jun 88 11:14:45 EDT Message-Id: <8806241514.AA26183@tom.sun.uucp> To: CommonLoops.pa@Xerox.COM Subject: The Law of Demeter Concerning the Law: You say that function calls inside a method M should use only certain objects as method selection arguments. How does the programmer know what arguments a function will use to dispatch according to type? How does the programmer know that a function is generic and will do such a dispatch? You say the Law prohibits functional composition of accessor functions which return non-slot objects. How does the programmer know that a function-call is a slot-access? You say it's okay to use objects that are created by the method in question, or by a function that it calls. How does the programmer know that an object returned by a function is newly-created? It seems that in order to use the Law, the programmer must have knowledge which violates an even older law: That of information-hiding. -john  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 11:33:33 EDT Received: from Semillon.ms by ArpaGateway.ms ; 24 JUN 88 08:29:47 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 24 JUN 88 08:28:25 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA24568; Fri, 24 Jun 88 08:26:02 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA06983; Fri, 24 Jun 88 08:21:57 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA07700; Fri, 24 Jun 88 08:26:18 PDT Message-Id: <8806241526.AA07700@suntana.sun.com> To: Brad.Myers@cs.cmu.edu Cc: commonloops.pa@Xerox.COM Subject: Re: CLOS Speed In-Reply-To: Your message of Fri, 24 Jun 88 10:36:58 -0400. <1988.6.24.14.21.48.Brad.Myers@A.GP.CS.CMU.EDU> Date: Fri, 24 Jun 88 08:26:15 -0700 From: kempf@Sun.COM With regard to the method vs. procedure call numbers, I presume this is a method with a single specialized parameter, inheritance is not involved, and you've taken no measures to defeat the generic function caching, correct? If so, then the numbers you've presented are about the same in Lucid Common Lisp on a Sun 3/110. With the stock PCL implementation from PARC, I'm typically seeing a factor of 3 difference between function calling and method invocation when the method function is cached. By modifying the caching dispatching function to heavily declare everything, that can be reduced to about a factor of 2. A factor of 2 difference between a function call and a method invocation is pretty good, about what you get in Objective-C, somewhat slower than C++ (three to 5 instructions). Polymorphic operations don't come free, unfortunately. It might be possible to reduce dispatch time even further by assembly coding the dispatch functions, but I have no data for Lucid Lisp. I did something similar in HP Lisp and the result was fast enough to program graphics applications. If a cache miss occurs, then you really pay. The default algorithm is linear in the number of methods defined on the generic function. I replaced the default algorithm with a hash table and am getting times which are about 9 times a function call, with no variation in the number of methods on the generic function. Again, this is for single dispatching. For multiple dispatching, the cost of doing the CLASS-OF operation rapidly comes to dominate the cache hit calculation as the number of parameters discriminated on increases. If a cache miss occurs, a similar kind of linear dependency on the number of methods defined on the generic function is observed. I have implemented an algorithm which is logarithmic in the number of methods, but have not finished measuring it yet. Before you decide not to use CLOS, I urgue you to code up tests using DEFSTRUCTs and functions with TYPECASE or COND having the same number of branches as methods on the generic function. I think you'll find that there will be some number of "methods" at which the TYPECASE or COND versions will start to exceed the generic function/method versions. As to slot access, since most compilers can optimize slot access for DEFSTRUCTs to one or two instructions, this comparison is not suprising. I believe Gregor is working on some code to significantly improve slot access in PCL. Slot access in CLOS will probably always be one instruction longer than for DEFSTRUCTs because of the need to support class redefinition, but there is still considerable room for improvement. Since generic functions should ultimately be definable on DEFSTRUCTs as well, you can define methods on DEFSTRUCTs if you still find slot access to be too slow. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 10:48:24 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 24 JUN 88 07:39:36 PDT Return-Path: Redistributed: commonloops.pa Received: from A.GP.CS.CMU.EDU by Xerox.COM ; 24 JUN 88 07:38:12 PDT Date: Fri, 24 Jun 88 10:36:58 EDT From: Brad.Myers@a.gp.cs.cmu.edu To: commonloops.pa@Xerox.COM cc: bam@a.gp.cs.cmu.edu Subject: CLOS Speed Message-ID: <1988.6.24.14.21.48.Brad.Myers@A.GP.CS.CMU.EDU> Our project is using the February 3rd, 1988 version of PCL (CLOS). I am trying to convince our group to continue to use CLOS, but the problem is that the speed of slot access and method call is so slow that we are thinking of using a home-brewed object system. Our measurements show that using CLOS is between 3 to 5 times slower than using structs and procedure calls on CMU Common Lisp on an IBM-RT. The times we are getting are: Simple CLOS Slot access: 17 microseconds Simple struct access: 4.7 " Method call: 56 " Procedure call: 20 " Are these numbers close to what other people observe? Can we expect to see a (significantly) faster version of CLOS? If so, how much faster, and when will it be available? I would like to stick with the CLOS standard, but we need resonable performance in our application. Thanks, Brad A. Myers Research Computer Scientist Computer Science Department Carnegie Mellon University Pittsburgh, PA 15213 (412) 268-5150 bam@a.gp.cs.cmu.edu  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 Jun 88 00:21:40 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 23 JUN 88 21:14:08 PDT Return-Path: <@HELIOS.NORTHEASTERN.EDU:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 23 JUN 88 21:13:02 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id aa16413; 23 Jun 88 22:56 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa10762; 23 Jun 88 22:53 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA07312; Thu, 23 Jun 88 22:55:34 EDT Date: Thu, 23 Jun 88 22:55:34 EDT From: karl lieberherr Message-Id: <8806240255.AA07312@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law of Demeter under debate Jim Kempf is not easy to convince but so far we have never failed to convince object-oriented programmers of the benefits of the Law. Each message from Jim leads to some further insight on our side. >Since generic functions are never defined >"on" a class (what class is the built-in generic function + defined >"on"?) the Law of Demeter makes little sense for CLOS. The Law of Demeter as stated in IEEE Computer, June 88, is not stated in CLOS terminology. Furthermore it is stated in terms of types while on this mailing list we have only discussed the object version which is the version of the Law to be followed conceptually. The CLOS formulation is given below and is the natural generalization of the IEEE Computer formulation: ----- LAW OF DEMETER (CLOS, object version) ------------- For all methods M, all function calls inside M must use only the following objects as method selection arguments: - M's argument objects or - slot values of method selection argument classes of M. (Objects created by a method, or by functions which it calls, and objects in global variables are viewed as being passed by arguments. A method selection argument is an argument which is used for identifying the applicable methods.) ---------------------------------------------------------- It is good to observe how one goes from message passing to generic functions: 1. Methods can be attached to several classes. 2. self is generalized to "method selection arguments". 3. instance variables become slot values of method selection arguments. In this formulation the Law makes a lot of sense for CLOS. > (defmethod sum-of-sqrt-of-difference ((x float) (y float)) > (+ (sqrt (- x y)) y)) > >What about the result of SQRT? If the >result of the subtraction is a negative number, then SQRT will return a >complex number, and that is most decidedly *not* a float. So the generic >function + would be applied to something which has neither an argument >type nor is an instance variable, a clear violation. This is not a violation. Look, SQRT returns a new object whether it is a float or a complex number (by definition it is a constructor function) and therefore we are allowed to use the result of SQRT as method selection argument of +. I can see your reasoning of considering it a violation. In the "type" version of the Law, the return types of constructor function calls are raised to the same level as the argument and instance variable types. In this example, complex would be considered an argument type. >>However, the Law prohibits functional composition of >>generic accessor functions. >Since all accessor functions in CLOS are generic, this would prohibit any >functional composition of accessor functions in CLOS. This is unrealistic, >I think. YOU ARE RIGHT. I did misformulate this implication of the Law. Thank you for pointing it out. The correct formulation is: The Law prohibits functional composition of generic accessor functions which return objects that are not slot objects. Remark: This will allow double nesting which is certainly needed. >I stand by my objections. What else can we do to convince you? -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 Jun 88 12:58:18 EDT Received: from Semillon.ms by ArpaGateway.ms ; 23 JUN 88 09:52:24 PDT Return-Path: <@HELIOS.NORTHEASTERN.EDU:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 23 JUN 88 09:51:12 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id aa04271; 23 Jun 88 8:46 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa00404; 23 Jun 88 8:43 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA05042; Thu, 23 Jun 88 08:45:24 EDT Date: Thu, 23 Jun 88 08:45:24 EDT From: karl lieberherr Message-Id: <8806231245.AA05042@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law and localization John Rose writes: Try a negative formulation. It seems like you are allowing every kind of argument __except__ those that potentially break abstraction boundaries. Classes local to the method are deemed to drop their abstraction boundaries inside the method. For me, the key illuminating comment on your Law was this: The idea is that it is a bad strategy to put a dependency on the C class into this method which is "attached to" A and Z. This is a start at a negative formulation, which is why it helped me. It was interesting to hear what the illuminating point was for you. Here is an attempt at a negative explanation: A generic function has the authority to make decisions and operate in ways which are DEPENDENT on the 'valid' method selection objects (argument objects and slot values of method selection arguments) and their types, but IS NOT ALLOWED to be dependent on the sub-parts of those objects. The deep structures of the objects are hidden from the generic function. John Rose writes further: General problem: When a representation changes, what pieces of code need to be recompiled? Or possibly rewritten? It looks like this Law is intended to keep these sets of code pieces small and easily determinable. "Small" I think is a good goal; "easily determinable" is not so important. Well, easily determinable is also important since the program will be read and understood by humans. I agree that a good tool makes the "easily determinable factor" less important. John Rose asks the following question: Consider this code: (DEFCLASS X () (X-SLOT)) (DEFCLASS Y () (Y-SLOT)) (TYPECASE MY-X-OR-Y (X (SLOT-VALUE MY-X-OR-Y 'X-SLOT)) (Y (SLOT-VALUE MY-X-OR-Y 'Y-SLOT))) It seems to me that this code is as semantically clean as the equivalent formulation with methods: (DEFMETHOD INSTEAD-OF-TYPECASE ((MY-X-OR-Y X)) (SLOT-VALUE MY-X-OR-Y 'X-SLOT)) (DEFMETHOD INSTEAD-OF-TYPECASE ((MY-X-OR-Y Y)) (SLOT-VALUE MY-X-OR-Y 'Y-SLOT)) I think the TYPECASE formulation is better style, don't you? No, I don't. The TYPECASE solution is less modular than the formulation with methods and is harder to maintain. When you add a class Z, you have to MODIFY code in the TYPECASE solution while in the good solution you only have to ADD code. Indeed, you can view the TYPECASE macro solution as violating the spirit of the Law of Demeter. Assume that the TYPECASE is in a method. The TYPECASE uses a generic function which returns the type of its argument. This object is then compared by a generic equality function with a class name. But the type returned is not a new object (it can be viewed as a part of the given object), and therefore we are not allowed to use it as method selection argument in another generic function call. -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 Jun 88 12:27:15 EDT Received: from Semillon.ms by ArpaGateway.ms ; 23 JUN 88 09:22:06 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 23 JUN 88 09:20:39 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA07651; Thu, 23 Jun 88 09:16:39 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA11857; Thu, 23 Jun 88 09:12:41 PDT Received: from localhost by suntana.sun.com (4.0/SMI-4.0) id AA05735; Thu, 23 Jun 88 09:17:00 PDT Message-Id: <8806231617.AA05735@suntana.sun.com> To: karl lieberherr Cc: commonloops.pa@Xerox.COM Subject: Re: Nesting and the Law In-Reply-To: Your message of Thu, 23 Jun 88 07:49:36 -0400. <8806231149.AA04866@corwin.CCS.Northeastern.EDU> Date: Thu, 23 Jun 88 09:16:57 -0700 From: kempf@Sun.COM >Jim Kempf's objections stem from a mis-understanding of the phrase >'objects created within the method are treated as arguments'. >Our idea is that a generic function does not neccessarily have to contain >an explicit 'make-instance' call (or its equivalent) to cause the >creation of a new object. If the generic function has within it >a call to a function which returns A Newly Created object then this >too is considered a creation of an object within the generic function. >Consider user defined constructor functions in C++. This isn't what your IEEE article says. On pg. 80 of the June issue in your article, there is an example given which is claimed to be in "poor" style that has the same structure as the examples in my note. Translating the IEEE example into CLOS, we have: (defmethod ref-search ((self reference-sec) (book book-identifier)) ;;The following two lines are identified in the text ;; as being in "poor" style (search (arch-microfilm archive) book) (search (arch-docs archive) book) ) Granted, the text of the article does qualify the categorization of functional composition as in "poor" style only when the returned object is not an instance variable or argument type of the class "on" which the method is defined. For generic functions, however, this is a gratuitious restriction. Since generic functions are never defined "on" a class (what class is the built-in generic function + defined "on"?) the Law of Demeter makes little sense for CLOS. >The example which Jim Kempf cites as being in bad style is indeed in good >style, for two reasons. > > (defmethod sum-of-sqrt-of-difference ((x float) (y float)) > (+ (sqrt (- x y)) y)) > >1. The type of x and y is given as float. If the result of the '-' application >is an instance of type float then, according to the Law as stated in >IEEE Computer, June 88, this object is an instance of an argument type (float) >and so it is a valid argument to the 'sqrt' function. Correct. >2. The application of the '-' to the x and y causes the creation of a new >instance of the float class which is initialized to a value representing >'x - y'. So calling '-' is just the same as creating a new object and >giving the instance variables of that object some initial values depending >on the arguments and some procedural processing. Thus the argument to the >sqrt function is again valid. Correct, but you missed the point. What about the result of SQRT? If the result of the subtraction is a negative number, then SQRT will return a complex number, and that is most decidedly *not* a float. So the generic function + would be applied to something which has neither an argument type nor is an instance variable, a clear violation. >However, the Law prohibits functional composition of generic accessor functions. Since all accessor functions in CLOS are generic, this would prohibt any functional composition of accessor functions in CLOS. This is unrealistic, I think. I stand by my objections. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 Jun 88 10:17:41 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 23 JUN 88 07:05:59 PDT Return-Path: <@HELIOS.NORTHEASTERN.EDU:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 23 JUN 88 07:05:03 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id ab03951; 23 Jun 88 8:30 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa00136; 23 Jun 88 8:20 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA04866; Thu, 23 Jun 88 07:49:36 EDT Date: Thu, 23 Jun 88 07:49:36 EDT From: karl lieberherr Message-Id: <8806231149.AA04866@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Nesting and the Law Jim Kempf took strong exception to our ideas in writing: After reading your IEEE Computer article, I must unfortunately take strong exception to your Law of Demeter for CLOS. This is a clear statement and requires a clear answer. We took his message (along with feedback from our students) as an opportunity to make our Law more clear: ----- LAW OF DEMETER (CLOS, object version, revised) ------------- For all methods M, all function calls inside M must use only the following objects as method selection arguments: - M's argument objects or - slot values of method selection argument classes of M. (Objects created by the method, or by functions which it calls, and objects in global variables are viewed as being passed by arguments. A method selection argument is an argument which is used for identifying the applicable methods.) ---------------------------------------------------------- Jim Kempf's objections stem from a mis-understanding of the phrase 'objects created within the method are treated as arguments'. Our idea is that a generic function does not neccessarily have to contain an explicit 'make-instance' call (or its equivalent) to cause the creation of a new object. If the generic function has within it a call to a function which returns A Newly Created object then this too is considered a creation of an object within the generic function. Consider user defined constructor functions in C++. The example which Jim Kempf cites as being in bad style is indeed in good style, for two reasons. (defmethod sum-of-sqrt-of-difference ((x float) (y float)) (+ (sqrt (- x y)) y)) 1. The type of x and y is given as float. If the result of the '-' application is an instance of type float then, according to the Law as stated in IEEE Computer, June 88, this object is an instance of an argument type (float) and so it is a valid argument to the 'sqrt' function. Point 1 above is a technical one and dependent on the Law's statement in terms of types. Point 2 is MUCH more relevant and involves the ideas above. 2. The application of the '-' to the x and y causes the creation of a new instance of the float class which is initialized to a value representing 'x - y'. So calling '-' is just the same as creating a new object and giving the instance variables of that object some initial values depending on the arguments and some procedural processing. Thus the argument to the sqrt function is again valid. It is important to note that we haven't "thrown out the baby with the bathwater" with this interpretation of 'object creation'. A generic function has the authority to make decisions and operate in ways which are DEPENDENT on the 'valid' objects (and their types), but IS NOT ALLOWED to be dependent on the sub-parts of those objects. The deep structures of the objects are hidden from the generic function. This is a real and important restriction on the programmer. The second example given by Jim Kempf " (defmethod output-document ((switches string) (filename pathname) (printer string)) (lpr printer (troff switches filename))) (defmethod lpr ((printer string) (document stream)) <> ) (defmethod troff ((switches string) (filename pathname)) <> ) " is again in good style since the object returned from 'troff' is a new object created and initialized to the appropriate value. The Law of Demeter has implications for the nesting of function calls. To discuss those implications, we classify functions as follows: A accessor function returns an object which exists before the function was called. A constructor function returns an object which did not exist before the function was called. The Law allows the nesting of constructor functions, as well as the nesting of non-generic functions. However, the Law prohibits functional composition of generic accessor functions. -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jun 88 18:36:38 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUN 88 15:29:51 PDT Date: Wed, 22 Jun 88 15:27 PDT From: Gregor.pa@Xerox.COM Subject: call-next-method bug To: CommonLoops.pa@Xerox.COM Message-ID: <19880622222738.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There is a bug having to do with call-next-method in the current version of PCL. I know I am supposed to be fixing them, not reporting them, and this message doesn't include a patch, but I thought I would let people know about this problem. In the following sequence, calling (foo (class-named 't)) will return T instead of signalling an error. This is because the extra "next-method" from foo leaks through and is made available to bar. This will be fixed properly in the next version of PCL. (defmethod foo ((x standard-class)) (bar x)) (defmethod foo ((x class)) (call-next-method)) (defmethod foo ((x t)) t) (defmethod bar ((x standard-class)) (call-next-method)) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jun 88 18:15:35 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 22 JUN 88 14:59:41 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 22 JUN 88 14:57:25 PDT To: Dale E Thoms cc: CommonLoops.pa@Xerox.COM In-reply-to: Your message of Tue, 21 Jun 88 10:21:27 -0400. <8806211421.AA00587@caen.engin.umich.edu> Date: Wed, 22 Jun 88 16:27:41 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880622-145941-2508@Xerox> Received: from BBN.COM by WILMA.BBN.COM id aa01448; 21 Jun 88 14:49 EDT Received: from wilma.bbn.com by BBN.COM id aa26287; 21 Jun 88 14:51 EDT Received: from BBN.COM by WILMA.BBN.COM id aa00938; 21 Jun 88 13:22 EDT Received: from wilma.bbn.com by BBN.COM id aa24887; 21 Jun 88 13:24 EDT Received: from BBN.COM by WILMA.BBN.COM id aa00559; 21 Jun 88 11:31 EDT Received: from parcvax.xerox.com by BBN.COM id aa23074; 21 Jun 88 11:37 EDT Received: by parcvax.xerox.com (5.54/1.15) id AA04429; Tue, 21 Jun 88 07:44:46 PDT Received: from Chardonnay.ms by ArpaGateway.ms ; 21 JUN 88 07:44:43 PDT Return-Path: Redistributed: CommonLoops.pa Received: from caen.engin.umich.edu by Xerox.COM ; 21 JUN 88 07:43:33 PDT Received: by caen.engin.umich.edu (5.54/umix-2.0) id AA00587; Tue, 21 Jun 88 10:21:27 EDT Date: Tue, 21 Jun 88 10:21:27 EDT From: Dale E Thoms Message-Id: <8806211421.AA00587@caen.engin.umich.edu> To: CommonLoops.pa@xerox.com Does the current version of PCL support (eql form) as a parameter specializer? From the code in methods.lisp it looks like it should, but I can't seem to get it to work. Is there a difference between the way it works and the way CLOS defines it? Thanks, Dale Thoms thoms@caen.engin.umich.edu eql specializers work for primary methods but :before :after and :around methods don't seem to work. This is a bug.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 22 Jun 88 17:53:57 EDT Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 22 Jun 88 14:46:14 PDT Received: by decwrl.dec.com (5.54.4/4.7.34) id AA21530; Wed, 22 Jun 88 14:46:01 PDT Message-Id: <8806222146.AA21530@decwrl.dec.com> From: piazza%lisp.DEC@decwrl.dec.com (Jeffrey Piazza) Date: 22 Jun 88 17:38 To: Common-Lisp-Object-System@sail.stanford.edu Subject: SYMBOL-MACROLET-UTILITY I'm getting to ready to submit this as a cleanup proposal; I thought I'd run it by here first. My intent in submitting the proposal for cleanup is to open the discussion of whether SYMBOL-MACROLET is really a desirable language feature. If it is resolved that SYMBOL-MACROLET is worth keeping, I have a follow-up proposal to at least make it a special form. /JEP =============================================================================== Status: DRAFT Issue: SYMBOL-MACROLET-UTILITY References: X3J13 document 88-002R, Chapter 2, pp. 2-81f., 2-88f., 2-92f. Category: DELETION Edit history: 21-Jun-88, Version 1 by Piazza Problem Description: Anything expressible with SYMBOL-MACROLET could also be written with regular MACROLET, except that the macro symbol could not stand alone as an expression; it would have to be enclosed in parentheses. The cost associated with implementing and maintaining the SYMBOL-MACROLET feature exceeds this incremental utility. Proposal (SYMBOL-MACROLET:FLUSH): Remove SYMBOL-MACROLET (and WITH-ACCESSORS and WITH-SLOTS) from 88-002R. Rationale: Flushing SYMBOL-MACROLET eliminates the cost of implementing and maintaining this feature, while MACROLET still provides most of SYMBOL-MACROLET's expressive power. ------------------------------------------------------------------------------ Current Practice: Portable Common Loops provides a code-walking implementation of SYMBOL-MACROLET as specified in 88-002R. Cost to Implementors: Presumably few implementors have implemented SYMBOL-MACROLET, excepting the implementation provided by PCL. If it is flushed from the language, no one will incur any implementation cost. Cost to Users: Users will lose the expressive ability provided by SYMBOL-MACROLET, WITH-ACCESSORS, and WITH-SLOTS, and will have to make do with MACROLET. Cost of Non-Adoption: Implementors must implement significant new functionality, adding to system size and language complexity. (A separate proposal, SYMBOL-MACROLET-SEMANTICS, addresses problems with the currently specified semantics of SYMBOL-MACROLET.) Benefits: SYMBOL-MACROLET:FLUSH reduces the implementation and maintenance costs for a Common Lisp implementation. It also simplifies the language by eliminating the concept of a "symbol macro." Aesthetics: There seem to be mixed feelings as to the desirability of SYMBOL-MACROLET as a construct in the language. Some feel it hairs up the language while offering only trivial benefit beyond what is already provided through normal macros. Others herald it as a important new language feature. Discussion: As it was adopted by X3J13 as part of CLOS, there has been no formal discussion on the pros and cons SYMBOL-MACROLET on its own.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jun 88 17:12:02 EDT Received: from Semillon.ms by ArpaGateway.ms ; 22 JUN 88 14:04:01 PDT Date: Wed, 22 Jun 88 14:01 PDT From: Gregor.pa@Xerox.COM Subject: CLOS chapters 1 and 2 accepted To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880622210138.6.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no It will be of interest to the people on this list to know that at last week's meeting of the X3J13 committee for the standardization of Common Lisp, the following motion was passed: The X3J13 Committee hereby accepts chapters 1 and 2 of the Common Lisp Object System, as defined in document 88-002R, for inclusion in the Common Lisp language being specified by this committee. Subsequent changes will be handled through the usual editorial and cleanup processes. This means that the non metaobject protocol parts of CLOS are now much more stable. It gives PCL a firm target which I can now shoot for. The TeX sources for this document will be available shortly. We expect the document to be widely distributed and reprinted. Initially, it will be appearing in SIGPLAN and The Journal of Lisp and Symbolic Computation. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 22 Jun 88 14:51:06 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 22 JUN 88 11:33:15 PDT Return-Path: Redistributed: Commonloops.pa Received: from media-lab.media.mit.edu by Xerox.COM ; 22 JUN 88 11:31:34 PDT Received: from paddington.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA08165; Wed, 22 Jun 88 14:30:11 EDT Received: by paddington (3.2/4.8) id AA10246; Wed, 22 Jun 88 14:29:50 EDT Date: Wed, 22 Jun 88 14:29:50 EDT From: Michael Sokolov Message-Id: <8806221829.AA10246@paddington> To: Commonloops.pa@Xerox.COM Subject: updates Can anyone tell me where I can get a copy of the latest PCL release via anonymous ftp? I tried xerox.com, but got a connection refused message from ftp... Thanks, Mike S.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Jun 88 19:07:10 EDT Received: from Semillon.ms by ArpaGateway.ms ; 21 JUN 88 16:01:59 PDT Date: Tue, 21 Jun 88 16:00 PDT From: Gregor.pa@Xerox.COM Subject: Re: A bug in 7debug for PCL on Symbolics 7.2 To: rich%linus@mitre-bedford.ARPA cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8806161440.AA20770@orbit.sun.uucp> Message-ID: <19880621230014.2.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Thu, 16 Jun 88 10:40:11 EDT From: rich%linus@mitre-bedford.ARPA Seems like the variable *uninteresting-functions* now points to a hash table instead of a list. Therefore in FRAME-INTERESTING-P in the 7debug file, the first member encountered should be a gethash. Thanks again for pointing this out. This is another 7.2 change that didn't get caught. Everyone who uses PCL in 7.2 should make this change to the 7debug.lisp file. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Jun 88 19:07:03 EDT Received: from Semillon.ms by ArpaGateway.ms ; 21 JUN 88 15:59:35 PDT Date: Tue, 21 Jun 88 15:57 PDT From: Gregor.pa@Xerox.COM Subject: Re: rel-7-2 patches need a patch! To: rich%linus@mitre-bedford.ARPA cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8806161439.AA20763@orbit.sun.uucp> Message-ID: <19880621225735.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Thu, 16 Jun 88 10:39:37 EDT From: rich%linus@mitre-bedford.ARPA We have a system which uses clos and also DEFSTRUCTs. Seems that your patch to COMPILE-FROM-STREAM-1 is missing the clause about MULTIPLE-DEFINITIONS, which causes the compilation of DEFSTRUCT to get all upset about DEFUNs and EVAL-WHENs not at the top level. Thanks for this fix. This was a 7.2 change that I didn't notice. Everyone who use PCL in 7.2 should make this change to rel-7-2-patches.lisp. The patch should really be as follows. The added clause has the comment "THIS CLAUSE NEEDS TO BE ADDED" before it. ;;; -*- Package: COMPILER; Mode: LISP; Syntax: Zetalisp -*- (DEFUN COMPILE-FROM-STREAM-1 (FORM &OPTIONAL (COMPILE-TIME-TOO NIL)) (CATCH-ERROR-RESTART (SYS:ERROR "Skip compiling form ~2,2\COMPILER:SHORT-S-FORMAT\" FORM) (LET ((DEFAULT-CONS-AREA (FUNCALL *COMPILE-FUNCTION* ':CONS-AREA))) (LET ((ERROR-MESSAGE-HOOK #'(LAMBDA () (DECLARE (SYS:DOWNWARD-FUNCTION)) (FORMAT T "~&While processing ~V,V\COMPILER:SHORT-S-FORMAT\" DBG:*ERROR-MESSAGE-PRINLEVEL* DBG:*ERROR-MESSAGE-PRINLENGTH* FORM)))) (SETQ FORM (FUNCALL *COMPILE-FUNCTION* ':MACRO-EXPAND FORM))) (WHEN (LISTP FORM) ;Ignore atoms at top-level (LET ((FUNCTION (FIRST FORM))) (SELECTQ FUNCTION ((QUOTE)) ;and quoted constants e.g. 'COMPILE ((PROGN) (DOLIST (FORM (CDR FORM)) (COMPILE-FROM-STREAM-1 FORM COMPILE-TIME-TOO))) ((EVAL-WHEN) (SI:CHECK-EVAL-WHEN-TIMES (CADR FORM)) (LET ((COMPILE-P (OR (MEMQ 'COMPILE (CADR FORM)) (AND COMPILE-TIME-TOO (MEMQ 'EVAL (CADR FORM))))) (LOAD-P (OR (MEMQ 'LOAD (CADR FORM)) (MEMQ 'CL:LOAD (CADR FORM)))) (FORMS (CDDR FORM))) (COND (LOAD-P (DOLIST (FORM FORMS) (COMPILE-FROM-STREAM-1 FORM (AND COMPILE-P ':FORCE)))) (COMPILE-P (DOLIST (FORM FORMS) (FUNCALL *COMPILE-FORM-FUNCTION* FORM ':FORCE NIL)))))) ((DEFUN) (LET ((TEM (DEFUN-COMPATIBILITY (CDR FORM) :WARN-IF-OBSOLETE T))) (IF (EQ (CDR TEM) (CDR FORM)) (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T) (COMPILE-FROM-STREAM-1 TEM COMPILE-TIME-TOO)))) ((MACRO) (FUNCALL *COMPILE-FORM-FUNCTION* FORM (OR COMPILE-TIME-TOO T) T)) ((DECLARE) (DOLIST (FORM (CDR FORM)) (FUNCALL *COMPILE-FORM-FUNCTION* FORM (OR COMPILE-TIME-TOO T) ;; (DECLARE (SPECIAL ... has load-time action as well. ;; All other DECLARE's do not. (MEMQ (CAR FORM) '(SPECIAL ZL:UNSPECIAL))))) ((COMPILER-LET) (COMPILER-LET-INTERNAL (CADR FORM) (CDDR FORM) #'COMPILE-FROM-STREAM-1 COMPILE-TIME-TOO)) ((SI:DEFINE-SPECIAL-FORM) (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T)) ;;; **************** THIS CLAUSE NEEDS TO BE ADDED ************************ ((MULTIPLE-DEFINITION) (DESTRUCTURING-BIND (NAME TYPE . BODY) (CDR FORM) (LET ((NAME-VALID (AND (NOT (NULL NAME)) (OR (SYMBOLP NAME) (AND (LISTP NAME) (NEQ (CAR NAME) 'QUOTE))))) (TYPE-VALID (AND (NOT (NULL TYPE)) (SYMBOLP TYPE)))) (UNLESS (AND NAME-VALID TYPE-VALID) (WARN "(~S ~S ~S ...) is invalid because~@ ~:[~S is not valid as a definition name~;~*~]~ ~:[~&~S is not valid as a definition type~;~*~]" 'MULTIPLE-DEFINITION NAME TYPE NAME-VALID NAME TYPE-VALID TYPE))) (LET* ((COMPILED-BODY NIL) (COMPILE-FUNCTION *COMPILE-FUNCTION*) (*COMPILE-FUNCTION* (LAMBDA (OPERATION &REST ARGS) (DECLARE (SYS:DOWNWARD-FUNCTION)) (SELECTQ OPERATION (:DUMP-FORM (PUSH (FUNCALL COMPILE-FUNCTION :OPTIMIZE-TOP-LEVEL-FORM (FIRST ARGS)) COMPILED-BODY)) (:INSTALL-DEFINITION (PUSH (FORM-FOR-DEFINE *COMPILER* (FIRST ARGS) (SECOND ARGS)) COMPILED-BODY)) (OTHERWISE (CL:APPLY COMPILE-FUNCTION OPERATION ARGS))))) (LOCAL-DECLARATIONS `((FUNCTION-PARENT ,NAME ,TYPE) ,@LOCAL-DECLARATIONS))) (DOLIST (FORM BODY) (COMPILE-FROM-STREAM-1 FORM COMPILE-TIME-TOO)) (FUNCALL COMPILE-FUNCTION :DUMP-FORM `(LOAD-MULTIPLE-DEFINITION ',NAME ',TYPE ',(NREVERSE COMPILED-BODY) NIL))))) ;;;; **************** END OF ADDED CLAUSE ************************************* ((pcl::top-level-form) (destructuring-bind (name times . body) (cdr form) (si:check-eval-when-times times) (let ((compile-p (or (memq 'compile times) (and compile-time-too (memq 'eval times)))) (load-p (or (memq 'load times) (memq 'cl:load times))) (fspec `(pcl::top-level-form ,name))) (cond (load-p (compile-from-stream-1 `(progn (defun ,fspec () . ,body) (funcall (function ,fspec))) (and compile-p ':force))) (compile-p (dolist (b body) (funcall *compile-form-function* form ':force nil))))))) (OTHERWISE (LET ((TEM (AND (SYMBOLP FUNCTION) (GET FUNCTION 'TOP-LEVEL-FORM)))) (IF TEM (FUNCALL *COMPILE-FORM-FUNCTION* (FUNCALL TEM FORM) COMPILE-TIME-TOO T) (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T)))))))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 21 Jun 88 10:49:51 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 21 JUN 88 07:44:43 PDT Return-Path: Redistributed: CommonLoops.pa Received: from caen.engin.umich.edu by Xerox.COM ; 21 JUN 88 07:43:33 PDT Received: by caen.engin.umich.edu (5.54/umix-2.0) id AA00587; Tue, 21 Jun 88 10:21:27 EDT Date: Tue, 21 Jun 88 10:21:27 EDT From: thoms@caen.engin.umich.edu (Dale E Thoms) Message-Id: <8806211421.AA00587@caen.engin.umich.edu> To: CommonLoops.pa@Xerox.COM Does the current version of PCL support (eql form) as a parameter specializer? From the code in methods.lisp it looks like it should, but I can't seem to get it to work. Is there a difference between the way it works and the way CLOS defines it? Thanks, Dale Thoms thoms@caen.engin.umich.edu  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jun 88 18:20:02 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 JUN 88 15:12:14 PDT Return-Path: <@RITTER.AI.SRI.COM:Felix@AI.SRI.COM> Redistributed: commonloops.pa Received: from RITTER.AI.SRI.COM by Xerox.COM ; 20 JUN 88 15:10:45 PDT Received: from HALFDOME.AI.SRI.COM by RITTER.AI.SRI.COM via CHAOS with CHAOS-MAIL id 14688; Mon 20-Jun-88 14:39:18 PDT Date: Mon, 20 Jun 88 14:39 PDT From: Francois F. Ingrand Subject: Does anybody have PCL running on Genera 7.2? To: SOBO@s66.prime.com, commonloops.pa@Xerox.COM In-Reply-To: <880620-125855-1415@Xerox> Message-ID: <19880620213944.9.FELIX@HALFDOME.AI.SRI.COM> >Date: 20 Jun 88 14:52:26 EDT >From: SOBO@s66.prime.com >To: (commonloops.pa@xerox.com) >From: Nadine Sobolevitch (sobo@s66) >Date: 20 Jun 88 2:24 PM >Subject: Does anybody have PCL running on Genera 7.2? >Help! >I have encountered a number of problems in trying to get PCL (St. >Patrick's Day version) working with Symbolics Genera 7.2: >1. The file "Rel-7-2-patches.lisp" contains a number of format strings >2. After worked around problem number 1, I was able to compile pcl (using >pcl::compile-pcl). It seems to work fine after being compiled. However, >after I booted the machine and tried to load pcl (using pcl::load-pcl), I >found that pcl was completely broken; any operation leads to the trap: > Trap: the second argument given to the ZL:MEMQ instruction, , was not a cons, or NIL. >This trap is entered recursively, over and over. I have been complaining about this problem for a while now. The only answer I got was something like: It is runing here on 7.2... I did not have time to spend trying to fix this problem (which is pretty anoying because you have to reboot the Lisp Machine) so I gave up. But if anybody around can tell us what's wrong with St Patricks Day release on Lisp Machine it would be very kind. Thanks in advance. Felix  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Jun 88 16:33:31 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 20 Jun 88 13:30:19 PDT Received: by ti.com id AA24079; Mon, 20 Jun 88 15:27:31 CDT Received: from Jenner by tilde id AA06995; Mon, 20 Jun 88 15:17:37 CDT Message-Id: <2791829681-8355429@Jenner> Date: Mon, 20 Jun 88 15:14:41 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Compile-file environment In order to compile in advance (compile-file time ) some implementation aspects of CLOS metaobjects, there must be some clos metaobjects residing in an implementation dependent environment, that do not visibly side effect the runtime environment. The visible entry points to this environment come from name to object mapping (FIND-CLASS and ENSURE-GENERIC-FUNCTION). I propose that a runtime environment CLOS object cannot visibly point to a compile-file environment object(No visible cross environment links). I think that makes metaclass programming a lot easier. Environment Capture When compiling CLOS DEF.. forms, a evaluation must take place that affects the compile-file environment, and this evaluation must be a similar to what happens when the forms are evaluated. I propose that the standard expansion of the DEF... macro be: (defclass foo () ()) => (eval-when (load eval compile) (add-named-class (class-prototype (find-class "STANDARD-CLASS" (name-environment env))) :name 'foo :environment (name-environment env))) Where name-environment take the value of a macroexpand environment and returns the right environment for the right situation. The value returned by name-environment can be passed as the environment argument to all CLOS functions that accept and environment argument. Presumably, when evaluated in the EVAL and COMPILE-TO-CORE situation, this name-environment returns NIL (the runtime environment). When evaluated in the COMPILE-FILE environment, it returns the compile-file environment. When evaluated in LOAD situation, it returns the runtime environment. Since the compiler and the evaluator have to treat this function differently, Logically, this is a special form. Environments behavior The compiler should be responsible for implementing the inheritance and shadowing of objects in different environments. However, find-class should not return a runtime object when the environment argument points to a compile-file environment. This avoids cross references across environments. I don't think this is a good idea for FIND-CLASS to return a created class object when an inheritance has to happen. I think that should be explicitly done by calling MAKE-DEFAULT-METAOBJECT. MAKE-DEFAULT-METAOBJECT metaobject-prototype name &optional environment. Generic-function The default method on standard-class returns a forwarded-class when the environment is a runtime environment, and does the implementation dependent environment inheritance or forwarded-class creation if the environment is a compile-file environment. Inside of ADD-NAMED-CLASS, MAKE-DEFAULT-METAOBJECT is called when (find-class class-name nil environment) returns NIL. Inside of ADD-NAMED-METHOD (or something like that), during the normalization of the specializers,MAKE-DEFAULT-METAOBJECT needs to be called if (find-class class-name nil environment) returns NIL when the environment is a compile-file environment. Inside of ENSURE-GENERIC-FUNCTION, we need to have the same mechanism. Either we extend FBOUNDP to accept an environment argument, or we come up with an equivalent of FIND-CLASS, does not matter much. MAKE-DEFAULT-METAOBJECT is specialized on standard-generic-function and returns the appropriate generic function object. Patrick.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 Jun 88 16:07:01 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 JUN 88 12:58:55 PDT Return-Path: <@EN-C06.Prime.COM,@S51.Prime.COM:SOBO@S66.Prime.COM> Redistributed: commonloops.pa Received: from EN-C06.Prime.COM ([192.5.58.32]) by Xerox.COM ; 20 JUN 88 12:54:03 PDT Received: from S51.Prime.COM by EN-C06.Prime.COM; 20 Jun 88 15:53:17 EDT Received: from S66.Prime.COM by S51.Prime.COM; 20 Jun 88 15:53:48 EDT Received: (from user SOBO) by S66.Prime.COM; 20 Jun 88 14:52:25 EDT To: commonloops.pa@Xerox.COM From: SOBO@S66.Prime.COM Date: 20 Jun 88 14:52:26 EDT Message-ID: <880620-125855-1415@Xerox> To: (commonloops.pa@xerox.com) From: Nadine Sobolevitch (sobo@s66) Date: 20 Jun 88 2:24 PM Subject: Does anybody have PCL running on Genera 7.2? Help! I have encountered a number of problems in trying to get PCL (St. Patrick's Day version) working with Symbolics Genera 7.2: 1. The file "Rel-7-2-patches.lisp" contains a number of format strings where the last character in the string is a back-slash, as in the following code fragment: (CATCH-ERROR-RESTART (SYS:ERROR "Skip compiling form ~2,2\COMPILER:SHORT-S-FORMAT\" FORM) Since the reader macro of the back-slash disables the reader macro of the double-quote, the reader never reads the second double-quote. I worked around this by adding a space just before the second double-quote. 2. After worked around problem number 1, I was able to compile pcl (using pcl::compile-pcl). It seems to work fine after being compiled. However, after I booted the machine and tried to load pcl (using pcl::load-pcl), I found that pcl was completely broken; any operation leads to the trap: Trap: the second argument given to the ZL:MEMQ instruction,
, was not a cons, or NIL. This trap is entered recursively, over and over. I am including the defsystem form from my version of "defsys.lisp" in the hope that somebody can tell me if I'm loading any wrong files. One other piece of information: The machine I'm running on is a Symbolics 3640 with microcode 3640-xsq-mic.mic.420 (extended sequencer microcode for use with Prolog). (defsystem pcl *pcl-directory* ;; file load compile files which port ;; environment environment force the of ;; recompilation ;; of this file ((rel-6-patches t t () rel-6) (rel-7-2-patches t t () rel-7) (ti-patches t t () ti) (pyr-patches t t () pyramid) (xerox-patches t t () xerox) (pkg t t ()) (walk (pkg) (pkg) ()) (macros (pkg walk) (pkg walk) ()) (low (pkg walk) (pkg macros) (macros)) (3600-low (low) (low) (low) Symbolics) (lucid-low (low) (low) (low) Lucid) (Xerox-low (low) (low) (low) Xerox) (ti-low (low) (low) (low) TI) (vaxl-low (low) (low) (low) vaxlisp) (kcl-low (low) (low) (low) KCL) (excl-low (low) (low) (low) excl) (cmu-low (low) (low) (low) CMU) (hp-low (low) (low) (low) HP) (gold-low (low) (low) (low) gclisp) (pyr-low (low) (low) (low) pyramid) (coral-low (low) (low) (low) coral) (fin t t (low)) (defs t t (macros)) (boot t t (defs fin)) (slots t t (boot defs low fin)) (mki t t (boot defs low fin)) (defclass t t (boot defs low fin)) (std-class t t (boot defs low fin)) (braid1 t t (boot defs low fin)) (fsc t t (boot defs low fin)) (methods t t (boot defs low fin)) (combin t t (boot defs low fin)) (dcode t t (defs low fin)) (dcode-pre1 t t (defs low fin dcode)) (fixup t t (boot defs low fin)) (high t t (boot defs low fin)) (compat t t ()) (7debug t t () rel-7) ))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 16 Jun 88 16:21:57 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 16 JUN 88 13:00:00 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 16 JUN 88 12:57:45 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA04083; Thu, 16 Jun 88 12:55:36 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA01795; Thu, 16 Jun 88 09:16:03 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA16404; Thu, 16 Jun 88 09:11:21 PDT Message-Id: <8806161611.AA16404@suntana.sun.com> To: karl lieberherr Cc: commonloops.pa@Xerox.COM Subject: Re: Law of good style for CLOS In-Reply-To: Your message of Thu, 09 Jun 88 17:23:54 -0400. <8806092123.AA12444@corwin.CCS.Northeastern.EDU> Date: Thu, 16 Jun 88 09:11:18 -0700 From: kempf@Sun.COM Karl: After reading your IEEE Computer article, I must unfortunately take strong exception to your Law of Demeter for CLOS. The reason is your law would prohibit functional composition, one of the foundations of Lisp. Indeed, the Law of Demeter, if applied to regular Lisp code, would prohibit functional composition for built-in generic functions (such as +). For example, the Law of Demeter says that the following code is in "poor" style: (defmethod sum-of-sqrt-of-difference ((x float) (y float)) (+ (sqrt (- x y)) y)) since the result of applying the built-in generic function - is an argument to the SQRT generic function, as is the result of SQRT to +. The result of applying - is neither a formal parameter to the function nor is it generated within the function body itself. This is exactly analogous to a user defined generic function in CLOS, since different implementations of the square root and addition algorithms will be run depending on the result of the subtraction and square root, respectively, so the actual parameters are involved in selecting the implementation. As a less trivial example, consider the following. In Unix, the pipe construct has the semantics of functional composition. Thus, to format a troff document and send it to the line printer the following command line is used: troff | lpr -P Using functional composition in Lisp/CLOS, we have: (defmethod output-document ((switches string) (filename pathname) (printer string)) (lpr printer (troff switches filename))) (defmethod lpr ((printer string) (document stream)) <> ) (defmethod troff ((switches string) (filename pathname)) <> ) The functional programming style is a useful and powerful one, though, as with all programming styles, it has its limitations. One of the advantages of CLOS is that it makes a combination of functional and object-oriented styles possible, allowing side effect producing operations to be limited in extent, which, in turn, makes proofs of correctness easier. By eliminating functional composition for generic functions, the Law of Demeter puts unnecessary restrictions on the programmer. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 16 Jun 88 10:55:11 EDT Received: from Salvador.ms by ArpaGateway.ms ; 16 JUN 88 07:47:25 PDT Return-Path: Redistributed: commonloops.pa Received: from mitre-bedford.ARPA by Xerox.COM ; 16 JUN 88 07:43:33 PDT Posted-From: The MITRE Corp., Bedford, MA Received: from orbit.sun.uucp by linus.MENET (3.2/4.7) id AA20696; Thu, 16 Jun 88 10:39:40 EDT Posted-Date: Thu, 16 Jun 88 10:39:37 EDT Received: from localhost by orbit.sun.uucp (3.2/SMI-3.0DEV3) id AA20763; Thu, 16 Jun 88 10:39:38 EDT Message-Id: <8806161439.AA20763@orbit.sun.uucp> To: CommonLoops.pa@Xerox.COM Subject: rel-7-2 patches need a patch! Date: Thu, 16 Jun 88 10:39:37 EDT From: rich%linus@mitre-bedford.ARPA We have a system which uses clos and also DEFSTRUCTs. Seems that your patch to COMPILE-FROM-STREAM-1 is missing the clause about MULTIPLE-DEFINITIONS, which causes the compilation of DEFSTRUCT to get all upset about DEFUNs and EVAL-WHENs not at the top level. The patch should really be as follows. The added clause has the comment "THIS CLAUSE NEEDS TO BE ADDED" before it. ;;; -*- Package: COMPILER; Mode: LISP; Syntax: Zetalisp -*- (DEFUN COMPILE-FROM-STREAM-1 (FORM &OPTIONAL (COMPILE-TIME-TOO NIL)) (CATCH-ERROR-RESTART (SYS:ERROR "Skip compiling form ~2,2\COMPILER:SHORT-S-FORMAT\" FORM) (LET ((DEFAULT-CONS-AREA (FUNCALL *COMPILE-FUNCTION* ':CONS-AREA))) (LET ((ERROR-MESSAGE-HOOK #'(LAMBDA () (DECLARE (SYS:DOWNWARD-FUNCTION)) (FORMAT T "~&While processing ~V,V\COMPILER:SHORT-S-FORMAT\" DBG:*ERROR-MESSAGE-PRINLEVEL* DBG:*ERROR-MESSAGE-PRINLENGTH* FORM)))) (SETQ FORM (FUNCALL *COMPILE-FUNCTION* ':MACRO-EXPAND FORM))) (WHEN (LISTP FORM) ;Ignore atoms at top-level (LET ((FUNCTION (FIRST FORM))) (SELECTQ FUNCTION ((QUOTE)) ;and quoted constants e.g. 'COMPILE ((PROGN) (DOLIST (FORM (CDR FORM)) (COMPILE-FROM-STREAM-1 FORM COMPILE-TIME-TOO))) ((EVAL-WHEN) (SI:CHECK-EVAL-WHEN-TIMES (CADR FORM)) (LET ((COMPILE-P (OR (MEMQ 'COMPILE (CADR FORM)) (AND COMPILE-TIME-TOO (MEMQ 'EVAL (CADR FORM))))) (LOAD-P (OR (MEMQ 'LOAD (CADR FORM)) (MEMQ 'CL:LOAD (CADR FORM)))) (FORMS (CDDR FORM))) (COND (LOAD-P (DOLIST (FORM FORMS) (COMPILE-FROM-STREAM-1 FORM (AND COMPILE-P ':FORCE)))) (COMPILE-P (DOLIST (FORM FORMS) (FUNCALL *COMPILE-FORM-FUNCTION* FORM ':FORCE NIL)))))) ((DEFUN) (LET ((TEM (DEFUN-COMPATIBILITY (CDR FORM) :WARN-IF-OBSOLETE T))) (IF (EQ (CDR TEM) (CDR FORM)) (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T) (COMPILE-FROM-STREAM-1 TEM COMPILE-TIME-TOO)))) ((MACRO) (FUNCALL *COMPILE-FORM-FUNCTION* FORM (OR COMPILE-TIME-TOO T) T)) ((DECLARE) (DOLIST (FORM (CDR FORM)) (FUNCALL *COMPILE-FORM-FUNCTION* FORM (OR COMPILE-TIME-TOO T) ;; (DECLARE (SPECIAL ... has load-time action as well. ;; All other DECLARE's do not. (MEMQ (CAR FORM) '(SPECIAL ZL:UNSPECIAL))))) ((COMPILER-LET) (COMPILER-LET-INTERNAL (CADR FORM) (CDDR FORM) #'COMPILE-FROM-STREAM-1 COMPILE-TIME-TOO)) ((SI:DEFINE-SPECIAL-FORM) (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T)) ;;; **************** THIS CLAUSE NEEDS TO BE ADDED ************************ ((MULTIPLE-DEFINITION) (DESTRUCTURING-BIND (NAME TYPE . BODY) (CDR FORM) (LET ((NAME-VALID (AND (NOT (NULL NAME)) (OR (SYMBOLP NAME) (AND (LISTP NAME) (NEQ (CAR NAME) 'QUOTE))))) (TYPE-VALID (AND (NOT (NULL TYPE)) (SYMBOLP TYPE)))) (UNLESS (AND NAME-VALID TYPE-VALID) (WARN "(~S ~S ~S ...) is invalid because~@ ~:[~S is not valid as a definition name~;~*~]~ ~:[~&~S is not valid as a definition type~;~*~]" 'MULTIPLE-DEFINITION NAME TYPE NAME-VALID NAME TYPE-VALID TYPE))) (LET* ((COMPILED-BODY NIL) (COMPILE-FUNCTION *COMPILE-FUNCTION*) (*COMPILE-FUNCTION* (LAMBDA (OPERATION &REST ARGS) (DECLARE (SYS:DOWNWARD-FUNCTION)) (SELECTQ OPERATION (:DUMP-FORM (PUSH (FUNCALL COMPILE-FUNCTION :OPTIMIZE-TOP-LEVEL-FORM (FIRST ARGS)) COMPILED-BODY)) (:INSTALL-DEFINITION (PUSH (FORM-FOR-DEFINE *COMPILER* (FIRST ARGS) (SECOND ARGS)) COMPILED-BODY)) (OTHERWISE (CL:APPLY COMPILE-FUNCTION OPERATION ARGS))))) (LOCAL-DECLARATIONS `((FUNCTION-PARENT ,NAME ,TYPE) ,@LOCAL-DECLARATIONS))) (DOLIST (FORM BODY) (COMPILE-FROM-STREAM-1 FORM COMPILE-TIME-TOO)) (FUNCALL COMPILE-FUNCTION :DUMP-FORM `(LOAD-MULTIPLE-DEFINITION ',NAME ',TYPE ',(NREVERSE COMPILED-BODY) NIL))))) ;;;; **************** END OF ADDED CLAUSE ************************************* ((pcl::top-level-form) (destructuring-bind (name times . body) (cdr form) (si:check-eval-when-times times) (let ((compile-p (or (memq 'compile times) (and compile-time-too (memq 'eval times)))) (load-p (or (memq 'load times) (memq 'cl:load times))) (fspec `(pcl::top-level-form ,name))) (cond (load-p (compile-from-stream-1 `(progn (defun ,fspec () . ,body) (funcall (function ,fspec))) (and compile-p ':force))) (compile-p (dolist (b body) (funcall *compile-form-function* form ':force nil))))))) (OTHERWISE (LET ((TEM (AND (SYMBOLP FUNCTION) (GET FUNCTION 'TOP-LEVEL-FORM)))) (IF TEM (FUNCALL *COMPILE-FORM-FUNCTION* (FUNCALL TEM FORM) COMPILE-TIME-TOO T) (FUNCALL *COMPILE-FORM-FUNCTION* FORM COMPILE-TIME-TOO T))))))))))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 16 Jun 88 10:54:47 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 16 JUN 88 07:45:41 PDT Return-Path: Redistributed: commonloops.pa Received: from mitre-bedford.ARPA by Xerox.COM ; 16 JUN 88 07:44:06 PDT Posted-From: The MITRE Corp., Bedford, MA Received: from orbit.sun.uucp by linus.MENET (3.2/4.7) id AA20700; Thu, 16 Jun 88 10:40:13 EDT Posted-Date: Thu, 16 Jun 88 10:40:11 EDT Received: from localhost by orbit.sun.uucp (3.2/SMI-3.0DEV3) id AA20770; Thu, 16 Jun 88 10:40:13 EDT Message-Id: <8806161440.AA20770@orbit.sun.uucp> To: CommonLoops.pa@Xerox.COM Subject: A bug in 7debug for PCL on Symbolics 7.2 Date: Thu, 16 Jun 88 10:40:11 EDT From: rich%linus@mitre-bedford.ARPA Seems like the variable *uninteresting-functions* now points to a hash table instead of a list. Therefore in FRAME-INTERESTING-P in the 7debug file, the first member encountered should be a gethash. Rich  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Jun 88 14:15:05 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 14 JUN 88 11:04:07 PDT Date: 14 Jun 88 11:02 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Space and Garbage In-reply-to: M V Lapolla 's message of Tue, 14 Jun 88 11:04:58 CDT To: marcos@AUSTIN.LOCKHEED.COM cc: kanderso@WILMA.BBN.COM, commonloops.pa@Xerox.COM Message-ID: <880614-110407-11459@Xerox> I realize that I missworded my question. I was really wondering if CLOS itself kept a reference to objects created above and beyond application reference. Thank you for the replies. No, CLOS is careful not to do this, for just that reason. danny  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Jun 88 12:19:35 EDT Received: from Semillon.ms by ArpaGateway.ms ; 14 JUN 88 09:09:02 PDT Return-Path: Redistributed: commonloops.pa Received: from shrike.Austin.Lockheed.COM by Xerox.COM ; 14 JUN 88 09:06:48 PDT Received: by shrike.Austin.Lockheed.COM (4.0/1.25); Tue, 14 Jun 88 11:04:58 CDT Received: by egret.AUSTIN.LOCKHEED.COM (3.2/1.4) for kanderso@WILMA.BBN.COM; Tue, 14 Jun 88 11:04:58 CDT Date: Tue, 14 Jun 88 11:04:58 CDT From: M V Lapolla Message-Id: <8806141604.AA16177@egret.AUSTIN.LOCKHEED.COM> To: kanderso@WILMA.BBN.COM Subject: Re: Space and Garbage Cc: commonloops.pa@Xerox.COM I realize that I missworded my question. I was really wondering if CLOS itself kept a reference to objects created above and beyond application reference. Thank you for the replies. M.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Jun 88 10:33:10 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 14 JUN 88 07:28:09 PDT Return-Path: Redistributed: commonloops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 14 JUN 88 07:27:10 PDT To: "M. V. LaPolla" cc: commonloops.pa@Xerox.COM Subject: Re: Space and Garbage In-reply-to: Your message of Mon, 13 Jun 88 14:18:43 -0500. <12406175738.36.CS.LAPOLLA@R20.UTEXAS.EDU> Date: Tue, 14 Jun 88 09:57:13 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880614-072809-10965@Xerox> Return-Path: Redistributed: commonloops.pa Date: Mon, 13 Jun 88 14:18:43 CDT From: "M. V. LaPolla" Subject: Space and Garbage To: commonloops.pa@xerox.com Message-Id: <12406175738.36.CS.LAPOLLA@R20.UTEXAS.EDU> I am using CLOS for a very large project. Many objects are created for this project. The application indexes objects in a hash table. When an application "object" is deleted this means that the slot in the hash table referencing the CLOS object is deleted. The CLOS object, however, is not. I am worried about space. Does CLOS garbage collect an if so what are the criteria for garbage. If it does not GC how may I delete a CLOS object and free up the space? Thanks, M. ------- PCL does not do any garbage collecting, as it expects the underlying lisp to provide it. If you want your objects GC'd make sure no other object references them. On a lisp machine with ephemeral GC, if the objects are long lived, they may pass through the Ephermeral GC, so you may want to play with its parameters a bit. k  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 14 Jun 88 01:17:31 EDT Received: from Salvador.ms by ArpaGateway.ms ; 13 JUN 88 22:13:57 PDT Return-Path: Redistributed: commonloops.PA Received: from uunet.UU.NET by Xerox.COM ; 13 JUN 88 22:12:14 PDT Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP id AA00654; Tue, 14 Jun 88 01:11:46 EDT Received: by mcvax.cwi.nl; Tue, 14 Jun 88 06:49:40 +0200 (MET) Received: by inria.inria.fr; Mon, 13 Jun 88 19:28:19 +0200 (MET) Received: from magnon.laas.fr (magnon.ARPA) by laas.laas.fr, Mon, 13 Jun 88 18:46:19 -0200 Date: Mon, 13 Jun 88 18:45:02 +0200 Received: by magnon.laas.fr, Mon, 13 Jun 88 18:45:02 +0200 From: mcvax!magnon.laas.fr!ralph@uunet.UU.NET (Ralph P. Sobek) Message-Id: <8806131645.AA05296@magnon.laas.fr> To: commonloops.PA@Xerox.COM Subject: CommonLoops Documentation Does there exist anything more recent or complete than "CommonLoops: Merging Lisp and Object-Oriented Programming," by Bobrow, et al, OOPSLA '86? Our version of PCL is dated "2-24-87." I have the feeling that it is not the most recent, seeing the discussions here. How valid a version is our version? Thanks in advance, Ralph P. Sobek | UUCP: uunet!mcvax!inria!lasso!ralph, or | ralph@lasso.uucp LAAS-CNRS | Internet: ralph@lasso.laas.fr, or 7, avenue du Colonel-Roche | ralph%lasso.laas.fr@uunet.UU.NET F-31077 Toulouse Cedex, FRANCE | ARPA: sobek@eclair.Berkeley.EDU (forwarded\ +(33) 61-33-62-66 | BITNET/EARN: SOBEK@FRMOP11 \ to UUCP )  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 13 Jun 88 15:31:58 EDT Received: from Salvador.ms by ArpaGateway.ms ; 13 JUN 88 12:22:03 PDT Return-Path: Redistributed: commonloops.pa Received: from R20.UTEXAS.EDU by Xerox.COM ; 13 JUN 88 12:19:05 PDT Date: Mon, 13 Jun 88 14:18:43 CDT From: M. V. LaPolla Subject: Space and Garbage To: commonloops.pa@Xerox.COM X-Good-Bye-1: R20.UTEXAS.EDU is going away Aug. 31, 1988. X-Good-Bye-2: Make other mail routing arrangements. Message-ID: <12406175738.36.CS.LAPOLLA@R20.UTEXAS.EDU> I am using CLOS for a very large project. Many objects are created for this project. The application indexes objects in a hash table. When an application "object" is deleted this means that the slot in the hash table referencing the CLOS object is deleted. The CLOS object, however, is not. I am worried about space. Does CLOS garbage collect an if so what are the criteria for garbage. If it does not GC how may I delete a CLOS object and free up the space? Thanks, M. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 12 Jun 88 18:20:39 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 12 JUN 88 15:10:52 PDT Return-Path: Redistributed: CommonLoops.pa Received: from ECLA.USC.EDU by Xerox.COM ; 12 JUN 88 15:09:55 PDT Date: Sun, 12 Jun 88 15:08:41 PDT From: Kim A. Barrett Subject: comments on 3/88 CLOS spec To: CommonLoops.pa@Xerox.COM cc: iim@ECLA.USC.EDU Message-ID: <12405944534.27.IIM@ECLA.USC.EDU> A couple of comments on the CLOS spec, dated March 1988. 1. In the discussion of Meta-Objects (Chapter 1, page 37), under the heading of Standard Metaclasses, it seems to me that there should be a mention of the metaclasses for the standard meta-objects other than standard-class. Without knowing what the metaclasses for these are, you can't define classes which are subclasses of them, so you can't define your own specialized generic-function classes, for example. 2. In the discussion of Integrating Types and Classes (Chapter 1, page 19), it is stated that the class that corresponds to a predefined Common Lisp type specifier can be implemented either as a standard-class, a structure-class, or a built-in class, and that doing much of anything with the object system involving built-in classes and their instances will signal an error. This doesn't leave any room for a particular implementation to define some of these in some special fashion available to it which will allow the object system to be used with them, perhaps using an implementation specific metaclass. I think the spec is overly restrictive, and doesn't really help with portability issues anyway (I assume that is why the restrictions were put in) since you don't know from one implementation to the next which types correspond to built-in classes vs. one of the other two, so you don't know which types can be specialized, slot-value'ed, and etc. kab -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Jun 88 15:52:10 EDT Received: from Semillon.ms by ArpaGateway.ms ; 10 JUN 88 12:43:47 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 10 JUN 88 12:40:56 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA23261; Fri, 10 Jun 88 12:39:35 PDT Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2) id AA06408; Fri, 10 Jun 88 12:36:13 PDT Received: by lukasiewicz.sun.com (4.0/SMI-4.0) id AA02575; Fri, 10 Jun 88 11:55:55 PDT Date: Fri, 10 Jun 88 11:55:55 PDT From: jrose@Sun.COM (John Rose) Message-Id: <8806101855.AA02575@lukasiewicz.sun.com> To: commonloops.pa@Xerox.COM In-Reply-To: karl lieberherr's message <8806092123.AA12444@corwin.CCS.Northeastern.EDU> Subject: Law of good style for CLOS I am very interested in your feedback regarding the understandability of our formulation of the Law of good style. Ok, I'll bite. Try a negative formulation. It seems like you are allowing every kind of argument __except__ those that potentially break abstraction boundaries. Classes local to the method are deemed to drop their abstraction boundaries inside the method. For me, the key illuminating comment on your Law was this: The idea is that it is a bad strategy to put a dependency on the C class into this method which is "attached to" A and Z. This is a start at a negative formulation, which is why it helped me. Then again, maybe I don't understand your Law at all. How about this for a positive formulation: Any slots used must be in one of the method's local classes. A "local" class is one which is used as an argument selector. That's approximately the rule of C++: You get privileged access to a class, not to an instance. You might want to go farther: Any slot accesses used must be applied to objects whose class is known. The principal (but not sole) means by which an object's class is known is the argument class specification (which is known to be enforced by method selection). I.e., you get privileged access to instances whose types are declared and checked. Perhaps the mode of declaration is restricted to method argument lists, perhaps not. Note the emphasis on slots. Access to a slot through a generic function is completely different from access through a slot primitive. Only the latter type of access can break CLOS abstraction boundaries. A useful tool idea: Given a piece of code (e.g., a method), automatically determine which classes it depends on knowing the slots of. This would be done by class inference on arguments to slot primitives. General problem: When a representation changes, what pieces of code need to be recompiled? Or possibly rewritten? It looks like this Law is intended to keep these sets of code pieces small and easily determinable. "Small" I think is a good goal; "easily determinable" is not so important, if the tool of the previous paragraph is available. As an example of a less easily-determinable class representation dependency, consider this code: (DEFCLASS X () (X-SLOT)) (DEFCLASS Y () (Y-SLOT)) (TYPECASE MY-X-OR-Y (X (SLOT-VALUE MY-X-OR-Y 'X-SLOT)) (Y (SLOT-VALUE MY-X-OR-Y 'Y-SLOT))) It seems to me that this code is as semantically clean as the equivalent formulation with methods: (DEFMETHOD INSTEAD-OF-TYPECASE ((MY-X-OR-Y X)) (SLOT-VALUE MY-X-OR-Y 'X-SLOT)) (DEFMETHOD INSTEAD-OF-TYPECASE ((MY-X-OR-Y Y)) (SLOT-VALUE MY-X-OR-Y 'Y-SLOT)) The representation-dependency detection tool would find both kinds of dependency on X and Y. I think the TYPECASE formulation is better style, don't you? -- John  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Jun 88 15:51:57 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 10 JUN 88 12:43:30 PDT Return-Path: Redistributed: commonloops.PA Received: from XV.MIT.EDU by Xerox.COM ; 10 JUN 88 12:42:09 PDT Received: from MITMS1-E40: by XV.MIT.EDU; 11 Mar 88 14:48:06 EST cc: Kevin_Crowston@XV.MIT.EDU To: commonloops.PA@Xerox.COM Subject: PCL:CALL-NEXT-METHOD From: Kevin_Crowston@XV.MIT.EDU Date: 10 Jun 88 15:42:51 EDT Message-ID: <0.43520.20995.49473.9838@XV.MIT.EDU> Sender: Kevin_Crowston@XV.MIT.EDU I have a method that calls PCL:CALL-NEXT-METHOD, but when I try to run or compile it, I get an error saying that PCL:CALL-NEXT-METHOD is undefined. I'm using the PCL dated 3/10/88 on a Xerox 1109, running Lyric Common Lisp. Here's a listing of the method: (PCL:DEFMETHOD WEB:MOVE-NODE ((CLENS::SELF CLENS::MESSAGE-TEMPLATE) CLENS::NEW-PARENT) (PCL:CALL-NEXT-METHOD) (CLENS::MARK-DIRTY CLENS::*MESSAGE-TEMPLATE-WEB-EDITOR*)) Any suggestions? Kevin Crowston  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 10 Jun 88 14:23:16 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 10 JUN 88 11:12:10 PDT Return-Path: <@helios.northeastern.edu:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 10 JUN 88 11:10:59 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id aa04994; 10 Jun 88 13:24 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa09642; 10 Jun 88 13:24 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA18865; Fri, 10 Jun 88 13:24:10 EDT Date: Fri, 10 Jun 88 13:24:10 EDT From: karl lieberherr Message-Id: <8806101724.AA18865@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law of good style for CLOS I was told that the counter examples I gave were not natural and I agree. An example which is natural but longer just appeared in IEEE Computer, June 88 in the Open Channel Section. You probably have easy access to it. If the Law is not clear after you read that example, please let me know. -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 9 Jun 88 20:02:20 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 09 JUN 88 16:57:19 PDT Return-Path: <@helios.northeastern.edu:lieber@corwin.ccs.northeastern.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 09 JUN 88 16:56:09 PDT Received: from helios.northeastern.edu by RELAY.CS.NET id aa20306; 9 Jun 88 17:25 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa18619; 9 Jun 88 17:23 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA12444; Thu, 9 Jun 88 17:23:54 EDT Date: Thu, 9 Jun 88 17:23:54 EDT From: karl lieberherr Message-Id: <8806092123.AA12444@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law of good style for CLOS All the feedback we got on the Law of good style for CLOS has prompted the Demeter team to find the proper generalization of our Flavors/Smalltalk/C++ Law to the CLOS Law. We give here our solution and explain it on some of the examples which you sent us. A pretty complete explanation will be in our OOPSLA '88 paper. A copy will be sent to Daniel Bobrow (as he requested). ----- LAW OF DEMETER (CLOS, object version) ------------- All function calls inside a method M must have one of the following method selection argument objects: - M's argument objects or - slot values of method selection argument classes of M. (Objects created by the method and objects in global variables are viewed as being passed by arguments. A method selection argument is an argument which is used for identifying the applicable methods.) ---------------------------------------------------------- This formulation is a natural generalization of the Flavors/ Smalltalk/C++ Law where there is exactly one method selection argument (the first one). Note that there is no restriction on non-generic function calls: they have 0 method selection arguments. The Law requires the programmer to be aware whether a function is generic (reversing our earlier point of view in our reply to Scott Fahlmann's message). Richard Gabriel invented the following example: >(defmethod hack-positions ((p1 position) (p2 position)) > (let ((p1-x (x-coord p1)) > (p1-y (y-coord p1)) > (p2-x (x-coord p2)) > (p2-y (y-coord p2))) > (let ((rho1 (sqrt (+ (* p1-x p1-x) (* p1-y p1-y)))) > (theta1 (atan p1-y p1-x)) > (rho2 (sqrt (+ (* p2-x p2-x) (* p2-y p2-y)))) > (theta2 (atan p2-y p2-x))) > (let* ((q (f rho2 theta2 rho1 theta1)) > (r (g q)) > (s (h r)) > (tt (i s)) > (u (j tt))) > (k u))))) >Is the call (x-coord p1) a violation? [It is not known whether it is a >slot access or a function call.] Is the call (x-coord p2) a violation? >[It is invoked on something besides the first argument to the method.] NO VIOLATION since p1 and p2 are method selection arguments. >Is the call to SQRT a violation? [Its first argument is a number, but is >not related to the first argument to the method.] NO VIOLATION since + returns a new object. How about the call to ATAN? >[Its first argument is related to the second argument to the method >via a LET variable.] A VIOLATION if we assume that the objects returned by (x-coord p1) and (y-coord p1) are not parts of p1. Otherwise no violation. >How about the call to f? [Its first argument is >derived from something related to the second argument to the method.] f is in GOOD STYLE since it gets all newly created objects. >The call to g? [Its first argument is indirectly related to the arguments to >the method. There is not enough type information here to tell. >Karl, if you could answer whether anything in HACK-POSITIONS violates the law >and why, we could begin to think about the issue you're raising. If nothing >here violates the law, could *you* provide a method that violates the law? Here is a simple example. ;;; A = B. (defclass A () ((B :type B))) ;;; B = C. (defclass B () ((C :type C))) ;;; C = D. (defclass C () ((D :type D))) (defmethod violation ((p1 A) (p2 Z)) (slot-value (slot-value (slot-value p1 'b) 'c))) The idea is that it is a bad strategy to put a dependency on the C class into this method which is "attached to" A and Z. --------------------------------- Jim Kempf's remark promotes further encapsulation. It enhances the Law but does not replace it. >If a class is defined with accessor generic functions whose names are >exported from the package, but are different from the slot names, >which are not exported (or "hidden"), then the only access to the >slots is through a functional interface. From the client's point of >view, invoking a generic function on the object need not have any >relation to slot access at all, much less an inherited or noninherited >slot. This is an even stronger form of encapsulation, since the structure >of the class is now completely hidden. Of course, an inheriting client >may still want access to that structure. I fully agree. It is good that CLOS allows to generate such an interface. ------------------------------------ For completeness I include the Smalltalk-80 version: ----- LAW OF DEMETER (Smalltalk-80, object version) ---- In all message expressions inside a method M the receiver must be one of the following objects: - an argument object of M including objects in pseudo variables self and super or - an instance variable object of the class to which M is attached. (Objects created by the method and objects in global variables are viewed as being passed by arguments.) -------------------------------------------------------- I am very interested in your feedback regarding the understandability of our formulation of the Law of good style. -- Karl  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 4 Jun 88 04:32:41 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 04 JUN 88 01:28:06 PDT Return-Path: Redistributed: commonloops.pa Received: from labrea.stanford.edu by Xerox.COM ; 04 JUN 88 01:26:38 PDT Received: by labrea.stanford.edu; Sat, 4 Jun 88 01:26:43 PDT Received: from bhopal.lucid.com by edsel id AA09936g; Sat, 4 Jun 88 01:15:38 PDT Received: by bhopal id AA04568g; Sat, 4 Jun 88 01:13:36 PDT Date: Sat, 4 Jun 88 01:13:36 PDT From: Jon L White Message-Id: <8806040813.AA04568@bhopal.lucid.com> To: rcp@sw.mcc.com Cc: Bobrow.pa@Xerox.COM, Timothy.Freeman@proof.ergo.cs.cmu.edu, commonloops.pa@Xerox.COM In-Reply-To: Rob Pettengill's message of Thu, 2 Jun 88 16:59:48 CDT <8806022159.AA20155@perseus.sw.mcc.com> Subject: Keywords in make-instance? re: Common Lisp does not specify that a keyword argument MUST come from the keyword package. They only do so by default. The keyword arguments for make-instance obey thi same rule. danny This was my interpretation as well. However, CLtL, does not explicitly say that the &key keyword can come from any package. At least one vendor, (Lucid 2.04), restricts function lambda list &key keywords to being in the keyword package. Danny is wrong here, as is your intuition too. See the first sentence on CLtL p62, which requires keyword parameter names to be "keywords" (i.e., symbols in the keyword package). There is even a "rationale" proffered for this decision. [This certainly is an easy one to overlook, since 1988 hindsight has so many advantages over 1983 foresight.] Lucid obeys the letter-of-the-law from CLtL, but has given full support to the X3J13 Cleanup Committee's proposal entitled KEYWORD-ARGUMENT-NAME-PACKAGE:ANY which relaxes the CLtL constraint. In fact, one of the motivating forces behind this proposal is so that CLOS methods aren't limited to having &key arguments named only in the "flat" namespace of package KEYWORD. [There is a reason why such a limitation is much more troublesome when using defmethod than when using defun or defmacro, but I'll not take time to go into it now.] Lucid release 2.1 and later doesn't seem to impose the constraint in compiled functions; I don't know about release 2.04. It is Lucid's intent to conform to the X3J13 proposal as soon as practical after its adoption. -- JonL --  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 4 Jun 88 00:59:06 EDT Received: from Salvador.ms by ArpaGateway.ms ; 03 JUN 88 21:51:45 PDT Return-Path: Redistributed: commonloops.pa Received: from hplabs.HP.COM by Xerox.COM ; 03 JUN 88 21:49:20 PDT Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Fri, 3 Jun 88 09:45:47 PST Received: from hplwhh.HPL.HP.COM (hplwhh.hpl.hp.com) by hplms2.HP.COM; Fri, 3 Jun 88 10:45:26 pdt Received: from hplwhh by hplwhh.HPL.HP.COM; Fri, 3 Jun 88 10:43:48 pdt To: Rob Pettengill Cc: commonloops.pa@Xerox.COM Subject: Re: Keywords in make-instance? X-Mailer: mh6.5 In-Reply-To: Your message of Thu, 02 Jun 88 16:59:48 -0500. <8806022159.AA20155@perseus.sw.mcc.com> Date: Fri, 03 Jun 88 10:43:46 PDT Message-Id: <13104.581363026@hplwhh> From: Warren Harris I think many lisp implementations (like Lucid and HP-CL) restrict &key arguments to be in the keyword package is because it becomes tedious to type: (xe:make-instance 'xe:window 'xe:width 30 'xe:height 20 ...) when the current package is not importing the symbols used in the command. The problem with this of course is that if the set of legal keywords is unioned (as it is in multiple inheritance systems) there is a chance of accidently shadowing some of the inherited parent's keywords if the parents exist in different packages and have different semantics for the same keyword name. For this reason, CLOS allows its init-keys to be in other packages besides the keyword package. The problem with the tediousness of explicitly typing the package name for each &key argument could be circumvented if CL were to adopt the Zetalisp convention of allowing the package prefix to prefix a form, rather than a symbol. The symbols contained within the form would be read with a default package corresponding to the prefix. The above expression would become: xe:(make-instance 'window 'width 30 'height 20 ...) which is just as easy to type as: (make-instance 'xe:window :width 30 :height 20 ...) but without the shadowing problems. I think this syntax allows the best of both worlds. Does anyone know if there is much chance of this convention being adopted by ANSI? Warren  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 2 Jun 88 19:52:20 EDT Received: from Semillon.ms by ArpaGateway.ms ; 02 JUN 88 15:04:39 PDT Date: Thu, 2 Jun 88 15:02 PDT From: Gregor.pa@Xerox.COM Subject: Re: CLOS bug To: Martin Kenner cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8806020338.AA15448@umn-cs.cs.umn.edu> Message-ID: <19880602220203.2.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Wed, 1 Jun 88 22:38:42 CDT From: kenner@umn-cs.cs.umn.edu (Martin Kenner) In trying to compile CLOS on a Symbolics 3640, I have encountered two problems in the file BOOT.LISP, function expand-defmethod-body-internal, in the flet form for walk-function. My guess is that your set of PCL sources is out of sync. Specifically, your boot.lisp file is probably newer than your walk.lisp file. I need these things to be fixed! It is, to say the least, aggravating to find these bugs when I read in the notes that the system is up and running at Xerox. We (at 3M) would really like to do some rigorous testing of CLOS, but are on the verge of giving up! I suspect that if rigorous testing of CLOS is what you are after you should just go ahead and give up. PCL does not claim to be a complete implementation of CLOS. My goal is to make it conform to the CLOS specification, and now that work on the CLOS specification is at a pause, I should have time to make substantial progress on that front. The first item on the agenda is performance however. P.S. Is it possible to get a copy of the list of those who are also working on CLOS? Basically everyone on this list is working with PCL with the belief that it is becoming an implementation of CLOS. As new releases of PCL come out, people have to update their code to make it conform to the new release, but eventually they will have CLOS programs. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 2 Jun 88 19:52:04 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUN 88 15:03:15 PDT Return-Path: <@MCC.COM:rcp%sw.MCC.COM@MCC.COM> Redistributed: commonloops.pa Received: from MCC.COM by Xerox.COM ; 02 JUN 88 15:00:59 PDT Received: from milano.sw.mcc.com by MCC.COM with TCP/SMTP; Thu 2 Jun 88 17:00:32-CDT Received: from perseus.sw.mcc.com by milano.sw.mcc.com (5.51/STP1.56) id AA20482; Thu, 2 Jun 88 17:00:53 CDT Date: Thu, 2 Jun 88 16:59:48 CDT From: Rob Pettengill Message-Id: <8806022159.AA20155@perseus.sw.mcc.com> Received: by perseus.sw.mcc.com (3.2/STP1.14) id AA20155; Thu, 2 Jun 88 16:59:48 CDT To: Bobrow.pa@Xerox.COM Cc: Timothy.Freeman@proof.ergo.cs.cmu.edu, commonloops.pa@Xerox.COM In-Reply-To: Danny Bobrow's message of 27 May 88 17:05 PDT <880527-170756-101@Xerox> Subject: Keywords in make-instance? Date: 27 May 88 17:05 PDT From: Danny Bobrow Make-instance takes keyword arguments like this: (make-instance 'class :key1 arg1 :key2 arg2 ...) It could take ordinary symbols instead of keywords like this: (make-instance 'class 'key1 arg1 'key2 arg2 ...) Common Lisp does not specify that a keyword argument MUST come from the keyword package. They only do so by default. The keyword arguments for make-instance obey thi same rule. danny This was my interpretation as well. However, CLtL, does not explicitly say that the &key keyword can come from any package. At least one vendor, (Lucid 2.04), restricts function lambda list &key keywords to being in the keyword package. ;rob Robert C. Pettengill, MCC Software Technology Program P. O. Box 200195, Austin, Texas 78720 ARPA: rcp@mcc.com PHONE: (512) 338-3533 UUCP: {ihnp4,seismo,harvard,gatech,pyramid}!ut-sally!im4u!milano!rcp  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 2 Jun 88 16:50:45 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 2 Jun 88 13:29:15 PDT Received: by ti.com id AA14212; Thu, 2 Jun 88 15:28:26 CDT Received: from Jenner by tilde id AA23256; Thu, 2 Jun 88 15:26:36 CDT Message-Id: <2790274788-645613@Jenner> Date: Thu, 2 Jun 88 15:19:48 CDT From: Patrick H Dussud To: Common-lisp-object-system@sail.stanford.edu Subject: [David N Gray : making structures] I thought I'd pass this along. There is no need to include Gray in the reply since he is out of town for two month. ------- Forwarded Message Patrick, The May 23 draft of the CLOS spec still has the following text on page 1-15: "Calling MAKE-INSTANCE to create an instance of STRUCTURE-CLASS signals an error." This still seems like an undesirable and unnecessary limitation to me. -- David Gray ------- End of Forwarded Message  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 2 Jun 88 12:22:17 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 02 JUN 88 09:12:35 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 02 JUN 88 09:10:27 PDT To: Martin Kenner cc: CommonLoops.pa@Xerox.COM Subject: Re: CLOS bug In-reply-to: Your message of Wed, 01 Jun 88 22:38:42 -0500. <8806020338.AA15448@umn-cs.cs.umn.edu> Date: Thu, 02 Jun 88 11:12:40 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880602-091235-6645@Xerox> Date: Wed, 1 Jun 88 22:38:42 CDT From: Martin Kenner Message-Id: <8806020338.AA15448@umn-cs.cs.umn.edu> To: CommonLoops.pa@xerox.com Subject: CLOS bug Cc: kenner@umn-cs.cs.umn.edu In trying to compile CLOS on a Symbolics 3640, I have encountered two problems in the file BOOT.LISP, function expand-defmethod-body-internal, in the flet form for walk-function. 1) In the parameter list, the function has three parameters and one aux parameter - yet the function walk-form only provides two. (I have tried making env optional with a default of env). In the version of walk-form i'm using, it calls walk-form-internal which funcalls walk-function with three arguments in the line: (funcall (env-walk-function env) form context env)) 2) the fifth clause in the cond is triggered in the compilation of (defmethod-setf method-class) in the file METHODS, it calls the function variable-class which in turn calls variable-declaration which is undefined. This is defined in walk.lisp, perhaps your walk.lisp is out if date. I need these things to be fixed! It is, to say the least, aggravating to find these bugs when I read in the notes that the system is up and running at Xerox. We (at 3M) would really like to do some rigorous testing of CLOS, but are on the verge of giving up! I have written twice before, but have received no response, and I am about at the end of my tolerance. I realize that this is not a supported product, but a little help will be greatly appreciated! By the way, I am using the St. Patrick's Day 1988 version of CLOS. Sorry i don't remember your earlier messages. I believe you should be able to get the latest version of PCL working on a 3600 without any difficulty, though you will need rel-7-2-patches.lisp to run in rel 7.2 and 7.1. If you still have problems, i could possibly mail you my version which fixes a few things. Thanks in advance for any and all help - Martin Kenner P.S. Is it possible to get a copy of the list of those who are also working on CLOS?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Jun 88 23:45:14 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 JUN 88 20:41:53 PDT Return-Path: Redistributed: CommonLoops.pa Received: from umn-cs.cs.umn.edu by Xerox.COM ; 01 JUN 88 20:40:58 PDT Received: by umn-cs.cs.umn.edu (5.51/4.7) id AA15448; Wed, 1 Jun 88 22:38:42 CDT Date: Wed, 1 Jun 88 22:38:42 CDT From: kenner@umn-cs.cs.umn.edu (Martin Kenner) Message-Id: <8806020338.AA15448@umn-cs.cs.umn.edu> To: CommonLoops.pa@Xerox.COM Subject: CLOS bug Cc: kenner@umn-cs.cs.umn.edu In trying to compile CLOS on a Symbolics 3640, I have encountered two problems in the file BOOT.LISP, function expand-defmethod-body-internal, in the flet form for walk-function. 1) In the parameter list, the function has three parameters and one aux parameter - yet the function walk-form only provides two. (I have tried making env optional with a default of env). 2) the fifth clause in the cond is triggered in the compilation of (defmethod-setf method-class) in the file METHODS, it calls the function variable-class which in turn calls variable-declaration which is undefined. I need these things to be fixed! It is, to say the least, aggravating to find these bugs when I read in the notes that the system is up and running at Xerox. We (at 3M) would really like to do some rigorous testing of CLOS, but are on the verge of giving up! I have written twice before, but have received no response, and I am about at the end of my tolerance. I realize that this is not a supported product, but a little help will be greatly appreciated! By the way, I am using the St. Patrick's Day 1988 version of CLOS. Thanks in advance for any and all help - Martin Kenner P.S. Is it possible to get a copy of the list of those who are also working on CLOS?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Jun 88 23:02:25 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 JUN 88 19:56:02 PDT Return-Path: Redistributed: CommonLoops.pa Received: from boulder.Colorado.EDU by Xerox.COM ; 01 JUN 88 19:55:13 PDT Return-Path: Received: by boulder.Colorado.EDU (cu.grandpoobah.052088) Received: by sigi.colorado.edu (cu.generic.041888) Date: Wed, 1 Jun 88 19:28:55 MDT From: Curt Stevens Message-Id: <8806020128.AA27813@sigi.colorado.edu> To: Bobrow.pa@Xerox.COM Subject: Re: Re: comment/question... Cc: CommonLoops.pa@Xerox.COM Wotd: sight thanks very much for your prompt reply. =============================================================================== |Curt Stevens (303)492-1218 | / | E-MAIL: | |University of Colorado at Boulder | o o | ------- | |Computer Science Department | | |arpa: stevens@boulder.colorado.edu| |Campus Box 430 | \_/ |csnet: stevens@boulder.csnet| |Boulder, Colorado 80309 | |uucp:{ncar|nbires}!boulder!stevens| =============================================================================== | my comments represent no one...... perhaps not even myself!! | =============================================================================== ======== | Curt | ========  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Jun 88 16:50:19 EDT Received: from Salvador.ms by ArpaGateway.ms ; 01 JUN 88 12:54:01 PDT Return-Path: Redistributed: commonloops.pa Received: from hplabs.HP.COM by Xerox.COM ; 01 JUN 88 12:51:01 PDT Received: from hplms2.HP.COM (hplms2) by hplabs.HP.COM with SMTP ; Wed, 1 Jun 88 11:50:24 PST Received: from hplsny.HPL.HP.COM (hplsny.hpl.hp.com) by hplms2.HP.COM; Wed, 1 Jun 88 12:50:06 pdt Received: from hplsny by hplsny.HPL.HP.COM; Wed, 1 Jun 88 12:49:37 pdt To: karl lieberherr Subject: Re: Law of good style for CLOS Cc: commonloops.pa@Xerox.COM Reply-To: snyder%hplabs@hplabs.HP.COM In-Reply-To: Your message of Sun, 29 May 88 05:36:32 -0400. <8805290936.AA06874@corwin.CCS.Northeastern.EDU> Date: Wed, 01 Jun 88 12:49:26 PDT Message-Id: <5166.581197766@hplsny> From: Alan Snyder Perhaps it would be helpful if you could tell us the INTENT of the law? There are two separate issues to discuss: (1) Is the INTENT a useful one -- i.e., does it help identify or promote "good style"? (2) Is the law an accurate reflection of the INTENT in a particular language? My guess at the intent is something like "objects should provide a complete interface rather than exposing part of their substructure to direct manipulation". Alan  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Jun 88 13:48:53 EDT Received: from Salvador.ms by ArpaGateway.ms ; 01 JUN 88 10:41:00 PDT Return-Path: Redistributed: commonloops.pa Received: from SAIL.Stanford.EDU by Xerox.COM ; 01 JUN 88 10:38:11 PDT Date: 01 Jun 88 10:37 PDT From: Dick Gabriel Subject: Law of Style To: commonloops.pa@Xerox.COM Message-ID: <880601-104100-5091@Xerox> There are two senses of the word ``law'' of interest here. One is in the sense of a natural law that exists and we observe it, the other is in the sense of a law obeyed by people using free will. From the statement of the Law and the responses, I'm not sure to which Karl is referring. Are we supposed to be searching for counterexamples to the law, the same way scientists a hundred years ago tried to find something that went faster than the speed of light? Or are we engaged in a macho display, such as ``well if you spit on my mother I'll kill your dog, law or no law.'' I assume that it's a law that we have to obey, and I will engage in the game of trying to guess a violation of the law, since I don't know what a violation would look like. (defmethod hack-positions ((p1 position) (p2 position)) (let ((p1-x (x-coord p1)) (p1-y (y-coord p1)) (p2-x (x-coord p2)) (p2-y (y-coord p2))) (let ((rho1 (sqrt (+ (* p1-x p1-x) (* p1-y p1-y)))) (theta1 (atan p1-y p1-x)) (rho2 (sqrt (+ (* p2-x p2-x) (* p2-y p2-y)))) (theta2 (atan p2-y p2-x))) (let* ((q (f rho2 theta2 rho1 theta1)) (r (g q)) (s (h r)) (tt (i s)) (u (j tt))) (k u))))) Is the call (x-coord p1) a violation? [It is not known whether it is a slot access or a function call.] Is the call (x-coord p2) a violation? [It is invoked on something besides the first argument to the method.] Is the call to SQRT a violation? [Its first argument is a number, but is related to the first argument to the method.] How about the call to ATAN? [Its first argument is related to the second argument to the method via a LET variable.] How about the call to f? [Its first argument is derived from something related to the second argument to the method.] The call to g? [Its first argument is indirectly related to the arguments to the method. The call to h? The call to i? The call to j? The call to k? [These last 4 are even more remotely related to the arguments to the method.] Karl, if you could answer whether anything in HACK-POSITIONS violates the law and why, we could begin to think about the issue you're raising. If nothing here violates the law, could *you* provide a method that violates the law? -rpg-  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 1 Jun 88 10:51:35 EDT Received: from Semillon.ms by ArpaGateway.ms ; 01 JUN 88 07:44:32 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 01 JUN 88 07:42:28 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA10302; Wed, 1 Jun 88 07:40:33 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA22256; Wed, 1 Jun 88 07:37:37 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA25000; Wed, 1 Jun 88 07:32:29 PDT Message-Id: <8806011432.AA25000@suntana.sun.com> To: karl lieberherr Cc: commonloops.pa@Xerox.COM Subject: Re: Law of good style for CLOS In-Reply-To: Your message of Sun, 29 May 88 05:36:32 -0400. <8805290936.AA06874@corwin.CCS.Northeastern.EDU> Date: Wed, 01 Jun 88 07:32:27 -0700 From: kempf@Sun.COM >As other man-made laws, the Law of Demeter allows room for >interpretation. For example, if we interpret "immediate part" as >the value of a slot which is declared for the given class (parameter >specializer of first argument) and not a value of an inherited >slot, we have a more restricted version of the Law (called the >strong Law) which has been studied in some of Alan Snyder's papers >on encapsulated software systems. If a class is defined with accessor generic functions whose names are exported from the package, but are different from the slot names, which are not exported (or "hidden"), then the only access to the slots is through a functional interface. From the client's point of view, invoking a generic function on the object need not have any relation to slot access at all, much less an inherited or noninherited slot. This is an even stronger form of encapsulation, since the structure of the class is now completely hidden. Of course, an inheriting client may still want access to that structure. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 31 May 88 23:30:00 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 31 MAY 88 20:25:09 PDT Return-Path: Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 31 MAY 88 20:23:56 PDT Received: from [129.10.1.2] by RELAY.CS.NET id ao21146; 31 May 88 11:27 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa26944; 31 May 88 11:17 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA06874; Sun, 29 May 88 05:36:32 EDT Date: Sun, 29 May 88 05:36:32 EDT From: karl lieberherr Message-Id: <8805290936.AA06874@corwin.CCS.Northeastern.EDU> To: CARNESE@SPAR-20.SPAR.SLB.COM, commonloops.pa@Xerox.COM Subject: Re: Law of good style for CLOS ----- LAW OF DEMETER FOR CLOS (object version)---------- All function calls inside a method M must have one of the following objects passed by their first argument: a value of M's parameters or an immediate part (the value of a slot) of the first argument. (Objects created by the method and objects in global variables are viewed as being passed by arguments.) ----------------------------------------------------------- Dan Carnese proposes the following violation: (defmethod violation ((l demeters-law)) (format t "How about this?")) We view here t as an object passed by a global variable and therefore this method is in good style. As other man-made laws, the Law of Demeter allows room for interpretation. For example, if we interpret "immediate part" as the value of a slot which is declared for the given class (parameter specializer of first argument) and not a value of an inherited slot, we have a more restricted version of the Law (called the strong Law) which has been studied in some of Alan Snyder's papers on encapsulated software systems. -- Karl Lieberherr  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 31 May 88 22:06:05 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 31 MAY 88 18:58:32 PDT Date: 31 May 88 18:56 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: comment/question... In-reply-to: Curt Stevens 's message of Sun, 29 May 88 14:07:27 MDT To: stevens@boulder.Colorado.EDU cc: CommonLoops.pa@Xerox.COM Message-ID: <880531-185832-4258@Xerox> On page 1-15 of the concepts draft of March 88 there is a statement that "...redefining a class may cause slots to be added or deleted. If a class is redefined in such a way that the set of local slots accessible in an instance is the same and the order of slots in storage is unchanged, no instances are updated." Does this mean that if I change the :allocation of a slot from :instance to :class while leaving everything else about the class unchanged, that the existing instances of the class will keep their local slot values? If you change the allocation of a slot from :instance to :class then the set of local slots (those with allocation :instance) will be changed in all instances of that class. The default method for update-instance-for-redefined-class will keep the local slot values for the remaining slots, but the slot whose allocation has changed will have a new value computed for the class, and that value will be the one accessible from each updated instance.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 31 May 88 18:07:26 EDT Received: from Semillon.ms by ArpaGateway.ms ; 31 MAY 88 14:53:34 PDT Date: Tue, 31 May 88 14:50 PDT From: Gregor.pa@Xerox.COM Subject: Re: PCL/CLOS running on 7.2? To: Francois F. Ingrand cc: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <19880531165326.2.FELIX@SENTINEL-ROCK.AI.SRI.COM>, <19880528031851.2.LISP-MACHINE@UNICORN.AI.SRI.COM>, The message of 27 May 88 20:18 PDT from Postmaster@BISHOP.AI.SRI.COM, The message of 27 May 88 20:18 PDT from A Lisp Machine Message-ID: <19880531215031.5.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Tue, 31 May 88 09:53 PDT From: Francois F. Ingrand I compile the last version of PCL, using patch rel-7-2-patches.lisp (instead of rel-7-patches.lisp). The compilation went fine... But here is the result of loading test.lisp (on a fresh machine) with only PCL/CLOS loaded. Command: Load File SENTINEL-ROCK:>pcl>src>test.lisp Loading SENTINEL-ROCK:>pcl>src>test.lisp.newest into package PCL . . Testing built-in-class-of... Trap: The array given to the ZL:AR-1 instruction, #, was 2-dimensional; the function expect ed a 1-dimensional one. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. . . Hmm, this doesn't happen for me, and it would seem that other people aren't having this problem either. Why don't you just ignore this problem for now. The test.lisp file doesn't really mean that much. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 31 May 88 13:03:44 EDT Received: from Semillon.ms by ArpaGateway.ms ; 31 MAY 88 09:56:41 PDT Return-Path: <@RITTER.AI.SRI.COM:Felix@AI.SRI.COM> Redistributed: CommonLoops.pa Received: from RITTER.AI.SRI.COM by Xerox.COM ; 31 MAY 88 09:52:43 PDT Received: from SENTINEL-ROCK.AI.SRI.COM by RITTER.AI.SRI.COM via CHAOS with CHAOS-MAIL id 13207; Tue 31-May-88 09:51:25 PDT Date: Tue, 31 May 88 09:53 PDT From: Francois F. Ingrand Subject: PCL/CLOS running on 7.2? To: CommonLoops.pa@Xerox.COM Included-msgs: <19880528031851.2.LISP-MACHINE@UNICORN.AI.SRI.COM>, The message of 27 May 88 20:18 PDT from Postmaster@BISHOP.AI.SRI.COM, The message of 27 May 88 20:18 PDT from A Lisp Machine Message-ID: <19880531165326.2.FELIX@SENTINEL-ROCK.AI.SRI.COM> I compile the last version of PCL, using patch rel-7-2-patches.lisp (instead of rel-7-patches.lisp). The compilation went fine... But here is the result of loading test.lisp (on a fresh machine) with only PCL/CLOS loaded. Command: Load File SENTINEL-ROCK:>pcl>src>test.lisp Loading SENTINEL-ROCK:>pcl>src>test.lisp.newest into package PCL Testing Memory Block Primitives...OK Testing Class Wrapper Caching...OK Testing Flushing Class-Wrapper caches...OK Testing Class Wrapper Caching... (80% hit) OK Testing types for early classes...OK Testing types for late classes...OK Testing built-in-class-of... Trap: The array given to the ZL:AR-1 instruction, #, was 2-dimensional; the function expect ed a 1-dimensional one. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. Trap: The second argument given to the ZL:MEMQ instruction, #
, was not a cons, or NIL. After that, you fall into the cold load stream, with an error message saying that there are two many errors. Anybody got PCL/CLOS running on 7.2? Thanks in advance, Felix  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 29 May 88 20:32:20 EDT Received: from Salvador.ms by ArpaGateway.ms ; 29 MAY 88 17:28:29 PDT Return-Path: <@MCC.COM,@BRAHMA.ACA.MCC.COM:Gumby@MCC.COM> Redistributed: commonloops.pa Received: from MCC.COM by Xerox.COM ; 29 MAY 88 17:25:33 PDT Received: from BRAHMA.ACA.MCC.COM by MCC.COM with TCP/SMTP; Sun 29 May 88 19:25:06-CDT Date: Sun, 29 May 88 19:25 CDT From: David Vinayak Wallace Subject: Law of good style for CLOS To: karl lieberherr cc: commonloops.pa@Xerox.COM In-Reply-To: <8805280303.AA01292@corwin.CCS.Northeastern.EDU> Message-ID: <880529192501.4.GUMBY@BRAHMA.ACA.MCC.COM> Date: Fri, 27 May 88 23:03:42 EDT From: karl lieberherr ----- LAW OF DEMETER FOR CLOS (object version)---------- All function calls (whether generic or not) inside a method M must have one of the following objects passed by their first argument: a value of M's parameters or an immediate part (the value of a slot) of the first argument. (Objects created by the method and objects in global variables are viewed as being transmitted by arguments.) So this code would be in violation: (defmethod iconify ((window special-window) (screen screen)) (set-top-left-position window *next-left-coordinate* *next-top-coordinate*) (incf *next-left-coordinate* *standard-icon-position-x-increment*) (incf *next-top-coordinate* *standard-icon-position-y-increment*)) since the INCFs would expand into (setf var (+ var var1)), and the arguments to plus would be the values of some special variables (presumably numbers)?  Received: from REAGAN.AI.MIT.EDU (CHAOS 13065) by AI.AI.MIT.EDU 29 May 88 16:17:33 EDT Received: from XEROX.COM by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 115394; 29 May 88 16:15:33 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 29 MAY 88 13:09:17 PDT Return-Path: Redistributed: CommonLoops.pa Received: from boulder.Colorado.EDU by Xerox.COM ; 29 MAY 88 13:08:05 PDT Return-Path: Received: by boulder.Colorado.EDU (cu.grandpoobah.052088) Received: by sigi.colorado.edu (cu.generic.041888) Date: Sun, 29 May 88 14:07:27 MDT From: Curt Stevens Message-Id: <8805292007.AA04305@sigi.colorado.edu> To: CommonLoops.pa@Xerox.COM Subject: comment/question... Wotd: pinwheel On page 1-15 of the concepts draft of March 88 there is a statement that "...redefining a class may cause slots to be added or deleted. If a class is redefined in such a way that the set of local slots accessible in an instance is the same and the order of slots in storage is unchanged, no instances are updated." Does this mean that if I change the :allocation of a slot from :instance to :class while leaving everything else about the class unchanged, that the existing instances of the class will keep their local slot values? Thanks very much for taking the time to answer. =============================================================================== |Curt Stevens (303)492-1218 | / | E-MAIL: | |University of Colorado at Boulder | o o | ------- | |Computer Science Department | | |arpa: stevens@boulder.colorado.edu| |Campus Box 430 | \_/ |csnet: stevens@boulder.csnet| |Boulder, Colorado 80309 | |uucp:{ncar|nbires}!boulder!stevens| =============================================================================== ======== | Curt | ========  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 28 May 88 01:39:11 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 27 MAY 88 22:29:48 PDT Return-Path: Redistributed: commonloops.pa Received: from SPAR-20.SPAR.SLB.COM by Xerox.COM ; 27 MAY 88 22:27:43 PDT Date: Fri, 27 May 88 22:27:14 PDT From: Dan Carnese Subject: Re: Law of good style for CLOS To: commonloops.pa@Xerox.COM In-Reply-To: <8805280303.AA01292@corwin.CCS.Northeastern.EDU> Message-ID: <12401830066.18.CARNESE@SPAR-20.SPAR.SLB.COM> Date: Fri, 27 May 88 23:03:42 EDT From: karl lieberherr Subject: Law of good style for CLOS ----- LAW OF DEMETER FOR CLOS (object version)---------- All function calls (whether generic or not) inside a method M must have one of the following objects passed by their first argument: a value of M's parameters or an immediate part (the value of a slot) of the first argument. (Objects created by the method and objects in global variables are viewed as being transmitted by arguments.) ---------------------------------------------------------------- I look forward to see some of your violations of the Law for which you can give a convincing argument that the violation is justified. (defmethod violation ((l demeters-law)) (format t "How about this?")) -- Dan -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 May 88 23:24:21 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 88 20:18:17 PDT Return-Path: Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 27 MAY 88 20:16:29 PDT Received: from [129.10.1.2] by RELAY.CS.NET id aa11844; 27 May 88 23:05 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa23143; 27 May 88 23:04 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA01292; Fri, 27 May 88 23:03:42 EDT Date: Fri, 27 May 88 23:03:42 EDT From: karl lieberherr Message-Id: <8805280303.AA01292@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law of good style for CLOS Thank you for your feedback. I would like to clarify a few points in reply to your messages. The motivation for the Law is that it buys you the following interrelated qualities of good programming style: Reduced coupling between your methods, more information restriction, localization of types, narrow interfaces, easier maintanance, smaller programming complexity and easier correctness proofs by structural induction. The details will be in the OOPSLA paper. Your feedback has prompted me to the following improved formulation: ----- LAW OF DEMETER FOR CLOS (object version)---------- All function calls (whether generic or not) inside a method M must have one of the following objects passed by their first argument: a value of M's parameters or an immediate part (the value of a slot) of the first argument. (Objects created by the method and objects in global variables are viewed as being transmitted by arguments.) ---------------------------------------------------------------- This Law does not exclude methods such as the one given by James Kempf: (defmethod display ((view text-window) (controller keyboard)) ... The Law does not restrict the number of arguments that can be specialized. It does not hinder the multi-dimensional implicit case analysis of CLOS. Nevertheless, the Law treats the first argument in a special way. Our experience indicates that this is very useful from a software engineering point of view. When you check your code for violations of the Law, it is good to search for nested function calls which have a nesting level of more than 2. The formulation of the Law is subtle: we formulate it here in terms of objects and not in terms of variables (as Gregor Kiczales suggested in his message). That would be too restrictive. We have a formulation in terms of types which is a little more generous than the object version, but compile-time enforceable for a useful subset of CLOS. I look forward to see some of your violations of the Law for which you can give a convincing argument that the violation is justified. -- Karl Lieberherr  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 May 88 20:45:08 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 88 17:07:56 PDT Date: 27 May 88 17:05 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: Keywords in make-instance? In-reply-to: Timothy.Freeman@PROOF.ERGO.CS.CMU.EDU's message of Fri, 20 May 88 18:01:07 EDT To: Timothy.Freeman@PROOF.ERGO.CS.CMU.EDU cc: commonloops.pa@Xerox.COM Message-ID: <880527-170756-101@Xerox> Make-instance takes keyword arguments like this: (make-instance 'class :key1 arg1 :key2 arg2 ...) It could take ordinary symbols instead of keywords like this: (make-instance 'class 'key1 arg1 'key2 arg2 ...) Common Lisp does not specify that a keyword argument MUST come from the keyword package. They only do so by default. The keyword arguments for make-instance obey thi same rule. danny  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 May 88 16:00:17 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 MAY 88 12:52:47 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 27 MAY 88 12:49:55 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM Subject: &aux and (call-next-method) Date: Fri, 27 May 88 15:37:04 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880527-125247-4699@Xerox> Apparently &aux variables get lost in the expansion of defmethod when the method body contains (call-next-method...): (defclass c () ()) ;; This works fine (defmethod method-1 ((a c) &aux l) (setq l (list a))) ;; Here L is declared special. (defmethod method-1 ((a c) &aux l) (setq l (list a)) (call-next-method) (print l))  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 May 88 15:45:03 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 27 MAY 88 12:34:17 PDT Return-Path: Redistributed: commonloops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 27 MAY 88 12:32:34 PDT To: "Francois F. Ingrand" cc: commonloops.pa@Xerox.COM Subject: Re: CLOS on Symbolics, Genera 7.2 In-reply-to: Your message of Fri, 27 May 88 10:22:00 -0700. <19880527172226.5.FELIX@SENTINEL-ROCK.AI.SRI.COM> Date: Fri, 27 May 88 15:30:48 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880527-123417-4671@Xerox> Yes, i think Gregor wasn't too clear on what to do with rel-7-2-patches.lisp. If you replace the old rel-7-patches with it PCL seems to work in 7.1 and 7.2! k  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 May 88 13:30:23 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 MAY 88 10:23:41 PDT Return-Path: <@RITTER.AI.SRI.COM:Felix@AI.SRI.COM> Redistributed: commonloops.pa Received: from RITTER.AI.SRI.COM by Xerox.COM ; 27 MAY 88 10:21:17 PDT Received: from SENTINEL-ROCK.AI.SRI.COM by RITTER.AI.SRI.COM via CHAOS with CHAOS-MAIL id 13155; Fri 27-May-88 10:20:11 PDT Date: Fri, 27 May 88 10:22 PDT From: Francois F. Ingrand Subject: CLOS on Symbolics, Genera 7.2 To: commonloops.pa@Xerox.COM Supersedes: <19880527170207.3.FELIX@SENTINEL-ROCK.AI.SRI.COM> Message-ID: <19880527172226.5.FELIX@SENTINEL-ROCK.AI.SRI.COM> I am new in this mail list, so I appologize if this question has already been answered lately. The last release of CLOS/PCL (St Patrick's Day March 88) does not run on 7.2 . I got a "big crash" last time I tried it. I notice a "patches-7-2.lisp" file in the directory where is CLOS/PCL, but this file does not seem to be declared in the defsys.lisp So what is the status of the current release? Running or not running on 7.2? Thanks in advance. Felix  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 May 88 11:18:42 EDT Received: from Salvador.ms by ArpaGateway.ms ; 27 MAY 88 08:15:57 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 27 MAY 88 08:13:53 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA26253; Fri, 27 May 88 08:10:40 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA11025; Fri, 27 May 88 08:07:56 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA01817; Fri, 27 May 88 08:02:39 PDT Message-Id: <8805271502.AA01817@suntana.sun.com> To: karl lieberherr Cc: commonloops.pa@Xerox.COM Subject: Re: Law of good style for CLOS In-Reply-To: Your message of Thu, 26 May 88 20:36:17 -0400. <880526-173709-3581@Xerox> Date: Fri, 27 May 88 08:02:37 -0700 From: kempf@Sun.COM > All generic function calls inside a method M must have > one of the following objects passed by their first argument: > a value of M's parameters (including self) or > an immediate part of self. As Scott's reply has indicated, I don't think it is reasonable to force CLOS into the old Flavors style of programming. The point of generic functions is that the client of a module need not care whether a particular operation is implemented as a function or a generic function. > Objects created by the method and non-local objects > are viewed as being transmitted by arguments. > self is the name of the first argument of method M. I'm not sure I understand you're meaning here, nor the motivation for the first sentence. I disagree with the second, though. As is usual for any function, the name of the first argument should be menumonic for whatever it does. For example: (defmethod display ( (view text-window) (controller keyboard) (model resistor) ) . . . ) (defmethod display ( (view graphics-window) (controller mouse) (model resistor) ) . . . ) might be a piece of code in the definition of a model-view-controller implementation (ala` Smalltalk) in CLOS. To constrain the name of first parameter of the lambda list and the implementation of the methods as your laws suggest would force model-view-controller back into the one dimensional world of restricted specialization, where only the first parameter can be specialized. In that world, this same code would look like: (defmethod display ( (self text-window) controller model ) (typecase model (resistor (typecase controller (mouse ) ... ) ) ... ) ) If you want to enforce these laws, then I suggest you look into an embedded language on top of CLOS. But I think you'd make life more difficult for application programmers. jak  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 27 May 88 11:16:29 EDT Received: from Semillon.ms by ArpaGateway.ms ; 27 MAY 88 08:11:40 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 27 MAY 88 08:09:51 PDT To: burdorf@RAND-UNIX.ARPA cc: CommonLoops.pa@Xerox.COM Subject: Re: init-method in PCL In-reply-to: Your message of Wed, 11 May 88 15:17:28 -0700. <8805112217.AA29660@rand.org> Date: Fri, 27 May 88 11:07:59 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880527-081140-4214@Xerox> Return-Path: Redistributed: CommonLoops.pa Received: from rand.org (RAND-UNIX.ARPA) by Xerox.COM ; 11 MAY 88 15:35:06 PDT Received: by rand.org; Wed, 11 May 88 15:17:34 PDT Message-Id: <8805112217.AA29660@rand.org> To: CommonLoops.pa@xerox.com Cc: burdorf@RAND-UNIX.ARPA Subject: init-method in PCL Date: Wed, 11 May 88 15:17:28 PDT From: burdorf@RAND-UNIX.ARPA Can anyone tell me how to do an "init-method" in PCL so that it works like init-method does in FLAVORS. I tried fiddling with the initialize-instance method but didn't get any good results. thanks chris burdorf We use something like this. You can use either the PCL way of specializing initialize-instance, or the old Flavors way of :INIT :AFTER methods, or something like the new Flavors way using MAKE-INSTANCE :AFTER. (defclass vanilla () ()) (defmethod MAKE-INSTANCE ((class symbol) &rest init-options) (apply #'make-instance (symbol-class class) init-options)) (defmethod MAKE-INSTANCE ((class standard-class) &rest init-options) (let ((instance (apply #'pcl:mki class init-options))) (apply #'make-instance instance init-options) (:init instance init-options) instance)) (defmethod MAKE-INSTANCE ((instance vanilla) &rest init-options) (declare (ignore init-options)) instance) (defmethod VANILLA :INIT (init-options) (declare (ignore init-options)) nil)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 May 88 20:44:03 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 MAY 88 17:37:09 PDT Return-Path: Redistributed: commonloops.pa Received: from SEF1.SLISP.CS.CMU.EDU by Xerox.COM ; 26 MAY 88 17:35:23 PDT Received: from SEF1.SLISP.CS.CMU.EDU by SEF1.SLISP.CS.CMU.EDU; 26 May 88 20:36:35 EDT To: karl lieberherr cc: commonloops.pa@Xerox.COM Subject: Re: Law of good style for CLOS In-reply-to: Your message of Thu, 26 May 88 15:37:02 -0400. <8805261937.AA22252@corwin.CCS.Northeastern.EDU> Date: Thu, 26 May 88 20:36:17 EDT From: Scott.Fahlman@B.GP.CS.CMU.EDU Message-ID: <880526-173709-3581@Xerox> We have identified the following law of good style (known in-house as the Law of Demeter) for CLOS programmers: ---------------------------------------------------------------- All generic function calls inside a method M must have one of the following objects passed by their first argument: a value of M's parameters (including self) or an immediate part of self. Objects created by the method and non-local objects are viewed as being transmitted by arguments. self is the name of the first argument of method M. ---------------------------------------------------------------- I have a better law of good style: someone writing Common Lisp code, whether within a method or not, should not have to be aware of which calls are generic and which are not. Therefore it is unreasonable to lay down laws about what the arguments to generic function calls may be. Do you disagree with this? -- Scott  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 May 88 19:48:41 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 MAY 88 16:38:15 PDT Date: Thu, 26 May 88 16:36 PDT From: Gregor.pa@Xerox.COM Subject: Re: Law of good style for CLOS To: karl lieberherr cc: commonloops.pa@Xerox.COM, rpg@SAIL.STANFORD.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: <8805261937.AA22252@corwin.CCS.Northeastern.EDU> Message-ID: <19880526233646.8.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Thu, 26 May 88 15:37:02 EDT From: karl lieberherr ---------------------------------------------------------------- All generic function calls inside a method M must have one of the following objects passed by their first argument: a value of M's parameters (including self) or an immediate part of self. Objects created by the method and non-local objects are viewed as being transmitted by arguments. self is the name of the first argument of method M. ---------------------------------------------------------------- I can't figure out what this law is. Part of my problem is that I don't understand what you mean by "non-local objects". In addition, you seem to be suggesting that the first argument to a generic function is special in some way that I don't understand. Let me try to rephrase what I understand you to be proposing. That way you will be able to tell me how I have misunderstood what you are proposing. Within the body of a method M, the first argument passed to any generic function must be one of: - one of the arguments received by M - an "immediate component" of the value of M's first argument - a newly created object - a "non-local object" Where "immediate component" probably means the value of one of the slots of M's first argument. and "non-local object" means some combination of: - the value of a lexical variable - the value of a special variable - the values returned by a function call from within the body of M One critical question is what "non-local object" means. Another critical question is why are you treating the first argument specially. CLOS is not a `message sending' system. In CLOS the generic function determines which methods are applicable for the arguments it received. This is in contrast to Smalltalk in which the object determines which method is appropriate for the message it received. A possibly related law is: Inside the body of a method M, the only legal use of slot-value is on "self", where self means the first argument, and the only argument which is specialized. How does this differ from what you are proposing? A paper on the Law of Demeter and its implications will be presented at OOPSLA '88. For a short version, see IEEE Computer, June 88, Open Channel. We use a version of this Law which we can enforce efficiently at compile-time. I can't understand what it would mean to enforce this at compile time until I understand what the law is exactly. It seems to me that all bets are off if non-local object includes the values returned by a function call. I am interested to know whether CLOS programmers are willing to constrain themselves to follow this Law. I look forward to your feedback. An important thing missing from your message is any motivation for following this law. What does this law buy me? -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 May 88 17:15:09 EDT Received: from Salvador.ms by ArpaGateway.ms ; 26 MAY 88 13:53:02 PDT Return-Path: Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 26 MAY 88 13:51:07 PDT Received: from [129.10.1.2] by RELAY.CS.NET id ab17888; 26 May 88 16:32 EDT Received: from corwin.ccs.northeastern.edu by helios.northeastern.edu id aa00117; 26 May 88 15:37 EDT Received: by corwin.CCS.Northeastern.EDU (5.51/SMI-3.2+CCS-main-2.4) id AA22252; Thu, 26 May 88 15:37:02 EDT Date: Thu, 26 May 88 15:37:02 EDT From: karl lieberherr Message-Id: <8805261937.AA22252@corwin.CCS.Northeastern.EDU> To: commonloops.pa@Xerox.COM Subject: Law of good style for CLOS Cc: rpg@SAIL.STANFORD.EDU Please can you forward this message to the CLOS community. -Thank you. We have identified the following law of good style (known in-house as the Law of Demeter) for CLOS programmers: ---------------------------------------------------------------- All generic function calls inside a method M must have one of the following objects passed by their first argument: a value of M's parameters (including self) or an immediate part of self. Objects created by the method and non-local objects are viewed as being transmitted by arguments. self is the name of the first argument of method M. ---------------------------------------------------------------- A paper on the Law of Demeter and its implications will be presented at OOPSLA '88. For a short version, see IEEE Computer, June 88, Open Channel. We use a version of this Law which we can enforce efficiently at compile-time. I am interested to know whether CLOS programmers are willing to constrain themselves to follow this Law. I look forward to your feedback. -- Karl Lieberherr  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 May 88 15:54:47 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 26 MAY 88 12:36:42 PDT Return-Path: Redistributed: CommonLoops.pa Received: from ECLA.USC.EDU by Xerox.COM ; 26 MAY 88 12:34:49 PDT Date: Thu, 26 May 88 12:34:12 PDT From: Kim A. Barrett Subject: pcl method cache bug To: CommonLoops.pa@Xerox.COM cc: iim@ECLA.USC.EDU Message-ID: <12401459965.56.IIM@ECLA.USC.EDU> While groveling through DCODE the other day, I noticed the comment in CACHE-METHOD about not being able to depend on without-interrupts. Since I happen to know that without-interrupts is real for our system, I rewrote CACHE-METHOD (and CACHED-METHOD, as well) to use it. While I was in the process of that rewrite, thinking about what the current code did to make sure I wasn't missing anything cute but unobvious, I realized that the current code is in fact wrong. Consider the following scenarios: 1. CACHE-METHOD with one key Compute offset, clobber offset entry to nil, and store method-function at offset+1. Get interrupted. While in the interrupt, cache a different method with a different key which happens to hash to the same offset. Return from the interrupt, and install the initial key at offset. Now a cache lookup on the initial key will return a function which has nothing to do with the key. 2. CACHED-METHOD Compute offset, and successfully check all the keys for a match. Get interrupted. While in the interrupt, cache a different method with a different set of keys which happen to hash to the same offset. Return from the interrupt, and incorrectly return the code now in the cache. There are plenty of other ways to lose besides the two examples I just gave. I actually spent some time thinking about how this could be dealt with without using without-interrupts, but haven't come up with anything bullet-proof. There always seems to be some critical place where either without-interrupts or a test-and-set capability (which could be implemented using without-interrupts) is needed. kab ;;; The current code (in both Valentine's Day and St. Patrick's Day versions) (defmacro cache-method (cache mask method-function &rest classes) `(let* ((.offset. (generic-function-cache-offset ,mask ,@classes))) ;; Once again, we have to endure a little brain damage because we can't ;; count on having without-interrupts. I suppose the speed loss isn't ;; too significant since this is only when we get a cache miss. (setf (generic-function-cache-entry ,cache .offset. 0) nil) ,@(iterate ((class in (cdr classes)) (key-no from 1)) (collect `(setf (generic-function-cache-entry ,cache .offset. ,key-no) ,class))) (prog1 (setf (generic-function-cache-entry ,cache .offset. ,(length classes)) ,method-function) (setf (generic-function-cache-entry ,cache .offset. 0) ,(car classes))))) (defmacro cached-method (cache mask &rest classes) `(let ((.offset. (generic-function-cache-offset ,mask . ,classes))) (and ,@(iterate ((class in classes) (key-no from 0)) (collect `(eq (generic-function-cache-entry ,cache .offset. ,key-no) ,class))) (generic-function-cache-entry ,cache .offset. ,(length classes))))) -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 26 May 88 14:04:18 EDT Received: from Semillon.ms by ArpaGateway.ms ; 26 MAY 88 10:53:06 PDT Return-Path: Redistributed: commonloops.pa Received: from vaxa.isi.edu by Xerox.COM ; 26 MAY 88 10:51:09 PDT Posted-Date: Thu, 26 May 88 10:51:34 PDT Message-Id: <8805261751.AA00905@vaxa.isi.edu> Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51) id AA00905; Thu, 26 May 88 10:51:39 PDT To: commonloops.pa@Xerox.COM Cc: macgreg@vaxa.isi.edu Subject: Problem with dynamic slots Date: Thu, 26 May 88 10:51:34 PDT From: macgreg@vaxa.isi.edu In our application of PCL, we create classes with many "optional" slots, which will contain the value NIL most of the time. To save space, we declare these slots with :allocation :dynamic. We hit a bug when we brought up the St. Patrick's Day version of PCL: When we execute the following on a Symbolics, we generate an error: (defclass foo () ((name :allocation :dynamic))) (setq i (make-instance 'foo)) (slot-value i 'name) D,#TD1PsT[Begin using 006 escapes](1 0 (NIL 0) (NIL :BOLD NIL) "CPTFONTCB")Trap: The function PCL:*SLOTD-UNSUPPLIED* is undefined. (2 0 (NIL 0) (NIL NIL NIL) "CPTFONT")While in the function  PCL:SLOT-VALUE-USING-CLASS--CLASS-INTERNAL The condition signalled was DBG:UNDEFINED-FUNCTION-TRAP 1PCL:SLOT-VALUE-USING-CLASS--CLASS-INTERNAL2: (P.C. = 241) (3 0 (NIL 0) (NIL :ITALIC NIL) "CPTFONTI")(from DOG-CHOW:>pcl>SLOTS) 2 Arg 0 (PCL:CLASS): # Arg 1 (PCL:OBJECT): # Arg 2 (PCL:SLOT-NAME): PCL:NAME Arg 3 (PCL:DONT-CALL-SLOT-MISSING-P): NIL Arg 4 (PCL:DEFAULT): NIL The top-level "fix" is to include an :initform option in our slot declaration: (defclass foo2 () ((name :allocation :dynamic :initform nil))) (setq i2 (make-instance 'foo2)) This works. However, our "fix" has the undesirable property that reading a such a dynamic slot causes space to be allocated on the association list, i.e., instead of saving space we are using four-times as much. (elt i2 3) --> NIL (slot-value i2 'name) (elt i2 3) --> (NAME NIL) Are we correct in thinking that reading an empty dynamic slot having no :initfunction should generate no space? We realize that dynamic slots aren't a part of the CLOS standard. Nevertheless, we find them useful, and hope that they will continue to appear in PCL (e.g., that they will survive the current round of permutation-vector optimizations).  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 May 88 14:00:15 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 26 May 88 10:54:57 PDT Received: from PERON.AI.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 26 May 88 13:55-EDT Date: Thu, 26 May 88 13:58 EDT From: Richard Mlynarik Subject: with-added-methods To: common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <19880526175838.6.MLY@PERON.AI.MIT.EDU> [Apologies if I am rehashing an issue which has been previously discussed -- the local CLOS archives are presently inaccessible.] with-added-methods seems incompatible with the restriction (mentioned in the doc for add-method) that a method can only be added to one generic function at a time. The doc for with-added-methods says: Each generic function is created by adding the set of methods specified by its method definitions to a copy of the lexically visible generic function of the same name and its methods. That for add-method says: If the method object is a method object of another generic function, an error is signaled. I would think that the new generic function created by with-added-methods must share all all the methods which were defined on the original generic function. I suppose that an alternate reading of the first piece of documentation is ``to a copy of the lexically visible generic function of the same name and TO A COPY OF its methods'' -- I'd like to think that this isn't what was intended, since it would seem to introduce far more problems than it solves. Some passing remarks about with-added-methods: * Does it really need to be a special form rather than a macro? I -believe- I could define it in terms of generic-flet -- however,' I haven't thought this through very thoroughly. * Is there sufficient Chapter 3 support to enable this kind of thing to be `portably' implemented? Apart from the above-mentioned lossage involving methods added to more than one generic function, there are problems brushed under the rug by ``A COPY OF the lexically visible generic function.'' Presumably there needs to be some cloning method for generic functions. * I guess I'll never actually use with-added-methods in any case because of inefficiencies due what I perceive as the fatal problem with method-combination...  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 May 88 18:06:08 EDT Received: from Semillon.ms by ArpaGateway.ms ; 25 MAY 88 14:53:30 PDT Return-Path: Redistributed: commonloops.pa Received: from avalon.berkeley.edu by Xerox.COM ; 25 MAY 88 14:51:29 PDT Received: by avalon.berkeley.edu (5.57/1.26) id AA00141; Wed, 25 May 88 14:52:17 PDT Date: Wed, 25 May 88 14:52:17 PDT From: scottl%avalon.Berkeley.EDU@berkeley.edu (Scott Luebking) Message-Id: <8805252152.AA00141@avalon.berkeley.edu> To: commonloops.pa@Xerox.COM Subject: Mailing list Hi, Please take me off the mailing list for commonloops. Thanks, Scott  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 May 88 15:52:48 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 25 MAY 88 12:25:57 PDT Return-Path: Redistributed: commonloops.pa Received: from CAD.CS.CMU.EDU by Xerox.COM ; 25 MAY 88 12:24:17 PDT Date: Wed, 25 May 88 15:24:09 EDT From: Robert.Joseph@CAD.CS.CMU.EDU To: commonloops.pa@Xerox.COM Subject: Mailing list Message-ID: <880525-122557-9047@Xerox> Please take me off the mailing list for commonloops. Thanks. --rj  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 25 May 88 13:43:01 EDT Received: from Semillon.ms by ArpaGateway.ms ; 25 MAY 88 10:33:02 PDT Date: Wed, 25 May 88 10:28 PDT From: Gregor.pa@Xerox.COM Subject: PCL in Genera 7.2 To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880525172812.4.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no There is a new version of rel-7-2-patches.lisp on parcvax.xerox.com. I believe this new version of this file is all that is needed to make PCL work in Genera 7.2. -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 May 88 14:11:11 EDT Date: 24 May 88 1105 PDT From: Dick Gabriel Subject: Callable Methods To: common-lisp-object-system@SAIL.Stanford.EDU I am aware of the proposed ontology of method objects, but I think we need to carefully think about how much of the hierarchy to uniquely specify in Ch3. That is, method objects are things that on the surface could be callable. Therefore, maybe the metaclass should be something distinct from from standard-class, but with the proviso that it is acceptable to either identify this metaclass with standard-class or to hang it under funcallable-standard-class. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 May 88 13:49:03 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 24 May 88 10:44:23 PDT Received: from Semillon.ms by ArpaGateway.ms ; 24 MAY 88 10:43:29 PDT Date: Tue, 24 May 88 10:43 PDT From: Gregor.pa@Xerox.COM Subject: Re: Method Objects are not Functions To: Dick Gabriel cc: common-lisp-object-system@SAIL.Stanford.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: The message of 23 May 88 23:32 PDT from Dick Gabriel Message-ID: <19880524174313.4.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: 23 May 88 23:32 PDT From: Dick Gabriel I don't understand the reasoning that would argue that a method object a priori cannot be a function. The metaclass of a method object is standard-class. Standard-class does not support the behavior which allows its metainstances to be funcallable objects. Only funcallable-standard-class does that. I suppose that some implementation could extend standard-class to do that, but I don't see that as a freedom we really need to allow. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 24 May 88 09:45:03 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 24 MAY 88 06:34:52 PDT Return-Path: Redistributed: commonloops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 24 MAY 88 06:33:37 PDT To: Timothy.Freeman%proof.ergo.cs.cmu.edu@vax.bbn.com cc: commonloops.pa@Xerox.COM Subject: Re: Keywords in make-instance? In-reply-to: Your message of Fri, 20 May 88 18:01:07 -0400. <3067.580168867@PROOF.ERGO.CS.CMU.EDU> Date: Tue, 24 May 88 09:29:10 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880524-063452-6402@Xerox> Pros for first choice: User doesn't have to mess with packages as much. Cons against first choice: If the keywords are the same as the names of slots, then forgetting the package may create collisions. You eventually have to face up to the issue of packages. If you go with :keywords you should warn the user about collisions somehow. Any others? CLOS lets you go either way. Why not make the initarg be the same as the accessor that way the users only need to remember 1 name. k  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 May 88 02:37:59 EDT Date: 23 May 88 2332 PDT From: Dick Gabriel Subject: Method Objects are not Functions To: common-lisp-object-system@SAIL.Stanford.EDU I don't understand the reasoning that would argue that a method object a priori cannot be a function. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 20:02:34 EDT Date: 23 May 88 1659 PDT From: Dick Gabriel Subject: Chapter 1 To: common-lisp-object-system@SAIL.Stanford.EDU The versions of Chapter 1 that are being sent to X3J13 are now on [cls,lsp] on SAIL. You know what it is; you know what to do. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 19:52:20 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 May 88 16:49:04 PDT Received: from Semillon.ms by ArpaGateway.ms ; 23 MAY 88 16:46:23 PDT Date: Mon, 23 May 88 16:46 PDT From: Gregor.pa@Xerox.COM Subject: Re: Mlynarik's comments To: Dick Gabriel cc: common-lisp-object-system@SAIL.Stanford.EDU Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: The message of 21 May 88 00:17 PDT from Dick Gabriel Message-ID: <19880523234612.1.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: 21 May 88 00:17 PDT From: Dick Gabriel Richard writes: ``1-22 2nd PP in `Intro to methods': The first and second sentences seem to be too directly contradictory. I would change the first to ``A method object is not NECESSARILY a function an IN GENERAL cannot be invoked as a function.'' '' The sentences in question are: ``A method object is not a function and cannot be invoked as a function. An implementation may extend the \OS\ so that method objects are functions.'' The reason it is stated this way is that no one writing portable code can take them to be functions, but we do not require them to not be functions in all implementations. Actually, the second sentence is wrong. We do prohibit them from being functions in all implementations. Chapter 3 is very clear on this issue. Methods are instances of the class standard-method which itself is an instance of standard-class. We should delete the second sentence. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 May 88 19:48:56 EDT Received: from Semillon.ms by ArpaGateway.ms ; 23 MAY 88 16:42:45 PDT Date: Mon, 23 May 88 16:41 PDT From: Gregor.pa@Xerox.COM Subject: test message 1 To: CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest Message-ID: <19880523234103.0.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no This is just a test message. I recently added a bunch of people to the list and this is to see how many of them work. Please forgive the inconvenience. Gregor -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 19:44:06 EDT Date: 23 May 88 1633 PDT From: Dick Gabriel Subject: check-keyword-arguments To: common-lisp-object-system@SAIL.Stanford.EDU function-arguments is a typo for function-keywords. That's what I get for talking on the phone while typing mail. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 19:34:15 EDT Date: 23 May 88 1600 PDT From: Linda DeMichiel Subject: check-keyword-arguments etc. To: moon@STONY-BROOK.SCRC.SYMBOLICS.COM, common-lisp-object-system@SAIL.Stanford.EDU From: David A. Moon Subject: check-keyword-arguments Date: 23 May 88 1234 PDT From: Dick Gabriel The two functions, compute-applicable-methods and function-arguments, will appear in chapter 2. The inline code for make-instance will appear in chapter 3. Is the name function-arguments a typo? Yes. It is called function-keywords in the draft that just went out to the printers. There are new chapter 2 files out on sail with these additions. There is also a new macros file that should fix the [Primary Method] formatting bug. -lgd  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 18:48:17 EDT Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 23 May 88 15:37:56 PDT Received: by labrea.stanford.edu; Mon, 23 May 88 15:37:54 PDT Received: from bhopal.lucid.com by edsel id AA01958g; Mon, 23 May 88 15:29:01 PDT Received: by bhopal id AA01677g; Mon, 23 May 88 15:32:51 PDT Date: Mon, 23 May 88 15:32:51 PDT From: Jon L White Message-Id: <8805232232.AA01677@bhopal.lucid.com> To: Moon@stony-brook.scrc.symbolics.com Cc: common-lisp-object-system@sail.stanford.edu In-Reply-To: David A. Moon's message of Sat, 21 May 88 19:04 EDT <19880521230422.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Subject: Comments on current state of Initialization. re: Date: Sat, 21 May 88 06:44:29 PDT From: Jon L White Why should there still be three initialization protocls: "shared- initialize", "initialize-instance", and "reinitialize-instance"? [Summary: replace reinitialize-instance with a keyword argument to initialize-instance --Moon] Two reasons come immediately to mind: shared-initialize is also used when a class is redefined or change-class is called; . . . It seemed obvious to me that the "internal" callers from change-class etc. could just as easily use a simpilifed definition of initialize-instance with keyword argument. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 18:45:55 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 May 88 15:37:00 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 409032; Mon 23-May-88 18:37:03 EDT Date: Mon, 23 May 88 18:36 EDT From: David A. Moon Subject: check-keyword-arguments To: Dick Gabriel cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 23 May 88 15:34 EDT from Dick Gabriel Message-ID: <19880523223659.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 23 May 88 1234 PDT From: Dick Gabriel The two functions, compute-applicable-methods and function-arguments, will appear in chapter 2. The inline code for make-instance will appear in chapter 3. Is the name function-arguments a typo?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 23 May 88 16:10:41 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 23 MAY 88 12:50:55 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 23 MAY 88 12:49:50 PDT Received: from snail.sun.com ([129.145.1.3]) by Sun.COM (4.0/SMI-4.0) id AA09132; Mon, 23 May 88 12:48:02 PDT Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2) id AA26295; Mon, 23 May 88 12:45:08 PDT Received: by clam.sun.com (3.2/SMI-3.2) id AA21012; Mon, 23 May 88 12:50:01 PDT Date: Mon, 23 May 88 12:50:01 PDT From: cperdue@Sun.COM (Cris Perdue) Message-Id: <8805231950.AA21012@clam.sun.com> To: commonloops.pa@Xerox.COM, piazza%lisp.DEC@decwrl.dec.com Subject: Re: PCL on VAXLisp Ver 2.0 > ...doesn't work. (due to implementation-specific code in walk.lsp) I've proposed portable code for handling MACROLET (and use it myself with Lucid's and Franz's Common Lisps). Has anyone tried it? Such a thing would help in cases like this. -Cris  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 16:01:23 EDT Date: 23 May 88 1234 PDT From: Dick Gabriel Subject: check-keyword-arguments To: common-lisp-object-system@SAIL.Stanford.EDU The two functions, compute-applicable-methods and function-arguments, will appear in chapter 2. The inline code for make-instance will appear in chapter 3. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 15:24:49 EDT Date: 23 May 88 1211 PDT From: Dick Gabriel Subject: Define-Method-Combination To: common-lisp-object-system@SAIL.Stanford.EDU I basically agree with Moon's replies to Richard's concerns. On the topic of the added option to define-method-combination: define-method-combination should accept an option (:generic-function ) and bind to the relevant generic function. I don't like the name ``:generic-function'' but I cannot think of a better one. We're moving compute-applicable-methods and function-keywords into chapter 2 today, so this wrinkle is minor. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 14:14:14 EDT Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 23 May 88 11:05:46 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191680; Mon 23-May-88 14:05:18 EDT Date: Mon, 23 May 88 14:05 EDT From: David A. Moon Subject: Re: define-method-combination To: kempf@Sun.COM cc: Richarrd MLYnaRIk , common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8805231533.AA04572@suntana.sun.com> Message-ID: <19880523180527.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 23 May 88 08:33:01 -0700 From: kempf@Sun.COM More importantly for commercial purposes, C++. That's the competition. While it is unlikely that we will be able to get performance comparible to C++ on the first round, given your Sufficiently Smart compiler, it should be possible to approach it. Whether a Sufficiently Smart CLOS compiler happens, however, is again a question of priorities. I agree with you, but would like to point out that I don't think the existence of method combination has any bearing on the issue. I think multiple inheritance and slot access are the areas that cause more performance impact compared to C++. Furthermore I think the real performance issues are entirely outside of CLOS, in areas such as garbage collection and other things that Lisp does for you but C++ does not, and in the fact that the performance comparison is likely to be on C's "home turf", hardware that is highly adapted for C and less well adapted for Lisp.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 14:06:28 EDT Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 23 May 88 10:55:02 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191675; Mon 23-May-88 13:54:24 EDT Date: Mon, 23 May 88 13:54 EDT From: David A. Moon Subject: define-method-combination To: Richarrd MLYnaRIk cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880522022721.6.MLY@PERON.AI.MIT.EDU> Message-ID: <19880523175424.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Sat, 21 May 88 22:27 EDT From: Richarrd MLYnaRIk Before I launch into the usual tirade, I'd like to make a suggestion which might have some hope of being considered: define-method-combination should accept an option (:generic-function ) and bind to the relevant generic function. This has much the same flavour as the existing :arguments option. I think that this is a nicer solution than binding a magic variable named `generic-function'. I agree. I think this just got overlooked when :arguments was added, because before that there wasn't any agreed-upon syntax for saying things like this. Group: Is there still time to change this? .... On the other hand, as long as I've been using lisp machines (up to this very day) I've encountered combined methods which weren't caught at compile-time. And as long as I've been using Lisp, I've encountered files that use a macro that has been changed, but no one remembered to recompile the file, so the caller of the macro was not updated. Few people propose to remove macros from Lisp for that reason. I just don't think your argument is relevant. .... My overall fear is that this sort of approach will create two classes of programs -- those which use the system's predefined method combination types and standard method definition (such as defmethod with :method-class standard-method) and those which use anything else. The first class of programs can expect a much higher level of support than the latter, because the compiler has been taught special tricks. I agree that that could happen, but I see no reason why it must. I like to think that one of the aims of CLOS in general (though Chapter 3-style specifications) is to expose as much of the underlying works as is necessary to allow non-`standard' classes/method-combination/etc to be able to expect a level of support which is at least of the same order of magnitude as that provided by the system. This certainly does not seem to be the case with user-defined method-combination types. I agree with your first sentence, but don't see why you think user-defined method-combination types are any different from anything else. Also, you've changed your argument. First you said user-defined method combination types require the existence of a compiler at load time (and implicitly you assumed that all Lisps are like most of today's (but not the 1950's!) Lisps, in that if you have a compiler at load time, you cannot get rid of it at run time). Now you're saying that user-defined method combination won't compile as efficiently as standard method combination, an entirely different argument. I think your new argument is analogous to saying that it's better to use DO than LOOP, not because you like the syntax better, but because DO as a built-in macro is likely to compile more efficient code than LOOP, as a user-defined macro. That's even true to some extent with some compilers, but few people change their whole programming style on the basis of that kind of consideration, and in all the arguments against LOOP I've heard over the years, I don't recall ever hearing that one. I really believe that method combination is just like a macro. However, if user-defined method combination is to be a toy which works 1/1000th as well as system-defined method combination (because it has to call out to the evaluator or otherwise do a bunch of unnecessary hair at run time or require the presence of a full lisp compiler) Please, please, please do not be confused by the interpreter-oriented presentation, any more than you would be confused by a Lisp textbook which explained the language in interpretive terms and only introduced the compiler in a late chapter. Semantics are easier to explain interpretively, but no one proposes calling out to the evaluator in any real implementation. then why bother specifying it at all? I'm sure most people will be happy with a few standard method combination types -- why clutter up the world and raise people's expectations with something which can't be guaranteed to work very well? Change "method combination type" to "macro" and read your argument again. Of course, there are people in the Scheme community who believe that argument. I think Common Lisp is way past aspiring to that level of purity, though. I don't believe Moon's argument that something less than a full lisp evaluator will do to interpret user-defined effective methods -- it is trivial to define a method combination type (and not even a particularly contrived one) which will defeat this. Of course. It's also trivial to write a program that cannot be compiled. In practice, people who care about the issue you're concerned with don't do those things.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 13:57:09 EDT Date: 23 May 88 1047 PDT From: Dick Gabriel Subject: More Check-Keyword-Arguments To: common-lisp-object-system@SAIL.Stanford.EDU I have no problems with compute-applicable-methods and function-keywords being in chapter 2, except that we are on top of the two-week rule and have to blast out to make it. Function-keywords is a good name because it is a generic function, and some Common Lisps might extend it to CL functions. I preferred valid-keywords because it did not talk about either functions or methods. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 13:41:59 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 May 88 09:48:04 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 23 MAY 88 09:47:58 PDT Date: 23 May 88 09:46 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: check-keyword-arguments In-reply-to: Dick Gabriel 's message of 20 May 88 22:06 PDT To: RPG@SAIL.Stanford.EDU cc: common-lisp-object-system@SAIL.Stanford.EDU Message-ID: <880523-094758-4593@Xerox> I am happy to see this version of make-instance PROVIDED we put compute-applicable-methods and function-keywords in chapter 2. I think both provide features which are useful to programmers working with CLOS as it stands rather than with possibly extending the system. compute-applicable-methods is parallel to find-method, and function-keywords is similar to method-qualifiers, both of which are in chapter 2. I mildly prefer the name method-keywords since its argument is a method.I would also suggest find-applicable-methods to parallel find-method.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 11:51:09 EDT Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 23 May 88 08:42:19 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA04663; Mon, 23 May 88 08:41:00 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA15995; Mon, 23 May 88 08:38:27 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA04572; Mon, 23 May 88 08:33:04 PDT Message-Id: <8805231533.AA04572@suntana.sun.com> To: Richarrd MLYnaRIk Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: define-method-combination In-Reply-To: Your message of Sat, 21 May 88 22:27:00 -0400. <19880522022721.6.MLY@PERON.AI.MIT.EDU> Date: Mon, 23 May 88 08:33:01 -0700 From: kempf@Sun.COM >On the other hand, as long as I've been using lisp machines (up to this >very day) I've encountered combined methods which weren't caught at >compile-time. So I suppose we should say that we would have Flavors as >existence proof in principle... Unfortunately, I suspect that you may be right about this. However, I don't necessarily believe that this makes user defined method combination types useless. Certainly, for prototype or experimental code, where performance is not as critical, they should be useful. And CLOS has been designed with the needs of experimentalists in mind. There may even be some applications which don't mind having a full evaluator or compiler around. In fact, how many Lisp applications run today *without* a full evaluator or compiler around (rhetorical question, very few I suspect). >I realize that CLOS is only specifying semantics, but why make things >harder than they need be, so hard they they need a Sufficiently Smart >Compiler Sufficiently Useful Magic-Unspecified-Declarations/ >Sufficiently Powerful Magic-Unspecified-Pattern-Matching-Language/ etc? >(For years there has been talk about sufficiently smart compilers taking >all of my troubles away, but I've yet to see evidence of such things.) When somebody manages to convince a funding agency like DARPA that research on advanced Lisp compilers is important, it will happen. Until then, forget it. Lots of people have plenty of ideas about how to make Lisp compilers Sufficiently Smart, unfortunately, maintenance of existing compilers, addition of features (like multiprocessing) and environmental support have taken precedence in the commercial field, because that is what customers are asking for. The way things are currently going, we should be happy if a product quality CLOS is available within a reasonable amount of time, and I'm not talking about the technical side of implementing it. >My overall fear is that this sort of approach will create two classes of >programs -- those which use the system's predefined method combination >types and standard method definition (such as defmethod with >:method-class standard-method) and those which use anything else. The >first class of programs can expect a much higher level of support than >the latter, because the compiler has been taught special tricks. I like >to think that one of the aims of CLOS in general (though Chapter 3-style >specifications) is to expose as much of the underlying works as is >necessary to allow non-`standard' classes/method-combination/etc to be >able to expect a level of support which is at least of the same order of >magnitude as that provided by the system. This certainly does not seem >to be the case with user-defined method-combination types. This is a goal, however, there is a real question of how much the underlying works can be exposed without constraining the implementation so much that the standard system defined generic functions and method combinations can't be compiled efficiently. Unless someone does an existence proof, it is unlikely that we will really know, because a paper specification might miss something important. After having tuned up PCL, I know that the level of metaobject support in PCL can be implemented very efficiently on stock hardware, however, the version of PCL I used didn't have method combination, much less user defined method combination. Of course, any attempt to add additional features invalidates the existence proof. >I guess Scheme has gone badly to my brain -- the mere hint of run-time >evaluation/compilation makes me feel ill (the symptoms are flames coming More importantly for commercial purposes, C++. That's the competition. While it is unlikely that we will be able to get performance comparible to C++ on the first round, given your Sufficiently Smart compiler, it should be possible to approach it. Whether a Sufficiently Smart CLOS compiler happens, however, is again a question of priorities. jak  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 23 May 88 09:55:07 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 23 May 88 06:44:34 PDT Received: by ti.com id AA26663; Mon, 23 May 88 08:43:54 CDT Received: from Jenner by tilde id AA28453; Mon, 23 May 88 08:31:19 CDT Message-Id: <2789386229-306446@Jenner> Date: Mon, 23 May 88 08:30:29 CDT From: Patrick H Dussud To: Dick Gabriel Cc: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: check-keyword-arguments In-Reply-To: Msg of 20 May 88 2206 PDT from Dick Gabriel Date: 20 May 88 2206 PDT From: Dick Gabriel Subject: check-keyword-arguments (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (let* ((proto (class-prototype class)) (methods (append (compute-applicable-methods #'allocate-instance `(,class)) (compute-applicable-methods #'initialize-instance `(,proto)) (compute-applicable-methods #'shared-initialize `(,proto nil))))) (unless (subsetp (let ((keys '())) (do ((plist initargs (cddr plist))) ((null plist) keys) (push (car plist) keys))) (union (class-slot-initargs class) (reduce #'union (mapcar #'function-keywords methods)))) (error ...))) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance)) I agree, expect that the second value returned by function-keywords needs to be looked at. Something like this would work (I think): (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (let* ((proto (class-prototype class)) (methods (append (compute-applicable-methods #'allocate-instance `(,class)) (compute-applicable-methods #'initialize-instance `(,proto)) (compute-applicable-methods #'shared-initialize `(,proto nil))))) (unless (block check-keys (let ((valid-keys (class-slot-initargs class))) (dolist (method methods) (multiple-value-bind (keys allow-other-keys-p) (function-keywords method) (if allow-other-keys-p (return-from check-keys t) (setf valid-keys (union keys valid-keys))))) (subsetp (let ((keys '())) (do ((plist initargs (cddr plist))) ((null plist) keys) (push (car plist) keys))) valid-keys))) (error ...))) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance)) Patrick.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 May 88 22:32:33 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 21 May 88 19:23:33 PDT Received: from PERON.AI.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 21 May 88 22:24-EDT Date: Sat, 21 May 88 22:27 EDT From: Richarrd MLYnaRIk Subject: define-method-combination To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880521230158.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <19880522022721.6.MLY@PERON.AI.MIT.EDU> Before I launch into the usual tirade, I'd like to make a suggestion which might have some hope of being considered: define-method-combination should accept an option (:generic-function ) and bind to the relevant generic function. This has much the same flavour as the existing :arguments option. I think that this is a nicer solution than binding a magic variable named `generic-function'. ====================================================================== I only partially believe what Moon says about define-method-combination. On the whole, I find his arguments unfortunate sorts of thing to have to claim, especially when there are another ways of declaring method combination this which avoids this sort of problem. (By constructing closures rather than s-expressions.) I do believe his arguments as applied to system-predefined method-combination -- after all, and as he says, we have Flavors as an existence proof. On the other hand, as long as I've been using lisp machines (up to this very day) I've encountered combined methods which weren't caught at compile-time. So I suppose we should say that we would have Flavors as existence proof in principle... I very much doubt that a user will in fact be able to declare enough to the system to generate the same quality of code as the specially- recognised predefined system method combination types -- let alone that s/he would be able to declare this is any portable way! I realize that CLOS is only specifying semantics, but why make things harder than they need be, so hard they they need a Sufficiently Smart Compiler Sufficiently Useful Magic-Unspecified-Declarations/ Sufficiently Powerful Magic-Unspecified-Pattern-Matching-Language/ etc? (For years there has been talk about sufficiently smart compilers taking all of my troubles away, but I've yet to see evidence of such things.) My overall fear is that this sort of approach will create two classes of programs -- those which use the system's predefined method combination types and standard method definition (such as defmethod with :method-class standard-method) and those which use anything else. The first class of programs can expect a much higher level of support than the latter, because the compiler has been taught special tricks. I like to think that one of the aims of CLOS in general (though Chapter 3-style specifications) is to expose as much of the underlying works as is necessary to allow non-`standard' classes/method-combination/etc to be able to expect a level of support which is at least of the same order of magnitude as that provided by the system. This certainly does not seem to be the case with user-defined method-combination types. (I know there are limits to this argument -- for example I doubt that J. Random Generic-function Metaclass could expect the same performance as implementation-tuned standard-generic-function.) However, if user-defined method combination is to be a toy which works 1/1000th as well as system-defined method combination (because it has to call out to the evaluator or otherwise do a bunch of unnecessary hair at run time or require the presence of a full lisp compiler) then why bother specifying it at all? I'm sure most people will be happy with a few standard method combination types -- why clutter up the world and raise people's expectations with something which can't be guaranteed to work very well? Especially, why clutter the world so much the EVAL becomes required (when nothing else in CLtL except for the section on the evaluator seems to require such a horrible thing)? BTW I've looked at the pattern-matchers (by no means ``the world's simplest'' -- PCL's uses a real code-walker) in both PCL and Flavors and still doubt that they can do enough before they become full lisp compilers. (When Flavor's pattern-matcher punts, it ends up calling compile.) I don't believe Moon's argument that something less than a full lisp evaluator will do to interpret user-defined effective methods -- it is trivial to define a method combination type (and not even a particularly contrived one) which will defeat this. I guess Scheme has gone badly to my brain -- the mere hint of run-time evaluation/compilation makes me feel ill (the symptoms are flames coming from the mouth.) There is another reason, though: I have recently had very bad experiences with a very large piece of software which suffered and suffered (and made me suffer) because of the way it called out to the evaluator. Anyway, this whole issue was originally filed under the ``Just to be contentious'' label -- I didn't expect and still do not expect to convince anybody. I am not going to continue to flame about this.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 May 88 19:12:08 EDT Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 21 May 88 16:04:55 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191453; Sat 21-May-88 19:04:12 EDT Date: Sat, 21 May 88 19:04 EDT From: David A. Moon Subject: Comments on current state of Initialization. To: Jon L White cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <8805211344.AA08392@bhopal.lucid.com> Message-ID: <19880521230422.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Sat, 21 May 88 06:44:29 PDT From: Jon L White Why should there still be three initialization protocls: "shared-initialize", "initialize-instance", and "reinitialize-instance"? [Summary: replace reinitialize-instance with a keyword argument to initialize-instance --Moon] Two reasons come immediately to mind: shared-initialize is also used when a class is redefined or change-class is called; reinitialize-instance is to be called directly by the user, but initialize-instance cannot be (review how the keyword arguments get validated).  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 May 88 19:10:32 EDT Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 21 May 88 16:02:23 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191452; Sat 21-May-88 19:01:56 EDT Date: Sat, 21 May 88 19:01 EDT From: David A. Moon Subject: define-method-combination To: Richard MlYNarIk cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880521191828.5.MLY@PERON.AI.MIT.EDU> Message-ID: <19880521230158.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Sat, 21 May 88 15:18 EDT From: Richard MlynBaOrik [common-lisp-object-system@SAIL.STANFORD.EDU removed] [Added back since I thought it was useful for the whole list to see the reply. I don't expect I'm embarrassing you.] Date: Fri, 20 May 88 20:02 EDT From: David A. Moon * I find the `evalness' of define-method-combination very disturbing. It seems to me that a full lisp compiler or evaluator will need to be present in any world into are loaded methods on generic functions which use user-defined method-combination. I would -very- much like to be convinced that this isn't the case. I don't understand your point. How is define-method-combination different from defmacro in this respect? Perhaps you've been misled by the way the spec describes everything as if it was interpreted into thinking that it cannot be compiled? I'm wondering how add-method works. If one does a random add-method to a generic function (say by loading a file containing a defmethod form) then whenever the combined (`effective') method is created (at instance instantiation time or whenever) something has got to look at the lisp code produced by the `macroexpansion' of a define-method-combination form. This macroexpasion can't be performed any earlier, because it depends on the applicable methods. That's quite a reasonable concern to have, however we've thought of it. The compiler can anticipate what add-method calls are going to be produced by forms the compiler has seen, such as defmethod forms. The code resulting from method-combination can be predicted at compile time and compiled then, with a simple mechanism to make sure at load time that that pregenerated code gets used. This is how it works in Flavors, so that's an existence proof. Of course if a program calls add-method at run time in a way the compiler can't anticipate, such techniques can't win. But I'd say that kind of program, which changes its structure at run time, should not be surprised to depend on having a compiler at run time. As I see it, either the lisp evaluator is used whenever the combined method is called or else the lisp code produced by define-method-combination has to be turned into something executable by `the machine.' It's also true that an evaluator different from the Lisp evaluator can be used. For example, the form returned by the method combination function can be recognized as an instance of a pattern and the effective method can be a closure of a preexisting function that knows how to "evaluate" such forms; the enclosed variables typically have methods or lists of methods as their values. The preexisting functions can even be generated automatically when the system is compiled, from declarative specifications (arrange for x type of method combination to work with n applicable methods in role z). Some types of method combination work this way in Flavors in 7.2 [oh, I see you know that], and I'm told PCL also works this way. I assume that CLOS can work this way, too, using the world's simplest pattern matcher to recognize forms returned by method combination functions.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 May 88 10:00:25 EDT Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 21 May 88 06:51:05 PDT Received: by labrea.stanford.edu; Sat, 21 May 88 06:51:30 PDT Received: from bhopal.lucid.com by edsel id AA20037g; Sat, 21 May 88 06:40:47 PDT Received: by bhopal id AA08392g; Sat, 21 May 88 06:44:29 PDT Date: Sat, 21 May 88 06:44:29 PDT From: Jon L White Message-Id: <8805211344.AA08392@bhopal.lucid.com> To: common-lisp-object-system@sail.stanford.edu Subject: Comments on current state of Initialization. Why should there still be three initialization protocls: "shared-initialize", "initialize-instance", and "reinitialize-instance" (sp?). Why not just "initialize-instance" with a keyword argument for whether or not it is a first-time initialization? In each case, the specialization needed is over the instance, and not over the slots-for-initforms argument, or the initargs argument, or any other arugment. And so _most_ of the processing will be the same regardless of whether the caller is make-instance or one of the update-instance-for--class functions (i.e., whether initializing afresh or whether re-initializing). In fact, for many classes I would guess that the particular list given as the 'slots-for-initforms' argument would adequately cover any necessary distinctions between fresh allocation and "update-instance-for--class". Direct user calls, if any, could pass this keyword argument, rather than decide between two differently named functions. I presume that the main primary method is the one whose chief purpose is to set slots, first from the initargs and then from the initforms, and that this wouldn't need to be modified by the user. [In fact, letting the user change this primary method is probably a mistake.] Again, I would guess that most user :after methods wouln't be concerned with the distinction between "fixing up" the initialization of a fresh instance, and that of "fixing up" the re-setting of slots on an "old" instance; in each case, the more important information is in the 'slots-for-initforms' argument. In short, what I fail to see is any justification for hairing up the protocol to inject a generic function that seems to have no particular user benefit: reinitialize-instance. Looking over back mail, I find this one comment from Danny: Date: 8 Apr 88 15:37 PDT From: Danny Bobrow Subject: Re: (re)initialization revisited In-Reply-To: kempf@Sun.COM's message of Thu, 07 Apr 88 12:13:45 -0700 To: kempf@Sun.COM Cc: common-lisp-object-system@SAIL.STANFORD.EDU Jim proposes removing some functions in the spec. I sympathize with this as a general goal. But in this case I think it is misguided. There are really four concepts 1) initializate (make a brand new instance have the right state) 2) reinitialize (make an old instance have a "standard" starting state) 3) class-changed (make a change from one form of current instance to another) 4) update-instance-structure (make an appropriate current instance from an outdated instance. Because there are four concepts, there must be four entries so that users can change what is done for each. Collapsing concepts into a commonly named fn just causes confusion. . . . Reinititializing must potentially take into account old values on slots. Initialization never has to. We introduced the general concept because we had two examples in CLOS itself that require it: instances of standard-class, and instances of standard-generic-function. Both must take into account previous state of the objects to be changed. But still, this is not justification for imposing a complexity that will almost never be used by the end user, and for which there is an adequate alternative: keyword argument to initialize-instance. Note that there is no need to split off re-initialization due to a difference in the ways in which it might be specialized. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 May 88 03:28:04 EDT Date: 21 May 88 0017 PDT From: Dick Gabriel Subject: Mlynarik's comments To: common-lisp-object-system@SAIL.Stanford.EDU First I'll address the general grammatical comments. As far as I can tell by reading the OED, ``congruent with'' is standard British English. Using Webster's Second Unabridged - the most prescriptive American English dictionary - I find ``congruent with'' used in general contexts and in most mathematical contexts. My perusal of math texts seems to indicate ``congruent to'' is acceptable when discussing number theory. I cannot find explicit grammatical justification for ``congruent to'' in any context. Because we are not talking about number theory, I don't believe any changes are necessary. It is currently correct to use the following rules for ``different'': The phrase ``different from'' is used when introducing a phrase while ``different than'' is used when introducing a clause. My references claim ``different from'' and ``different than'' have both appeared for the last 300 years. British usage admits ``different to.'' Note there is no use of ``different than'' (or ``different from'') in chapter 1. To comment further on the grammar in chapters 1 and 2. Linda and I are both relatively careful writers in terms of grammar, and I can assure you that we have not dashed off this piece. Furthermore, we have engaged copy editors to proofread major drafts of these chapters before they are sent out. The style of writing might be academic, but I believe it corresponds to acceptable Amercian English in all cases, and even the editors of the OED now accept American usage as standard. The remainder of this message is a response to Richard's comments. I have left out specific comments to which Moon responded with remarks with which I agree. Richard writes: ``1-22 2nd PP in `Intro to methods': The first and second sentences seem to be too directly contradictory. I would change the first to ``A method object is not NECESSARILY a function an IN GENERAL cannot be invoked as a function.'' '' The sentences in question are: ``A method object is not a function and cannot be invoked as a function. An implementation may extend the \OS\ so that method objects are functions.'' The reason it is stated this way is that no one writing portable code can take them to be functions, but we do not require them to not be functions in all implementations. If we wrote it your way then someone could legitimately understand that within a single implementation a particular method object may or may not be a function. The style we use consistently throughout is to state a constraint and then allow extensions. Richard writes: ``1-25 To this reader, the statement in the 4th enumerated PP that ``The checking of the validity of keyword names is done in the generic function, not in each method'' seems inconsistent with the second PP on 1-26 ``If a method is passed a keyword argument is does not accept, an error is signaled.'' Is the indent to draw some distinction between &key args from DEFGENERIC and those which come from random DEFMETHODs? If so, this should be made a lot clearer.'' Moon's remark is correct and the passage has been repaired. Richard writes: ``1-31 2nd PP. ``to the :method-combination option to defgeneric or TO THE :METHOD-COMBINATION OPTION TO any of the other forms that specify generic function options.'' The uppercase text seems redundant.'' It is redundant and intentionally so: You cannot possibly misread the current version. A misreading would be ``To specify that a generic function is to use one of these method combination types, the name of the method combination type is given as the argument ... to any of the other forms that specify generic function options.'' Richard writes: ``1-31 5th PP. I would replace this with ``The simple build-in method combination types COULD HAVE BEEN defined...'' '' ``Could have been'' but weren't? Your rewrite talks about an implementation choice that may or may not be relevant, whereas the current language discusses semantics. Richard writes: ``1-32 '' I agree with Richard on the weirdness of this description, but I could not (and still cannot) think of a more precise approach to describing this. I have spent weeks on the bulleted item over the last 2 years. Richard writes: ``1-39 Last PP. I would write ``The second argument to shared-initialize may be one of the following:'' '' Right. Richard writes: ``1-39 The section `Shared-Initialize' The introduction of this section at this point seems very unmotivated. Nowhere above (except by implication of the `--'-bulleted PPs on 1-37) is it made clear that shared-initialize is an `underlying' method called by all the various (re)initialization methods. Some small preamble at the beginning of this section would make a first-time reading of the the spec somewhat easier.'' Right. I added such an introduction to shared-initialize early in the section. Richard writes: ``1-40 4th bulleted PP. It should be noted that ``This happens regardless of whether or not the slot is specified by the second argument.'' or something along those lines -- make it completely clear that this first step in initialization depends only on the &key initarg, not on the slot-name-specification arg. I'd also like to see a similar comment in the Chapter 2 doc for shared-initialize.'' Right. Richard writes: ``1-41 Last PP. What ``certain optimizations are permitted.'' Nothing is mentioned here or in the Chapter 2 description of initialize-instance to explain what these might be, any how they might affect writers of methods on initialize-instance or shared-initialize. The Chapter 2 description of shared-initialize explains this -- there should be some xref.'' I thought it already cross-references to shared-initialize. Richard writes: ``1-42 Last PP. I found this hard to read. Suggestion....'' This paragraph has been rewritten based on the newthink on the check-initargs problem. Richard writes: `` My feeling is that the vagueness in this section is very unpleasant, and quite inconsistent with the general precision in the rest of the document. I have some ideas on how to improve this, if there is any interest in re-opening this issue and in listening to them.'' Yes, I would like to hear your ideas. Richard writes: ``1-43 6th PP. The aside ``This two-step process ...'' disrupts the description of what the process is. Is should be moved below, after the sentence ``... and other user-defined actions.'' '' This paragraph is now different enough that this comment isn't as valid. In particular, other circumstances have been added in which the process can start up, and the discussion of when it can happen is the current focus of the paragraph. Richard writes: ``1-44 6th PP, 1-46 last PP, 1-48 4th PP. I find these incredibly disjointed. For starters, only half of the contract of the ``system-supplied primary method'' is mentioned -- the other half is to be found two paragraphs down -- in a different section! ....'' Good idea. I've so modified the sections. -rpg-  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 21 May 88 01:17:02 EDT Date: 20 May 88 2206 PDT From: Dick Gabriel Subject: check-keyword-arguments To: common-lisp-object-system@SAIL.Stanford.EDU I think Moon's suggestion for the name FUNCTION-KEYWORD is acceptable. Here is the corrected code (Having Moon around to read code is almost as good as having a computer. In fact, it's better because sometimes he cracks a joke.): (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (let* ((proto (class-prototype class)) (methods (append (compute-applicable-methods #'allocate-instance `(,class)) (compute-applicable-methods #'initialize-instance `(,proto)) (compute-applicable-methods #'shared-initialize `(,proto nil))))) (unless (subsetp (let ((keys '())) (do ((plist initargs (cddr plist))) ((null plist) keys) (push (car plist) keys))) (union (class-slot-initargs class) (reduce #'union (mapcar #'function-keywords methods)))) (error ...))) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 May 88 23:20:23 EDT Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 20 May 88 20:09:12 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191392; Fri 20-May-88 23:08:50 EDT Date: Fri, 20 May 88 23:08 EDT From: David A. Moon Subject: check-keyword-arguments To: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: The message of 19 May 88 19:13 EDT from Dick Gabriel Message-ID: <19880521030857.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 19 May 88 1613 PDT From: Dick Gabriel I want to present one more alternative to the initargs checking problem. [Getting rid of check-initargs & successors, writing the code inline, and putting it in chapter 3.] This sounds good to me, with a couple modifications suggested below. Let's go with it. We could introduce a new generic function called valid-keywords, which takes an object; if it is something with keywords (like a generic function, a method, or a function), valid-keywords returns two values: a list of the explicitly named keywords and a boolean which states whether &allow-other-keys had been specified in the definition. function-keywords would be a better name. Otherwise okay. I have no quarrel with the dual return values. [Yes, I know (subtypep 'method 'function) => nil t. Nonetheless, in this context the method is used in a functionesque way.] I assume method-applicable-keywords, p.27 of the most recent draft of ch.3 that I've seen (the one handed out at X3J13 in March), would go away. Then we could write make-instance like this: (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (let* ((proto (class-prototype class)) (methods (union (compute-applicable-methods #'allocate-instance `(,class)) (union (compute-applicable-methods #'initialize-instance `(,proto nil)) (compute-applicable-methods #'shared-initialize `(,proto)))))) I think you want append rather than union, since there won't be any methods in common between distinct generic functions. Also the args for initialize-instance and shared-initialize have accidentally gotten interchanged. (unless (subsetp (let ((keys '())) (do ((plist initargs (cddr plist))) ((null plist) keys) (push (car plist) keys))) (union (class-slot-initargs class) (reduce #'union (mapcar #'valid-keywords methods)))) (error ...))) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 May 88 20:13:06 EDT Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 20 May 88 17:03:03 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 408054; 20 May 88 20:02:25 EDT Date: Fri, 20 May 88 20:02 EDT From: David A. Moon Subject: Comments on new draft chapter 1 (dated May 13 20:53) To: Richard Mlynarik cc: common-lisp-object-system@SAIL.STANFORD.EDU In-Reply-To: <19880520213530.4.MLY@PERON.AI.MIT.EDU> Message-ID: <19880521000213.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 20 May 88 17:35 EDT From: Richard Mlynarik Comments on a subset of your comments, not to imply that the remainder should be ignored. In general I agree with them. 1-25 To this reader, the statement in the 4th enumerated PP that ``The checking of the validity of keyword names is done in the generic function, not in each method'' seems inconsistent with the second PP on 1-26 ``If a method is passed a keyword argument is does not accept, an error is signaled.'' Is the indent to draw some distinction between &key args from DEFGENERIC and those which come from random DEFMETHODs? If so, this should be made a lot clearer. I missed this one in my recent review of the document. I believe the word "method" in the 2nd pp on 1-26 is a typo and should be "generic function." Clearer would be "If a generic function is passed a keyword argument that no applicable method accepts, an error is signaled." Also, for consistency with the last paragraph on CLtL p.62, it should be "an error should be signaled" rather than "an error is signaled." Not that I am a fan of implementations that allow you to turn off error checking. 1-32 I don't follow. 1-33 Penultimate PP. I am probably just plain confused on this point, but is it possible that ``and instances of the classes standard-method, ...'' should read just ``the classes standard-method, ...''? The reference to standard-method in the following bulleted PP reinforces my probably-mistaken belief. No, the text is correct as it stands. Everything involving meta objects is inherently confusing because it's difficult to keep the two levels straight. 1-39 3rd PP. I question the use of the word ``captured'' (which occurs in other places in both Chapters 1 and 2.) ``Inherited'' seems more straight-forward to me. This is probably just a personal preference. "Captured" refers to lexical capturing, not class inheritance. I'm not sure it's necessary to repeat "captured" periodically; we could just leave it to the explanation on 1-10 and again on 1-35. 1-39 Table. The last line would seem to imply that the defaulted initlist must always be '(a 1 a 2 b 2), ruling out the `optimization' (a 1 b 2). Is this the intent? It seems to unnecessarily constrain the behaviour of default-initargs methods. "a 2" was not put in by defaulting, it was supplied explicitly by the caller. Given that, I don't think we want to change the table. 1-39 The section `Shared-Initialize' The introduction of this section at this point seems very unmotivated. Nowhere above (except by implication of the `--'-bulleted PPs on 1-37) is it made clear that shared-initialize is an `underlying' method called by all the various (re)initialization methods. Some small preamble at the beginning of this section would make a first-time reading of the the spec somewhat easier. The spec is deliberately made difficult to read to discourage people from making implementations without reading it slowly and carefully :-) At this point I suppose I might as well express my misgivings about the name `shared-initialize' -- it seems to imply to me something to do with `shared' (ie class-allocated) slots or something like that. For what it's worth, I'll state that the names `initialize-slots,' `basic-initialize' and even `common-initialize' (or even `initialize'!) appeal to me more than `shared-initialize.' The false connotation of shared slots is the same comment I had. However, all four of your suggested alternatives have problems, and we spent so much time trying to find a better name that I think we should go with the one we have for this round of the document, and let X3J13 instruct us to change it if they so desire. 1-40 First (bulleted) PP. What if the instance doesn't have a slot with named by one of the elements of the list? Is it ``an error?'' Is slot-missing called? You're right, we need to specify this. Let's make it "the results are unspecified." 1-41 Definition of make-instance. Is nobody else bothered by the fact that the use DEFAULT-INITARGS may be a consful operation in the presence of :default-initargs? It would be very easy for the evaluation of DEFAULT-INITARGS to consume more storage (to construct a merged initargs list) than that of ALLOCATE-INSTANCE does in creation of the instance itself! Of course. But the spec defines the semantics of the language, not how to do semantics-preserving implementation-dependent optimizations. I don't think complicating the specification to make it slightly more obvious how to optimizations is a good tradeoff. Also, with reasonable garbage collectors, which are starting to emerge even on traditional hardware, consing is not such a burden. Finally, just to be contentious (I'm not inviting replies): Yes, CLOS definitely has that design-by-committee aroma. * I find the `evalness' of define-method-combination very disturbing. It seems to me that a full lisp compiler or evaluator will need to be present in any world into are loaded methods on generic functions which use user-defined method-combination. I would -very- much like to be convinced that this isn't the case. I don't understand your point. How is define-method-combination different from defmacro in this respect? Perhaps you've been misled by the way the spec describes everything as if it was interpreted into thinking that it cannot be compiled?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 May 88 18:25:34 EDT Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 20 May 88 15:08:46 PDT Received: from PERON.AI.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 20 May 88 17:32-EDT Date: Fri, 20 May 88 17:35 EDT From: Richard Mlynarik Subject: Comments on new draft chapter 1 (dated May 13 20:53) To: common-lisp-object-system@sail.stanford.edu Message-ID: <19880520213530.4.MLY@PERON.AI.MIT.EDU> These comments come from someone who has been keeping an eye on the cl-o-o-p mail, but hasn't been reading the specs regularly and closely. I'm omitting remarks which would overlap those in <380679.880518.MOON@AI.AI.MIT.EDU> A general remark on all of the documents -- as a non-American and as something of a pedant I feel my blood-pressure rising every time I encounter ``congruent with'' or ``different than'' in the documents (as opposed to ``congruent to'' and ``different from'' respectively.) Is this really Standard American English? Another general remark is that Chapter 1 and Chapter 2 do not stand very well apart from Chapter 3 -- there are too many functions mentioned in passing which are never defined in any further fashion (or even mentioned again!) This certainly makes for rather hard reading and comprehension. 1-22 2nd PP in `Intro to methods': The first and second sentences seem to be too directly contradictory. I would change the first to ``A method object is not NECESSARILY a function an IN GENERAL cannot be invoked as a function.'' 1-25 To this reader, the statement in the 4th enumerated PP that ``The checking of the validity of keyword names is done in the generic function, not in each method'' seems inconsistent with the second PP on 1-26 ``If a method is passed a keyword argument is does not accept, an error is signaled.'' Is the indent to draw some distinction between &key args from DEFGENERIC and those which come from random DEFMETHODs? If so, this should be made a lot clearer. 1-31 2nd PP. ``to the :method-combination option to defgeneric or TO THE :METHOD-COMBINATION OPTION TO any of the other forms that specify generic function options.'' The uppercase text seems redundant. 1-31 5th PP. I would replace this with ``The simple build-in method combination types COULD HAVE BEEN defined...'' 1-32 1-33 Penultimate PP. I am probably just plain confused on this point, but is it possible that ``and instances of the classes standard-method, ...'' should read just ``the classes standard-method, ...''? The reference to standard-method in the following bulleted PP reinforces my probably-mistaken belief. 1-39 3rd PP. I question the use of the word ``captured'' (which occurs in other places in both Chapters 1 and 2.) ``Inherited'' seems more straight-forward to me. This is probably just a personal preference. 1-39 Table. The last line would seem to imply that the defaulted initlist must always be '(a 1 a 2 b 2), ruling out the `optimization' (a 1 b 2). Is this the intent? It seems to unnecessarily constrain the behaviour of default-initargs methods. 1-39 The section `Shared-Initialize' The introduction of this section at this point seems very unmotivated. Nowhere above (except by implication of the `--'-bulleted PPs on 1-37) is it made clear that shared-initialize is an `underlying' method called by all the various (re)initialization methods. Some small preamble at the beginning of this section would make a first-time reading of the the spec somewhat easier. At this point I suppose I might as well express my misgivings about the name `shared-initialize' -- it seems to imply to me something to do with `shared' (ie class-allocated) slots or something like that. For what it's worth, I'll state that the names `initialize-slots,' `basic-initialize' and even `common-initialize' (or even `initialize'!) appeal to me more than `shared-initialize.' 1-39 Last PP. I would write ``The second argument to shared-initialize may be one of the following:'' 1-40 First (bulleted) PP. What if the instance doesn't have a slot with named by one of the elements of the list? Is it ``an error?'' Is slot-missing called? 1-40 4th bulleted PP. It should be noted that ``This happens regardless of whether or not the slot is specified by the second argument.'' or something along those lines -- make it completely clear that this first step in initialization depends only on the &key initarg, not on the slot-name-specification arg. I'd also like to see a similar comment in the Chapter 2 doc for shared-initialize. 1-41 `Definitions of make-instance and initialize-instance' I think that it would make the manual a lot easier to read if similar sample definitions were provided for the other initializations methods (reinitialize-instance, update-instance-for-xxx, ...) I think that moving this section of sample definitions forward in the manual (perhaps before the `shared-initialize' section, perhaps even very early in `Objection Creation and Initialization') would provide much better understanding of what the various generic functions do. This would also somewhat alleviate my above-mentioned problems with the unmotivated appearance of `shared-initialize.' When I started reading from `Object Creation and Initialization' I encountered a whole slew of names of generic functions on which I would define methods, but no real reason for why I should want to do so for around 7 more pages. I personally find it much easier to be presented with an overall framework of code and then later `fill in the blanks' by reading what the purpose of the various functions are than to wade though pages of passing references to lots of functions before discovering how they fit together and how they are supposed to be useful. 1-41 Definition of make-instance. Is nobody else bothered by the fact that the use DEFAULT-INITARGS may be a consful operation in the presence of :default-initargs? It would be very easy for the evaluation of DEFAULT-INITARGS to consume more storage (to construct a merged initargs list) than that of ALLOCATE-INSTANCE does in creation of the instance itself! My first reaction to this is to suggest a definition like: (defmethod make-instance ((class standard-class) &rest initargs) (apply #'with-defaulted-initargs (lambda (&rest defaulted-initargs) ...initarg error-checking code... (let ((instance (apply #'allocate-instance class defaulted-initargs))) (apply #'initialize-instance instance defaulted-initargs) instance)) class initargs)) [where any implementation worth its salt would provide some way to declare the dynamic extent of the INITARGS argument and the LAMBDA-expression.] Of course there are other ways to do this sort of thing. I don't believe that the permissible optimizations mentioned are sufficient to stop me worrying about this point. So, has nobody else considered this issue, or does nobody else consider it an issue? 1-41 Last PP. What ``certain optimizations are permitted.'' Nothing is mentioned here or in the Chapter 2 description of initialize-instance to explain what these might be, any how they might affect writers of methods on initialize-instance or shared-initialize. The Chapter 2 description of shared-initialize explains this -- there should be some xref. 1-42 Last PP. I found this hard to read. Suggestion: ``As a result of various optimizations, not all of the functions and methods involved in initialization need necessarily be called on every call to {\bf make-instance} and, if called, they may not receive exactly the arguments that one would expect based on the sample implementation above.'' The example of a permitted optimization is bogus, because check-keyword-arguments is not a method, and so the user has no business redefining it, and so user methods have no way of telling whether it has already been called or not (since it is stated that it won't signal an error.) My feeling is that the vagueness in this section is very unpleasant, and quite inconsistent with the general precision in the rest of the document. I have some ideas on how to improve this, if there is any interest in re-opening this issue and in listening to them. 1-43 6th PP. The aside ``This two-step process ...'' disrupts the description of what the process is. Is should be moved below, after the sentence ``... and other user-defined actions.'' 1-44 6th PP, 1-46 last PP, 1-48 4th PP. I find these incredibly disjointed. For starters, only half of the contract of the ``system-supplied primary method'' is mentioned -- the other half is to be found two paragraphs down -- in a different section! Secondly, I don't think much would be lost be replacing each occurrence of the intrusively-long Initialization arguments are declared as valid by using the {\bf :initarg} option to {\bf defclass} or by defining methods for {\bf } or for {\bf shared-initialize}. See the section ``Declaring the Validity of Initialization Arguments'' for more information. with simply: (See the section ``Declaring the Validity of Initialization Arguments'' for more information.) Here's a suggested rewrite (I'd find code easier to read than this turgid techno-English any day...): There is a system-supplied primary method for {\bf update-instance-for-redefined-class} whose parameter specializer for its instance argument is the class {\bf standard-object}. This method first checks the validity of initialization arguments and signals an error if an initialization argument is supplied that is not declared as valid. (See the section ``Declaring the Validity of Initialization Arguments'' for more information.) Then it calls the generic function {\bf shared-initialize} with arguments of the instance, a list of names of the newly added slots, and the initialization arguments it received. The now-redundant second half of the descriptions of these methods (with appear in the ``Customizing foo'' sections) could be replaced by just Methods for {\bf shared-initialize} may be defined to customize class redefinition. See the section ``Shared-Initialize'' for more information. Finally, just to be contentious (I'm not inviting replies): * I'm still convinced (after two years (even after reading all the archived mail on the subject)) that optionals should be defaulted in the generic function rather than the methods.... Oh well. * I think it is a real loss that there is no way of specifying an `interface function' such as New Flavors has. The mess with the stupid optional arg for DOCUMENTATION methods in chapter 2 is an example of this. * I'm aware of the problems they entail -- however I still find it a pity that there is no provision for `private' methods and slots. * I find the omission of defclass :constructors to be a significant loss, based on past experience with implementing this sort of thing. * I rely upon and heavily use New Flavors defun-in-method. I don't see how I could get equivalent performance via the use of WITH-SLOTS (since I don't believe (the equivalent of) usage of a mapping table will be done outside of method bodies.) * I think that the use of STANDARD method combination for the various initialization methods is a mistake. It is too easy (for a ready example, see the mistake Moon pointed out in <380731.880518.MOON@AI.AI.MIT.EDU> about 2-15) to bash the useful system-defined method. It is not at all clear to me that it is ever useful to do this deliberately -- the only thing it could do (which could not be done by defining an `auxiliary' method on it or on shared-initialize) is inhibit error-checking. I hold that the `two-pass' method-combination used in Flavors for initialize-instance is the right sort of thing: initialize-instance and reinitialize-instance should use `progn-with-:after' method combination, and update-instance-for-redefined-class and update-instance-for-different-class should use `progn-with-:before' method combination (I can't think of a use for :after methods on these gf's.) Besides, use of non-STANDARD method-combination would actually show readers that all this method-combination hair is actually good for anything! * I find the `evalness' of define-method-combination very disturbing. It seems to me that a full lisp compiler or evaluator will need to be present in any world into are loaded methods on generic functions which use user-defined method-combination. I would -very- much like to be convinced that this isn't the case. * IWBNI GET and (SETF GET) were made generic, though I suppose the same sort of argument could be made for dozens of other CLtL functions.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 May 88 18:20:05 EDT Received: from Salvador.ms by ArpaGateway.ms ; 20 MAY 88 15:01:25 PDT Return-Path: Redistributed: commonloops.pa Received: from PROOF.ERGO.CS.CMU.EDU by Xerox.COM ; 20 MAY 88 14:59:33 PDT Received: from PROOF.ERGO.CS.CMU.EDU by PROOF.ERGO.CS.CMU.EDU; 20 May 88 18:01:10 EDT To: commonloops.pa@Xerox.COM Subject: Keywords in make-instance? Date: Fri, 20 May 88 18:01:07 EDT Message-ID: <3067.580168867@PROOF.ERGO.CS.CMU.EDU> From: Timothy.Freeman@PROOF.ERGO.CS.CMU.EDU Make-instance takes keyword arguments like this: (make-instance 'class :key1 arg1 :key2 arg2 ...) It could take ordinary symbols instead of keywords like this: (make-instance 'class 'key1 arg1 'key2 arg2 ...) I'm making an object-oriented system that has a similar syntax for make-instance, and I have a choice about which way to do it. Does anyone have any advice about the pros and cons of the two alternatives? I see these: Pros for first choice: User doesn't have to mess with packages as much. Cons against first choice: If the keywords are the same as the names of slots, then forgetting the package may create collisions. Any others?  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 May 88 13:07:04 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 MAY 88 09:54:59 PDT Date: Fri, 20 May 88 09:52 PDT From: Gregor.pa@Xerox.COM Subject: Re: clos in 7.2 To: kanderso@WILMA.BBN.COM cc: Jim Kelly , pcl-user@vax.bbn.com, CommonLoops.pa@Xerox.COM Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest In-Reply-To: The message of 20 May 88 08:53 PDT from kanderso@WILMA.BBN.COM Message-ID: <19880520165203.3.GREGOR@PORTNOY.parc.xerox.com> Line-fold: no Date: Fri, 20 May 88 11:53:35 -0400 From: kanderso@WILMA.BBN.COM Received: from vax.bbn.com by WILMA.BBN.COM id aa28791; 20 May 88 11:13 EDT Date: Fri, 20 May 88 11:13:22 EDT From: Jim Kelly To: kanderson@vax.bbn.com cc: pcl-user@vax.bbn.com Subject: clos in 7.2 A few weeks ago when we were discussing some clos/7.2 bugs gregor@xerox said alot of the hacks written to get it to work in 7.1 didn't work in 7.2 and to wait "a few days". Are we getting some new code which will fix 7.2 problems? Would it be good|ok|bad to start using clos/7.2 or to continue waiting for something? -Jim Unfortunately, I haven't heared anything. Perhaps you and Rich should try it again, so we can see how bad things really are. Here is his message, which gives a hint as to what the problems are: I am totally swamped right now, which is why I have been negligent answering PCL related mail. I have a version which runs in 7.2 which I will try to release next week after this deadline is accomplished. -------  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 May 88 12:14:15 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 20 MAY 88 09:01:07 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM by Xerox.COM ; 20 MAY 88 09:00:13 PDT Received: by WILMA.BBN.COM id aa28949; 20 May 88 11:51 EDT To: Jim Kelly cc: pcl-user@vax.bbn.com, CommonLoops.pa@Xerox.COM Subject: Re: clos in 7.2 In-reply-to: Your message of Fri, 20 May 88 11:13:22 -0400. Date: Fri, 20 May 88 11:53:35 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880520-090107-2004@Xerox> Received: from vax.bbn.com by WILMA.BBN.COM id aa28791; 20 May 88 11:13 EDT Date: Fri, 20 May 88 11:13:22 EDT From: Jim Kelly To: kanderson@vax.bbn.com cc: pcl-user@vax.bbn.com Subject: clos in 7.2 A few weeks ago when we were discussing some clos/7.2 bugs gregor@xerox said alot of the hacks written to get it to work in 7.1 didn't work in 7.2 and to wait "a few days". Are we getting some new code which will fix 7.2 problems? Would it be good|ok|bad to start using clos/7.2 or to continue waiting for something? -Jim Unfortunately, I haven't heared anything. Perhaps you and Rich should try it again, so we can see how bad things really are. Here is his message, which gives a hint as to what the problems are: This message is only of interest to people who run PCL on Symbolics 36xx machines. As near as I can tell, PCL doesn't work at all in 7.2. The hacks which I wrote to cause the compiler to compile random top-level forms don't This is the top-level-form SPECIAL FORM in rel-7-patches.lisp. work, the fixes I made to the compiler to treat #, properly don't work, This is load-time-eval and related compiler hacks in 3600-low.lisp and as a result nothing really works for beans. I suggest that you wait at least a few days before trying to run PCL in 7.2. ------- You should be able to play around with these files without loading all of PCL. k  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 May 88 12:14:04 EDT Received: from Semillon.ms by ArpaGateway.ms ; 20 MAY 88 08:57:31 PDT Return-Path: Redistributed: commonloops.pa Received: from decwrl.dec.com by Xerox.COM ; 20 MAY 88 08:55:25 PDT Received: by decwrl.dec.com (5.54.4/4.7.34) id AA23885; Fri, 20 May 88 08:51:48 PDT Date: Fri, 20 May 88 08:51:48 PDT Message-Id: <8805201551.AA23885@decwrl.dec.com> From: piazza%lisp.DEC@decwrl.dec.com (Jeffrey Piazza) To: sengupta@asu.edu Subject: PCL on VAXLisp Ver 2.0 ...doesn't work. The latest version of PCL contains implementation-specific code in WALK.LSP for each known implementation. The code to support the latest PCL on VAX Lisp relies on architectural changes made for V2.2. Therefore, to run St. Patrick's Day PCL, you need to upgrade to V2.2. As PCL is under continuing development, we (DEC) are unable to provide even the current unofficial level of support for PCL on incompatible versions of VAX Lisp. You might or might not be able to devise a patch by looking at pre-V2.2 versions of PCL. Best of luck, Jeffrey Piazza VAX Lisp Development Digital Equipment Corporation m/s DLB5-2/B10 290 Donald Lynch Boulevard Marlboro, MA 01752  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 20 May 88 07:00:46 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 20 MAY 88 03:48:11 PDT Return-Path: <@RELAY.CS.NET:sengupta@asu.edu> Redistributed: commonloops.pa Received: from RELAY.CS.NET by Xerox.COM ; 20 MAY 88 03:46:30 PDT Received: from relay2.cs.net by RELAY.CS.NET id bz10613; 20 May 88 6:38 EDT Received: from asu.edu by RELAY.CS.NET id ak27762; 20 May 88 4:37 EDT Received: by asuvax (5.51/5.17) id AA19753; Wed, 18 May 88 16:35:52 MST Date: Wed, 18 May 88 16:35:52 MST From: "Uttam K. Sengupta" To: commonloops.pa@Xerox.COM Subject: PCL on VAXLisp Ver 2.0 Message-ID: <880520-034811-1750@Xerox> Tried to compile PCL (latest version) on our VAX VMS running VAXLisp 2.0, and had compilation errors in the LOW module. Has anybody come across this problem and if they have cracked this one, could they share their expertise with us. Would sure appreciate any help. In the meantime we will continue to work on this and keep you all posted about our progress (or lack thereof). Thanks, Uttam Sengupta, AI Laboratory, Computer Science Department, Arizona State University, Tempe, AZ 85287. e-mail : sengupta@asu.csnet ;;; ********************************************************************** Dribbling to SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]SCRIPT2.;1 NIL -------------------------------------------------------------------------------- ==> (pcl::compile-pcl) Compiling PKG... Starting compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]PKG.LSP;1 Finished compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]PKG.LSP;1 0 Errors, 0 Warnings Loading binary of PKG... Compiling WALK... Starting compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]WALK.LSP;1 Finished compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]WALK.LSP;1 0 Errors, 0 Warnings Loading binary of WALK... Compiling MACROS... Starting compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]MACROS.LSP;1 Finished compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]MACROS.LSP;1 0 Errors, 0 Warnings Loading binary of MACROS... Compiling LOW... Starting compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]LOW.LSP;1 Error in %INSTANCE-CLASS-OF Compile time error while executing MACROEXPAND-1 Error signalled by ERROR Error message would have been: "Argument must be a list: #((SYSTEM::%COMPILED-CLOSURE% (#(NIL NIL ((#:G5043 ((SYSTEM::%LEXICAL-CLOSURE% (LAMBDA (FORM CONTEXT ENV &AUX AUX) (DECLARE (IGNORE CONTEXT ENV)) (OR (AND (LISTP FORM) (SETQ AUX (ASSQ (CAR FORM) *ITERATE-RESULT-TYPES*)) (SETQ RESULT-TYPE (IF (NULL RESULT-TYPE) (FUNCALL (CDR AUX) FORM NIL (QUOTE CREATE-RESULT-TYPE)) (FUNCALL (CDR AUX) FORM RESULT-TYPE (QUOTE CHECK-RESULT-TYPE)))) (FUNCALL (CDR AUX) FORM RESULT-TYPE (QUOTE MACROEXPAND))) FORM)) ((BINDS MC) (VAR-INIT-STEPS (#:G12456 *META-CLASSES* (CDR #:G12456))) (PRE-END-TESTS (NULL #:G12456)) (POST-END-TESTS) (PRE-BODIES (SETQ MC (CAR #:G12456))) (POST-BODIES) (RESULT-TYPE COLLECT #:G12457 ((#:G12457 NIL)) (NREVERSE #:G12457)) (BODY (COLLECT (CONS (CONS (QUOTE EQ) (CONS (CONS (QUOTE %INSTANCE-META-CLASS) (CONS ARG (QUOTE NIL))) (CONS (CONS (QUOTE LOAD-TIME-EVAL) (CONS (CONS (QUOTE CLASS-NAMED) (CONS (CONS (QUOTE QUOTE) (CONS (CAR MC) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL)))) (CONS (CONS (QUOTE FUNCALL) (CONS (CONS (QUOTE FUNCTION) (CONS (CDR MC) (QUOTE NIL))) (CONS ARG (QUOTE NIL)))) (QUOTE NIL))))) (CONTROLS (MC IN *META-CLASSES*)) (ENV) (SYSTEM:: ITERATE ((MC IN *META-CLASSES*)) (COLLECT (CONS (CONS (QUOTE EQ) (CONS (CONS (QUOTE %INSTANCE-META-CLASS) (CONS ARG (QUOTE NIL))) (CONS (CONS (QUOTE LOAD-TIME-EVAL) (CONS (CONS (QUOTE CLASS-NAMED) (CONS (CONS (QUOTE QUOTE) (CONS (CAR MC) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL)))) (CONS (CONS (QUOTE FUNCALL) (CONS (CONS (QUOTE FUNCTION) (CONS (CDR MC) (QUOTE NIL))) (CONS ARG (QUOTE NIL)))) (QUOTE NIL)))))) NIL ((ITERATE)) NIL) NIL NIL NIL))))) #) NIL ((#:G5043 ((SYSTEM::%LEXICAL-CLOSURE% (LAMBDA (FORM CONTEXT ENV &AUX AUX) (DECLARE (IGNORE CONTEXT ENV)) (OR (AND (LISTP FORM) (SETQ AUX (ASSQ (CAR FORM) *ITERATE-RESULT-TYPES*)) (SETQ RESULT-TYPE (IF (NULL RESULT-TYPE) (FUNCALL (CDR AUX) FORM NIL (QUOTE CREATE-RESULT-TYPE)) (FUNCALL (CDR AUX) FORM RESULT-TYPE (QUOTE CHECK-RESULT-TYPE)))) (FUNCALL (CDR AUX) FORM RESULT-TYPE (QUOTE MACROEXPAND))) FORM)) ((BINDS MC) (VAR-INIT-STEPS (#:G12456 *META-CLASSES* (CDR #:G12456))) (PRE-END-TESTS (NULL #:G12456)) (POST-END-TESTS) (PRE-BODIES (SETQ MC (CAR #:G12456))) (POST-BODIES) (RESULT-TYPE COLLECT #:G12457 ((#:G12457 NIL)) (NREVERSE #:G12457)) (BODY (COLLECT (CONS (CONS (QUOTE EQ) (CONS (CONS (QUOTE %INSTANCE-META-CLASS) (CONS ARG (QUOTE NIL))) (CONS (CONS (QUOTE LOAD-TIME- EVAL) (CONS (CONS (QUOTE CLASS-NAMED) (CONS (CONS (QUOTE QUOTE) (CONS (CAR MC) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL)))) (CONS (CONS (QUOTE F UNCALL) (CONS (CONS (QUOTE FUNCTION) (CONS (CDR MC) (QUOTE NIL))) (CONS ARG (QUOTE NIL)))) (QUOTE NIL))))) (CONTROLS (MC IN *META-CLASSES*)) (ENV) (SYSTEM:: ITERATE ((MC IN *META-CLASSES*)) (COLLECT (CONS (CONS (QUOTE EQ) (CONS (CONS (QUOTE %INSTANCE-META-CLASS) (CONS ARG (QUOTE NIL))) (CONS (CONS (QUOTE LOAD-TIME-EVAL) (CONS (CONS (QUOTE CLASS-NAMED) (CONS (CONS (QUOTE QUOTE) (CONS (CAR MC) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL)))) (CONS (CONS (QUOTE FUNCALL) (CONS (CONS (QUOTE FUNCTION) (CONS (CDR MC) (QUOTE NIL))) (CONS ARG (QUOTE NIL)))) (QUOTE NIL)))))) NIL ((ITERATE)) NIL) (PUSH (CONS (CONS (QUOTE EQ) (CONS (CONS (QUOTE %INSTANCE-META-CLASS) (CONS ARG (QUOTE NIL))) (CONS (CONS (QUOTE LOAD-TIME-EVAL) (CONS (CONS (QUOTE CLASS-NAMED) (CONS (CONS (QUOTE QUOTE) (CONS (CAR MC) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL))) (QUOTE NIL)))) (CONS (CONS (QUOTE FUNCALL) (CONS (CONS (QUOTE FUNCTION) (CONS (CDR MC) (QUOTE NIL))) (CONS ARG (QUOTE NIL)))) (QUOTE NIL))) #:G12457) NIL NIL))))" Finished compilation of file SYS$VMSC_USER:[UD.GCSS.SENGUPTA.PCL]LOW.LSP;1 1 Errors, 0 Warnings Errors were detected in the following functions: %INSTANCE-CLASS-OF The following are assumed to be functions, but were not declared or defined: CLASS-OF Loading binary of LOW... Compiling VAXL-LOW...Error using function COMPILE-FILE (signaled by CERROR). Prompt for new file name. Input file does not exist: SYS$USERDISK:[UD.GCSS.SENGUPTA.PCL]vaxl_low.LSP;0 SYS$USERDISK:[UD.GCSS.SENGUPTA.PCL]vaxl_low.LSP;0 -------------------------------------------------------------------------------- ==> (dribble)  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 May 88 21:30:00 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 19 MAY 88 17:42:02 PDT Return-Path: Redistributed: commonloops.PA Received: from Score.Stanford.EDU by Xerox.COM ; 19 MAY 88 17:40:53 PDT Date: Thu, 19 May 88 17:40:18 PDT From: Art Altman Subject: mailing list To: commonloops.PA@Xerox.COM cc: altman@Score.Stanford.EDU Message-ID: <12399680679.9.ALTMAN@Score.Stanford.EDU> I'm a new user of commonloops (clos). I work at the Rockwell Science Lab on University Avenue. I understand that there is a mailing list for information about clos. Would you please see to it that I am placed on any appropriate mailing lists? Thank you very much, (Art) altman@score.stanford.edu -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 May 88 19:25:58 EDT Date: 19 May 88 1613 PDT From: Dick Gabriel Subject: check-keyword-arguments To: common-lisp-object-system@SAIL.Stanford.EDU I want to present one more alternative to the initargs checking problem. This alternative was the result of a couple of hours' discussion with Guy Steele tuesday night. There are two parts to it. One is the real technical proposal, and the remainder is the packaging for chapter 1. We could introduce a new generic function called valid-keywords, which takes an object; if it is something with keywords (like a generic function, a method, or a function), valid-keywords returns two values: a list of the explicitly named keywords and a boolean which states whether &allow-other-keys had been specified in the definition. Then we could write make-instance like this: (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-initargs class initargs)) (let* ((proto (class-prototype class)) (methods (union (compute-applicable-methods #'allocate-instance `(,class)) (union (compute-applicable-methods #'initialize-instance `(,proto nil)) (compute-applicable-methods #'shared-initialize `(,proto)))))) (unless (subsetp (let ((keys '())) (do ((plist initargs (cddr plist))) ((null plist) keys) (push (car plist) keys))) (union (class-slot-initargs class) (reduce #'union (mapcar #'valid-keywords methods)))) (error ...))) (let ((instance (apply #'allocate-instance class initargs))) (apply #'initialize-instance instance initargs) instance)) Or something like this: the details of the code are not important for chapters 1 and 2. This is not a very simple piece of code to present in chapter 1. So the proposal requires a sample of how to explain this: \beginsubSection{Definitions of Make-Instance and Initialize-Instance} The generic function {\bf make-instance} behaves as if it were defined as follows, except that certain optimizations are permitted: \screen! (defmethod make-instance ((class standard-class) &rest initargs) (setq initargs (default-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 (find-class class-name) initargs)) \endscreen! The elided code in the definition of {\bf make-instance} checks the supplied initialization arguments to determine whether an initialization argument was supplied that neither filled a slot nor supplied an argument to an applicable method. This check could be implemented using the generic functions {\bf class-prototype}, {\bf compute-applicable-methods}, {\bf valid-keywords}, and {\bf class-slot-initargs}. See Chapter~3 for a description of this initialization argument check. The generic function {\bf initialize-instance} behaves as if it were defined as follows, except that certain optimizations are permitted: \screen! (defmethod initialize-instance ((class standard-class) &rest initargs) (apply #'shared-initialize instance t initargs))) \endscreen! These procedures can be customized at either the Programmer Interface level, the meta-object level, or both. Customizing at the Programmer Interface level includes using the {\bf :initform}, {\bf :initarg}, and {\bf :default-initargs} options to {\bf defclass}, as well as defining methods for {\bf make-instance} and {\bf initialize-instance}. It is also possible to define methods for {\bf shared-initialize}, which would be invoked by the generic functions {\bf reinitialize-instance}, {\bf update-instance-for-redefined-class}, {\bf update-instance-for-different-class}, and {\bf initialize-instance}. The meta-object level supports additional customization by allowing methods to be defined on {\bf make-instance}, {\bf default-initargs}, and {\bf allocate-instance}. Chapters~2 and~3 document each of these generic functions and the system-supplied primary methods. Implementations are permitted to make certain optimizations to {\bf initialize-instance} and {\bf shared-initialize}. The description of {\bf shared-initialize} in Chapter~2 mentions the possible optimizations. Because of optimization, the check for valid initialization arguments might not be implemented using the generic functions {\bf class-prototype}, {\bf compute-applicable-methods}, {\bf valid-keywords}, and {\bf class-slot-initargs}. In addition, methods for the generic function {\bf default-initargs}, and the system-supplied primary methods for {\bf allocate-instance}, {\bf initialize-instance}, and {\bf shared-initialize} may not be called on every call to {\bf make-instance} or may not receive exactly the arguments that would be expected. \endsubSection%{Definitions of MAKE-INSTANCE and Initialize-Instance}  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 May 88 18:41:57 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 19 MAY 88 15:22:12 PDT Return-Path: Redistributed: CommonLoops.pa Received: from WILMA.BBN.COM ([128.89.1.216]) by Xerox.COM ; 19 MAY 88 15:20:08 PDT To: CommonLoops.pa@Xerox.COM Cc: kanderson@WILMA.BBN.COM, pcl-user@WILMA.BBN.COM Subject: class-all-default-initargs #:slot-unbound Date: Thu, 19 May 88 15:15:09 -0400 From: kanderso@WILMA.BBN.COM Message-ID: <880519-152212-1130@Xerox> The classes at the top of the metabraid seem to have their class-all-default-initargs unbound, although it seems like they should be (). THis causes mki to fail. Here's a patch but i don't know what the correct solution is: (setf (class-all-default-initargs (symbol-class 't)) ()) (setf (class-all-default-initargs (symbol-class 'standard-class)) ()) (setf (class-all-default-initargs (symbol-class 'class)) ()) (setf (class-all-default-initargs (symbol-class 'standard-slot-description)) ())  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 May 88 14:12:19 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 19 MAY 88 10:49:16 PDT Return-Path: Redistributed: commonloops.pa Received: from media-lab.media.mit.edu by Xerox.COM ; 19 MAY 88 10:29:30 PDT Received: from paddington.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA06089; Thu, 19 May 88 13:28:37 EDT Received: by paddington (3.2/4.8) id AA20851; Thu, 19 May 88 13:23:15 EDT Date: Thu, 19 May 88 13:23:15 EDT From: Michael Sokolov Message-Id: <8805191723.AA20851@paddington> To: burdorf@rand-unix.arpa Cc: commonloops.pa@Xerox.COM, burdorf@rand-unix.arpa In-Reply-To: burdorf@rand-unix.arpa's message of Tue, 17 May 88 13:21:16 PDT <8805172021.AA13002@rand.org> Subject: Flavors in Commonlisp >Does anybody know of a public domain flavors that runs in Common lisp. >thanks, >chris burdorf -Can anyone stop this message?!? It seems to be regenerating itself, like some sort of diabolical eternal question. Mike Sokolov  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 19 May 88 14:12:03 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 19 MAY 88 10:35:03 PDT Return-Path: Redistributed: commonloops.pa Received: from media-lab.media.mit.edu by Xerox.COM ; 19 MAY 88 10:29:30 PDT Received: from paddington.media.mit.edu by media-lab.media.mit.edu (5.59/4.8) id AA06089; Thu, 19 May 88 13:28:37 EDT Received: by paddington (3.2/4.8) id AA20851; Thu, 19 May 88 13:23:15 EDT Date: Thu, 19 May 88 13:23:15 EDT From: Michael Sokolov Message-Id: <8805191723.AA20851@paddington> To: burdorf@rand-unix.arpa Cc: commonloops.pa@Xerox.COM, burdorf@rand-unix.arpa In-Reply-To: burdorf@rand-unix.arpa's message of Tue, 17 May 88 13:21:16 PDT <8805172021.AA13002@rand.org> Subject: Flavors in Commonlisp >Does anybody know of a public domain flavors that runs in Common lisp. >thanks, >chris burdorf -Can anyone stop this message?!? It seems to be regenerating itself, like some sort of diabolical eternal question. Mike Sokolov  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 May 88 23:14:40 EDT Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 18 May 88 20:06:58 PDT Date: Wed, 18 May 88 23:11:11 EDT From: "David A. Moon" Subject: Comments on new draft chapter 2 (dated May 16 15:09) To: Common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <380731.880518.MOON@AI.AI.MIT.EDU> There is also one comment on chapter 1 in here. 2-6 first paragraph: I'm not sure what is meant by behavior intrinsic to a generic function itself. I think this probably means a contract that all methods must obey (as distinguished from idiosyncratic behavior of one particular method). 2-12: This says call-next-method signals an error, but I thought we changed it to call a generic function whose default method signals an error. 2-15: In the defmethod, change "&rest initargs" to "&key" for better style, since this method doesn't use or define any initargs, it should have an empty set of &key parameters. Also this method should be a :before method; not a :after method, because we want to initialize the slots ourselves, not let the primary method initialize them from initforms then reinitialize them ourselves. I think 1-44 and 1-47 should be modified to reflect this valid use of :before methods for the two update- functions; they differ in this respect from initialize-instance and reinitialize-instance. 2-17: The method signatures imply that only standard classes have names, but I believe the intent was that all classes have names. Certainly built-in and structure classes do have names. 2-21 3rd paragraph: Someone complained that "The slot-name argument is a symbol that can be used as a Common Lisp variable name." was ambiguous. What we mean is that the symbol is syntactically valid for use as a variable name, what we don't mean is that referencing a variable with this name will access the slot. This should be rephrased if possible. 2-33 last paragraph: The value returned by define-method-combination should be the method combination meta object (now that we have them), not the name. 2-37 2nd paragraph: I don't understand what this paragraph is doing here. Keyword options to what? Did this paragraph drift in from somewhere earlier in the define-method-combination section perhaps? 2-43: There is documentation for slot descriptor objects now too. Since only chapter 3 describes those, I don't know whether slot documentation should be documented in the normal way, or just mentioned as a remark. I think I prefer the former. 2-45 4th paragraph: Because of the way rule 4 for lambda-list congruence is defined, I think this has to speak not of the old and new lambda-lists for the generic function being congruent, but of the new lambda-list for the generic function being congruent with the lambda-lists of all existing methods. If an implementation can sometimes optimize this into a comparison with the old lambda list for the generic function, that's merely an optimization. 2-55 2nd paragraph: I don't think the system supplied primary method for initialize-instance checks the validity of the arguments, since chapter 1 says make-instance takes care of that. Unlike reinitialize-instance, initialize-instance is not meant to be called by the user. 2-55 Remarks field: This is not really accurate, as the generic functions for which methods can be defined varies. Chapter 1 describes this better, maybe the description should not be repeated here. It would be useful to have a remark that the programmer is intended to define :after methods for initialize-instance. 2-58: Formatting of method signatures is particularly ugly here. How about right-justifying "[Primary Method]" throughout this chapter? 2-74,5,6: Are you sure slot-boundp, slot-exists-p, and slot-makunbound are generic? slot-value isn't. I guess Gregor has final say on this point. 2-85: Same comments as for 2-15. 2-90 first remarks paragraph: same comment as for 2-45. 2-92: with-slots should cross-reference with-accessors  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 May 88 21:26:06 EDT Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 18 May 88 18:18:27 PDT Date: Wed, 18 May 88 21:22:40 EDT From: "David A. Moon" Subject: Comments on new draft chapter 1 (dated May 13 20:53) To: Common-lisp-object-system@SAIL.STANFORD.EDU Message-ID: <380679.880518.MOON@AI.AI.MIT.EDU> 1-12 fourth bullet: typos "an :documentation", "documentation documentation" 1-30 first bullet, also second dash bullet: These say an error is signalled if call-next-method is called when there is no next method. I thought we changed that to call a generic function whose name escapes me at the moment, whose default method signals an error. 1-31 last bullet: ditto 1-35: Should the four simple mechanisms listed be augmented with shared-initialize as a fifth bullet? 1-38 4th paragraph: maybe this should be "initialize-instance or shared-initialize methods should be used instead." 1-39 penultimate paragraph: shared-initialize does not take three arguments, it takes two required arguments plus a set of &key arguments. The initialization arguments are passed as separate arguments, not as a list. 1-40 first paragraph after first three bullets: should be "whose first parameter specializer is the class standard-object". 1-41 1st paragraph: same comment as 1-39. 1-41 last line: the parameter name is instance, not class, and the parameter specializer is standard-object, not standard-class. 1-43 4th paragraph: There is a stray sentence fragment "the value of the shared slot in the old class." 1-43 6th paragraph: I think this should mention that the process can also be triggered by an explicit call to the function make-instances-obsolete. 1-44 6th paragraph: Rather than saying update-instance-for-redefined-class takes an &rest argument which is a list of initialization arguments, I believe it is more correct terminology to say that it takes &key arguments which are the initialization arguments. The default method may receive these with an &rest parameter, but the generic function's lambda-list says &key, not &rest. 1-44 last paragraph: same comment as 1-39. 1-46 penultimate paragraph: same comment as 1-44 6th. 1-47 last paragraph: same comment as 1-39. 1-48 3rd paragraph: same comment as 1-44 6th. 1-48 last paragraph: same comment as 1-39.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 May 88 14:11:00 EDT Received: from ti.com by SAIL.Stanford.EDU with TCP; 18 May 88 11:01:24 PDT Received: by ti.com id AA20889; Wed, 18 May 88 07:13:51 CDT Received: from Jenner by tilde id AA06761; Wed, 18 May 88 07:12:44 CDT Message-Id: <2788949394-1458237@Jenner> Date: Wed, 18 May 88 07:09:54 CDT From: Patrick H Dussud To: common-lisp-object-system@SAIL.STANFORD.EDU Subject: Re: check-keyword-arguments In-Reply-To: Msg of 17 May 88 13:38 PDT from Danny Bobrow I am now satisfied that your more general version of check-keyword-arguments can be useful. It would be good to have this last issue for chapter 2 (check-keyword-arguments) settled, and am happy to have it as last specified. I agree. Patrick.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 17 May 88 17:23:36 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 MAY 88 14:14:00 PDT Return-Path: Redistributed: commonloops.pa Received: from rand.org (RAND-UNIX.ARPA) by Xerox.COM ; 17 MAY 88 14:12:09 PDT Received: by rand.org; Tue, 17 May 88 13:21:20 PDT Message-Id: <8805172021.AA13002@rand.org> To: commonloops.pa@Xerox.COM Cc: burdorf@rand-unix.ARPA Subject: Flavors in Commonlisp Date: Tue, 17 May 88 13:21:16 PDT From: burdorf@rand-unix.ARPA Does anybody know of a public domain flavors that runs in Common lisp. thanks, chris burdorf  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 17 May 88 16:48:30 EDT Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 May 88 13:40:43 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 MAY 88 13:38:44 PDT Date: 17 May 88 13:38 PDT Sender: Bobrow.pa@Xerox.COM From: Danny Bobrow Subject: Re: check-keyword-arguments In-reply-to: Dick Gabriel 's message of 15 May 88 13:56 PDT To: RPG@SAIL.Stanford.EDU cc: common-lisp-object-system@SAIL.Stanford.EDU Message-ID: <880517-133844-2742@Xerox> I have no worries that someone who is writing his own version of make-instance could look in chapter 3 or 4 to find out how to do error checking. Therefore, only a check-keyword-arguments that is more generally useful justifies going beyond specifying a procedural definition of make-instance that is reasonable only for correct invocations of it. I am now satisfied that your more general version of check-keyword-arguments can be useful. It would be good to have this last issue for chapter 2 (check-keyword-arguments) settled, and am happy to have it as last specified.  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 17 May 88 13:09:06 EDT Received: from Cabernet.ms by ArpaGateway.ms ; 17 MAY 88 09:58:41 PDT Return-Path: Redistributed: Commonloops.pa Received: from rand.org (RAND-UNIX.ARPA) by Xerox.COM ; 17 MAY 88 09:55:56 PDT Received: by rand.org; Tue, 17 May 88 09:46:54 PDT Message-Id: <8805171646.AA10898@rand.org> To: Commonloops.pa@Xerox.COM Subject: Flavors in Commonlisp Date: Tue, 17 May 88 09:43:24 PDT From: burdorf@rand-unix.ARPA Sorry to bother you all with more Flavors discussion, but several of my higher ups want to know if there is a public domain version of Flavors that runs in commonlisp. Thanks chris burdorf  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 17 May 88 07:47:32 EDT Received: from Salvador.ms by ArpaGateway.ms ; 17 MAY 88 04:37:47 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 17 MAY 88 04:35:08 PDT Received: from suntoo.sun.com (suntoo-bb.sun.com) by Sun.COM (4.0/SMI-4.0) id AA22689; Tue, 17 May 88 04:34:01 PDT Received: by suntoo.sun.com (3.2/SMI-3.2) id AA23529; Tue, 17 May 88 04:38:06 PDT Received: by sunpitt.uucp (3.2/SMI-2.0) id AA20379; Tue, 17 May 88 07:22:44 EDT Received: from canaletto.sun.com by eti.com (3.2/SMI-3.2) id AA01907; Fri, 13 May 88 22:20:01 EDT Received: by canaletto.sun.com (3.2/SMI-3.2) id AA00639; Fri, 13 May 88 22:19:52 EDT Date: Fri, 13 May 88 22:19:52 EDT From: sunpitt!eti!canaletto!rick@Sun.COM (Rick Busdiecker) Message-Id: <8805140219.AA00639@canaletto.sun.com> To: sunpitt!sun!xerox.com!commonloops.pa@Sun.COM Cc: sunpitt!sun!cs.cmu.edu!rfb@Sun.COM Reply-To: Rick.Busdiecker@CS.CMU.EDU Subject: PCL losing on TI I just grabbed the PCL sources from parcvax's /pub/pcl/ and tried to compile them on a TI Explorer and lost big. I've enclosed a log of the lossage at the end of this message. Can someone help me? Do patches that are sent to this mailing from PCL maintainers get incorporated into the sources on parcvax? If this isn't happening currently, should it be? If this is just a case of my missing some messages about patches, would someone please remail them? I'd appreciate it if any replies are sent to Rick.Busdiecker@CS.CMU.EDU as it's more reliable than my usenet address. Thanks. Rick Busdiecker Expert Technologies, Inc. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > (load "pg:rick.pcl;defsys.lisp") ; Loading Assassin: RICK.PCL; DEFSYS.LISP#> into package PCL #FS::LISPM-PATHNAME "Assassin: RICK.PCL; DEFSYS.LISP#2" > pcl::*pcl-system-date* "3/17/88 St. Patrick's Day PCL" > pcl::*pcl-directory* #FS::LISPM-PATHNAME "Assassin: RICK.PCL;" > (pcl::compile-pcl) Loading binary of TI-PATCHES... Loading binary of PKG... Loading binary of WALK... Loading binary of MACROS... Loading binary of LOW... Loading binary of TI-LOW... Loading binary of FIN... Loading binary of DEFS... Loading binary of BOOT... Compiling SLOTS... << While compiling COPY-SLOTD >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE COPY-SLOTD) (QUOTE NIL) (QUOTE (STANDARD-SLOT-DESCRIPTION)) ...) the function spec (METHOD COPY-SLOTD (STANDARD-SLOT-DESCRIPTION)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling SLOT-VALUE-USING-CLASS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE SLOT-VALUE-USING-CLASS) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T)) ...) the function spec (METHOD SLOT-VALUE-USING-CLASS (STANDARD-CLASS T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling PUT-SLOT-USING-CLASS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE PUT-SLOT-USING-CLASS) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T T)) ...) the function spec (METHOD PUT-SLOT-USING-CLASS (STANDARD-CLASS T T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling SLOT-BOUNDP-USING-CLASS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE SLOT-BOUNDP-USING-CLASS) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T)) ...) the function spec (METHOD SLOT-BOUNDP-USING-CLASS (STANDARD-CLASS T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. The variable CLASS is bound but never used. << While compiling REMOVE-DYNAMIC-SLOT-USING-CLASS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE REMOVE-DYNAMIC-SLOT-USING-CLASS) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T)) ...) the function spec (METHOD REMOVE-DYNAMIC-SLOT-USING-CLASS (STANDARD-CLASS T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling ALL-SLOTS-USING-CLASS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE ALL-SLOTS-USING-CLASS) (QUOTE NIL) (QUOTE (STANDARD-CLASS T)) ...) the function spec (METHOD ALL-SLOTS-USING-CLASS (STANDARD-CLASS T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling REMOVE-DYNAMIC-SLOT-USING-CLASS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE REMOVE-DYNAMIC-SLOT-USING-CLASS) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T)) ...) the function spec (METHOD REMOVE-DYNAMIC-SLOT-USING-CLASS (STANDARD-CLASS T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling SLOT-ALLOCATION-USING-CLASS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE SLOT-ALLOCATION-USING-CLASS) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T)) ...) the function spec (METHOD SLOT-ALLOCATION-USING-CLASS (STANDARD-CLASS T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling SLOT-EXISTS-P >> (EQ VAL FLAG) should probably use EQUAL instead. << While compiling SLOT-MISSING >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE SLOT-MISSING) (QUOTE NIL) (QUOTE (T T)) ...) the function spec (METHOD SLOT-MISSING (T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling SLOTS-WITH-ALLOCATION >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE SLOTS-WITH-ALLOCATION) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T)) ...) the function spec (METHOD SLOTS-WITH-ALLOCATION (STANDARD-CLASS T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling SLOTS-WITH-ALLOCATION-NOT >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE SLOTS-WITH-ALLOCATION-NOT) (QUOTE NIL) (QUOTE (STANDARD-CLASS T T)) ...) the function spec (METHOD SLOTS-WITH-ALLOCATION-NOT (STANDARD-CLASS T T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling OPTIMIZE-SLOT-VALUE >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE OPTIMIZE-SLOT-VALUE) (QUOTE NIL) (QUOTE (STANDARD-CLASS T)) ...) the function spec (METHOD OPTIMIZE-SLOT-VALUE (STANDARD-CLASS T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling OPTIMIZE-SET-SLOT-VALUE >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE OPTIMIZE-SET-SLOT-VALUE) (QUOTE NIL) (QUOTE (STANDARD-CLASS T)) ...) the function spec (METHOD OPTIMIZE-SET-SLOT-VALUE (STANDARD-CLASS T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling CLASS-HAS-INSTANCES-P >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE CLASS-HAS-INSTANCES-P) (QUOTE NIL) (QUOTE (STANDARD-CLASS)) ...) the function spec (METHOD CLASS-HAS-INSTANCES-P (STANDARD-CLASS)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling ALLOCATE-INSTANCE >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE ALLOCATE-INSTANCE) (QUOTE NIL) (QUOTE (STANDARD-CLASS)) ...) the function spec (METHOD ALLOCATE-INSTANCE (STANDARD-CLASS)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. The variable INITARGS is bound but never used. << While compiling INITIALIZE >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE INITIALIZE) (QUOTE NIL) (QUOTE (OBJECT T)) ...) the function spec (METHOD INITIALIZE (OBJECT T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling INITIALIZE-FROM-DEFAULTS >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE INITIALIZE-FROM-DEFAULTS) (QUOTE NIL) (QUOTE (OBJECT)) ...) the function spec (METHOD INITIALIZE-FROM-DEFAULTS (OBJECT)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. << While compiling INITIALIZE-FROM-INIT-PLIST >> Error in compile-time evaluation of (LOAD-DEFMETHOD (QUOTE STANDARD-METHOD) (QUOTE INITIALIZE-FROM-INIT-PLIST) (QUOTE NIL) (QUOTE (OBJECT T)) ...) the function spec (METHOD INITIALIZE-FROM-INIT-PLIST (OBJECT T)) is invalid. TO DEBUG THIS, recompile with COMPILER:WARN-ON-ERRORS set to NIL. Loading binary of SLOTS... ;;; At this point it dropped into a break look complaining about ;;; copy-method (I think) missing . . . I'm not really sure why dribble ;;; didn't include that output, but it's fairly clear that things are ;;; screwy already just from the output so far. > (dribble)  Received: from REAGAN.AI.MIT.EDU (CHAOS 13065) by AI.AI.MIT.EDU 16 May 88 22:45:24 EDT Received: from SAIL.STANFORD.EDU by REAGAN.AI.MIT.EDU via INTERNET with SMTP id 112420; 16 May 88 20:42:19 EDT Date: 16 May 88 1524 PDT From: Linda DeMichiel Subject: Chapter 2 To: common-lisp-object-system@SAIL.Stanford.EDU New Chapter 2 files are now available as functi.*[cls,lsp] on sail. This material should now be up-to-date except for whatever we decide to do with check-keyword-arguments. Please send comments and corrections to me by Thursday morning. -lgd  Received: from Xerox.COM (TCP 1500006350) by AI.AI.MIT.EDU 16 May 88 17:21:47 EDT Received: from Chardonnay.ms by ArpaGateway.ms ; 16 MAY 88 14:08:25 PDT Return-Path: Redistributed: commonloops.pa Received: from Sun.COM by Xerox.COM ; 16 MAY 88 14:06:12 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0) id AA12192; Mon, 16 May 88 14:05:08 PDT Received: from suntana.sun.com by snail.sun.com (4.0/SMI-3.2) id AA23009; Mon, 16 May 88 14:02:55 PDT Received: from localhost by suntana.sun.com (3.2/SMI-3.2) id AA05332; Mon, 16 May 88 13:57:22 PDT Message-Id: <8805162057.AA05332@suntana.sun.com> To: commonloops.pa@Xerox.COM Subject: Bug in PCL involving method lookup Date: Mon, 16 May 88 13:57:18 -0700 From: kempf@Sun.COM Has anyone else noticed the following bug in the 3/17/88 PCL running in Sun Common Lisp 2.1? It occurs during the loading of high.lbin. It seems to occur when the method describe-class is loaded, and it may have something to do with garbage collection and the funky way generic funct