From: Steven D. Majewski
Subject: Package Madness!
Date: 
Message-ID: <Pine.A32.3.93.970108124420.22966A-100000@elvis.med.Virginia.EDU>
I had quite a few problems mastering the intricacies of Lisp 
Packages -- particularly when they involve using packages to
redefine and shadow existing functions, until I discovered
( in CLtL1 ) the mnemonic "Put in seven extremely random 
interface commands" - which corresponds to the  sequence:
	Provide
	IN-package
	Shadow
	EXport
	Require
	USE-package
	Import
	Commands==Contents of package/module

Which is the order you (mostly) have to use those statements to
be able to Require your package without tripping over any name
clashes. ( Actually, I've been sticking "Provide" at the *end*
of my packages so that if it is provided, that indicates that 
it did load successfully. That shouldn't make any difference with
a well tested module, but it helps with something that I'm 
interactively editing and testing. If PROVIDE executes and *then* 
the module bombs out, I have to manually LOAD the module before
reloading the module which REQUIREd it. ) 


That technique has mostly worked for me, however, I have still 
seen some dependencies on the order in which my modules are 
loaded. I ignored or worked around most of these glitches until
I was trying to compile some of the more finished modules and 
save them into my workspace. 

I found that some of the name clashes had to do with using a 
symbol in a non defining position, such as an argument list. 

These problems were with XlispStat 3.47 ( for the Macintosh ). 
Since Xlisp is not quite Common Lisp -- it includes a lot of
functions for Common Lisp compatibility, but things like packages
and symbol binding are where I would suspect the most compatibility
problems -- I also tried simulating a similar case in KCL ( the 
particular code where I noticed the problem had too many XlispStat
and intermodule dependencies for me to easily load that code ),
and I get a similar error. 


The two sessions below both generate errors from a name conflict
on the symbol 'SEQ. In both, SEQ is defined and exported in 
package "X". In the first case, #'SEQ is used in a definition
before the ( USE-PACKAGE "X" ) statement. In the second, SEQ
is merely used in the argument list in defining another function. 
 This is basically the same cases that are generating my errors
in XlispStat, although the exact error message is slight different.
It's basically the same error. On both systems, ( FIND-SYMBOL "SEQ" )
returns NIL before the use of the symbol in the USER package, and
returns the values SEQ, :INTERNAL after it's use. 
( The only significant difference I've noticed is that in some cases,
  the symbol XlispStat complains about is :SEQ -- presumably in the
  keyword package, even thought the string ":SEQ" is never used in 
  my code. ) 


 *  Am I doing something wrong here ? 

 *  Is this error normal Lisp behavior for other implementations 
    or is this behavior according to Common Lisp standard ? 

  [ And if it *is* normal or standard, isn't it terribly inconvenient? 
    ( I can swallow the first case, but the second being an error
      is pretty extreme! ) 
    I have been finding Lisp packages a horribly intricate maze 
    compared to the simple module system in Python. ( I haven't 
    yet tried to do anything complex in Java, so I can't contrast
    its packages. ) ] 


$ kcl
AKCL (Austin Kyoto Common Lisp)  Version(1.505) Sat Dec 22 02:25:20 EST  1990
Contains Enhancements by W. Schelter
Changes in version 1-455 definitely require recompilation of user files.

>( defun a () ( seq a ))
A
>( setf a ( list 1 2 3 4 ))
(1 2 3 4)
>( make-package "X" )
#<"X" package>
>( in-package "X" )
#<"X" package>
X>( EXPORT '( SEQ ))
T
X>( defun seq ( &rest args ) args )
SEQ
X>( in-package "USER" )
#<"USER" package>
>( use-package "X" )

Error: Cannot use #<"X" package>
       from #<"USER" package>,
       because X:SEQ and SEQ will cause
       a name conflict.
Error signalled by USE-PACKAGE.

Broken at USE-PACKAGE.  Type :H for Help.
>>



AKCL (Austin Kyoto Common Lisp)  Version(1.505) Sat Dec 22 02:25:20 EST
1990
Contains Enhancements by W. Schelter
Changes in version 1-455 definitely require recompilation of user files.

>( defun MOST ( &rest seq ) ( cdr seq ))
MOST
>( make-package "X" )
#<"X" package>
>( in-package "X" )
#<"X" package>
X>( export '( seq ))
T
X>( defun seq ( &rest args ) args )
SEQ
X>( in-package "USER" )
#<"USER" package>
>( use-package "X" )

Error: Cannot use #<"X" package>
       from #<"USER" package>,
       because X:SEQ and SEQ will cause
       a name conflict.
Error signalled by USE-PACKAGE.

Broken at USE-PACKAGE.  Type :H for Help.



---|  Steven D. Majewski   (804-982-0831)  <·····@Virginia.EDU>  |---
---|  Department of Molecular Physiology and Biological Physics  |---
---|  University of Virginia             Health Sciences Center  |---
---|  P.O. Box 10011            Charlottesville, VA  22906-0011  |---
         By doing just a little every day, you can gradually 
                let the task completely overwhelm you.

From: Riesbeck
Subject: Re: Package Madness!
Date: 
Message-ID: <riesbeck-0801971729560001@riesbeck.ils.nwu.edu>
In article
<········································@elvis.med.Virginia.EDU>, "Steven
D. Majewski" <·····@Virginia.EDU> wrote:

> I found that some of the name clashes had to do with using a 
> symbol in a non defining position, such as an argument list. 

Defining has nothing to do with packages. The mere occurrence
of the symbol *as a symbol* causes the Lisp reader to create
that symbol if need be, leading to the name conflicts you're seeing.

>  *  Is this error normal Lisp behavior for other implementations 
>     or is this behavior according to Common Lisp standard ? 

It's the standard behavior.

>     I have been finding Lisp packages a horribly intricate maze 
>     compared to the simple module system in Python. 

It's the Python-based intuitions you have that make it intricate
because they're based on a different model. The reader-based 
model for packages is actually pretty simple and consistent.
Unfortunately, symbol-hiding is not the same as function/variable
hiding. 

  >( defun a () ( seq a ))

*reading* this (not executing it) put SEQ into the current package
-- at this point, simply saying

  > (use-package (make-package "X"))
  > (export 'X::SEQ "X")

will cause a name conflict because you're trying to have the current
package read "SEQ" as both it's own SEQ and the one in "X"

  >( defun MOST ( &rest seq ) ( cdr seq ))

makes SEQ just like the previous defun -- for that matter, simply 
typing

  > 'SEQ

will make SEQ (unless it already exists or is accessible in 
the current package).

-- 
-- Chris
From: Ken Tilton
Subject: Re: Package Madness!
Date: 
Message-ID: <32D489C2.6A52@bway.net>
Riesbeck wrote:
> 
> In article
> <········································@elvis.med.Virginia.EDU>, "Steven
> D. Majewski" <·····@Virginia.EDU> wrote:
> 
> >     I have been finding Lisp packages a horribly intricate maze
> >     compared to the simple module system in Python.
> 
> It's the Python-based intuitions you have that make it intricate
> because they're based on a different model. The reader-based
> model for packages is actually pretty simple and consistent.

Just to give Majewski some moral support I would like to say I found
packages to be harder to figure out than should have been necessary.

One problem being neither Graham nor Norvig spent much time on them. And
I can never understand Steele unless I already 70% understand the topic.
:)

FWIW,

 Ken
From: Riesbeck
Subject: Re: Package Madness!
Date: 
Message-ID: <riesbeck-0901971355060001@riesbeck.ils.nwu.edu>
In article <·············@bway.net>, ····@bway.net wrote:

> Riesbeck wrote:
> > 
> > In article
> > <········································@elvis.med.Virginia.EDU>, "Steven
> > D. Majewski" <·····@Virginia.EDU> wrote:
> > 
> > >     I have been finding Lisp packages a horribly intricate maze
> > >     compared to the simple module system in Python.
> > 
> > It's the Python-based intuitions you have that make it intricate
> > because they're based on a different model. The reader-based
> > model for packages is actually pretty simple and consistent.
> 
> Just to give Majewski some moral support I would like to say I found
> packages to be harder to figure out than should have been necessary.

As do many. My point was only that the actual model is simple. 
Being simple doesn't mean easy to understand, however, and things 
get worse if you have some other model already in mind.

Steven's confusions are very common.

> One problem being neither Graham nor Norvig spent much time on them. And
> I can never understand Steele unless I already 70% understand the topic.

By Graham, I assume you mean his book ANSI Common Lisp. It's a fine
book and I use it now in my intro to AI programming course instead
of Wilensky's Common LispCraft, but I warn the students about
how poor the package write up is.

I thought Steele was pretty good here, but it gets a little
confusing separating CL1 from CL2 conventions. 

Since a lot of people start asking questions *after* name conflicts
arise, I have a web page that tries to cover some common errors. I can
already see some changes I want to make, but comments are welcome
on what's there:

http://www.cs.nwu.edu/academics/courses/c25/readings/packages.html

-- 
-- Chris
From: Rainer Joswig
Subject: Re: Package Madness!
Date: 
Message-ID: <joswig-ya023180000901970101170001@news.lavielle.com>
In article
<········································@elvis.med.Virginia.EDU>, "Steven
D. Majewski" <·····@Virginia.EDU> wrote:

>  *  Am I doing something wrong here ? 

You have not understood packages, yet. ;-)

>  *  Is this error normal Lisp behavior for other implementations 
>     or is this behavior according to Common Lisp standard ? 

This is normal. MCL gives you on the first example:



> Error: Using #<Package "X"> in #<Package "COMMON-LISP-USER"> 
>        would cause name conflicts with symbols already present in that
package: 
>        SEQ  X:SEQ
>        
> While executing: CCL::USE-PACKAGE-1
> Type Command-/ to continue, Command-. to abort.
> If continued: Try again to use #<Package "X"> in #<Package "COMMON-LISP-USER">
See the Restarts� menu item for further choices.
define-setf-method
1 > 



MCL gives you in its restart menu some ways to deal with this
error.



>   [ And if it *is* normal or standard, isn't it terribly inconvenient? 
>     ( I can swallow the first case, but the second being an error
>       is pretty extreme! ) 

No, symbols are symbols. There is not a symbol in a defining position.
It is just a symbol.

>     I have been finding Lisp packages a horribly intricate maze 
>     compared to the simple module system in Python. ( I haven't 
>     yet tried to do anything complex in Java, so I can't contrast
>     its packages. ) ] 

Once you understand it, it is not that difficult.

If you have a symbol in a package and you want to
import a symbol with the same symbol name from a different
package, you have to decide (better first) what you want
to do (unintern the first symbol or shadow it). 

> $ kcl
> AKCL (Austin Kyoto Common Lisp)  Version(1.505) Sat Dec 22 02:25:20 EST  1990
> Contains Enhancements by W. Schelter
> Changes in version 1-455 definitely require recompilation of user files.
> 
> >( defun a () ( seq a ))

so you have a symbol "SEQ" in package "USER" (which by the way is
old CL).


> A
> >( setf a ( list 1 2 3 4 ))
> (1 2 3 4)
> >( make-package "X" )
> #<"X" package>
> >( in-package "X" )
> #<"X" package>
> X>( EXPORT '( SEQ ))
> T

so you have a symbol "SEQ" in package "X" and you have exported
it. So you can use it with  x:seq .

> X>( defun seq ( &rest args ) args )
> SEQ
> X>( in-package "USER" )
> #<"USER" package>
> >( use-package "X" )
> 
> Error: Cannot use #<"X" package>
>        from #<"USER" package>,
>        because X:SEQ and SEQ will cause
>        a name conflict.
> Error signalled by USE-PACKAGE.

Yeah, sure. You try to import a symbol name which is already
present. So, what you want to do?

See for example "SHADOWING-IMPORT": 

SHADOWING-IMPORT symbols &optional package
[Function]
imports symbols (which should be a symbol or list of symbols) into
package, a package object or package name. This function does not error if
the importation causes a conflict with symbols already accessible in
package. The symbols are placed in package's shadowing-symbols list.


Or use UNINTERN to remove the first symbol (in package "USER").

But make sure that you really want to shadow or to unintern.
It may not be wise for example to try to unintern "CAR"
in package "LISP" (or nowadays "COMMON-LISP").


Rainer Joswig
From: Marco Antoniotti
Subject: Re: Package Madness!
Date: 
Message-ID: <s08oheystby.fsf@crawdad.ICSI.Berkeley.EDU>
It must also be noted that COMMON LISP has (and encourages the use of)
a DEFPACKAGE declaration/definition.  It is also suggested that such
definition be stored in a separate file and that the following scheme
be used all over.

;;; File my-module-pkg.lisp

(defpackage "MY-MODULE" (:use "COMMON-LISP") ; usually you need this -
                                             ; other package go here
                                             ; as needed.
   (:nickname "MYM")
   (:export "SOMETHING-IN-MY-MODULE" #| .. more .. |#)
   (:import "MY-OTHER-PACKAGE"
            "SOMETHING-IN-MY-OTHER-PACKAGE" #| .. more .. |#)
   (:shadow "SOME-PACKAGE" "I-AM-SHADOWING" #| .. more .. |#)
   (:shadowing-import "SOME-PACKAGE" "I-AM-SHADOWING-IN-A-SOPHISTICATED-WAY"
                       #| .. more .. |#)

;;; end of file -- my-module-pkg.lisp --


;;; File my-module.lisp

(eval-when (load compile eval)
   (unless (find-package "MYM"))
      (load "my-module-pkg"))    ; Assuming same directory

(in-package "MYM")

;;; Code in "MY-MODULE"

;;; end of file -- my-module.lisp --


-- 
Marco Antoniotti - Resistente Umano
	...it is simplicity that is difficult to make.
	...e` la semplicita` che e` difficile a farsi.
				Bertholdt Brecht