From: Dave Pearson
Subject: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o2al4.st.davep.news@hagbard.davep.org>
I'm playing with some CL code and have run into a little problem that
suggests to me that I'm missing a point somewhere. I wonder if someone can
give me a shove in the right direction?

I've got two totally unrelated classes in two different packages and I'm
trying to do a `use-package' on both the packages. Both of these packages
have accessor's that have the same name. When doing `use-package' I get a
clash.

The problem code can probably be best described as follows:

-- cut here ----------------------------------------------------------------
(defpackage foo 
  (:use common-lisp)
  (:export "FOO-CLASS" "XXX"))

(in-package :foo)

(defclass foo-class ()
  ((xxx :accessor xxx :initform nil)))

(defpackage bar 
  (:use common-lisp)
  (:export "BAR-CLASS" "XXX"))

(in-package :bar)

(defclass bar-class ()
  ((xxx :accessor xxx :initform nil)))

(in-package :cl-user)
(use-package :foo)
(use-package :bar)
-- cut here ----------------------------------------------------------------

(note that in the code I'm playing with I'm not actually declaring multiple
classes in one file with a package per class, the above is just a condensed
version of what I'm toying with). In all CL implementations that I've got to
hand I get a clash on XXX wheh the second `use-package' is executed.

What's got me confused here is that I can declare the two classes within the
same package and fall foul of this.

Am I simply writing "bad" CL code? Am I perhaps missing a key concept about
packages? Any pointers would be appreciated.

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.

From: Barry Margolin
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <Qoag7.5$6D6.1430@burlma1-snr2>
In article <························@hagbard.davep.org>,
Dave Pearson <·····@davep.org> wrote:
>I'm playing with some CL code and have run into a little problem that
>suggests to me that I'm missing a point somewhere. I wonder if someone can
>give me a shove in the right direction?
>
>I've got two totally unrelated classes in two different packages and I'm
>trying to do a `use-package' on both the packages. Both of these packages
>have accessor's that have the same name. When doing `use-package' I get a
>clash.

That's to be expected.  You can't have two symbols in the same package with
the same name.  The fact that they're being used to name accessors is
irrelevant; the package system is just about symbols, not their bindings.

>What's got me confused here is that I can declare the two classes within the
>same package and fall foul of this.

In that case they're both defining methods on the same generic function,
and CLOS's dispatching mechanism will select the appropriate method.  But
with different packages you're defining two unrelated generic functions,
since generic functions are found by looking up the symbol that names them.

>Am I simply writing "bad" CL code? Am I perhaps missing a key concept about
>packages? Any pointers would be appreciated.

You're missing the concept that packages are about symbols, not the objects
they refer to.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o2ft9.st.davep.news@hagbard.davep.org>
* Barry Margolin <······@genuity.net>:

> In article <························@hagbard.davep.org>,
> Dave Pearson <·····@davep.org> wrote:
> 
> >What's got me confused here is that I can declare the two classes within
> >the same package and fall foul of this.
> 
> In that case they're both defining methods on the same generic function,
> and CLOS's dispatching mechanism will select the appropriate method. But
> with different packages you're defining two unrelated generic functions,
> since generic functions are found by looking up the symbol that names
> them.

Ok, thanks, that confirms what I thought was happening. Can you suggest what
someone should consider doing when faced with this situation? Is this a case
of a bad mix of CLOS and packages or is there something I can do that makes
the code work "as is"?

> >Am I simply writing "bad" CL code? Am I perhaps missing a key concept
> >about packages? Any pointers would be appreciated.
> 
> You're missing the concept that packages are about symbols, not the
> objects they refer to.

Well, to be fair, I don't think I am missing that concept. What I am missing
is a method of untangling the problem.

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Barry Margolin
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <VNbg7.6$6D6.1483@burlma1-snr2>
In article <························@hagbard.davep.org>,
Dave Pearson <·····@davep.org> wrote:
>* Barry Margolin <······@genuity.net>:
>
>> In article <························@hagbard.davep.org>,
>> Dave Pearson <·····@davep.org> wrote:
>> 
>> >What's got me confused here is that I can declare the two classes within
>> >the same package and fall foul of this.
>> 
>> In that case they're both defining methods on the same generic function,
>> and CLOS's dispatching mechanism will select the appropriate method. But
>> with different packages you're defining two unrelated generic functions,
>> since generic functions are found by looking up the symbol that names
>> them.
>
>Ok, thanks, that confirms what I thought was happening. Can you suggest what
>someone should consider doing when faced with this situation? Is this a case
>of a bad mix of CLOS and packages or is there something I can do that makes
>the code work "as is"?

You could use a single package for both files.  Or you could use a third
package for the public names, and import these symbols into both packages,
e.g.

(defpackage public-stuff
  (:export :xxx))

(defpackage internal-1
  (:use :public-stuff :common-lisp)
  (:export :xxx))

(defpackage internal-2
  (:use :public-stuff :commin-lisp)
  (:export :xxx))

Then when you define the XXX accessors in INTERNAL-1 and INTERNAL-2,
they'll both be referencing PUBLIC-STUFF:XXX.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o42i6.st.davep.news@hagbard.davep.org>
* Barry Margolin <······@genuity.net>:

> In article <························@hagbard.davep.org>,
> Dave Pearson <·····@davep.org> wrote:
>
> >Ok, thanks, that confirms what I thought was happening. Can you suggest
> >what someone should consider doing when faced with this situation? Is
> >this a case of a bad mix of CLOS and packages or is there something I can
> >do that makes the code work "as is"?
> 
> You could use a single package for both files.  

That had obviously occurred to me but that's a case of "ignoring the
problem". Not that it is a "problem" as such, I'm simply fascinated by what
someone should do if, for example, they took two packages from two places
that happened to present this set of circumstances.

>                                                 Or you could use a third
> package for the public names, and import these symbols into both packages,
> e.g.

Thanks, I'll have a play.

Out of interest, is there any solution that doesn't involve modifying the
original files? For example, there's no reason why I couldn't be presented
with this set of circumstances while trying to use two compiled lisp files
is there (nothing to edit)?

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Barry Margolin
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <ekug7.5$KT.313@burlma1-snr2>
In article <························@hagbard.davep.org>,
Dave Pearson <·····@davep.org> wrote:
>Out of interest, is there any solution that doesn't involve modifying the
>original files? For example, there's no reason why I couldn't be presented
>with this set of circumstances while trying to use two compiled lisp files
>is there (nothing to edit)?

The problem is with the initial design.  By putting the names in different
packages, you're saying that they're not related to each other.  But in
fact, you really intended that both classes should be defining methods on
the same generic function, so you should be using the same name.

Given this intent, you need to use a common namespace, and packages define
symbol namespaces.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o52ud.st.davep.news@hagbard.davep.org>
* Barry Margolin <······@genuity.net>:

> In article <························@hagbard.davep.org>,
> Dave Pearson <·····@davep.org> wrote:
>
> >Out of interest, is there any solution that doesn't involve modifying the
> >original files? For example, there's no reason why I couldn't be
> >presented with this set of circumstances while trying to use two compiled
> >lisp files is there (nothing to edit)?
> 
> The problem is with the initial design. By putting the names in different
> packages, you're saying that they're not related to each other. But in
> fact, you really intended that both classes should be defining methods on
> the same generic function, so you should be using the same name.

That's fine if the design that has the problem is coming from one source
(which, in my case, it is so I can easily fix this). However, I'm now
wondering about the wider issue and the above doesn't seem to address this.

The wider issue I had in mind (and you quote) is when I get two bodies of
code from two different sources. Two different designs that are out of my
control. In this case the problem wouldn't be with the initial design would
it? The initial designs would be of things that are not related to each
other. The problem here would be that (excuse me if I get the terminology
wrong, I do have in mind that packages are for) I want to use the packages
that "contain" those classes without the need to prefix everything with the
package names.

I can see how this is fixed if this is related code under my control but I
can't see the fix if we're talking about unrelated code that isn't under my
control.

I'm wondering this against the backdrop of a discussion that took place here
a while ago about using packages to separate out different "people's" code.
With this in mind I've been toying with how this would work for some
play-code that I've been writing (see nntp.lisp and newsrc.lisp in the misc
section of my web site) and, in doing so, wondering what would happen if
those two files came from totally different sources.

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Barry Margolin
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <dhwg7.15$KT.186@burlma1-snr2>
In article <························@hagbard.davep.org>,
Dave Pearson <·····@davep.org> wrote:
>The wider issue I had in mind (and you quote) is when I get two bodies of
>code from two different sources. Two different designs that are out of my
>control. In this case the problem wouldn't be with the initial design would
>it? The initial designs would be of things that are not related to each
>other. The problem here would be that (excuse me if I get the terminology
>wrong, I do have in mind that packages are for) I want to use the packages
>that "contain" those classes without the need to prefix everything with the
>package names.

OK, now this is a different issue.  When you earlier wrote that it "worked"
when the classes were in the same package, I interpreted that as meaning
that both classes were trying to define methods for a common generic
function.

If these are really totally unrelated pieces of code, and they just happen
to define functions with the same names, you can't simply USE-PACKAGE both
of them.  However, this doesn't mean you have to prefix *everything*.  For
the conflicting symbols, you can use SHADOWING-IMPORT to pick one of them,
and then you'll only need to use a package prefix to access the other one.

Clearly, if the two functions are unrelated, you need some way to
disambiguate them.  The package prefix is that mechanism.  What Common Lisp
lacks that many module systems provide is a way to alias a name as it's
being imported, in order to get around clashes like this.  What you'll have
to do is define functions in your own package that accomplish it:

(declaim (inline accessor-alias))
(defun accessor-alias (object)
  (package1:accessor object))
(defsetf accessor-alias (object) (value)
  `(setf (package1:accessor ,object) ,value))

This works for functions.  If your issue were with variables, I don't think
there would be an easy solution.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o55vf.st.davep.news@hagbard.davep.org>
* Barry Margolin <······@genuity.net>:

> In article <························@hagbard.davep.org>,
> Dave Pearson <·····@davep.org> wrote:
>
> >[SNIP but what if I don't control the code?]
> 
> OK, now this is a different issue. [SNIP]

First raised in <························@hagbard.davep.org>, apologies if
it wasn't clear then.

> If these are really totally unrelated pieces of code, and they just happen
> to define functions with the same names, 

I take it that accessors come under the heading of "functions" here?

>                                          you can't simply USE-PACKAGE both
> of them. However, this doesn't mean you have to prefix *everything*. For
> the conflicting symbols, you can use SHADOWING-IMPORT to pick one of them,
> and then you'll only need to use a package prefix to access the other one.

Thanks, I'll take a look at how that would work.

> Clearly, if the two functions are unrelated, you need some way to
> disambiguate them. The package prefix is that mechanism. What Common Lisp
> lacks that many module systems provide is a way to alias a name as it's
> being imported, in order to get around clashes like this.

Good point. Again, heading off on a tangent, I started wondering about
package naming in general and providing nicknames for packages. My thoughts
here were revolving around some advice that was kicking around here a while
ago, I think it was to do with that CL code collection whose exact name
escapes me at the moment, and the idea of namespacing packages using domains
and the like (:org.davep.foo, :org.davep.bar, ...). I kept thinking that
such a scheme makes sense but that it's cumbersome when faced with the
problem I've been playing with.

If :org.davep.foo and :org.davep.bar provided nicknames then I'd be back in
a position where there might be clashes because someone might have written a
package :com.lisphacker.foo and given it a nickname of :foo (or would I?
come to think if it I've not actually *tested* what would happen there, only
assumed it would be a problem).

Sorry, end of tangent.

> (declaim (inline accessor-alias))
> (defun accessor-alias (object)
>   (package1:accessor object))
> (defsetf accessor-alias (object) (value)
>   `(setf (package1:accessor ,object) ,value))

That looks interesting. Thanks.

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Barry Margolin
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <1Syg7.23$KT.872@burlma1-snr2>
In article <························@hagbard.davep.org>,
Dave Pearson <·····@davep.org> wrote:
>* Barry Margolin <······@genuity.net>:
>
>> In article <························@hagbard.davep.org>,
>> Dave Pearson <·····@davep.org> wrote:
>>
>> >[SNIP but what if I don't control the code?]
>> 
>> OK, now this is a different issue. [SNIP]
>
>First raised in <························@hagbard.davep.org>, apologies if
>it wasn't clear then.
>
>> If these are really totally unrelated pieces of code, and they just happen
>> to define functions with the same names, 
>
>I take it that accessors come under the heading of "functions" here?

Yes.  When you define a CLOS accessor, you're just defining a method in a
generic function.

>If :org.davep.foo and :org.davep.bar provided nicknames then I'd be back in
>a position where there might be clashes because someone might have written a
>package :com.lisphacker.foo and given it a nickname of :foo (or would I?
>come to think if it I've not actually *tested* what would happen there, only
>assumed it would be a problem).

Yes, vendor-supplied nicknames like this would cause the problems that the
domain-style package names are designed to prevent.  You, the user, could
devise local nicknames for the packages you've installed, and then you
could ensure that you don't create conflicts.  But it would be
inappropriate for the vendors to do this.


-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o6knl.st.davep.news@hagbard.davep.org>
* Barry Margolin <······@genuity.net>:

> In article <························@hagbard.davep.org>,
> Dave Pearson <·····@davep.org> wrote:
> 
> >If :org.davep.foo and :org.davep.bar provided nicknames then I'd be back
> >in a position where there might be clashes because someone might have
> >written a package :com.lisphacker.foo and given it a nickname of :foo (or
> >would I? come to think if it I've not actually *tested* what would happen
> >there, only assumed it would be a problem).
> 
> Yes, vendor-supplied nicknames like this would cause the problems that the
> domain-style package names are designed to prevent. You, the user, could
> devise local nicknames for the packages you've installed, and then you
> could ensure that you don't create conflicts. But it would be
> inappropriate for the vendors to do this.

I thought you'd mentioned something like this before in the thread but,
looking back, I can't see it. How do you, as a user of a package, create a
locally defined nickname? Would I simply define my own packages that
important the original packages and then re-export all exported symbols or
is there a way of externally" adding a nickname to a package?

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Pierre R. Mai
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <87itfggvgo.fsf@orion.bln.pmsf.de>
··········@davep.org (Dave Pearson) writes:

> I thought you'd mentioned something like this before in the thread but,
> looking back, I can't see it. How do you, as a user of a package, create a
> locally defined nickname? Would I simply define my own packages that
> important the original packages and then re-export all exported symbols or
> is there a way of externally" adding a nickname to a package?

You can use RENAME-PACKAGE to add your own locally-defined nicknames
to a package, e.g.

(defun add-package-nicknames (package &rest nicknames)
  "Adds the given `nicknames' to the nicknames of `package', returning
the complete new set of nicknames of `package' as a result."
  (assert (notany #'find-package nicknames) (nicknames)
          "The following nicknames already name a package:~%  ~{~A~^~, ~}~%"
          (remove-if-not #'find-package nicknames))
  (let ((new-nicknames (union (package-nicknames package) nicknames
                              :test #'string=)))
    (rename-package package package new-nicknames)
    new-nicknames))

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Thomas A. Russ
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <ymin14sx811.fsf@sevak.isi.edu>
"Pierre R. Mai" <····@acm.org> writes:

> (defun add-package-nicknames (package &rest nicknames)
>   "Adds the given `nicknames' to the nicknames of `package', returning
> the complete new set of nicknames of `package' as a result."
>   (assert (notany #'find-package nicknames) (nicknames)
>           "The following nicknames already name a package:~%  ~{~A~^~, ~}~%"
>           (remove-if-not #'find-package nicknames))
>   (let ((new-nicknames (union (package-nicknames package) nicknames
>                               :test #'string=)))
>     (rename-package package package new-nicknames)
>     new-nicknames))
> 
> Regs, Pierre.

One minor suggestion:  Move the ASSERT form inside the LET and have it
operate on the new-nicknames.  That way you would not raise an error if
you were redundantly adding an existing nickname to a package.

This would be useful if you, for example, invoked the
add-package-nicknames function more than once with the same nickname for
the same package.  I could easily see this happening during development,
particularly if you ended up having the form in a file which was loaded
more than once.

-Tom.

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Pierre R. Mai
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <87lmk9w12n.fsf@orion.bln.pmsf.de>
···@sevak.isi.edu (Thomas A. Russ) writes:

> "Pierre R. Mai" <····@acm.org> writes:
> 
> > (defun add-package-nicknames (package &rest nicknames)
> >   "Adds the given `nicknames' to the nicknames of `package', returning
> > the complete new set of nicknames of `package' as a result."
> >   (assert (notany #'find-package nicknames) (nicknames)
> >           "The following nicknames already name a package:~%  ~{~A~^~, ~}~%"
> >           (remove-if-not #'find-package nicknames))
> >   (let ((new-nicknames (union (package-nicknames package) nicknames
> >                               :test #'string=)))
> >     (rename-package package package new-nicknames)
> >     new-nicknames))
> > 
> > Regs, Pierre.
> 
> One minor suggestion:  Move the ASSERT form inside the LET and have it
> operate on the new-nicknames.  That way you would not raise an error if
> you were redundantly adding an existing nickname to a package.

I wouldn't do this in an operation named ADD-PACKAGE-NICKNAMES, but
rather in an operation named ENSURE-PACKAGE-NICKNAMES, which I'd agree
would be a better interface for most stuff people might want to do.

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Kent M Pitman
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sfwae0syysn.fsf@world.std.com>
"Pierre R. Mai" <····@acm.org> writes:

> 
> ··········@davep.org (Dave Pearson) writes:
> 
> > I thought you'd mentioned something like this before in the thread but,
> > looking back, I can't see it. How do you, as a user of a package, create a
> > locally defined nickname? Would I simply define my own packages that
> > important the original packages and then re-export all exported symbols or
> > is there a way of externally" adding a nickname to a package?
> 
> You can use RENAME-PACKAGE to add your own locally-defined nicknames
> to a package, e.g.
> 
> (defun add-package-nicknames (package &rest nicknames)
>   "Adds the given `nicknames' to the nicknames of `package', returning
> the complete new set of nicknames of `package' as a result."
>   (assert (notany #'find-package nicknames) (nicknames)
>           "The following nicknames already name a package:~%  ~{~A~^~, ~}~%"
>           (remove-if-not #'find-package nicknames))
>   (let ((new-nicknames (union (package-nicknames package) nicknames
>                               :test #'string=)))
>     (rename-package package package new-nicknames)
>     new-nicknames))

I think you should maybe also check that the added nicknames are not
the proper name of the package.  (It's perhaps not "obvious enough"
what the term "conflicts with" means in the definition of rename-package.)
Also, I don't know if I'd signal an error in the case of adding a nickname
that was already a proper name, or just make sure not to pass a redundant
nickname in new-nicknames to rename-package.  What I'd be tempted to do
would be to demote the package name to a nickname, but for the fact that
it wouldn't be obvious what to promote as the new name, so there's no way
to proceed on that intent; probably that fact argues for signaling an error,
to make sure the user knows what he's doing.

Of late, I've come to feel that nicknames should be highly maleable but
that package-name should be firmly affixed.  In that theory, certainly
not part of the spec, just my own private thought, it matters quite a lot
what is a package-name and what's a nickname, since things that are package
names are not eligible to be package nicknames.  FORTUNATELY, in that 
same theory as I've been cooking up, all package names have dots in them
and all package nicknames don't, so it's not such a big deal.  (By which
I mean "COM.HYPERMETA.DOC.MIME.BASE64" might be a package name, but "BASE64"
would be a nickname.  The former would be fixed, so it could be dumped 
reliably in output files such as fasl files, but the later would be 
established by a body of code or purposes of loading that code but could
not be relied upon to survive after the body of code loaded (because it
could know and debug any package renames that might happen due to code it 
loads but it couldn't know or expect any package renames due to code that
loads it or due to runtime effects beyond its own comfortable little scope).

In this regard, I'm soon going to make my own variant of defpackage that
basically allows nicknames to freely clobber one another without error, with
a "most recent claimant wins" theory, perhaps doing typeout for informational
purposes when this steals a nickname from someone else.  

Has anyone else done any thoughts in this general area?
From: Daniel Barlow
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <87zo8say9s.fsf@noetbook.telent.net>
Kent M Pitman <······@world.std.com> writes:
> In this regard, I'm soon going to make my own variant of defpackage that
> basically allows nicknames to freely clobber one another without error, with
> a "most recent claimant wins" theory, perhaps doing typeout for informational
> purposes when this steals a nickname from someone else.  

What I'd really like is something that addresses the situation of
providers of layered functionality.  As the author of, say,
"NET.TELENT.MAIL.IMAP" (a fictional package, please don't ask me for
the code) I'd like to refer to your "COM.HYPERMETA.DOC.MIME.BASE64"
package using the prefix "BASE64", but without forcing that nickname
to be visible to users of _my_ package.

A nickname-clobbering defpackage-like form will get most of the way
there, but is kind of messy during development.  If I have a running
system in which I want to edit some form in "NET.TELENT.MAIL.IMAP",
and the form has BASE64:FOO in it, I can no longer simply recompile
that function using C-z C-c in emacs or what-have-you, because the
user may by now be using "BASE64" to point to some other package.
Instead I have to reload the package declaration and the entire file -
and then the package declarations for the user's packages to restore
the nicknames to their "normal" values.  This is probably great news
for vendors of defsystem facilities, but just another thing to go
wrong for anyone else.

But no, I don't have a better answer that doesn't involve
implementation extensions ...

(defpackage "NET.TELENT.MAIL.IMAP"
  (:use ("COM.HYPERMETA.DOC.MIME.BASE64" :nickname "BASE64")
        ("USENET.COMP.LANG.LISP.STRING-UTILITIES" :nickname "STRING")
        ;; ....
        ))


-dan

-- 

  http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources 
From: Pierre R. Mai
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <87pu9odsg2.fsf@orion.bln.pmsf.de>
Kent M Pitman <······@world.std.com> writes:

> "Pierre R. Mai" <····@acm.org> writes:
> 

[...]

> > You can use RENAME-PACKAGE to add your own locally-defined nicknames
> > to a package, e.g.
> > 
> > (defun add-package-nicknames (package &rest nicknames)
> >   "Adds the given `nicknames' to the nicknames of `package', returning
> > the complete new set of nicknames of `package' as a result."
> >   (assert (notany #'find-package nicknames) (nicknames)
> >           "The following nicknames already name a package:~%  ~{~A~^~, ~}~%"
> >           (remove-if-not #'find-package nicknames))
> >   (let ((new-nicknames (union (package-nicknames package) nicknames
> >                               :test #'string=)))
> >     (rename-package package package new-nicknames)
> >     new-nicknames))
> 
> I think you should maybe also check that the added nicknames are not
> the proper name of the package.  (It's perhaps not "obvious enough"
> what the term "conflicts with" means in the definition of rename-package.)

Hmmm, doesn't the assert do this already?  I.e. if any added nickname
names a package (either as a nickname or a proper name, including the
package being affected), find-package will find it, and hence cause an
error... Or am I misunderstanding you?

> In this regard, I'm soon going to make my own variant of defpackage that
> basically allows nicknames to freely clobber one another without error, with
> a "most recent claimant wins" theory, perhaps doing typeout for informational
> purposes when this steals a nickname from someone else.  
> 
> Has anyone else done any thoughts in this general area?

I've thought that maybe adding "file-local" nicknames, which are
specified through some form of extended in-package form might be the
ticket, i.e. something like

(in-package* :NET.PMSF.APPS.FUTURE-PERFECT
  (:access-as :NET.PMSF.LIBS.CLASH :CLASH)
  (:access-as :NET.PMSF.LIBS.CLIX :CLIX))

This would be good if the added nick-names were as transient as the
effect of the in-package form in a file to be compiled, but that is
difficult to achieve without implementation cooperation, so the free
clobbering of nicknames might be a more workable solution.

I'm not sure whether it would be better to have this kind of stuff in
a defpackage* form (less typing, but less immediacy w.r.t. the thing
one might want to affect, and more suggested permanence), and/or
allowing both.

Though I have to admit I haven't thought this kind of thing through
very seriously, so this might run afoul of lots of things...

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Marco Antoniotti
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <y6cy9ocqbed.fsf@octagon.mrl.nyu.edu>
"Pierre R. Mai" <····@acm.org> writes:

	...

> I've thought that maybe adding "file-local" nicknames, which are
> specified through some form of extended in-package form might be the
> ticket, i.e. something like
> 
> (in-package* :NET.PMSF.APPS.FUTURE-PERFECT
>   (:access-as :NET.PMSF.LIBS.CLASH :CLASH)
>   (:access-as :NET.PMSF.LIBS.CLIX :CLIX))
> 
> This would be good if the added nick-names were as transient as the
> effect of the in-package form in a file to be compiled, but that is
> difficult to achieve without implementation cooperation, so the free
> clobbering of nicknames might be a more workable solution.

This is akin to Ada 'renames' operation.  As long as the scope is well
delimited I like it.

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Pierre R. Mai
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <87d75lw0js.fsf@orion.bln.pmsf.de>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> "Pierre R. Mai" <····@acm.org> writes:
> 
> 	...
> 
> > I've thought that maybe adding "file-local" nicknames, which are
> > specified through some form of extended in-package form might be the
> > ticket, i.e. something like
> > 
> > (in-package* :NET.PMSF.APPS.FUTURE-PERFECT
> >   (:access-as :NET.PMSF.LIBS.CLASH :CLASH)
> >   (:access-as :NET.PMSF.LIBS.CLIX :CLIX))
> > 
> > This would be good if the added nick-names were as transient as the
> > effect of the in-package form in a file to be compiled, but that is
> > difficult to achieve without implementation cooperation, so the free
> > clobbering of nicknames might be a more workable solution.
> 
> This is akin to Ada 'renames' operation.  As long as the scope is well
> delimited I like it.

Yes, but scoping is the key problem here, since file-wide scoping
probably needs support from the implementation...

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Marco Antoniotti
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <y6cr8u0dn2a.fsf@octagon.mrl.nyu.edu>
"Pierre R. Mai" <····@acm.org> writes:

> Marco Antoniotti <·······@cs.nyu.edu> writes:
> 
> > "Pierre R. Mai" <····@acm.org> writes:
> > 
> > 	...
> > 
> > > I've thought that maybe adding "file-local" nicknames, which are
> > > specified through some form of extended in-package form might be the
> > > ticket, i.e. something like
> > > 
> > > (in-package* :NET.PMSF.APPS.FUTURE-PERFECT
> > >   (:access-as :NET.PMSF.LIBS.CLASH :CLASH)
> > >   (:access-as :NET.PMSF.LIBS.CLIX :CLIX))
> > > 
> > > This would be good if the added nick-names were as transient as the
> > > effect of the in-package form in a file to be compiled, but that is
> > > difficult to achieve without implementation cooperation, so the free
> > > clobbering of nicknames might be a more workable solution.
> > 
> > This is akin to Ada 'renames' operation.  As long as the scope is well
> > delimited I like it.
> 
> Yes, but scoping is the key problem here, since file-wide scoping
> probably needs support from the implementation...

Exactly my point.

And what about things like...

	(in-package "ZUT")

	;;; stuff

	(in-package "ZOT")

	;;; other stuff

	;;; eof.

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Kent M Pitman
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sfwhev0uhcd.fsf@world.std.com>
"Pierre R. Mai" <····@acm.org> writes:

> > I think you should maybe also check that the added nicknames are not
> > the proper name of the package.  (It's perhaps not "obvious enough"
> > what the term "conflicts with" means in the definition of rename-package.)
> 
> Hmmm, doesn't the assert do this already?  I.e. if any added nickname
> names a package (either as a nickname or a proper name, including the
> package being affected), find-package will find it, and hence cause an
> error... Or am I misunderstanding you?

No.  I'm just braindead today, I guess.  Sigh.

> I've thought that maybe adding "file-local" nicknames, which are
> specified through some form of extended in-package form might be the
> ticket, i.e. something like
> 
> (in-package* :NET.PMSF.APPS.FUTURE-PERFECT
>   (:access-as :NET.PMSF.LIBS.CLASH :CLASH)
>   (:access-as :NET.PMSF.LIBS.CLIX :CLIX))
> 

This might be fine or might not, depending on what you mean.  If by
"file local" you mean "dynamically scoped to the load of the package",
that could work by having in-package* communicate with LOAD in order
to tell it how to instantiate and de-instantiate these.  Recursive loads
would also have to undo them temporarily and then re-instantiate them.
But the effect would not be lexical, so code that delayed syntax
(e.g. storing strings that were later read-from-string'd) or that did
later interning would not see these.

Also, remember that CLTL1's IN-PACKAGE allowed you to specify :USE and we
moved away from that because different calls to IN-PACKAGE disagreed on
the use list.  It wasn't obvious if they were trying to edit the definition
made by a previous IN-PACKAGE (to remove :USE'd stuff) or just be shorthand
to avoid having to use the same list of packages every time.  That's why
we separated "package definition" (defpackage) from "package selection
(in-package) in the ANSI-CL spec.  So the above usage moves away from that.

The truly right solution would probably be associating globally a set of
relative names available when in a given package.  The Lisp Machine has this.
It also allows you to associate them by syntax (approximately, readtable)
so that in CL (i.e., CLTL1) syntax, package "USER" gets a "CL-USER"
package but in ZL (i.e., Zetalisp) syntax, package "USER" gets "ZL-USER".
But it's hard to make that kind of thing work without system cooperation
because you have to minimally rewrite READ since any call to read will
see package prefixes and that in turn will try to do FIND-PACKAGE using
the system's algorithm instead of any shadowed user one that tries to
implement a new abstraction.  And since COMPILE-FILE calls READ...
One could perhaps make a readtable in which every character was a trampoline
to an alternate reader that worked differently, but even so, maintaining an
efficient implementation of READ on every Lisp implementation would be tough.

So I just don't see a way to do that.

The simpler thing (in the spirit of worse-is-better) would simply be to
say that user programs at runtime must use package names, not package
nicknames, and that only at load-time or user interaction time were you
allowed to use nicknames... 

On the other hand, I've made a big project the last six months of writing
a LOT of code using much-smaller-than-usual packages, more like Java,
with the result being that it was much easier to decide to :USE just
the functionality I need, and there were many fewer symbol conflicts.
So I could almost always USE pacakges instead of doing explicit references,
and in the RARE case where an explicit package reference is needed, it's
not really that awkward to use the long name.  So I'm starting to mostly
disbelieve the short names are ever REALLY needed, other than for backward
compatibility.
From: Pierre R. Mai
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <878zg9vyyw.fsf@orion.bln.pmsf.de>
Kent M Pitman <······@world.std.com> writes:

> > I've thought that maybe adding "file-local" nicknames, which are
> > specified through some form of extended in-package form might be the
> > ticket, i.e. something like
> > 
> > (in-package* :NET.PMSF.APPS.FUTURE-PERFECT
> >   (:access-as :NET.PMSF.LIBS.CLASH :CLASH)
> >   (:access-as :NET.PMSF.LIBS.CLIX :CLIX))
> > 
> 
> This might be fine or might not, depending on what you mean.  If by
> "file local" you mean "dynamically scoped to the load of the package",
> that could work by having in-package* communicate with LOAD in order
> to tell it how to instantiate and de-instantiate these.  Recursive loads
> would also have to undo them temporarily and then re-instantiate them.
> But the effect would not be lexical, so code that delayed syntax
> (e.g. storing strings that were later read-from-string'd) or that did
> later interning would not see these.

I'd opt for the worse-is-better solution, which was scoped like an
in-package form at top-level (which also has only dynamically scoped
effect, since compile-file and load both re-bind *package* around the
operation).  Invoking the reader at run-time already has to worry
about letting *package* be the right package, so worrying about
nicknames would probably not be too onerous.

In effect this would be as if there was a special variable
*current-nicknames*, which was rebound around compile-file/load, and
which was modified by the in-package* form via setq (possibly
non-destructively merging existing content).

> Also, remember that CLTL1's IN-PACKAGE allowed you to specify :USE and we
> moved away from that because different calls to IN-PACKAGE disagreed on
> the use list.  It wasn't obvious if they were trying to edit the definition
> made by a previous IN-PACKAGE (to remove :USE'd stuff) or just be shorthand
> to avoid having to use the same list of packages every time.  That's why
> we separated "package definition" (defpackage) from "package selection
> (in-package) in the ANSI-CL spec.  So the above usage moves away from that.

Not really, if we started to think of nicknames as something that
isn't associated with the package (i.e. part of the package
definition), but rather is part of the current global state of the
reader, much like *readtable*.  One could of course think of
USE-PACKAGE relations in a similar vein, and I'd say that e.g. EXPORTs
are distinctly part of the package state, and should hence be part of
the package definition.

Or then again one could of move the nicknames into the "target
package", and specify access-as relationships in the defpackage form
of _that_ package.

But any of this stuff needs cooperation from the implementation to be
implemented cleanly, and hence this is something that will likely not
happen in the next couple of years, especially since some of the
changes would likely have some kind of user impact.

> On the other hand, I've made a big project the last six months of writing
> a LOT of code using much-smaller-than-usual packages, more like Java,
> with the result being that it was much easier to decide to :USE just
> the functionality I need, and there were many fewer symbol conflicts.
> So I could almost always USE pacakges instead of doing explicit references,
> and in the RARE case where an explicit package reference is needed, it's
> not really that awkward to use the long name.  So I'm starting to mostly
> disbelieve the short names are ever REALLY needed, other than for backward
> compatibility.

Indeed, even using larger-size packages, I've found that conflicts are
rare enough that this really isn't that much of a problem, so making
short nick-names work is probably something not to worry about.  The
in-package* stuff was just something that's been bouncing around in my
head each time nicknames were brought up, so I thought I'd bring it
up now, before it got lost again...

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Christophe Rhodes
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sqvgjgworb.fsf@lambda.jesus.cam.ac.uk>
··········@davep.org (Dave Pearson) writes:

> If :org.davep.foo and :org.davep.bar provided nicknames then I'd be
> back in a position where there might be clashes because someone
> might have written a package :com.lisphacker.foo and given it a
> nickname of :foo (or would I?  come to think if it I've not actually
> *tested* what would happen there, only assumed it would be a
> problem).

Before someone else says it, I'll chip in: *testing* isn't what you
want to do here; I strongly suggest that you read what the
specification, which is (more-or-less) available online, has to say
about this.

Christophe
-- 
Jesus College, Cambridge, CB5 8BL                           +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/                  (defun pling-dollar 
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o6p8i.st.davep.news@hagbard.davep.org>
* Christophe Rhodes <·····@cam.ac.uk>:

> ··········@davep.org (Dave Pearson) writes:
> 
> > (or would I? come to think if it I've not actually *tested* what would
> > happen there, only assumed it would be a problem).
> 
> Before someone else says it, I'll chip in: *testing* isn't what you want
> to do here; I strongly suggest that you read what the specification, which
> is (more-or-less) available online, has to say about this.

Apologies, that was sloppy wording wasn't it? When I say testing I mean
"read the docs, see what they say, test my understanding by playing with it
in a couple of implementations".

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Kent M Pitman
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sfwofp9basd.fsf@world.std.com>
··········@davep.org (Dave Pearson) writes:

> * Barry Margolin <······@genuity.net>:
> 
> > In article <························@hagbard.davep.org>,
> > Dave Pearson <·····@davep.org> wrote:
> >
> > >Out of interest, is there any solution that doesn't involve modifying the
> > >original files? For example, there's no reason why I couldn't be
> > >presented with this set of circumstances while trying to use two compiled
> > >lisp files is there (nothing to edit)?
> > 
> > The problem is with the initial design. By putting the names in different
> > packages, you're saying that they're not related to each other. But in
> > fact, you really intended that both classes should be defining methods on
> > the same generic function, so you should be using the same name.
> 
> That's fine if the design that has the problem is coming from one source
> (which, in my case, it is so I can easily fix this). However, I'm now
> wondering about the wider issue and the above doesn't seem to address this.
> 
> The wider issue I had in mind (and you quote) is when I get two bodies of
> code from two different sources. Two different designs that are out of my
> control. In this case the problem wouldn't be with the initial design would
> it? The initial designs would be of things that are not related to each
> other. The problem here would be that (excuse me if I get the terminology
> wrong, I do have in mind that packages are for) I want to use the packages
> that "contain" those classes without the need to prefix everything with the
> package names.
> 
> I can see how this is fixed if this is related code under my control but I
> can't see the fix if we're talking about unrelated code that isn't under my
> control.

Either the maintainers need to get email from you explaining the problem
or else you need to encourage whoever owns the unmaintained code to get a
maintainer that you can communicat with or else the code, de facto, has
a desire not to be linked in the way you want to do.

That doesn't mean there isn't a technical workaround, but it does mean the
Right solution has been denied you.

Communciation and code editing IS the right solution.
 
> I'm wondering this against the backdrop of a discussion that took place here
> a while ago about using packages to separate out different "people's" code.

I don't agree that separating people's code can be the whole answer.
One cannot cooperate without some degree of communication.  There is
an obligation not only to separate (use DEFPACKAGE) but also to publish/share
(use EXPORT/IMPORT).  If you fail to do this, you're just separating people
you are isolating them.

> With this in mind I've been toying with how this would work for some
> play-code that I've been writing (see nntp.lisp and newsrc.lisp in the misc
> section of my web site) and, in doing so, wondering what would happen if
> those two files came from totally different sources.

To do it without editing sources is tricky, but it can be done, I think.
You have to figure which package you are loading first.  Then you have
to take the package declaration for the second and copy it into another
file.  Then the procedure is:

 (load "system1-loader.lisp")
 (load "system2-package-declaration.lisp")
 (setf (symbol-function 'system2::my-shared-generic-function)
       (symbol-function 'system1::my-shared-generic-function))
 (load "system2-loader.lisp")

This is different than the solution Barry proposes (though his will work
also--it requires some editing of the files).  In this case, you're causing
the generic function itself to be pre-loaded into system2's symbol.  That
way, when system2 does ensure-generic-function on the relevant symbol,
system2::my-shared-generic-function in my example, there will
already be a generic function object.  Methods will just be added to that,
and those methods will be reflectd by the symbols in both packages.

At least, that's the way I understand it to work.  I never tried it
myself.  Personally, I think this is a silly way to resolve the
problem.  The right way is, as Barry suggests, to edit the package
declaration of one or both systems.  However, my point here is to say
that in spite of that, I think CL is robust enough to work around the
problem in any case--probably better than most languages would.  But
the fact that a solution exists to a bizarrely framed problem does not
imply you should rush to use it rather than revisiting the problem
statement with a skeptical eye.
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o6l6e.st.davep.news@hagbard.davep.org>
* Kent M Pitman <······@world.std.com>:

> ··········@davep.org (Dave Pearson) writes:
> 
> > I'm wondering this against the backdrop of a discussion that took place
> > here a while ago about using packages to separate out different
> > "people's" code.
> 
> I don't agree that separating people's code can be the whole answer. One
> cannot cooperate without some degree of communication. There is an
> obligation not only to separate (use DEFPACKAGE) but also to publish/share
> (use EXPORT/IMPORT). If you fail to do this, you're just separating people
> you are isolating them.

I'm afraid I can't see the meaning in the above. First you seem to disagree,
in part, with the idea of different authors using different packages but
then you seem to suggest that it's an obligation. Apologies for my lack of
comprehension. Could you elaborate?

> At least, that's the way I understand it to work. I never tried it myself.
> Personally, I think this is a silly way to resolve the problem. The right
> way is, as Barry suggests, to edit the package declaration of one or both
> systems. However, my point here is to say that in spite of that, I think
> CL is robust enough to work around the problem in any case--probably
> better than most languages would. But the fact that a solution exists to a
> bizarrely framed problem does not imply you should rush to use it rather
> than revisiting the problem statement with a skeptical eye.

Why is it a bizarrely framed problem? I ran into exactly this problem with
my own code. Now, obviously, I own the code and I can fix it. However, the
next obvious question seems to be "what if the code comes from different
sources and what if the code is seen, at least for now, as a black box". As
Barry has said, using package prefixes is the solution here and some
languages allow you to use aliases when you import a package/module, saving
you the effort of having to type com.a-really-long-package.prefix before
each symbol.

What's bizarrely framed about that?

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Kent M Pitman
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sfwhev0k15d.fsf@world.std.com>
··········@davep.org (Dave Pearson) writes:

> * Kent M Pitman <······@world.std.com>:
> 
> > ··········@davep.org (Dave Pearson) writes:
> > 
> > > I'm wondering this against the backdrop of a discussion that took place
> > > here a while ago about using packages to separate out different
> > > "people's" code.
> > 
> > I don't agree that separating people's code can be the whole answer. One
> > cannot cooperate without some degree of communication. There is an
> > obligation not only to separate (use DEFPACKAGE) but also to publish/share
> > (use EXPORT/IMPORT). If you fail to do this, you're just separating people
> > you are isolating them.
> 
> I'm afraid I can't see the meaning in the above. First you seem to disagree,
> in part, with the idea of different authors using different packages but
> then you seem to suggest that it's an obligation. Apologies for my lack of
> comprehension. Could you elaborate?

I'm saying they may well need to separate their "scratch areas" but they
must not separate their "communication area".  They have an obligation
to export symbols and import others symbols in order to assure that a
symbol FOO that they need to cooperate about is the same symbol and not
a different one.

If they are working on a project with a certain common API, they should
probably have a common package definition that they both inherit that has
the symbols they will both want to use. e.g.,

 (defpackage "ACME-COMMON-PROTOCOL"
   (:use)
   (:export "FOO" "BAR"))

 (defpackage "FRED-STUFF"
   (:use "LISP" "ACME-COMMON-PROTOCOL")
   (:export "FOO"))

 (defpackage "SALLY-STUFF"
   (:use "LISP" "ACME-COMMON-PROTOCOL")
   (:export "BAR"))

These people can both cross-call in their use of FOO and BAR, which will
be the same symbol.  Yet they can make independent choices about what 
symbols to export.

> > At least, that's the way I understand it to work. I never tried it myself.
> > Personally, I think this is a silly way to resolve the problem. The right
> > way is, as Barry suggests, to edit the package declaration of one or both
> > systems. However, my point here is to say that in spite of that, I think
> > CL is robust enough to work around the problem in any case--probably
> > better than most languages would. But the fact that a solution exists to a
> > bizarrely framed problem does not imply you should rush to use it rather
> > than revisiting the problem statement with a skeptical eye.
> 
> Why is it a bizarrely framed problem? I ran into exactly this problem with
> my own code.

Because you refuse to edit any of the code.  It's very rare that you 
can understand the code well enough to see what the problem is, yet not
have access to code to edit.

> Now, obviously, I own the code and I can fix it.

Exactly.

> However, the
> next obvious question seems to be "what if the code comes from different
> sources and what if the code is seen, at least for now, as a black box".

Then it's unlikely they really are managing the same GF, and so it's unlikely
there's a conflict.

> As
> Barry has said, using package prefixes is the solution here and some
> languages allow you to use aliases when you import a package/module, saving
> you the effort of having to type com.a-really-long-package.prefix before
> each symbol.
> 
> What's bizarrely framed about that?
From: Dave Pearson
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <slrn9o6ph3.st.davep.news@hagbard.davep.org>
* Kent M Pitman <······@world.std.com>:

> ··········@davep.org (Dave Pearson) writes:
> 
> > Why is it a bizarrely framed problem? I ran into exactly this problem
> > with my own code.
> 
> Because you refuse to edit any of the code. 

Where have I refused to edit any code?

>                                             It's very rare that you can
> understand the code well enough to see what the problem is, yet not have
> access to code to edit.

All I'm asking about is, if someone was presented with a situation where
they don't have the source (I'm assuming that this is possible in CL,
perhaps it isn't and I've missed this subtle point?) for the two packages
and the package names are annoyingly long, what would be a good route out of
this.

I'm not sure how someone can read refusal to edit code from that.

> > Now, obviously, I own the code and I can fix it.
> 
> Exactly.

Not exactly really because the question has moved on from my own code. That
issues had been addressed (thanks to everyone who gave input) and I've moved
on in my question.

> > However, the next obvious question seems to be "what if the code comes
> > from different sources and what if the code is seen, at least for now,
> > as a black box".
> 
> Then it's unlikely they really are managing the same GF, and so it's
> unlikely there's a conflict.

GF?

> [SNIP the rest of my post quoted]

Was that a snip slip or did some of your text go missing?

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Pierre R. Mai
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <87elq4gtis.fsf@orion.bln.pmsf.de>
··········@davep.org (Dave Pearson) writes:

> > > However, the next obvious question seems to be "what if the code comes
> > > from different sources and what if the code is seen, at least for now,
> > > as a black box".
> > 
> > Then it's unlikely they really are managing the same GF, and so it's
> > unlikely there's a conflict.
> 
> GF?

Generic function.  It seems to me that there's a certain level of
talking at cross purposes going on, so I'll take the liberty of
retelling some of the things said in a different way:

- Your original problem is that two non-cooperating packages export
  two "same-named" symbols.  Then a problem occurs when you want to
  use (in the use-package sense!) both packages in your own package.

  The simplest solution of course is not to use (again use-package
  sense) both packages, but rather to refer to one (or both) via
  package prefixes (either via full package names, or more likely via
  useful, (possibly locally defined) package nicknames).  This IMHO
  will also increase readability to the human reader, since he'll
  likely be similarly confused as the CL reader.

  A slightly more complex solution, but one which allows you to write
  most code without package prefixes, would be to still use
  (use-package sense!) both packages, and decide which of the two
  conflicting symbols you want to be available without a prefix, and
  which not, using SHADOWING-IMPORT (or more likely the
  SHADOWING-IMPORT-FROM keyword argument of DEFPACKAGE):

  (defpackage :my-own-package 
    (:shadowing-import-from :OTHER1 #:CLASHING-SYMBOL)
    (:use :OTHER1 :OTHER2))

  In this way no conflict arises, because everything can be
  unambiguously resolved, since in MY-OWN-PACKAGE CLASHING-SYMBOL will
  now be EQ to OTHER1:CLASHING-SYMBOL, and OTHER2:CLASHING-SYMBOL must
  be accessed with a package prefix.

  And if you don't want to favour one symbol against the other, you
  can use SHADOW (or the :SHADOW keyword argument of DEFPACKAGE), to
  force both SYMBOLS to be accessed with a package prefix, reserving
  the unprefixed notation for a new symbol in your own package:

  (defpackage :my-own-package 
    (:shadow #:CLASHING-SYMBOL)
    (:use :OTHER1 :OTHER2))

  All of these solutions don't require any form of source access or
  source editing in foreign code.

- Since there is no general theory of merging different symbols into
  one (which would require merging all of their properties, like
  symbol-values, symbol-functions, symbol-properties, etc., as well as
  violating many important identity-preservation laws), there exists
  no general solution which will can let both OTHER1:CLASHING-SYMBOL
  and OTHER2:CLASHING-SYMBOL be accessible in MY-OWN-PACKAGE without a
  package prefix needed for disambiguation.  This is no problem, since
  the symbols in question aren't semantically equivalent (or at least
  compatible) in the first place, hence merging would be a confusing
  and dangerous thing to do.

- In your particular case, since the symbols in question only name
  generic functions (here an accessors), which in this case don't have
  overlapping definitions (methods defined on them), a specific theory
  for merging those into one can be thought of, and people have given
  you hints on how one might go about this kind of merging after the
  fact.

- BUT, again, this kind of merging seems only defensible, IFF the two
  generic functions are indeed semantically equivalent, i.e. the
  operation defined by each GF (not to be confused by the actions
  carried out by their methods) is semantically equivalent.

  Since this kind of thing doesn't generally happen by accident, it
  must be assumed that it was achieved by design.  But in that case
  the authors of the different packages should have cooperated some
  more, and ensured that they defined their methods on one, shared GF
  in the first place (which means one shared symbol), and hence your
  problem would never have occurred anyway.

  And if it did happen by accident, now is the time to reintegrate
  this accidental discovery into the design of each package, again via
  either cooperation between the authors (prompted by feed-back from
  the user(s)), or through the users themselves if support from the
  original authors can (no-longer) be obtained.

  And if the GFs aren't semantically equivalent, then it would be a
  grave error to merge them into one, regardless of which package they
  were defined in (even if its the same package and different
  symbols).

- AFAIU, the issue of coordination between authors for ensuring that
  semantically equivalent things (like GFs) are defined on a shared
  symbol, is what KMP was talking about.  Without some form of
  (out-of-band) coordination, it is not even possible to ensure
  that the two things in question are indeed semantically equivalent,
  and the package system issues are only technical side-issues in
  that context.  The package system ensures total isolation between
  worlds automatically (if used correctly), without any form of
  cooperation/coordination needed.  When you decide to breach
  that isolation in order to cooperate/coordinate, you must also
  coordinate your actions through out-of-band channels, or else chaos
  will ensue.

I hope this helps clear up some of the issues involved...

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Thomas A. Russ
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <ymilmkcx7op.fsf@sevak.isi.edu>
"Pierre R. Mai" <····@acm.org> writes:

> - BUT, again, this kind of merging seems only defensible, IFF the two
>   generic functions are indeed semantically equivalent, i.e. the
>   operation defined by each GF (not to be confused by the actions
>   carried out by their methods) is semantically equivalent.
> 
>   Since this kind of thing doesn't generally happen by accident, it
>   must be assumed that it was achieved by design.

Although for certain "common" accessor names, one may easily end up
getting serendipitous name overlaps.  For example NAME or ID seem like
they might be common enough to have such overlaps.

However, unless you are building a very general purpose tool like an
object browser, it seems likely that you would not be using objects from
the two packages interchangeably in your code.  At any given point, you
would most likely need to know which general sort of object you were
using, so this is unlikely to present a real problem in practice.
(Which is a long-winded way of saying that I agree with you).


-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Kent M Pitman
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sfwitffqvbs.fsf@world.std.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> "Pierre R. Mai" <····@acm.org> writes:
> 
> > - BUT, again, this kind of merging seems only defensible, IFF the two
> >   generic functions are indeed semantically equivalent, i.e. the
> >   operation defined by each GF (not to be confused by the actions
> >   carried out by their methods) is semantically equivalent.
> > 
> >   Since this kind of thing doesn't generally happen by accident, it
> >   must be assumed that it was achieved by design.
> 
> Although for certain "common" accessor names, one may easily end up
> getting serendipitous name overlaps.  For example NAME or ID seem like
> they might be common enough to have such overlaps.

Yes, I have run into conflicts of this kind with NAME and ID.  CL ran into
this with BOOLEAN which CLIM wanted to add and which some implementations
like Symbolics already had and it was tricky to unify them.  So you're right
it does happen.  But always the answer is to figure out who's going to load
first and get one to modify their defpackage, or else to make some sort of
"common" package that all concerned agree to use and share... or else you
end up doing the thing barry suggested with :shadowing-import.
From: Tim Bradshaw
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <nkjg0ajglzj.fsf@omega.tardis.ed.ac.uk>
···@sevak.isi.edu (Thomas A. Russ) writes:

> 
> Although for certain "common" accessor names, one may easily end up
> getting serendipitous name overlaps.  For example NAME or ID seem like
> they might be common enough to have such overlaps.

I recently worked on some code where I wanted to use ID as an accessor
name for classes I wrote.  The system already used ID in classes it
defined for the same purpose I wanted to use it, but unfortunately all
the 'accessors' it defined had a lambda list of (x &key), causing me
enormous pain.  I forget how I solved this - maybe I gave up and
defined a method on ID which called my internal ID accessor
immediately...

--tim
From: Pierre R. Mai
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <87heuxw0lr.fsf@orion.bln.pmsf.de>
···@sevak.isi.edu (Thomas A. Russ) writes:

> "Pierre R. Mai" <····@acm.org> writes:
> 
> > - BUT, again, this kind of merging seems only defensible, IFF the two
> >   generic functions are indeed semantically equivalent, i.e. the
> >   operation defined by each GF (not to be confused by the actions
> >   carried out by their methods) is semantically equivalent.
> > 
> >   Since this kind of thing doesn't generally happen by accident, it
> >   must be assumed that it was achieved by design.
> 
> Although for certain "common" accessor names, one may easily end up
> getting serendipitous name overlaps.  For example NAME or ID seem like
> they might be common enough to have such overlaps.

While these name overlaps might occur quite often, I'd question
whether the operations in question are really semantically equivalent
in most of those cases.  An ID might be something quite different for
the one package than for the other (e.g. one dealing with Ethernet
networking interfaces using MAC addresses, vs. one dealing with unix
processes), and so the restraints put on methods implementing those
GFs could likewise differ substantially.

So even if this clash happens accidentally, finding out whether the
semantics match will always have to be a conscious choice.

I've been bitten a number of times when overloading or "re-using" a GF
for another purpose that semantically differed only minimally, which
later got me into trouble when I'd forgotten about it.  Since then
I've become very defensive w.r.t. protocol design issues like these.
I'd rather have one GF too many than one too few, and that includes
accessors.  Which is one reason why I wouldn't have NAME or ID
accessors in the first place, but rather something more specialized
like NETWORK-INTERFACE-GUID, etc.

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Kent M Pitman
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sfwbsl8yzh4.fsf@world.std.com>
"Pierre R. Mai" <····@acm.org> writes:

> I hope this helps clear up some of the issues involved...

It does for me.  (... including not having read Barry's message
carefully enough to realize that he was talking about shadowing-import
only at the receiving end, and so I confused things by saying his
required a source code edit.  Sorry, Barry.  Thanks, Pierre.)
From: Paolo Amoroso
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <SKiDO3sn03AkJNrgo=7+V3mr2iVd@4ax.com>
On Wed, 22 Aug 2001 07:24:30 GMT, Kent M Pitman <······@world.std.com>
wrote:

>  (defpackage "ACME-COMMON-PROTOCOL"
>    (:use)
>    (:export "FOO" "BAR"))

What is the empty :USE clause used for?


Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://web.mclink.it/amoroso/ency/README
[http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/]
From: Thomas A. Russ
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <ymik7zwx7jr.fsf@sevak.isi.edu>
Paolo Amoroso <·······@mclink.it> writes:

> On Wed, 22 Aug 2001 07:24:30 GMT, Kent M Pitman <······@world.std.com>
> wrote:
> 
> >  (defpackage "ACME-COMMON-PROTOCOL"
> >    (:use)
> >    (:export "FOO" "BAR"))
> 
> What is the empty :USE clause used for?

It blocks the default application of (:use "COMMON-LISP") which is what
would happen if no :use clause was present at all.

In most cases, people want to have the COMMON-LISP package available to
them inside their own packages (at least if writing code, otherwise you
have to supply package prefixes for all of the built-in language forms),
but for interface packages (like what Kent is suggesting) or if you are
trying to implement your own variant programming language, it is
sometimes useful not to have dragged all of COMMON-LISP into the
package.



-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Thomas A. Russ
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <ymielq27gz1.fsf@sevak.isi.edu>
···@sevak.isi.edu (Thomas A. Russ) writes:
> It blocks the default application of (:use "COMMON-LISP") which is what
> would happen if no :use clause was present at all.

Actually, as Kent Pitman pointed out in his response, the default set of
packages is implementation dependent...

-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Kent M Pitman
Subject: Re: accessor name clashes when using packages
Date: 
Message-ID: <sfwitfgujjq.fsf@world.std.com>
Paolo Amoroso <·······@mclink.it> writes:

> 
> On Wed, 22 Aug 2001 07:24:30 GMT, Kent M Pitman <······@world.std.com>
> wrote:
> 
> >  (defpackage "ACME-COMMON-PROTOCOL"
> >    (:use)
> >    (:export "FOO" "BAR"))
> 
> What is the empty :USE clause used for?

It keeps it from :use'ing the default set of packages (which are
implementation-dependent).  Not that it would matter if one were
not programming in the package anwyay, but jsut for conceptual 
simplicity.