Hi all,
I'm fairly new to Lisp so please bear with me.
I'm trying to develop a modularized application using packages.
I have defined a package which defines a couple of classes within it. I
also export the classes' names in the package definition.
The problem I have is that when I want to access a slot of any of these
classes from outside the package, I get an error that the class does
not know the slot. I was suggested to use a syntax like:
(slot-value classname 'package::slot-name)
However, this could become tiresome. Is there a better way to just be
able to reference slot names from a different package without having to
qualify the slot name with the package name?
Thanks,
Waldo
Hi Waldo, exporting a class name only exports the symbol. that means
if you have a class and a function and a variable of that same name in
the package they are all effectively exported. On the flip side of
this, exporting a class name does not automatically export the accessor
names, nor the slot names, nor its sub and superclass names.
If you want to be able to access the slot names from a different
package you should probably export the slot names as well--same for the
accessor functions.
This is annoyance sometimes but can also be a useful feature in that a
class may have slots from different packages. Those different packages
do not have to worry about colliding with slot names from other
packages.
If package PACKAGE-A defines CLASS-A which has SLOT-X, and PACKAGE-B
defines CLASS-B which also has SLOT-X, then in PACKAGE-C you define a
CLASS-C which mixes in CLASS-A and CLASS-B; then CLASS-C has slots
PACKAGE-A::SLOT-X and also PACKAGE-B::SLOT-X.
it is not clear which one you would want to simply refer to as SLOT-X
-jim
Waldo wrote:
> Hi all,
>
> I'm fairly new to Lisp so please bear with me.
>
> I'm trying to develop a modularized application using packages.
>
> I have defined a package which defines a couple of classes within it. I
> also export the classes' names in the package definition.
>
> The problem I have is that when I want to access a slot of any of these
> classes from outside the package, I get an error that the class does
> not know the slot. I was suggested to use a syntax like:
>
> (slot-value classname 'package::slot-name)
>
> However, this could become tiresome. Is there a better way to just be
> able to reference slot names from a different package without having to
> qualify the slot name with the package name?
export the slot name (well, the name of accessor, which could be
different) as well.
You got it right: you exported the class /name/. Not every name (er,
symbol) associated with the class. Might seem like a pain, but it gives
you a chance to document which slots are meant to be part of the public
interface and which are meant to be private (even though one /can/ use
PKG::whatever to get at them).
kt
Thanks. It does seem to be a bit of a pain. I understand your point
about "private" slots.
However, I realize that I still need to qualify exported names with the
package name, but instead of using package::symbol, I can use
package:symbol. I'm only saving one keystroke. I would think that the
exporting of symbols would allow the use of their "unqualified" symbol
names.
Did I miss something?
Thanks,
Waldo
Waldo wrote:
> Thanks. It does seem to be a bit of a pain. I understand your point
> about "private" slots.
>
> However, I realize that I still need to qualify exported names with the
> package name, but instead of using package::symbol, I can use
> package:symbol. I'm only saving one keystroke. I would think that the
> exporting of symbols would allow the use of their "unqualified" symbol
> names.
>
> Did I miss something?
Packages can "use" other packages. For example, in the Lisp listener you
can say something like this:
CL-USER> (use-package 'some-package)
...or for your own package, you can declare a use-relationship:
(defpackage "MY-PACKAGE"
(:use "COMMON-LISP" "SOME-PACKAGE"))
In those cases, you can use exported symbols without qualification (but
not the internal ones). So some-package:some-symbol can simply be
some-symbol, but some-package::some-symbol has to remain the same. (It's
typically a bad idea to use internal symbols of other packages like that.)
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
Waldo wrote:
> Thanks. It does seem to be a bit of a pain. I understand your point
> about "private" slots.
>
> However, I realize that I still need to qualify exported names with the
> package name, but instead of using package::symbol, I can use
> package:symbol. I'm only saving one keystroke. I would think that the
> exporting of symbols would allow the use of their "unqualified" symbol
> names.
>
> Did I miss something?
Funny you used the words using and use. :)
It gets confusing.
Suppose you load accounting.lisp, with code that references functions or
classes from some arithmetic.lisp. These both define their own packages,
accounting and arithmetic, but for now imagine the accounting.lisp code
has no use-package form or using option on its own defpackage.
So far you are dead, because I never said to load the arithmetic
package. :) So any reference to its symbols (with one, two or zero
colens) by code in accounting.lisp will of course produce "undefined
XXX" errors. Duh.
Now we load arithmetic.lisp. The Lisp environment now nows about those
symbols. Some are exported some are not. At this point, any code in
accounting.lisp with two colens can get to any symbol in
arithmetic.lisp. Code with one colen can get only to exported symbols.
You could use two, but that would be overkill and misleading and
dangerous in that that symbol might someday get refactored into being
unexported and one would never know it.
Now we have accounting.lisp USE the arithmetic package. We still need
two colens to get to unexported symbols. Zero through two colens will
get to exported symbols.
kt
On 2006-01-07 17:52:08 +0000, Kenny Tilton <·············@nyc.rr.com> said:
> Now we have accounting.lisp USE the arithmetic package. We still need
> two colons
> to get to unexported symbols. Zero through two colens will get to
> exported symbols.
I'm not well versed into CLOS (yet) but what has just been described about
packages and their interaction with CLOS seem to imply that there is, at
most, a ONE level name space.
I was expecting PKG:CLS:FLD where each class would be defining a name
space for its slots, but this is not apparently so, according to this
thread.
Is that true?
--
JFB
verec wrote:
> On 2006-01-07 17:52:08 +0000, Kenny Tilton <·············@nyc.rr.com> said:
>
>> Now we have accounting.lisp USE the arithmetic package. We still need
>> two colons
>> to get to unexported symbols. Zero through two colens will get to
>> exported symbols.
>
>
> I'm not well versed into CLOS (yet) but what has just been described about
> packages and their interaction with CLOS seem to imply that there is, at
> most, a ONE level name space.
>
> I was expecting PKG:CLS:FLD where each class would be defining a name
> space for its slots, but this is not apparently so, according to this
> thread.
>
> Is that true?
Right, packages are unrelated to CLOS. Something like PKG:CLS:FLD would
mean that the package system has knowledge about how CLOS is defined.
However, the package system was introduced before CLOS, is intentionally
neutral with regard to what is packaged. So all the package system does
is package names as symbols, and nothing else.
What's nice about this is that you can rely on the package system for
the abstractions that you introduce yourself.
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
verec wrote:
> On 2006-01-07 17:52:08 +0000, Kenny Tilton <·············@nyc.rr.com> said:
>
>> Now we have accounting.lisp USE the arithmetic package. We still need
>> two colons
>> to get to unexported symbols. Zero through two colens will get to
>> exported symbols.
>
>
> I'm not well versed into CLOS (yet) but what has just been described about
> packages and their interaction with CLOS seem to imply that there is, at
> most, a ONE level name space.
>
> I was expecting PKG:CLS:FLD where each class would be defining a name
> space for its slots,
Perhaps you are thinking of something like C structs and nested structs,
where one might have person.address.street. Anyway, no, nothing like
that in CLOS or Lisp. In the end it is quite simple. Packages just deal
with symbols and other packages. That said, one can get into a bit of a
mess with packages and symbols.
When that happens -- usually with Lisp saying some symbol is undefined
when I know full well I have defined it, I use (APROPOS "symbol") to
find out everything the Lisp runtime knows about any symbol of that name
in any package.
The AllegroCL IDE has a nice apropos dialog that shows at a glance which
packages include the symbol, which are exported, and whether each symbol
in each package has bound to a function or constant or class.
kt
Waldo wrote:
>
> The problem I have is that when I want to access a slot of any of these
> classes from outside the package, I get an error that the class does
> not know the slot. I was suggested to use a syntax like:
>
> (slot-value classname 'package::slot-name)
>
> However, this could become tiresome. Is there a better way to just be
> able to reference slot names from a different package without having to
> qualify the slot name with the package name?
I wouldn't use slot-value to access the slot. I'd use the :accessor
option in the slot definition to ensure that there was a generic
function available to get the slot, then I'd make sure the generic
function were exported (if that were appropriate).