Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ucbvax!elmer-fudd.berkeley.edu!konstan From: konstan@elmer-fudd.berkeley.edu (Joe Konstan) Newsgroups: comp.lang.clos Subject: Re: CLOS Private Methods Message-ID: <42474@ucbvax.BERKELEY.EDU> Date: 26 Jun 91 05:51:53 GMT References: <9106260502.AA11848@kuwait> Sender: nobody@ucbvax.BERKELEY.EDU Organization: Picasso Research Group, UCB Computer Science Division Lines: 83 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 (from the paper _Developing a GUIDE Using Object-Oriented Programming_ by me and Lawrence A. Rowe to appear at this year's OOPSLA) take the classes HOUSE and BOAT. Logically, as a user of multiple inheritance, I would like to create a child class HOUSEBOAT that inherits from both. Methods defined for one or the other of the superclasses work fine as do methods completely overridden in the subclass. Let's take the example of the generic function CLEAN, though. (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. I can't even write a method such as: (defmethod CLEAN ((self HOUSEBOAT)) (CLEAN (HOUSE self)) (CLEAN (BOAT self))) In fact, I not only have to add call-next-method into the CLEAN method for at least one superclass, but I may have to make other changes as well (perhaps HOUSE is a subclass of DWELLING and DWELLING has a CLEAN method HOUSE doesn't call.....) This type of problem is at the heart of what I consider a predisposition against encapsulation. I realize that metaclass hacking can get around almost any individual problem like this, and that clever coding can sometimes do so as well, but for the average CLOS user, these problems constitute a failure in encapsulation. As for the issue of packages, I think that the reason most Common Lisp programmers fear or avoid them is related to the nasty interaction they have with the reader and with compiled-versus-interpreted code. One recent problem I'd hoped to use packages to solve illustrates some of these problems. I wanted to have two packages, VIDEO and FAKE-VIDEO, which would export the same symbols (functions such as PLAY and state variables such as PLAYER-STATE) and of which only one package would be in use at a time (based on whether the hardware could support video). I found this to be a difficult enough problem so as to make it not worth pursuing far. When interpreted, I could load one set of code or the other, use that package, and then load the code that called the video successfully. But, there was no way to compile the code that called the video or even load it in advance since to compile or load that code it needed to resolve the package of the symbols and would create them locally if they weren't already imported. Similarly, it is frustrating that even an export call creates symbols in the current package (so that I end up using (defpackage foo (:exports "FOO-SYM-1" "FOO-SYM-2")) since putting symbols in there would create them in the current package). One solution would be to have some sort of external declaration such as (defpackage video-user (:external play player-status)) which would indicate that the symbols play and player-status should be resolved at use-time rather than compile or load-time. This is getting a bit away from CLOS, but the point I'm trying to make is that CLOS really doesn't have viable encapsulation and that packages, while they could be used for that, are awkward enough that most CL programmers don't use them much. So long as this is the case, application writers desiring encapsulation will likely avoid CLOS. Joe Konstan konstan@cs.berkeley.edu