From: Wayne Christopher
Subject: Re: Using Packages With CLOS
Date: 
Message-ID: <26581@pasteur.Berkeley.EDU>
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:

	1. Make foo import the symbol name from bar, or vice versa --
	   not too modular.
	
	2. Use keywords for accessor functions.  Pretty ugly.

	3. Don't use-package either foo or bar, and use foo:name or
	   bar:name when necessary.
	
	4. Call the accessor functions foo-name and bar-name, as with
	   structures.

I've been using (4), but it was sort of an annoying surprise to
realize that converting my program to use packages would require
me to change all my accessor function names.

	Wayne
From: Barry Margolin
Subject: Re: Using Packages With CLOS
Date: 
Message-ID: <41192@think.Think.COM>
In article <·····@pasteur.Berkeley.EDU> ·······@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.

······@think.com
{uunet,harvard}!think!barmar