Hornig@riverside.scrc.symbolics.com (Charles Hornig) (06/26/91)
Date: Wed, 26 Jun 1991 03:15 EDT From: barmar@think.com (Barry Margolin) References <LGM.91Jun25201133@cbnewsc.ATT.COM>, <9106260502.AA11848@kuwait>, <42474@ucbvax.BERKELEY.EDU> Reply-To : barmar@think.com Subject : Re: CLOS Private Methods In article <42474@ucbvax.BERKELEY.EDU> konstan@elmer-fudd.berkeley.edu (Joe Konstan) writes: >Re: Encapsulation and fear of packages > >I think that the lack of encapsulation problem is more than merely a fear of >packages. With CLOS, there are many cases where a useful functionality is >unavailable unless you have (and can modify) the source code to a class and/or >the methods which specialize on that class. For one example ... >(defmethod CLEAN ((self HOUSE)) > (wash-windows self) > (scrub-floors self)) > >(defmethod CLEAN ((self BOAT)) > (scrape-barnacles self)) ;; I show my ignorance about boats > >The default behavior I want for HOUSEBOAT is to do both. I can't do this by >not defining a method, since neither HOUSE not BOAT does a call-next-method >and therefore only the first superclass will have its method called. Here is one possibility: (defgeneric CLEAN (thing) (:method-combination progn)) (defmethod CLEAN progn ((self HOUSE)) (wash-windows self) (scrub-floors self)) (defmethod CLEAN progn ((self BOAT)) (scrape-barnacles self)) ;; I show my ignorance about boats Note that boats and houses do not have to know about each other.
konstan@elmer-fudd.berkeley.edu (Joe Konstan) (06/27/91)
I'm not sure I made my houseboat problem clear enough in my first posting. I've seen three postings and some E-mail suggesting either designing the CLEAN methods to call-next-method (when one is available) or designing CLEAN as a generic function with method-combination type progn. This is why I feel that neither of these is an acceptable solution: 1. First and foremost, these require that HOUSE and BOAT be assured that no superclass of theirs ever has a CLEAN method defined. In fact, I might very well have defined HOUSE as a subclass of BUILDING and RESIDENCE where BUILDING has a CLEAN method defined on it which should NOT be used by HOUSE. As a result, HOUSE's CLEAN cannot (call-next-method) as this will call in the janitors to clean the BUILDING. Further, CLEAN cannot use method-combination type progn since I may have defined BOAT as a subclass of SEA-VESSEL and some other class where I want to inherit CLEAN using standard method combination. 2. Since I am not provided with the source code, I consider it unreasonable to implement any solution (such as the progn solution) that requires changing the methods themselves. Here is what I would consider an adequate solution (or at least a good start): 1. Let each method have its own method-combination type used to determine how to interpret call-next-method among its inherited methods (i.e., the superclasses). 2. In this case, the method-combination type for HOUSEBOAT could be progn, but the method-combination types for HOUSE and for BOAT could be completely different and should not matter. What matters is that I, as the creator of the HOUSEBOAT class, can decide that I want to do both the HOUSE and BOAT operations for CLEAN. 3. This is clearly harder to optimize and needs to be better defined with respect to the execution order when :around, :before, and :after methods are added in, but I think it is workable. I'm not disputing the claim that a complete system can be designed well so these problems do not arise. I don't think this is adequate, however, since designing a system well in CLOS is hard, and most of the code we would like to borrow from others will not have been designed well. As a result, the language must support techniques for getting the most out of existing classes and methods without modifying their source code. Joe Konstan konstan@cs.berkeley.edu