Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!samsung!xylogics!merk!alliant!linus!think!barmar From: barmar@think.com (Barry Margolin) Newsgroups: comp.lang.lisp Subject: Re: Using Packages With CLOS Message-ID: <41192@think.Think.COM> Date: 1 Aug 90 00:51:17 GMT References: <26581@pasteur.Berkeley.EDU> Sender: news@Think.COM Organization: Thinking Machines Corporation, Cambridge MA, USA Lines: 54 In article <26581@pasteur.Berkeley.EDU> faustus@fir.Berkeley.EDU (Wayne Christopher) writes: >The problem with using packages and CLOS is that unless you are careful >you can get lots of name conflicts. Say I have two rather general >classes, foo and bar, each in its own package. Each has a slot called >"name", and, following the convention used in the CLOS book, I have >defined and exported accessors called "name" for both. When I try to >use both classes in one package, I get a symbol conflict. There are a >few ways to avoid this: The problem isn't that you put each class in its own package, the problem is that you exported poorly-named symbols from the packages, and then tried to USE-PACKAGE both of them in another package. If you intend for people to USE-PACKAGE your package, then you should give the exported symbols names that make sense to use without a package prefix. Also, USE-PACKAGE must be used carefully; packages exist to *prevent* name conflicts, but when you USE-PACKAGE more than one package you are explicitly tearing down the wall that the package system puts up (but you still don't get as many conflicts as you would without packages at all, because of the internal/external distinction). Consider this: if the two classes had been in the same package wouldn't you also have gotten a conflict? The conflict wouldn't be noticed by the package system, but the conflict would have been between the two classes that define methods named NAME. In this case the conflict is benign, because they are both slot accessor methods. However, if you were to use both of them as superclasses for a new class there would only be one NAME slot, which may confuse other methods of the classes. For instance, if methods of one class expect the slot to hold a symbol, while methods of the other class expect it to hold a string, some of them won't find what they expect; if these expectations are made explicit using the :TYPE slot option, the slot in the subclass would have an effective type of (AND STRING SYMBOL), which is an empty type, so any assignment to the slot would be invalid. And what if, instead of an automatically-generated slot accessor it had been a real generic function, e.g. (defclass named-thing () (name)) (defmethod name ((object named-thing) language) (name-in-language (slot-value object 'name) language)) (defclass other-thing () ((name :accessor name))) In this case the conflict will be noticed by CLOS, because the NAME method defined automatically for OTHER-THING doesn't have a congruent lambda list to the one defined defined by the explicit DEFMETHOD. -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar