Path: utzoo!utgpu!watserv1!watmath!att!mcdchg!laidbak!ism.isc.com!uunet!snorkelwacker!apple!sun-barr!cs.utexas.edu!ut-emx!lad-shrike!aihaug From: aihaug@AUSTIN.LOCKHEED.COM (Daniel A Haug) Newsgroups: comp.lang.lisp Subject: Re: Common Lisp Package System Considered Harmful Message-ID: <388@shrike.AUSTIN.LOCKHEED.COM> Date: 19 Oct 90 14:59:27 GMT References: <271E0D40.451E@wilbur.coyote.trw.com> Organization: Lockheed Austin Div. Lines: 94 Last year, we completed a project that involved several hundred thousand lines of CLOS-intensive Lisp code. Just guessing, I'd say that we had around 1000 classes, and perhaps 2000 generic functions. We used the package system to isolate layered functionality. For example, the CLOS-based window system was in one package, the CLOS-based user-interface management system was in another package, the CLOS-based communications system in yet another. You get the idea. In each system, public class slots were exported. So were public interface functions. Private slots and functions were not exported. No big deal. Also, I didn't understand the earlier comment about how defclass generates all of these other hidden functions (?). I do not know what functions outside of the CLOS-specified functions are generated. (defclass a () ((b :initform nil :accessor a-b))) This only generates one new method: a-b. All of the other functions are part of the CLOS spec (e.g. make-instance, initialize-instance, slot-value). Now back to how one would use our system: If I were then writing an application that would use the communications system, the window system, and the UIMS, then I would create my own application package that uses those packages: (make-package :my-application :use '(:common-lisp :clos :window-system :uims :communications)) Then my application package would inherit all of the public slots and interfaces from these subsystems. Then suppose that the window-system has class BASIC-WINDOW with public slot BACKGROUND-COLOR, and that all of my application windows will have blue background colors (back in the old pre-X days of hardcoded display preferences ;-), I would write: (defclass my-app-window (basic-window) ((background-color :initform :blue))) Thus, it is fairly easy to generate subclasses based on public (read: exported) class information. I have not violated object boundaries. My application window class doesn't interfere with other users of :window-system. Now, in practice, since we had such a large system, this approach worked well 99% of the time. Occasionally we had name conflicts arise within the package. No big deal... find it and resolve it. Also, we would have occasional package conflicts, two subsystem packages exporting similar symbol names. Again, no big deal, just choose the desired symbol to inherit, and shadow the others. Or, don't use :USE-PACKAGE at all: (defclass my-app-window (window-system:basic-window) ((window-system:background-color :initform :blue))) To me, there is flexibility to suit many approaches to this. From article <271E0D40.451E@wilbur.coyote.trw.com>, by scott@wiley.uucp (Scott Simpson): > > [...] I don't find > packages very useful and I wouldn't cry a tear if they were simply > removed from the language. I don't know if I agree that CLOS deals > with information hiding. How do you mean? No! We would have DIED in our project without the package system. We probably had 50 packages in the end. I can't begin to imagine life without the package system! Having done a substantial amount of work in C, which has no real namespace support (other than: everyone gets it, or no-one outside of this file gets it), I am very appreciative of languages that provide such a facility (e.g. Lisp, Ada, Modula-II,...). In C, one is forced to use implicit namespace dividers by prepending a pseudo-system name on each symbol (e.g. Xt, X, Xm, Xaw,...) which is pretty ridiculous (IMHO). My only serious gripe about the package system is the inability (within pure CL) to lock a package. In our project, we had a few inexperienced engineers who would develop the window-system side of their application in the window-system package. As their application would be loaded late into the lisp world, their additions to the window-system package would suddenly be inherited by all other users of the window-system, and everyone would indubitably lose. A nice safeguard would have been to lock the window-system package after that system had been loaded. Finally, to summarize my posting: We had success by using packages to isolate subsystems, including class definitions and methods. As we usually had only one or two people working on a system, name-conflicts rarely arose. Public vs. Private class information was accomplished via exporting symbols. dan haug -- Internet: haug@austin.lockheed.com UUCP: ut-emx!lad-shrike!aihaug Phone: (512) 448-5634