Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

packages

13 views
Skip to first unread message

Vojin Jovanovic

unread,
Sep 20, 2001, 2:24:52 PM9/20/01
to
I don't understand "packages" issue. I use CLISP and I'd like to implement
a small CLOS from a book in order to learn more about it. However, how do I
remove the CLOS provided with CLISP which is used by COMMON-LISP package?
In the implementation notes Bruno says just to (unuse-package "CLOS"), but
when I do that "defclass", for example, still works. In short, how do I
have just a regular lisp environment without CLOS?

vin


Kent M Pitman

unread,
Sep 20, 2001, 3:31:59 PM9/20/01
to
"Vojin Jovanovic" <vjov...@stevens-tech.edu> writes:

I don't know what was in Bruno's head when he told you this, but here's
my advice as to good style in this case:

Never use UNUSE-PACKAGE or any other package-editing function for any package
you didn't yourself define.

Instead, define a new package which contains the symbols you want.

e.g.,

(defpackage "CL-MINUS-CLOS"
(:use "CL")
(:shadow "DEFCLASS" "DEFGENERIC" "DEFMETHOD" ...others you don't like...))

Then use the CL-MINUS-CLOS package for your work. This doesn't affect
existing packages but allows you to do the work you want.

If you want to re-export all but those symbols, you might want to
do something programmatic like:

(macrolet ((do-it ()
(let ((symbols-to-remove '("DEFCLASS" "DEFGENERIC" ...))
(new-exports '("DEFCLASS" "MY-DEFMETHOD" "FOO" ...)))
`(defpackage "CL-MINUS-CLOS"
(:use "CL")
(:shadow ,@symbols-to-remove)
(:export ,@(let ((exports new-exports))
(do-external-symbols (symbol "CL")
(pushnew (symbol-name symbol) exports
:test #'string=))
exports))))))
(do-it))

[I didn't test this code, but it should at least be approximately right.
You have to fill in the "..."'s of course before you try.]

p.s. One problem about the CLOS package is that the standard doesn't
require it to exist, so code is gratuitously not portable. The
techniques I've used above don't acknoweldge that package and are,
as a consequence, portable.

Christopher Stacy

unread,
Sep 20, 2001, 3:33:41 PM9/20/01
to
>>>>> On Thu, 20 Sep 2001 14:24:52 -0400, Vojin Jovanovic ("Vojin") writes:
Vojin> In short, how do I have just a regular lisp environment without CLOS?

A regular Lisp environment is one that includes CLOS!

(I understand your question, though, and someone who knows how to
eliminate CLOS from CLISP will be able to answer if that's possible.)

Russell Senior

unread,
Sep 20, 2001, 7:16:44 PM9/20/01
to
>>>>> "Kent" == Kent M Pitman <pit...@world.std.com> writes:

Kent> (defpackage "CL-MINUS-CLOS" (:use "CL") (:shadow "DEFCLASS"
Kent> "DEFGENERIC" "DEFMETHOD" ...others you don't like...))

Here is a stupid question: when I see "shadow" is expressions like
that above, does that mean the referent casts a shadow or the shadow
is cast on it? Just trying to understand the sematics without reading
anything ;-) (and actually, having read the spec on this subject a
while ago, I recall that the semantics were not terribly obvious).
Thanks for indulging me.

--
Russell Senior ``The two chiefs turned to each other.
sen...@aracnet.com Bellison uncorked a flood of horrible
profanity, which, translated meant, `This is
extremely unusual.' ''

Jochen Schmidt

unread,
Sep 20, 2001, 7:20:59 PM9/20/01
to
Russell Senior wrote:

>>>>>> "Kent" == Kent M Pitman <pit...@world.std.com> writes:
>
> Kent> (defpackage "CL-MINUS-CLOS" (:use "CL") (:shadow "DEFCLASS"
> Kent> "DEFGENERIC" "DEFMETHOD" ...others you don't like...))
>
> Here is a stupid question: when I see "shadow" is expressions like
> that above, does that mean the referent casts a shadow or the shadow
> is cast on it? Just trying to understand the sematics without reading
> anything ;-) (and actually, having read the spec on this subject a
> while ago, I recall that the semantics were not terribly obvious).
> Thanks for indulging me.

CL-MINUS-CLOS "looks" at CL but does not see DEFCLASS ... in it because
they are hidden in the shadows. ;-)

ciao,
Jochen

--
http://www.dataheaven.de

Kent M Pitman

unread,
Sep 20, 2001, 11:09:33 PM9/20/01
to
Jochen Schmidt <j...@dataheaven.de> writes:

Yes, that's right.

Approximately, if x shadows y, it means that x places y in its shadow
(or in the shadow of some newer element it designates), rendering the
prior thing harder to see.

Again, approximately, the passive form, "is shadowed by" has the
reverse meaning. "y is shadowed by x" means "y is placed in the
shadow of x".

Specifically, though, from the ANSI CL glossary:

shadow v.t.
1. to override the meaning of.
``That binding of X shadows an outer one.''
2. to hide the presence of.
``That macrolet of F shadows the outer flet of F.''
3. to replace.
``That package shadows the symbol cl:car with its own symbol car.''

If you aren't used to looking in the glossary, you will find this a valuable
source of terminology for speaking casually about the language. There are
nearly 60 hardcopy pages of normative terms there. Part of their reason to
be there was that it centralized the definition of things needed by the spec,
but part of it also was my belief that people already did use that terminology
in the circles I moved in, and I wanted to normalize the spoken interchange
among us all. That's one reason why I tolerated sometimes 3 or more
definitions on the same term rather than making new ones that were
unambiguous--because that's really how people have spoken about the language
for quite some time, and because I think the spoken form of a language is
as important as the written semantics to the overall feeling of comfort in
using the language.

Kalle Olavi Niemitalo

unread,
Sep 20, 2001, 6:18:15 PM9/20/01
to
"Vojin Jovanovic" <vjov...@stevens-tech.edu> writes:

> In the implementation notes Bruno says just to (unuse-package "CLOS"), but
> when I do that "defclass", for example, still works.

(describe *package*)

If you start CLISP with -a (more ANSI CL compliance), the
COMMON-LISP-USER package is the default. It uses only the
COMMON-LISP package and gets the CLOS symbols from there, so
(unuse-package "CLOS") has no effect.

However, if you start CLISP without -a, the USER package is the
default. It uses packages CLOS and LISP, and there you can unuse
the CLOS package and leave the LISP symbols.

Even if you start CLISP with -a, you can switch to the USER
package with (in-package "USER") and thereafter unuse the CLOS
package, or you can create a package of your own like Mr. Pitman
explained.

Or at least that's how it works in CLISP 2000-03-06.

Thomas A. Russ

unread,
Sep 20, 2001, 5:52:16 PM9/20/01
to
"Vojin Jovanovic" <vjov...@stevens-tech.edu> writes:

Well, one simple solution would be to use the package system to allow
you to do what you want. Create a package of your own for working with
this new CLOS. Let's say you call the package "VOJIN", you would set
it up like the following:

(defpackage "VOJIN"
(:use "CL")
(:shadow "DEFCLASS" "DEFMETHOD" ...) ;; all the symbols you plan to
) ;; define in your small CLOS

Then develop in the VOJIN package. That will let you use all of the
normal Common Lisp functions without needing package prefixes -- except
for those that you explicitly shadow. The ones you explicitly shadow
are the ones that you plan to build yourself.


--
Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu

Tim Bradshaw

unread,
Sep 21, 2001, 5:00:31 AM9/21/01
to
* Kent M Pitman wrote:
> If you want to re-export all but those symbols, you might want to
> do something programmatic like:

[...]

This is more-or-less what my CONDUITS system does - it lets you define
packages which are `like' other packages except for some symbols.
It's actually slightly more (slightly too) flexible because it lets
you do elaborate things like define a package which is stitched
together out of bits of various other packages. It can be be found at
http:///www.tfeb.org/lisp/hax.html#CONDUITS.

--tim

Kent M Pitman

unread,
Sep 21, 2001, 7:17:34 AM9/21/01
to
Tim Bradshaw <t...@cley.com> writes:

Heh. Thanks for the pointer, but I have my own hack for doing this,
too. I tend to prefer explaining it longhand, though, when answering
"how to" questions on comp.lang.lisp...

Vojin Jovanovic

unread,
Sep 26, 2001, 5:34:35 PM9/26/01
to
> > In the implementation notes Bruno says just to (unuse-package "CLOS"),
but
> > when I do that "defclass", for example, still works. In short, how do I
> > have just a regular lisp environment without CLOS?
>
> I don't know what was in Bruno's head when he told you this, but here's
> my advice as to good style in this case:

Well, he never told me this, but he wrote it in his implementation notes
http://clisp.cons.org/impnotes.html#types

Ok, now, I did what you suggested in a new file myclos.lsp like this ....

(defpackage "MYCLOS" (:use "CL") (:shadow "DEFMETHOD" "DEFCLASS"
"MAKE-INSTANCE" "CLASS" "FIND-CLASS" "CLASS-NAME" "MAKE-CLASS"
"FIND-METHOD"))

(in-package "MYCLOS")

.
.
.

Now, when I load this file into clisp I don't get the change of package
automatically and I am still in COMMON-LISP-USER.
Why is it that (in-package "MYCLOS") does not change the package when the
file is loaded into clisp?

Vin


Pierre R. Mai

unread,
Sep 27, 2001, 6:37:35 AM9/27/01
to
"Vojin Jovanovic" <vjov...@stevens-tech.edu> writes:

> (defpackage "MYCLOS" (:use "CL") (:shadow "DEFMETHOD" "DEFCLASS"
> "MAKE-INSTANCE" "CLASS" "FIND-CLASS" "CLASS-NAME" "MAKE-CLASS"
> "FIND-METHOD"))
>
> (in-package "MYCLOS")

> Now, when I load this file into clisp I don't get the change of package


> automatically and I am still in COMMON-LISP-USER.
> Why is it that (in-package "MYCLOS") does not change the package when the
> file is loaded into clisp?

Because load re-binds *package* around the load process, so that all
changes to *package* will only affect the file being loaded, and will
not persist afterwards. Just because you load a file doesn't mean you
want to change the package as seen from the lisp-listener, after all.

In pseudo-code, you can imagine LOAD as being defined like this:

(defun load (filespec &key verbose print if-does-not-exist external-format)
(let ((*package* *package*))
(internal-load filespec verbose print if-does-not-exist external-format)))

See the HyperSpec entry for load for further details.

So if you want to interactively work in the new package, you have to
evaluate

(in-package "MYCLOS")

at the prompt.

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Vojin Jovanovic

unread,
Sep 27, 2001, 10:57:45 AM9/27/01
to
> Because load re-binds *package* around the load process, so that all
> changes to *package* will only affect the file being loaded, and will
> not persist afterwards. Just because you load a file doesn't mean you
> want to change the package as seen from the lisp-listener, after all.

But, what if it means exactly that, what do I do then?
I want to have my own definition of CLOS. When I load a file I want to
shadow the current CLOS and use my own provided by the file.
Is it possible to do that somehow automatically?

I have to do something like the above since I can't (unuse-package "CLOS")
as Bruno suggested in his own CLISP implementation notes
http://clisp.cons.org/impnotes.html#types !? But why is that? After all,
what is the purpose of unuse-package function?

In CLISP when it is started the *package* is COMMON-LISP-USER. This package
uses packages "COMMON-LISP" and "EXIT". Now if you do (in-package
"COMMON-LISP")
and (unuse-package "CLOS"), the (package-use-list "COMMON-LISP") gives nil,
but defmacro
defclass is still available for example? Again, what is the purpose of
unuse-package function if the definitions from "CLOS" are still available?

Vin

Erik Naggum

unread,
Sep 27, 2001, 11:06:59 AM9/27/01
to
* Vojin Jovanovic

> But, what if it means exactly that, what do I do then? I want to have my
> own definition of CLOS. When I load a file I want to shadow the current
> CLOS and use my own provided by the file. Is it possible to do that
> somehow automatically?

There is usually a top-level or system-global variable that you can set
in an initialization file, but the way these things usually work is that
you really do set the package you want to work within. E.g., a system I
built which uses an initialization file to set things up because so much
depends on weird interactions, goes like this:

(setf tpl::*saved-package*
(setf *package*
(setf (system:global-symbol-value '*package*)
(find-package :tdn))))

(setf (cdr (assoc '*package* *cl-default-special-bindings*))
'(find-package :tdn))

(when (lep:lep-is-running)
(lep::eval-in-emacs "(setq-default fi:package \"tdn\")"))

> In CLISP when it is started the *package* is COMMON-LISP-USER. This
> package uses packages "COMMON-LISP" and "EXIT". Now if you do
> (in-package "COMMON-LISP") and (unuse-package "CLOS"), the
> (package-use-list "COMMON-LISP") gives nil, but defmacro defclass is
> still available for example? Again, what is the purpose of unuse-package
> function if the definitions from "CLOS" are still available?

Are you sure you know in which package the symbol defclass is defined?
You just look so hopelessly confused it is hard to figure out if giving
you any answers will help you, but the clue to your problems is probably
to define your own package and import only the symbols you need from the
common-lisp package and _not_ to import the symbols you would like to
redefine. I think you need to re-examine your problem before you start
to complain about the solutions.

///
--
Why did that stupid George W. Bush turn to Christian fundamentalism to
fight Islamic fundamentalism? Why use terms like "crusade", which only
invokes fear of a repetition of that disgraceful period of Christianity
with its _sustained_ terrorist attacks on Islam? He is _such_ an idiot.

Vojin Jovanovic

unread,
Sep 27, 2001, 12:11:03 PM9/27/01
to
> I think you need to re-examine your problem before you start
> to complain about the solutions.

Of course I am hopelessly confused since CLISP documentation is not helping
me.

Here is my problem. I have an implementation of CLOS from a book and I
would like to play with it in order to learn more about its implementation.
However, symbols like defmacro, defmethod and make-instance, ( (defstruct
class () ...) also reports redefining class) are already in CLISP.
I tried what Kent suggested but as you know I can't get to be in the
automatically in the package that I defined in the file (I still have to
study your initialization file to see what you do).

However, the following I don't understand.

In the CLISP implementation notes it says

Classes [CLHS-4.3]
The CLOS symbols are EXPORTed from the package "CLOS" and thus normally
visible in all user packages. If you do not want them (for example, if you
want to use the PCL implementation of CLOS instead of the native one), do
(UNUSE-PACKAGE "CLOS").

But, this suggestion doesn't work for me, or I don't know how to do it. If
you can explain to me what this suggestion is suppose to mean it would be
very helpful.

I thought that defclass is defined in CLOS. Isn't that a part of object
oriented system?

> but the clue to your problems is probably
> to define your own package and import only the symbols you need from the
common-lisp package and >_not_ to import the symbols you would like to
redefine.

I would try that if I knew how to do that. If you can be a little more
specific it would be appreciated.

Vin

Kalle Olavi Niemitalo

unread,
Sep 27, 2001, 2:05:11 AM9/27/01
to
"Vojin Jovanovic" <vjov...@stevens-tech.edu> writes:

> Why is it that (in-package "MYCLOS") does not change the package when the
> file is loaded into clisp?

"load binds *readtable* and *package* to the values they held
before loading the file." So it changes the package, but when
LOAD finishes loading, it gets changed back.

Vojin Jovanovic

unread,
Sep 27, 2001, 12:24:55 PM9/27/01
to
> However, symbols like defmacro, defmethod and make-instance, ( (defstruct

Sorry, I made a mistake in the previous message, not defmacro but defclass.

Vin


Kent M Pitman

unread,
Sep 27, 2001, 12:27:33 PM9/27/01
to
"Vojin Jovanovic" <vjov...@stevens-tech.edu> writes:

> > Because load re-binds *package* around the load process, so that all
> > changes to *package* will only affect the file being loaded, and will
> > not persist afterwards. Just because you load a file doesn't mean you
> > want to change the package as seen from the lisp-listener, after all.
>
> But, what if it means exactly that, what do I do then?
> I want to have my own definition of CLOS. When I load a file I want to
> shadow the current CLOS and use my own provided by the file.
> Is it possible to do that somehow automatically?

You're intended to say (in-package "MY-CLOS-USER") or whatever at toplevel.
Of course, you can always put this in a function
(defun my-initialize ()
...
(setq *package* (find-package "MY-CLOS-USER"))
...)

(load "my-system")
(my-initialize)

As a point of style, it's a bad idea for loading code to do initializations.
It means you can't load the code to debug it.

Erik Naggum

unread,
Sep 27, 2001, 1:49:18 PM9/27/01
to
* Vojin Jovanovic

> Of course I am hopelessly confused since CLISP documentation is not
> helping me.

But this is really about making a new package that picks and chooses
symbols from another package than of using or unusing some packages
wholesale.

> I tried what Kent suggested but as you know I can't get to be in the
> automatically in the package that I defined in the file (I still have to
> study your initialization file to see what you do).

My initialization file is for Allegro CL 5, actually, but you might be
able to find something fairly similar in CLISP. I have no idea, though.

> However, the following I don't understand.
>
> In the CLISP implementation notes it says
>
> Classes [CLHS-4.3]
> The CLOS symbols are EXPORTed from the package "CLOS" and thus normally
> visible in all user packages. If you do not want them (for example, if you
> want to use the PCL implementation of CLOS instead of the native one), do
> (UNUSE-PACKAGE "CLOS").

The symbols you talk about are not "CLOS symbols". defclass, for
instance, is in the common-lisp package. Whether it came from a CLOS
package is quite immaterial when you use the common-lisp package.

> I thought that defclass is defined in CLOS. Isn't that a part of object
> oriented system?

I think you may confuse packages with something else. Try to evaluate
(symbol-package 'defclass) and see what you get.

> I would try that if I knew how to do that. If you can be a little more
> specific it would be appreciated.

I suggest you start with reading up on defpackage.

Tim Bradshaw

unread,
Sep 28, 2001, 9:09:24 AM9/28/01
to
* Vojin Jovanovic wrote:

> Classes [CLHS-4.3]
> The CLOS symbols are EXPORTed from the package "CLOS" and thus normally
> visible in all user packages. If you do not want them (for example, if you
> want to use the PCL implementation of CLOS instead of the native one), do
> (UNUSE-PACKAGE "CLOS").

I think that this is wrong - or rather it's correct in the sense that
the `CLOS symbols' (which is not a really well defined concept, of
course) are exported from the CLOS package in CLISP, but it is *not*
the case that unusing that package will make CLOS not available. I
presume this *was* true in some older CLISP (I only have 2.27 to look
at).

I'm probably going to make a hash of explaining this: I think I
understand things, but it's hard to describe without a huge long
article. Also of course I may not actually understand it.

The following glosses over a lot of issues.

The real issue is that there are two ways that a symbol can be found
from a package (by `found from a package' I mean, pretty much, that
what (find-symbol x p) does for x being the name of the symbol and p
the package): it can be directly present in the package, otherwise
known as `interned' in the package, and it can be inherited from a
package that the package uses.

A symbol can be interned in more than one package. Even though its
home package (the thing that SYMBOL-PACKAGE gets you) is always a
single package, it can be interned in several packages.

It can, in fact be both interned in a package *and* available by
inheritance in that package, and this is an OK thing to happen:
looking up a symbol in that case will return that it is interned in
the package.

Finally, in order for a package to export a symbol (so other packages
can do a USE-PACKAGE on that package and see the symbol), the symbol
must be interned in that package. Indeed, EXPORT will intern the
symbol in the package if it is not already so interned (for instance
if it is available by inheritance).

And finally finally: the definition of CL says that all the standard
CL symbols are exported from the COMMON-LISP package. This means that
*all those symbols must be interned in the CL package*. So even if
some of those symbols have home packages which are not CL, that
doesn't matter, since they are interned in CL too. In particular, it
doesn't matter to users of the CL package whether the CL package uses
other packages or not.

OK, well I have made a hash of explaining it, sorry. Here is a small
example to show what is happening.

--tim

--cut--
;;;;;

(in-package "CL-USER")

(defpackage "FOO-IMPLEMENTATION" ;like CLOS in CLISP
(:export "FROB-FOO" "DEFINE-FOO"))

(defpackage "FOO" ;like CL in CLISP
(:use "FOO-IMPLEMENTATION")
(:export "FROB-FOO" "DEFINE-FOO" "CRUN"))

#||
;;; The above definition of FOO is *roughly* equivalent to this
;;;
(let ((p (make-package "FOO")))
(use-package (find-package "FOO-IMPLEMENTATION")
p)
(dolist (s '("FROB-FOO" "DEFINE-FOO" "CRUN"))
(intern s p)
(export s p)))
||#

;;; And the end result can be seen by running this function:

(defun print-foo-state (&optional (stream *standard-output*))
;; Note this is *NOT* general. It works for the packages I defined above
;; but quite apart from the obvious assumptions it has many others
;; which are not in general true
(let ((p (find-package "FOO")))
(format stream "~&FOO uses ~{~A~^, ~}~%"
(mapcar #'package-name (package-use-list p)))
(dolist (s '("FROB-FOO" "DEFINE-FOO" "CRUN"))
(multiple-value-bind (sym status) (find-symbol s p)
(format stream "~&~A is ~A in FOO.~%"
(symbol-name sym)
(string-downcase (symbol-name status))))
(dolist (u (package-use-list p))
(multiple-value-bind (sym status) (find-symbol s u)
(when (and sym (eq status ':external))
(format stream "~&~4TIt is also inherited from ~A.~%"
(package-name u)))))))
(values))

;;; OK this actually demonstrate the issues.

(defun show-foo-unuse-use (&optional (stream *standard-output*))
;; Again this is *specific* to the packages above
(let* ((p (find-package "FOO"))
(ul (package-use-list p)))
(format stream "~&FOO initial state~%")
(print-foo-state stream)
(dolist (u ul)
(unuse-package u p))
(format stream "~&FOO using no packages~%")
(print-foo-state stream)
(format stream "~&(reusing packages...)~%")
(dolist (u ul)
(use-package u p))
(values)))

(show-foo-unuse-use)


0 new messages