From: Ignacio Bellido Montes
Subject: Problems with Lisp Packages
Date: 
Message-ID: <117@bosco.dit.upm.es>
	European users knows this article, I posted it some time ago but, as
I haven't receive any answer, I send it to every body.

	Could someone of you help me on a Common Lisp problem?.

	The trouble I have comes from the package management. I haven't found
any book or manual that explain the uses of this CL feature. I've tried to use
it, and I've found I don't know how.

	I use a Hewlett-Packard 9000-350 with Lucid Common Lisp II. I made a
group of functions which made things like:

	(DEFUN FOO (X)
		(COND ((EQUAL (CAR X) 'YES) ... )
		      ((EQUAL (CAR X) 'NO) ... )
		      (T (PRINT 'ERROR)))
	)

	When the current package is the same where the function is defined,
the function is well evaluated. But when I use the function from another
package, using (PACKAGE-FOO::FOO), the predicate EQUAL fails.

	I stepped the function, but the only thing I saw is that the constants
YES or NO, are not qualified by the interpreter with the package identifier.

	If some one knows how can I do that, or better, where can I find good,
and explained, examples of package use (Steele's book is not a good help)
please e-mail me or post a new.

	Thanks in advance,
				ibm (in low case)

===========================================================================
Ignacio Bellido Fernandez-Montes,

Departamento de Ingenieria de           Department of Telematic
Sistemas Telematicos (dit),		Systems Enginering,
Laboratorio de Inteligencia Artificial.	Artificial Intelligence Laboratory.
Universidad Politecnica de Madrid.	Madrid University of Technology.

e-mail:	········@dit.upm.es or	  Phone: Work: 34 - 1 - 5495700 ext 368
	········@goya.uucp		 Home: 34 - 1 - 2533365
TELEX" 47430 ESTIST E			 Fax:  34 - 1 - 2432077
===========================================================================

From: Barry Margolin
Subject: Re: Problems with Lisp Packages
Date: 
Message-ID: <36624@think.UUCP>
In article <···@bosco.dit.upm.es> ···@bosco.UUCP (Ignacio Bellido Montes) writes:
>	(DEFUN FOO (X)
>		(COND ((EQUAL (CAR X) 'YES) ... )
>		      ((EQUAL (CAR X) 'NO) ... )
>		      (T (PRINT 'ERROR)))
>	)
>
>	When the current package is the same where the function is defined,
>the function is well evaluated. But when I use the function from another
>package, using (PACKAGE-FOO::FOO), the predicate EQUAL fails.

The definition of EQUAL specifies that symbols are EQUAL if and only
if they are EQ.  Therefore, if (CAR X) is a symbol in a different
package from the one where FOO was defined, the EQUAL will return NIL.

If you just want to compare the names of the symbols, not the actually
identities, you should use STRING-EQUAL.

>	I stepped the function, but the only thing I saw is that the constants
>YES or NO, are not qualified by the interpreter with the package identifier.

I'm not sure what you're saying here.  Which symbols aren't being
qualified, the ones in the function or the ones in the parameter?  If
it's the ones in the function, then perhaps the symbols have been
imported into the other package (but then the EQUAL should succeed).

To clear up some possible confusion: the interpreter doesn't do
anything with packages.  Packages are only used by READ and PRINT.
The package of a symbol you type is going to be whatever package was
current at the time you typed it.  If that's different from the
package that was current when the function was defined, then you'll
get different symbols.

Barry Margolin
Thinking Machines Corp.

······@think.com
{uunet,harvard}!think!barmar
From: Cronus Usenet Admin
Subject: Re: Problems with Lisp Packages
Date: 
Message-ID: <1519@papaya.bbn.com>
From: ····@pineapple.bbn.com (Hunter Barr)
Path: pineapple.bbn.com!barr

In article <···@bosco.dit.upm.es> ···@bosco.UUCP (Ignacio Bellido Montes) writes:
>	(DEFUN FOO (X)
>		(COND ((EQUAL (CAR X) 'YES) ... )
>		      ((EQUAL (CAR X) 'NO) ... )
>		      (T (PRINT 'ERROR)))
>	)
>
>	When the current package is the same where the function is defined,
>the function is well evaluated. But when I use the function from another
>package, using (PACKAGE-FOO::FOO), the predicate EQUAL fails.

My answer comes in two parts.

1) Read Barry Margolin's answer, especially where he says:

>To clear up some possible confusion: the interpreter doesn't do
>anything with packages.  Packages are only used by READ and PRINT.
>The package of a symbol you type is going to be whatever package was
>current at the time you typed it.  If that's different from the
>package that was current when the function was defined, then you'll
>get different symbols.

I just thought that bore repeating.  What you are seeing is this:

Inside your function definition you have a symbol 'YES, which is in
package PACKAGE-FOO:.  Think of this as the symbol 'PACKAGE-FOO:YES,
but the package prefix is not necessary while your default package is
PACKAGE-FOO:.

If you change your default package to PACKAGE-BAR:, and then read
'YES, you are really getting 'PACKAGE-BAR:YES, because the reader is
effectively tacking the default package onto every symbol read.  The
exception to this is when there is an explicit package override.  You
used an explicit package override when you used (PACKAGE-FOO::FOO)
while your defualt package was PACKAGE-BAR:.

This leads to what you saw:
(EQUAL 'PACKAGE-FOO:YES 'PACKAGE-BAR:YES)
=> NIL

A package is just a symbol-table, and all the package prefix does is
tell the reader which table to search for the symbol.  If there is no
explicit package, the reader looks in the default package.


2) I don't know how the rest of your program works, but here are a
couple of suggestions for getting it to work:

First try to use the Keyword package, i.e. symbols that just start
with a #\Colon, like :YES and :NO.  Since they are always in the
Keyword package, it won't matter what your default package is.

E.g.:
In package PACKAGE-FOO:
(DEFUN FOO (X)
  (COND ((EQUAL (CAR X) ':YES) ... )
        ((EQUAL (CAR X) ':NO) ... )
        (T (PRINT 'ERROR))))

In PACKAGE-BAR:
(PACKAGE-FOO::FOO '(:YES ...))

Then, if you cannot use Keywords (maybe you are reading a data-file
which you cannot alter), use string-equal, which will convert the
symbols to strings and compare the strings.  They will lose the
package prefix that way, and so come out equal.

E.g.:
(STRING-EQUAL 'PACKAGE-FOO:YES 'PACKAGE-BAR:YES)
=> T

which is equivalent to:
(STRING-EQUAL "YES" "YES")
=> T

I hope this helps.
                            ______
                            HUNTER
From: Eliot Handelman
Subject: Re: Problems with Lisp Packages
Date: 
Message-ID: <6729@phoenix.Princeton.EDU>
In article <···@bosco.dit.upm.es> ···@bosco.UUCP (Ignacio Bellido Montes) writes:
>	(DEFUN FOO (X)
>		(COND ((EQUAL (CAR X) 'YES) ... )
>		      ((EQUAL (CAR X) 'NO) ... )
>		      (T (PRINT 'ERROR)))
>	)

>	When the current package is the same where the function is defined,
>the function is well evaluated. But when I use the function from another
>package, using (PACKAGE-FOO::FOO), the predicate EQUAL fails.


I haven't seen anyone suggest what seems to me the most obvious solution,
given that you really want to set up the problem as above: simply export
all of the symbols that you really need. For example:

(in-package 'package-foo)

(export '(foo yes no))

(defun foo (x) ...)

-Eliot
From: Barry Margolin
Subject: Re: Problems with Lisp Packages
Date: 
Message-ID: <36889@think.UUCP>
In article <····@phoenix.Princeton.EDU> ·····@phoenix.Princeton.EDU (Eliot Handelman) writes:
>I haven't seen anyone suggest what seems to me the most obvious solution,
>given that you really want to set up the problem as above: simply export
>all of the symbols that you really need. For example:

Maybe because it doesn't solve the problem.  Exporting symbols doesn't
automatically make them accessible anywhere else.  It allows them to
be typed with a single colon instead of a double colon package
delimiter.  And it makes them accessible in other packages that :USE
the original package and don't shadow the exported symbols.


Barry Margolin
Thinking Machines Corp.

······@think.com
{uunet,harvard}!think!barmar
From: Stephanie Miller
Subject: Re: Problems with Lisp Packages
Date: 
Message-ID: <2075@pembina.UUCP>
In article <···@bosco.dit.upm.es>, ···@bosco.dit.upm.es (Ignacio Bellido Montes) writes:
> 
>  ...
> 	I use a Hewlett-Packard 9000-350 with Lucid Common Lisp II. I made a
> group of functions which made things like:
> 
> 	(DEFUN FOO (X)
> 		(COND ((EQUAL (CAR X) 'YES) ... )
> 		      ((EQUAL (CAR X) 'NO) ... )
> 		      (T (PRINT 'ERROR)))
> 	)
> 
> 	When the current package is the same where the function is defined,
> the function is well evaluated. But when I use the function from another
> package, using (PACKAGE-FOO::FOO), the predicate EQUAL fails.
> ===========================================================================
> Ignacio Bellido Fernandez-Montes,

   I use Lucid common lisp and had exactly the same problem when starting
to use packages. There are three ways I can think of to fix the problem
(and I use them all in various places).
  
1) Any global constants like YES or No can be exported from the main
package you run things from (user hopefully). Then for each package you
set up, let it "use" the user package (I'm not sure how your common lisp
works, but ours lets you have a keyword parameter :use on the in-papackage
command). This will make all uses of that constant be the one in the user
package.
 
2) If you are starting from the same top level package each time, you can 
just prepend user:: on each constant you are testing - this only works if
all you input comes from the same package originally.
 
3) You can use find-symbol to find that symbol in the current package, and
then compare it (that only works if you have interned all possible constants
you will get into the package already).
 
4) You can explode the constant's name, strip off the package name (ends with :)and implode the rest to get the basic constant and then compare that.
I have routines that do that - let me know if you want them.
 
  Actually thats 4 ways!
 
   - Stephanie Miller
     ·····@alberta.uucp
From: Marty Hall
Subject: Re: Problems with Lisp Packages
Date: 
Message-ID: <861@jhunix.HCF.JHU.EDU>
In <···@bosco.dit.upm.es> ···@bosco.UUCP (Ignacio Bellido Montes) writes:
>	I use a Hewlett-Packard 9000-350 with Lucid Common Lisp II. I made a
>group of functions which made things like:
>
>	(DEFUN FOO (X)
>		(COND ((EQUAL (CAR X) 'YES) ... )
>		      ((EQUAL (CAR X) 'NO) ... )
>		      (T (PRINT 'ERROR)))
>	)
>
>	When the current package is the same where the function is defined,
>the function is well evaluated. But when I use the function from another
>package, using (PACKAGE-FOO::FOO), the predicate EQUAL fails.

If I follow your example correctly, I think you are telling the LISP
interpreter to use functions in another package, but not symbols there.
For instance, assume that you define the following in package foo:

(defun Equal-to-A? (Arg)
  (equal Arg 'A) )

Now, suppose USER or something other than FOO is the current package:

> (Foo::Equal-to-A? 'A)
NIL

> (Foo::Equal-to-A? 'Foo::A)
T

Does that help at all?
				- Marty Hall

········@jhunix.hcf.jhu.edu   Artificial Intelligence Laboratory, MS 100/601
...uunet!jhunix!apl_aimh      AAI Corporation
········@jhunix.bitnet        PO Box 126
(301) 683-6455                Hunt Valley, MD  21030
From: Michael Sokolov
Subject: Re: Problems with Lisp Packages
Date: 
Message-ID: <3591@mit-amt>
In article <···@bosco.dit.upm.es> ···@bosco.UUCP (Ignacio Bellido Montes) writes:
>	(DEFUN FOO (X)
>		(COND ((EQUAL (CAR X) 'YES) ... )
>		      ((EQUAL (CAR X) 'NO) ... )
>		      (T (PRINT 'ERROR)))
>	)
>
>	When the current package is the same where the function is defined,
>the function is well evaluated. But when I use the function from another
>package, using (PACKAGE-FOO::FOO), the predicate EQUAL fails.

	This can be very annoying. The problem is that there are two
different symbols: foo is defined differently in two packages. There
are a few things you can do. One is to use strings instead of symbols.
Another is to use keywords (symbols beginning with a ":", like :yes
and :no), which are ALL defined in the keyword package and are thus
shared by other packages. Finally, (kind of ugly) if you really insist
on doing what you describe, you can do the following (in package foo):

(in-package 'foo)
	(defun test (x)
	...
		(equal (find-symbol (car x) 'foo) 'yes)
	...)

Happy hacking!

-MS