Re: same symbol name in 2 different packages



Sacha wrote:
I need to use this make-parser in a web application in order to define a
grammar for url parsing. So i have this kind of declaration :

(defpackage :web-app-gui
(:use :common-lisp :cl-who :tbnl :cl-drp :web-app-dal))

Note that USE-PACKAGE and the related :USE syntax in the DEFPACKAGE
macro are a crude tool. When you USE a package, you are
indiscriminately bringing in all of its exported symbols. So yes,
clashes can happen, because people often think of the same symbols.
This is particularly true when people use packages, because then they
(rightly) think they are free to use short simple names.

Even if there are no conflicts now, they can arise in the future, when
a code maintainer upgrades to new versions of some or all of the
packages! Some packages are particularly dangerous, like the various
extension packages provided by a Lisp implementation. Their contents
tend to churn in between releases.

Today, everything my be cool, but tomorrow, MYPACKAGE might get a CONC
symbol that is exported, and so might YOURPACKAGE.

Today everything loads, tomorrow it breaks.

It might be a good idea to implement package versioning. Instead of
blindly changing the contents of a package in between software
releases, make new versions of a package, e.g.

FOO-PACKAGE-1-0
FOO-PACKAGE-1-1
FOO-PACKAGE-1-2
FOO-PACKAGE-CURRENT

FOO-PACKAGE-CURRENT is where the latest churning is taking place. The
other packages import only the correct historic symbols from the
current one, and re-export them. So a program depending on just the 1-0
interface can readily :USE the FOO-PACKAGE-1-0, and know that it won't
be pulling in any new crap from FOO-PACKAGE-CURRENT.

As you can see, the web application is using the cl-who library (from Edi
Weitz) as well, which is exporting a symbol (a function really) with the
same symbol name "conc". So you guessed it, there is a naming conflict with
these two symbols.

I could change the name of this symbol in my parser library, but this
doesn't teach me anything.
Or maybe not "use-package" the library and use fully qualified symbol names.

Or, better yet, specify the precise list of symbols that you want to
import from a package.

:import-from <package> <symbol> ...

:shadowing-import-from <package> <symbol> ...

Typically, :use is just used for some base package like COMMON-LISP.
You :use CL, and then from everything else you do a shadowing-import of
the specific symbols that you want.

The shadowing part takes care of any future clashes.

Say that from package FOO you shadowing-import the FROBOZZ symbol. If
the contents of the CL package change in the future so that CL exports
FROBOZZ, you are covered. The shadowing-import ensures that the
FOO:FROBOZZ silently wins over the CL one. A regular import will
complain about the conflict.

But now i'm bound to use very long symbol names in the production rules of
my parser, which really doesn't make sense.

Well, you do have to use a long name for /one/ of the two CONC's if you
have to refer to both of them in the same context. You have to pick.


I can't imagine writing
(defrule a-then-b-then-c (cl-drp:conc a b c))

Okay, then it's settled: it's your CONC that has to win. Do not import
the CONC symbol from Edi's package: refer to that as CL-WHO:CONC when
you need it.

There are other tricks you can pull, based on the semantics of that
symbol. For instance if CL-WHO:CONC names a function, you could create
an inline function with a different name in your package which calls
that one:

(defun wconc (&rest args) (apply #'cl-who:conc args))

If it's a constant, you could make your own constant which inherits its
value. Etc.

.



Relevant Pages

  • Re: flets in macros
    ... >> Exporting COLLECT and NEXT is preferable. ... you mean like LOOP does? ... If you use the package system then the user has the option of not ... But if your macro digs up ...
    (comp.lang.lisp)
  • RE: Modifying @INC
    ... More importantly the package 'package_name' should be exporting the ... This is how exporting is done. ... Subject: Modifying @INC ... the symbols to resolve the package namespace. ...
    (perl.beginners)
  • Re: Understanding CLOS Encapsulation
    ... exporting of symbols would allow the use of their "unqualified" symbol ... because I never said to load the arithmetic package. ... any code in accounting.lisp with two colens can get to any symbol in arithmetic.lisp. ...
    (comp.lang.lisp)
  • Re: export setf expansion
    ... > So, if I define a setf function in a package, how can I export it? ... The effects of exporting are that one can refer to the symbol using the ... Regardless of whether you export the symbol, in Common Lisp the ... underlying function, setf expander, etc. is always available for use. ...
    (comp.lang.lisp)
  • Re: flets in macros
    ... >> list or lists and binds COLLECT and NEXT to functions that allow the ... >> Now, my problem is that I'm defining this an a utility package, but I ... > Exporting COLLECT and NEXT is preferable. ... What happens when I want to use MAP-COLLECT? ...
    (comp.lang.lisp)