From: Drew McDermott
Subject: Merging symbols in packages
Date: 
Message-ID: <353CF57B.51F1F64F@yale.edu>
I realize that there is no way to solve the following problem iin Common
Lisp, but I often wish there were:

Suppose you define two packages "TH" and "AN", each exporting a symbol
with name "FOO".  The two are developed independently, and then you put
them together.  Specifically, say, a third package, "SYN", uses both of
them.   Lisp complains that there is a name conflict between the symbols
TH:FOO and AN:FOO.

Sometimes this is due to a genuine conflict; for example, TH:FOO and
AN:FOO name procedures that are both needed by "SYN".  However, in many
cases the apparent clash is illusory, and everyone would be happy if the
two symbols just happened to be EQ.  In other words, I'd really like to
be able to write

(defpackage "SYN"
     ...
    (:merging-import "TH" "FOO" "AN" "FOO")
    ...)

meaning, If these symbols have already been created and are not EQ,
signal an error; if just one has been created, make the other EQ to it;
otherwise, create both and make them identical.

I can see some objections to this, but the alternatives are no fun.  You
can either rename one of the symbols (often very unpalatable), or change
the way each package is defined so that it looks to see if the other
exists before proceeding (really ugly), or have each package create the
symbol with name "FOO" in a fourth package (usually, "CL-USER"), and
then import it (probably the best idea).

                                                       -- Drew McDermott

From: Kent M Pitman
Subject: Re: Merging symbols in packages
Date: 
Message-ID: <sfwlnsy9avx.fsf@world.std.com>
Drew McDermott <··············@yale.edu> writes:

> I realize that there is no way to solve the following problem iin Common
> Lisp, but I often wish there were:
> 
> Suppose you define two packages "TH" and "AN", each exporting a symbol
> with name "FOO".  The two are developed independently, and then you put
> them together.  Specifically, say, a third package, "SYN", uses both of
> them.   Lisp complains that there is a name conflict between the symbols
> TH:FOO and AN:FOO.
> 
> Sometimes this is due to a genuine conflict; for example, TH:FOO and
> AN:FOO name procedures that are both needed by "SYN".  However, in many
> cases the apparent clash is illusory, and everyone would be happy if the
> two symbols just happened to be EQ.  In other words, I'd really like to
> be able to write
> 
> (defpackage "SYN"
>      ...
>     (:merging-import "TH" "FOO" "AN" "FOO")
>     ...)
> 
> meaning, If these symbols have already been created and are not EQ,
> signal an error; if just one has been created, make the other EQ to it;
> otherwise, create both and make them identical.
> 
> I can see some objections to this, but the alternatives are no fun.  You
> can either rename one of the symbols (often very unpalatable), or change
> the way each package is defined so that it looks to see if the other
> exists before proceeding (really ugly), or have each package create the
> symbol with name "FOO" in a fourth package (usually, "CL-USER"), and
> then import it (probably the best idea).

These days I usually just do your last solution:

 +---------- anth.lisp -----------

 (defpackage "ANTH-COMMON-SUPPORT"
   (:use)
   (:export "FOO"))

 +--------- an.lisp ----------

 (eval-when (:execute :load-toplevel :compile-toplevel)
   (unless (find-package "ANTH-COMMON-SUPPORT") (load "anth")))

 (defpackage "AN" (:use "COMMON-LISP" "ANTH-COMMON-SUPPORT") (:export "FOO" "A" "B" "C"))

 +--------- th.lisp ----------

 (eval-when (:execute :load-toplevel :compile-toplevel)
   (unless (find-package "ANTH-COMMON-SUPPORT") (load "anth")))

 (defpackage "TH" (:use "COMMON-LISP" "ANTH-COMMON-SUPPORT") (:export "FOO" "X" "Y" "Z"))

Having done this, the definition of "SYN" can naturally import from both
"AN" and "TH"" without conflict.

It's not as quick and dirty as what you might like, but it usually
results in better structured code.  Often you find the common
thing is a protocol set or something like that and actually has a
very appropriate name.

If the load order is well-defined (e.g., CLIM might reliably precede other systems),
I might resort to the other popular:

 (defpackage "FOO"
   (:use "COMMON-LISP" #+CLIM "CLIM")
   #+CLIM
   (:shadowing-import-from "CLIM" "BOOLEAN" "PATHNAME"))

where #+CLIM selects an extra package and ALSO selects a :shadowing-import-from
to break the inheritance ties.

Anyway, I'll note your comment for thought if/when future standards work happens.
From: Sunil Mishra
Subject: Re: Merging symbols in packages
Date: 
Message-ID: <efy90oysyo2.fsf@yorktown.cc.gatech.edu>
In article <·················@yale.edu> Drew McDermott <··············@yale.edu> writes:

   I realize that there is no way to solve the following problem iin Common
   Lisp, but I often wish there were:

   Suppose you define two packages "TH" and "AN", each exporting a symbol
   with name "FOO".  The two are developed independently, and then you put
   them together.  Specifically, say, a third package, "SYN", uses both of
   them.   Lisp complains that there is a name conflict between the symbols
   TH:FOO and AN:FOO.

   Sometimes this is due to a genuine conflict; for example, TH:FOO and
   AN:FOO name procedures that are both needed by "SYN".  However, in many
   cases the apparent clash is illusory, and everyone would be happy if the
   two symbols just happened to be EQ.  In other words, I'd really like to
   be able to write

   (defpackage "SYN"
	...
       (:merging-import "TH" "FOO" "AN" "FOO")
       ...)

   meaning, If these symbols have already been created and are not EQ,
   signal an error; if just one has been created, make the other EQ to it;
   otherwise, create both and make them identical.

   I can see some objections to this, but the alternatives are no fun.  You
   can either rename one of the symbols (often very unpalatable), or change
   the way each package is defined so that it looks to see if the other
   exists before proceeding (really ugly), or have each package create the
   symbol with name "FOO" in a fourth package (usually, "CL-USER"), and
   then import it (probably the best idea).

							  -- Drew McDermott

Well, if you just want to solve the problem, there is a way to do it,
though somewhat tedious. It would work of course only if you don't care if
the symbols in the two packages are eq (they will be).

1. Use one package, say TH. You will inherit only one version of FOO.
2. Make the second package, AN. Doesn't matter if you don't include a use
   list, since that will be fixed when you actually load the AN package.
3. Import TH:FOO into AN.
4. Load AN. AN will then use TH:FOO as well.

I believe something like this is what :merging-import would have to do in
any case, and it ought to be relatively easy to codify as a function or
macro.

Sunil