From: Dobes Vandermeer
Subject: Packages (?)
Date: 
Message-ID: <37166E96.BC6F6B2C@mindless.com>
I am having difficulty understanding the mechanism and uses of packages.

What I do understand is that packages expand your name space by
providing a seperate set of symbol objects that are not the same.  This
is fine, but of course the obvious question arises from that, "but then
how can I use defun?  Which symbol is that function, and all other
functions that I always want to use, bound to?"  This is where things
get cloudy, because you can import/export symbols between packages, but
what exactly the implications of that are, are what I lack.

For example, when you are "sharing" symbols with another package, does
that mean that the symbol exists in both packages, and is "eq" in both? 
(i.e. if you (defun defun () ...) in one package, that will interfere
with the operation of other packages using the same defun)

Or am I mistaken, and rather than "sharing" symbols, you snapshot them
from the other package, and whatever state or function they had, you
get, but any future changes are lost ?

If you execute (in-package ...), does this cause the reader to intern
all symbols not in that package (or one of the packages it imports from,
I guess) into the specified package, or are symbol refernces adjusted
after reading to point to the right package's symbol?

Thanks
Dobes

From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfwu2uhif0o.fsf@world.std.com>
Dobes Vandermeer <·····@mindless.com> writes:

> For example, when you are "sharing" symbols with another package, does
> that mean that the symbol exists in both packages, and is "eq" in both? 

Yes.

> (i.e. if you (defun defun () ...) in one package, that will interfere
> with the operation of other packages using the same defun)

You are forbidden to defun defun because it's part of the common-lisp
package and redefining it would break other programs.

You should use (:SHADOW "DEFUN") in the defpackage description of your
package if you want to get a new symbol named DEFUN that you are free
to redefine without screwing up the DEFUN that others know and love.
 
> Or am I mistaken, and rather than "sharing" symbols, you snapshot them
> from the other package, and whatever state or function they had, you
> get, but any future changes are lost ?

No, it doesn't do this.

> If you execute (in-package ...), does this cause the reader to intern
> all symbols not in that package (or one of the packages it imports from,
> I guess) into the specified package,

Well, sort of.  It specifically just does (setq *package* ....)
and really nothing more.  It's not that action which does what
you just said, but rather it's the fact that intern interns into
the package which is the current binding of *package*.  The only
subtle difference between your mostly-right definition and what I've
said relates to what happens if someone later sets or binds *package*.
IN-PACKAGE is just one of many ways that *package* can be changed.
But having changed *package*, you're right that this controls the
package into which symbols not present in or inherited by the
current package are interned.

> or are symbol refernces adjusted
> after reading to point to the right package's symbol?

No.  This couldn't work.  You couldn't adjust any object to be
EQ to another--the object was either EQ from the start or never will be.

> Thanks
> Dobes

Sure.  Good luck.
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <3717BCCE.BE468AF4@mindless.com>
Kent M Pitman wrote:
> 
> Dobes Vandermeer <·····@mindless.com> writes:
> 
> > For example, when you are "sharing" symbols with another package, does
> > that mean that the symbol exists in both packages, and is "eq" in both?
> 
> Yes.

OK, that helps.

> > (i.e. if you (defun defun () ...) in one package, that will interfere
> > with the operation of other packages using the same defun)
> 
> You are forbidden to defun defun because it's part of the common-lisp
> package and redefining it would break other programs.

Of course!  But it stills shows my meaning... if I were to define a
function of the same name in two packages, if I wanted to maintain them
as different I would have to ensure that the symbol was not "shared".

> > Or am I mistaken, and rather than "sharing" symbols, you snapshot them
> > from the other package, and whatever state or function they had, you
> > get, but any future changes are lost ?
> 
> No, it doesn't do this.

OK.

I can extrapolate, then, that if packages foo and fum share symbol quux,
then 

(foo:quux "Test")

Will call the same function as:

(fum:quux "Test")

?

> > If you execute (in-package ...), does this cause the reader to intern
> > all symbols not in that package (or one of the packages it imports from,
> > I guess) into the specified package,
> 
> Well, sort of.  It specifically just does (setq *package* ....)
> and really nothing more.  

Aha... but what package is the symbol *package* in?  is it cl:*package*
?

I can only assume that the "main" packages ("cl", "cl-user", etc.) are
always available in every package, correct?

What symbols does this implicitly add to your current package that you
do not know about?

To use a fairly vivid example of a (maybe) plausible bug:

(in-package "fum")
(setf (get 'defun 'example) t)

(defun check-example () (get 'defun 'example))

(in-package "foo")
(setf (get 'defun 'example) nil)

Then calling (check-example) would give unpredictable results... nowhere
has it been explicitly declared that "defun"'s properties are shared
between packages.  Of course, in real life, this woudl be a symbol more
like "file-author" or some other uncommonly seen symbol.

Is this actually possible?  I would obviously want to avoid bugs like
this... but would an environment typically detect errors like this and
give a warning?

CU
Dobes
From: Barry Margolin
Subject: Re: Packages (?)
Date: 
Message-ID: <0JPR2.73$oQ5.4127@burlma1-snr2>
In article <·················@mindless.com>,
Dobes Vandermeer  <·····@mindless.com> wrote:
>I can extrapolate, then, that if packages foo and fum share symbol quux,
>then 
>
>(foo:quux "Test")
>
>Will call the same function as:
>
>(fum:quux "Test")
>
>?

Of course.  FOO:QUUX and FUM:QUUX are two ways of naming the same symbol,
and a symbol only has one function cell.

>> > If you execute (in-package ...), does this cause the reader to intern
>> > all symbols not in that package (or one of the packages it imports from,
>> > I guess) into the specified package,
>> 
>> Well, sort of.  It specifically just does (setq *package* ....)
>> and really nothing more.  
>
>Aha... but what package is the symbol *package* in?  is it cl:*package*
>?

All the symbols mentioned in the Common Lisp standard are either in the
COMMON-LISP package or the KEYWORD package.

>I can only assume that the "main" packages ("cl", "cl-user", etc.) are
>always available in every package, correct?

No.  When you create a package, you specify the packages that it inherits
from, via the :USE argument to MAKE-PACKAGE.  If you don't specify, it
defaults to the COMMON-LISP package.

>What symbols does this implicitly add to your current package that you
>do not know about?

Calling IN-PACKAGE doesn't add any symbols to your current package, it just
changes what package is current.  It's like "cd" in Unix.

>To use a fairly vivid example of a (maybe) plausible bug:
>
>(in-package "fum")
>(setf (get 'defun 'example) t)
>
>(defun check-example () (get 'defun 'example))
>
>(in-package "foo")
>(setf (get 'defun 'example) nil)
>
>Then calling (check-example) would give unpredictable results... nowhere

Actually, since FUM:EXAMPLE and FOO:EXAMPLE are presumably different
symbols (you haven't said anything to imply that these two packages share
the same symbol named EXAMPLE) the second SETF has no effect on the first.
Assuming both packages are inheriting from the COMMON-LISP package (the
default, as I mentioned above), DEFUN's property list would look like:

(FUM::EXAMPLE T FOO::EXAMPLE NIL ...)

>has it been explicitly declared that "defun"'s properties are shared
>between packages.  Of course, in real life, this woudl be a symbol more
>like "file-author" or some other uncommonly seen symbol.

Properties have nothing to do with packages, they're associated with
symbols.  You still don't seem to get this: Packages are just a way of
going from symbol names to symbols -- everything else is referenced from
the symbols themselves.  You can even make symbols that aren't in any
package, but they still have all the same attributes.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <37182E93.5882538D@mindless.com>
Paul Foley wrote:
> 
> On Fri, 16 Apr 1999 22:42:22 GMT, Dobes Vandermeer wrote:

> > I can only assume that the "main" packages ("cl", "cl-user", etc.) are
> > always available in every package, correct?
> 
> No.  COMMON-LISP is "used" by default by any new package without a
> use-list (c.f. DEFPACKAGE, etc.), but you can provide an empty
> use-list, or one with packages other than COMMON-LISP listed.

OK, so its more of a "default" import, then.

> > What symbols does this implicitly add to your current package that you
> > do not know about?
> 
> None.  It adds all the symbols exported by the packages you use
> (COMMON-LISP, in this case).  You ought to know what they are.

I would say not... The library is very large, and the average person
would not be conciously avoiding possible conflicts with symbols between
packages.

> > To use a fairly vivid example of a (maybe) plausible bug:
> 
> > (in-package "fum")
> > (setf (get 'defun 'example) t)
> 
> > (defun check-example () (get 'defun 'example))
> 
> > (in-package "foo")
> > (setf (get 'defun 'example) nil)
> 
> > Then calling (check-example) would give unpredictable results... nowhere
> > has it been explicitly declared that "defun"'s properties are shared
> > between packages.  Of course, in real life, this woudl be a symbol more
> 
> Wrong.  When you created FOO and FUM you got to decide whether
> neither, one, or both of them used the COMMON-LISP package (or any
> other package that defines a different DEFUN.  Presumably they do use
> COMMON-LISP, since they use SETF and GET unprefixed), and hence
> whether or not the DEFUNs they refer to are the same symbol.  If
> they're the same symbol, they naturally have the same property list.
> Nothing unpredictable about it.

Certainly... it is not the havng of knowledge that is the problem, but
the LACK of knowledge.  I have not memorised the list of symbols in
COMMON-LISP, nor do I intend to.  For that matter, I also have no
intention of adding an import statement to acquire all symbols from CL
that I use from it, I use too many symbols to make that worthwhile.

Anyway, my purpose, I suppose, is not necessarily to attack packages,
but rather to determine what they do, and whether they are useful to
me.  Any time you are "sometimes" sharing functions/symbols and
sometimes not makes me leary.

A more likely example of a package symbol sharing problem that I think
of offhand:

(in-package "case-tools")
(export add-model add-form delete-object... more entries ...
update-process remove-process modify-process ... )

(defun remove-process (name) (modify-process name :length 0 :status
"Terminated") (unlink-case-object name))

(defun delete-object (name) (when (eq (object-type name) 'process)
(remove-process name))

;; Function definitions for all of the above

(in-package "multitasking")
;; This package uses "case-tools" so that it can display task
information
;; for the user (just as an almost completely random example)
(use-package "case-tools")
(export create-process remove-process send-process-signal)
;; This SHOULD say (shadow "remove-process") here, but the "case-tools"
library
;; is very big, and the programmer didn't notice that it was duplicated.

(defun remove-process (id) (send-process-signal id 9)) ;; SIGKILL

;; Suddenly we have an issue about removing process objects..
remove-process has been
;; redefined in the other package, so that package will fail.

Unless this example is wrong, I dont think that packages are "safe"..
and I'd rather adopt a better strategy.

CU
Dobes
From: Vassil Nikolov
Subject: Re: Packages (?)
Date: 
Message-ID: <7fad8i$91n$1@nnrp1.dejanews.com>
In article <·················@mindless.com>,
  Dobes Vandermeer <·····@mindless.com> wrote:
(...)
> A more likely example of a package symbol sharing problem that I think
> of offhand:
>
> (in-package "case-tools")

One would be better off with "CASE-TOOLS" or :case-tools here
(unless one wants to be saying things like |case-tools|::foo).

(The readtable-case worms are out of the can, let's hope no
one will notice...)

> (export add-model add-form delete-object... more entries ...
> update-process remove-process modify-process ... )

EXPORT is a function so one should say

  (export 'add-model ...)

But more importantly, one wants DEFPACKAGE here, rather than
calls to EXPORT etc.  The same goes for the other package below.
(By the way, with DEFPACKAGE it is better to use strings
to avoid creating spurious symbols.)

> (defun remove-process (name) (modify-process name :length 0 :status
> "Terminated") (unlink-case-object name))
>
> (defun delete-object (name) (when (eq (object-type name) 'process)
> (remove-process name))
>
> ;; Function definitions for all of the above
>
> (in-package "multitasking")
> ;; This package uses "case-tools" so that it can display task
> information
> ;; for the user (just as an almost completely random example)
> (use-package "case-tools")
> (export create-process remove-process send-process-signal)
> ;; This SHOULD say (shadow "remove-process") here, but the "case-tools"

Not here, but earlier; one reason why DEFPACKAGE is useful.

> library
> ;; is very big, and the programmer didn't notice that it was duplicated.
>
> (defun remove-process (id) (send-process-signal id 9)) ;; SIGKILL
                                                    ^^^
This isn't REMOVE-PROCESS, this is NUKE-PROCESS...

> ;; Suddenly we have an issue about removing process objects..
> remove-process has been
> ;; redefined in the other package, so that package will fail.
>
> Unless this example is wrong, I dont think that packages are "safe"..
> and I'd rather adopt a better strategy.

Nothing is "safe" with computers unless you keep them shut down
permanently (recommended by the Programmer General).

In your particular case, the programmer deserves to be---shall
I say reprimanded---for using a package without looking at the
symbols that package exports.  That is *not* good practice.
If one finds that too many symbols are exported and can't possibly
find the time to check them, it is possible to:
* import only the necessary symbols;
* use CASE-TOOLS:FOO to refer to external symbols in CASE-TOOLS;
* use SHADOW.

By the way, as an additional (implementation-dependent) service
to the user, many implementation would issue a warning about
redefining the function REMOVE-PROCESS that used to be defined
in a different file, so life under Lisp isn't that dangerous.

Although packages are not the easiest thing about Common
Lisp, they _are_ explained in the literature.  (In
particular, there are elaborate examples in Chapter 11 of
CLtL2, about the end of the chapter.  They are useful even
though they introduce REQUIRE/PROVIDE at the same time.)

Good luck,
Vassil.

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Lieven Marchand
Subject: Re: Packages (?)
Date: 
Message-ID: <m37lrb2dvj.fsf@localhost.localdomain>
Dobes Vandermeer <·····@mindless.com> writes:

> I would say not... The library is very large, and the average person
> would not be conciously avoiding possible conflicts with symbols between
> packages.

The average person doesn't need to take that trouble. Implementations
will issue warnings whenever you're redefining stuff from
COMMON-LISP. Also, there are few places where the use of a name that
is in COMMON-LISP is a problem. You often see scheme code as follows:

(define frob (lst) .....)

where lst is a variable intended to contain a list because in scheme
naming the variable list would shadow the standard definition as a
function. This is not the case in Common Lisp, so a function

(defun cl-frob (list) .....) 

does not constitute a conflict.

> Anyway, my purpose, I suppose, is not necessarily to attack packages,
> but rather to determine what they do, and whether they are useful to
> me.  Any time you are "sometimes" sharing functions/symbols and
> sometimes not makes me leary.

I think you need some rethinking about module and package systems in
general. It is a complex subject and I haven't seen the perfect
solution yet.

> Unless this example is wrong, I dont think that packages are "safe"..
> and I'd rather adopt a better strategy.

They are safe in the sense that the implementation will warn you about
stuff you haven't declared in front (shadowing etc.). They are
certainly a better solution than obarrays. But perhaps you should
start with specifying what you want your strategy to achieve first.

-- 
Lieven Marchand <···@bewoner.dma.be>
If there are aliens, they play Go. -- Lasker
From: Barry Margolin
Subject: Re: Packages (?)
Date: 
Message-ID: <KXIS2.4$fQ1.29@burlma1-snr2>
In article <·················@mindless.com>,
Dobes Vandermeer  <·····@mindless.com> wrote:
>Anyway, my purpose, I suppose, is not necessarily to attack packages,
>but rather to determine what they do, and whether they are useful to
>me.  Any time you are "sometimes" sharing functions/symbols and
>sometimes not makes me leary.

How are packages different from many other module systems?  Any language
that allows you to inherit all the exported names from a module and use
them in an abbreviated way (i.e. without having to prefix them with an
explicit module/package name) you may encounter this problem.

>(export create-process remove-process send-process-signal)
>;; This SHOULD say (shadow "remove-process") here, but the "case-tools"
>library
>;; is very big, and the programmer didn't notice that it was duplicated.
>
>(defun remove-process (id) (send-process-signal id 9)) ;; SIGKILL
>
>;; Suddenly we have an issue about removing process objects..
>remove-process has been
>;; redefined in the other package, so that package will fail.

Many Lisp implementations will warn when they notice the same function
being defined in two different source files.  The above error should result
in such a warning.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Howard R. Stearns
Subject: Re: Packages (?)
Date: 
Message-ID: <371B5C90.24F9F49B@elwood.com>
The fundamental concept that I'm not sure you're getting (and that
Barmar has twice tried to explain) is that packages are really more
about the reader than they are about other things like function
definitions or evaluation.  Look at it this way:

1. Evaluation in Lisp, whether of interpreted or compiled code, is based
on bindings that are named by symbols.  They are NOT named by tokens,
strings, positions in a file or anything else.  Symbols have an
existance at run time, and this is a fundamentally different concept
that that of other popular programming languages.  (By the way, a
compiler can deal with lexical variables and functions in such a way
that symbols may or may not be present at run time to name them, but
that's an optimization that doesn't change the fundamental story.)

2. The fully qualified name for a symbol involes two things, the name of
the package, and the name of the symbol within the package.  There is a
single "namespace" for package names (i.e., each package name must be
globally unique) so there is no reason for tree-structured package
NAMES.  (This is not to say that there is no reason for tree structured
package inheritance, as we shall see.)

3. The interpreter and compiler both operate on code that is represented
as lists with symbols in them.  The file compiler and the Lisp top-level
use a function called READ which converts characters in a stream to this
data.  

There is a very general syntax that can always be used in the standard
reader to identify a symbol: package-name::symbol-name.  When the reader
sees this, it locates the actual package object with the given name, and
then locates the symbol with that name that has been defined to be
accessible in that package.  It will create the symbol if necessarry.

4. The package-name::symbol-name syntax is kind of sloppy, because you
don't know if the symbol was really meant to be part of the public API
for that package.  Programmers can use various techniques to set up a
package which explicitly "exports" certain symbols, and this indicates
that they are part of the public API.  You can safely use only exported
symbols by always writing package-name:symbol-name (with one colon).  If
the symbol is not explicitly exported, the reader will signal an error.

5. Even the package-name:symbol-name syntax is a bit verbose, so the
reader has a shortcut.  There is always one particular package (that you
specify) that is the "current package" USED BY THE READER.  When
refering to any symbol in this current package, you can leave off the
package-name:: part, but the reader will behave as though it had read
package-name:: before each symbol-name.

(I keep saying reader, and really the current *package* is used by
INTERN, which is used by the reader.  I don't believe this subtelty is
very important in this discussion.  I don't think you'll go wrong if
just think of packages as something used only at read-time.)

6. There are various features of packages that are additional
conveniences. For example, you can define a new package which "uses"
others.  This simply means that the trick of leaving off package-name::
will locate symbols that are not only directly present in the the
current *package*, but also those which have been exported from any of
the used packages.  The "use" mechanism will tell you about conflicts
between two used packages which happen to export a different symbol with
the same symbol-name, and there are further tools you can use
(shadowing) to distinguish between the two.

Again, the important thing is that these features change only how text
in a stream that is not fully qualified will be converted by the reader
into a symbol.  It is only this resulting symbol that matters to the
intepreter or compiler.

------------------------------
Many people have trouble understanding the distinctions between that
which is done at read-time versus compile-time versus load-time versus
run-time.  I have talked about some read-time issues, and another
subthread has been disucssing some compile-time versus load-time
subtelties of package definition.  

I think that students, teachers and textbook writers would do well to
concentrate on these issues, and that they will then find that packages
and other perenially problematic areas are more easily understood in
terms of reader, compiler, eval-when, run-time, etc.
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <371BBE30.914411AB@mindless.com>
"Howard R. Stearns" wrote:
> 
> 6. There are various features of packages that are additional
> conveniences. For example, you can define a new package which "uses"
> others.  This simply means that the trick of leaving off package-name::
> will locate symbols that are not only directly present in the the
> current *package*, but also those which have been exported from any of
> the used packages.

Aha... you are right, this is fundamental detail that was escaping me.

Using a package ust means that the reader will look in that package for
unqualified symbols it finds.

Hmm.. well that certainly is a much clearer perspective.. thanks.

CU
Dobes
From: Barry Margolin
Subject: Re: Packages (?)
Date: 
Message-ID: <IMJS2.5$fQ1.758@burlma1-snr2>
In article <·················@elwood.com>,
Howard R. Stearns <······@elwood.com> wrote:
>2. The fully qualified name for a symbol involes two things, the name of
>the package, and the name of the symbol within the package.  There is a
>single "namespace" for package names (i.e., each package name must be
>globally unique) so there is no reason for tree-structured package
>NAMES.  (This is not to say that there is no reason for tree structured
>package inheritance, as we shall see.)

FYI, the original MIT Lisp Machine had a hierarchical namespace for
packages, as well.  So you might have MACSYMA:RISCH:INTEGRATE and
MACSYMA:SIN:INTEGRATE (to use the example from the Chineual).  However,
this version of the package system didn't have internal vs. external
symbols or inheritance, except that a package automatically inherited all
the packages in the hierarchy above it.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Marco Antoniotti
Subject: Re: Packages (?)
Date: 
Message-ID: <lwlnfnzndf.fsf@copernico.parades.rm.cnr.it>
Barry Margolin <······@bbnplanet.com> writes:

> In article <·················@elwood.com>,
> Howard R. Stearns <······@elwood.com> wrote:
> >2. The fully qualified name for a symbol involes two things, the name of
> >the package, and the name of the symbol within the package.  There is a
> >single "namespace" for package names (i.e., each package name must be
> >globally unique) so there is no reason for tree-structured package
> >NAMES.  (This is not to say that there is no reason for tree structured
> >package inheritance, as we shall see.)
> 
> FYI, the original MIT Lisp Machine had a hierarchical namespace for
> packages, as well.  So you might have MACSYMA:RISCH:INTEGRATE and
> MACSYMA:SIN:INTEGRATE (to use the example from the Chineual).  However,
> this version of the package system didn't have internal vs. external
> symbols or inheritance, except that a package automatically inherited all
> the packages in the hierarchy above it.

Once again, some historical recount would be useful. Since on the
surface, hierarchical packages seem useful, why have they not been
included in Common Lisp?

Just curious.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfw90bne8fn.fsf@world.std.com>
Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:

> > FYI, the original MIT Lisp Machine had a hierarchical namespace for
> > packages, as well.  So you might have MACSYMA:RISCH:INTEGRATE and
> > MACSYMA:SIN:INTEGRATE (to use the example from the Chineual).  However,
> > this version of the package system didn't have internal vs. external
> > symbols or inheritance, except that a package automatically inherited all
> > the packages in the hierarchy above it.
> 
> Once again, some historical recount would be useful. Since on the
> surface, hierarchical packages seem useful, why have they not been
> included in Common Lisp?

I think it was another one of those cases of only wanting to take some of
what the LispM had to not grow too big.  I probably have notes about this,
but they are in storage.

On the other hand, though the LispM had this, I don't recall ever seeing
any code anywhere that used this.  I don't know if that was for lack of
knowledge or a real rason--maybe administratively complex(?).  So I have
no real data.  I'd seen it in the manual and know the mechanism, but that's
it. Maybe someone else reading along has seen it used...?
From: Guy Footring
Subject: Re: Packages (?)
Date: 
Message-ID: <wt1zhfnuun.fsf@thcsv01.trafford.ford.com>
Kent M Pitman <······@world.std.com> writes:

> 
> Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:
> 
> > > FYI, the original MIT Lisp Machine had a hierarchical namespace for
> > > packages, as well.  So you might have MACSYMA:RISCH:INTEGRATE and
> > > MACSYMA:SIN:INTEGRATE (to use the example from the Chineual).  However,
> > > this version of the package system didn't have internal vs. external
> > > symbols or inheritance, except that a package automatically inherited all
> > > the packages in the hierarchy above it.
> > 
> > Once again, some historical recount would be useful. Since on the
> > surface, hierarchical packages seem useful, why have they not been
> > included in Common Lisp?
> 
> I think it was another one of those cases of only wanting to take some of
> what the LispM had to not grow too big.  I probably have notes about this,
> but they are in storage.
> 
> On the other hand, though the LispM had this, I don't recall ever seeing
> any code anywhere that used this.  I don't know if that was for lack of
> knowledge or a real rason--maybe administratively complex(?).  So I have
> no real data.  I'd seen it in the manual and know the mechanism, but that's
> it. Maybe someone else reading along has seen it used...?
> 

Wasn't it used by the CLOE development stuff on the LISPM so that
you could have different packages called LISP or COMMON-LISP or
whatever that didn't conflict with each other - providing of course
you'd managed to set up your hierarchy context correctly?

I.e CLOE:COMMON-LISP was a different package to ZETALISP:COMMON-LISP
(I can't remember if these were the actually package hierarchy names)
and each package had different implementations of, for instance, IF
which catered for the differences between LISPM syntax of (IF then &rest else)
and 'strict' CL of (IF then else).
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfw7lr7ov32.fsf@world.std.com>
Guy Footring <········@thcsv01.trafford.ford.com> writes:

> > > Once again, some historical recount would be useful. Since on the
> > > surface, hierarchical packages seem useful, why have they not been
> > > included in Common Lisp?
> > 
> > I think it was another one of those cases of only wanting to take some of
> > what the LispM had to not grow too big.  I probably have notes about this,
> > but they are in storage.
> > 
> > On the other hand, though the LispM had this, I don't recall ever seeing
> > any code anywhere that used this.  I don't know if that was for lack of
> > knowledge or a real rason--maybe administratively complex(?).  So I have
> > no real data.  I'd seen it in the manual and know the mechanism, but that's
> > it. Maybe someone else reading along has seen it used...?
> > 
> 
> Wasn't it used by the CLOE development stuff on the LISPM so that
> you could have different packages called LISP or COMMON-LISP or
> whatever that didn't conflict with each other - providing of course
> you'd managed to set up your hierarchy context correctly?

No, CLOE used "syntax" space (the readtable) to separate the package
systems.

I implemented things like SYS:FIND-PACKAGE-FOR-SYNTAX that was underneath
the FIND-PACKAGE.  Each dialect's FIND-PACKAGE was closed over a syntax.
Kind of a kludge, but no one ever noticed and it let the LispM have many
co-resident dialects in the same address space without most people ever
noticing...  The only place you can feel it is when you have to talk across
package universes, which seems fair.

> I.e CLOE:COMMON-LISP was a different package to ZETALISP:COMMON-LISP

CLOE:::USER:CAR vs ZL:::USER:CAR is a better example.

> (I can't remember if these were the actually package hierarchy names)
> and each package had different implementations of, for instance, IF
> which catered for the differences between LISPM syntax of (IF then &rest else)
> and 'strict' CL of (IF then else).
From: Sunil Mishra
Subject: Re: Packages (?)
Date: 
Message-ID: <efy7lr7z9zs.fsf@cleon.cc.gatech.edu>
Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:

> Barry Margolin <······@bbnplanet.com> writes:
> > MACSYMA:SIN:INTEGRATE (to use the example from the Chineual).  However,
> > this version of the package system didn't have internal vs. external
> > symbols or inheritance, except that a package automatically inherited all
> > the packages in the hierarchy above it.
> 
> Once again, some historical recount would be useful. Since on the
> surface, hierarchical packages seem useful, why have they not been
> included in Common Lisp?
> 
> Just curious.

Not a historical note (I would be by no means qualified), but what would a
hierarchical package system buy you that export/import/use-package don't? I 
can't think of a single situation where such a setup would be desirable (as 
opposed to what we have now.)

Sunil
From: Marco Antoniotti
Subject: Re: Packages (?)
Date: 
Message-ID: <lwr9pf8ilv.fsf@copernico.parades.rm.cnr.it>
Sunil Mishra <·······@cleon.cc.gatech.edu> writes:

> Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:
> 
> > Barry Margolin <······@bbnplanet.com> writes:
> > > MACSYMA:SIN:INTEGRATE (to use the example from the Chineual).  However,
> > > this version of the package system didn't have internal vs. external
> > > symbols or inheritance, except that a package automatically inherited all
> > > the packages in the hierarchy above it.
> > 
> > Once again, some historical recount would be useful. Since on the
> > surface, hierarchical packages seem useful, why have they not been
> > included in Common Lisp?
> > 
> > Just curious.
> 
> Not a historical note (I would be by no means qualified), but what would a
> hierarchical package system buy you that export/import/use-package don't? I 
> can't think of a single situation where such a setup would be desirable (as 
> opposed to what we have now.)

Succinctness?

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfw676rov0g.fsf@world.std.com>
Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:

> > Not a historical note (I would be by no means qualified), but what
> > would a hierarchical package system buy you that
> > export/import/use-package don't? I can't think of a single
> > situation where such a setup would be desirable (as opposed to
> > what we have now.)
> 
> Succinctness?

No, lack of a flat namespace.  The right analogy is to directory structure
in a file system.  Ask yourself what the introduction of the Hierarchical
File System on the Mac back in Mac Plus days bought over the file system
where all files were in one directory... :-)
From: Barry Margolin
Subject: Re: Packages (?)
Date: 
Message-ID: <kLvR2.43$oQ5.946@burlma1-snr2>
In article <·················@mindless.com>,
Dobes Vandermeer  <·····@mindless.com> wrote:
>For example, when you are "sharing" symbols with another package, does
>that mean that the symbol exists in both packages, and is "eq" in both? 
>(i.e. if you (defun defun () ...) in one package, that will interfere
>with the operation of other packages using the same defun)
>
>Or am I mistaken, and rather than "sharing" symbols, you snapshot them
>from the other package, and whatever state or function they had, you
>get, but any future changes are lost ?

Symbols have existence and identity independent of packages.  A package is
simply a registry that maps a name (a string) to a specific symbol that has
that name.  When two packages share a symbol, that means that they both map
its name to the same symbol.  Changes are made to the symbol itself, and
will be seen no matter which package you find the symbol through.

If you're familiar with hash tables, you can think of a package as a hash
table that uses the symbol name as the key, and the symbol as the value (in
fact, this is probably how packages are usually implemented).  A simple
INTERN might look like:

(defun intern (symbol-name &optional (package *package*))
  (multiple-value-bind (symbol how-found) (find-symbol symbol-name package)
    (if foundp
        (values symbol how-found)
        (let ((symbol (make-symbol symbol-name)))
          (setf (symbol-package symbol) package
                (gethash symbol-name package) symbol)
          (values symbol nil)))))

(defun find-symbol (symbol-name &optional (package *package*))
  (multiple-value-bind (symbol foundp) (gethash symbol-name package)
    (values symbol (if foundp :internal nil))))

This simple implementation ignores package inheritance, shadowing, internal
vs. external, etc., but it demonstrates the relationship between packages
and the symbols they contain.

>If you execute (in-package ...), does this cause the reader to intern
>all symbols not in that package (or one of the packages it imports from,
>I guess) into the specified package, or are symbol refernces adjusted
>after reading to point to the right package's symbol?

Calling IN-PACKAGE simply sets the value of *PACKAGE*.  The reader
(actually INTERN, which is used by the reader) uses this as the package to
intern unqualified symbols in from that time on.  Interning a symbol in a
package may involve searching the packages it inherits from.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: John Atwood
Subject: Re: Packages (?)
Date: 
Message-ID: <7f81qf$nhb$1@news.NERO.NET>
>Dobes Vandermeer  <·····@mindless.com> wrote:
  [questions about packages]

sounds like you may not be aware of the function (use-package ...)
See chapter 11 of the hyperspec.


John Atwood
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <3717BF68.BABA3463@mindless.com>
Barry Margolin wrote:
> 
> In article <·················@mindless.com>,
> Dobes Vandermeer  <·····@mindless.com> wrote:
> >For example, when you are "sharing" symbols with another package, does
> >that mean that the symbol exists in both packages, and is "eq" in both?
> >(i.e. if you (defun defun () ...) in one package, that will interfere
> >with the operation of other packages using the same defun)
> >
> >Or am I mistaken, and rather than "sharing" symbols, you snapshot them
> >from the other package, and whatever state or function they had, you
> >get, but any future changes are lost ?
> 
> Symbols have existence and identity independent of packages.  A package is
> simply a registry that maps a name (a string) to a specific symbol that has
> that name.  When two packages share a symbol, that means that they both map
> its name to the same symbol.  Changes are made to the symbol itself, and
> will be seen no matter which package you find the symbol through.

OK, thats roughly what I thought.

> If you're familiar with hash tables, you can think of a package as a hash
> table that uses the symbol name as the key, and the symbol as the value (in
> fact, this is probably how packages are usually implemented).  A simple
> INTERN might look like:

That makes sense... perhaps I will implement it that way myself.

> This simple implementation ignores package inheritance, shadowing, internal
> vs. external, etc., but it demonstrates the relationship between packages
> and the symbols they contain.

OK, I'll have to look these topics up seperately I suppose.

> Calling IN-PACKAGE simply sets the value of *PACKAGE*.  The reader
> (actually INTERN, which is used by the reader) uses this as the package to
> intern unqualified symbols in from that time on.  Interning a symbol in a
> package may involve searching the packages it inherits from.

I guess its actually the value of cl:*package*.


How often do people actually use packages?  

Just in passing, they seem to be solving the right problem in possibly
the wrong way.  You can never be completely sure what symbols you are
sharing with what package, and there seems to be a few different ways to
achieve the same ends in some cases (make-package vs. defpackage).

CU
Dobes
From: Barry Margolin
Subject: Re: Packages (?)
Date: 
Message-ID: <UPPR2.74$oQ5.4127@burlma1-snr2>
In article <·················@mindless.com>,
Dobes Vandermeer  <·····@mindless.com> wrote:
>How often do people actually use packages?  

Quite often.  It allows independent pieces of software to be loaded into
the same Lisp image without interfering.

>Just in passing, they seem to be solving the right problem in possibly
>the wrong way.  You can never be completely sure what symbols you are
>sharing with what package, and there seems to be a few different ways to
>achieve the same ends in some cases (make-package vs. defpackage).

If you want to be sure what symbols you're sharing, you use explicit IMPORT
lists.  If you just want to inherit all the symbols exported from some
other package, you use USE-PACKAGE.  The latter means that you're at the
mercy of the maintainer of that package -- if he changes his export list,
it can affect you unpredictably.  That's why export lists need to be
maintained very carefully; this is true in most languages that provide some
kind of module system.

As for MAKE-PACKAGE vs. DEFPACKAGE, that's just the way Lisp is.  It often
provides low-level and high-level interfaces into the same feature.  It's
analogous to SETF of SYMBOL-FUNCTION vs. DEFUN.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <3717FAC3.29C08C7C@mindless.com>
Barry Margolin wrote:
> 
> In article <·················@mindless.com>,
> Dobes Vandermeer  <·····@mindless.com> wrote:
> >How often do people actually use packages?
> 
> Quite often.  It allows independent pieces of software to be loaded into
> the same Lisp image without interfering.
> 
> >Just in passing, they seem to be solving the right problem in possibly
> >the wrong way.  You can never be completely sure what symbols you are
> >sharing with what package, and there seems to be a few different ways to
> >achieve the same ends in some cases (make-package vs. defpackage).
> 
> If you want to be sure what symbols you're sharing, you use explicit IMPORT
> lists.  

That sounds pretty arduous to me, but I suppose it only counts when you
are trying to protect yourself from bugs, if you are writing the usual
"toy LISP apps" then you wouldn't have to wory about explicit imports.

> If you just want to inherit all the symbols exported from some
> other package, you use USE-PACKAGE.  The latter means that you're at the
> mercy of the maintainer of that package -- if he changes his export list,
> it can affect you unpredictably.

Hmm.... :/

> That's why export lists need to be
> maintained very carefully; this is true in most languages that provide some
> kind of module system.

I would disagree; in most languages that provide some kind of module
system that I have had experience with (C, C++, Ada, E, Java, and
Objective-C) export lists are generally not maintained carefully,
instead naming conventions are established that not only help you
identify the source of a name but also distinguish it from a "similar"
name from anotehr module.  Object oriented languages also expand their
name space by having class variables and, inside functions, instance
variables, that are clearly scoped.  Any duplication of names in these
languages becomes apparent quite quickly if it is between functions
because the compiler reports an error.

You are right, however, where global variables are concerned.  It is
usually the case that exports of global variables have to carefully
controlled (with "static" in C).

> As for MAKE-PACKAGE vs. DEFPACKAGE, that's just the way Lisp is.  It often
> provides low-level and high-level interfaces into the same feature.  It's
> analogous to SETF of SYMBOL-FUNCTION vs. DEFUN.

Not really.. THAT kind of ("defxxx" and "setf symbol-xxx") duality is
common and provides differing functionality, but make-package and
defpackage only appear to differ in the number of keywords they support.

CU
Dobes
From: Tim Bradshaw
Subject: Re: Packages (?)
Date: 
Message-ID: <ey3r9pja85x.fsf@lostwithiel.tfeb.org>
* Dobes Vandermeer wrote:
> I would disagree; in most languages that provide some kind of module
> system that I have had experience with (C, C++, Ada, E, Java, and
> Objective-C) export lists are generally not maintained carefully,
> instead naming conventions are established that not only help you
> identify the source of a name but also distinguish it from a "similar"
> name from anotehr module.  

Is this really true?  If so it must mean that the module systems for
these things have essentially failed.  The whole point of the package
system (which isn't a module system in the sense people who want
module systems think of them) is to avoid the kind of nightmare you
had in interlisp, and today in elisp where big subsystems have to name
everything like gnus-xxx or vm-xxx.

I don't find maintaining export lists burdensome, once I realised that
the symbols you export are essentially the API to my packages.  If I
change the exports I'm changing the API.

> Not really.. THAT kind of ("defxxx" and "setf symbol-xxx") duality is
> common and provides differing functionality, but make-package and
> defpackage only appear to differ in the number of keywords they support.

DEFPACKAGE is equivalent to a MAKE-PACKAGE followed by a bunch of the
other package functions.  It also happens at the correct time when
you're compiling, which you'd have to arrange to happen with
MAKE-PACKAGE & friends.

--tim
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfwogknl6xb.fsf@world.std.com>
Tim Bradshaw <···@tfeb.org> writes:

> > Not really.. THAT kind of ("defxxx" and "setf symbol-xxx") duality is
> > common and provides differing functionality, but make-package and
> > defpackage only appear to differ in the number of keywords they support.
> 
> DEFPACKAGE is equivalent to a MAKE-PACKAGE followed by a bunch of the
> other package functions.  It also happens at the correct time when
> you're compiling, which you'd have to arrange to happen with
> MAKE-PACKAGE & friends.

DEFPACKAGE is related to MAKE-PACKAGE functionally, but the difference
is really about "when" not "what" (again repeating my remarks about
DEFMACRO vs functions not evaluating arguments).

The best uses of DEFPACKAGE are to statically declare a package in a
source file in a way that is easy to read and not changing.

The best uses of MAKE-PACKAGE are (a) to dynamically create a package,
e.g., in an embedded system, or else (b) to create a package
statically using parameters that can only be computed by use of Lisp's
introspective tools for examining the state of other packages and
conjuring a package to match.  (Because CL imposes a requirement that
the compile-time package structure match the runtime package
structure, though, the latter activity, (b), can usually also be done
by a macro that expands into a DEFPACKAGE.)

DEFPACKAGE didn't exist in early CL and so a lot of uses of MAKE-PACKAGE
you'll find in code now are "legacy" uses and could (or even should) be
rewritten as DEFPACKAGE.
From: Juliusz Chroboczek
Subject: Re: Packages (?)
Date: 
Message-ID: <dh3n207s2h5.fsf@iolla.dcs.ed.ac.uk>
Kent M Pitman <······@world.std.com>:

KMP> DEFPACKAGE is related to MAKE-PACKAGE functionally, but the difference
KMP> is really about "when" not "what" (again repeating my remarks about
KMP> DEFMACRO vs functions not evaluating arguments).

KMP> The best uses of DEFPACKAGE are to statically declare a package in a
KMP> source file in a way that is easy to read and not changing.

And what when you have a statically declared package the exports list
of which is maintained programmatically?  Would you advise DEFPACKAGE
followed by EXPORT, or MAKE-PACKAGE followed by EXPORT?

The concrete example is as follows: a large system in which a number
of files do something like

  (eval-when (compile load eval)
    (dolist (s '(foo bar baz))
      (pushnew s *exports*)))

and the very last file exports all the symbols in *EXPORTS*.

                                        J.
From: Vassil Nikolov
Subject: Re: Packages (?)
Date: 
Message-ID: <7ff158$v2e$1@nnrp1.dejanews.com>
In article <···············@iolla.dcs.ed.ac.uk>,
  Juliusz Chroboczek <···@dcs.ed.ac.uk> wrote:
> Kent M Pitman <······@world.std.com>:
(...)
> KMP> The best uses of DEFPACKAGE are to statically declare a package in a
> KMP> source file in a way that is easy to read and not changing.
>
> And what when you have a statically declared package the exports list
> of which is maintained programmatically?  Would you advise DEFPACKAGE
> followed by EXPORT, or MAKE-PACKAGE followed by EXPORT?
>
> The concrete example is as follows: a large system in which a number
> of files do something like
>
>   (eval-when (compile load eval)
>     (dolist (s '(foo bar baz))
>       (pushnew s *exports*)))
>
> and the very last file exports all the symbols in *EXPORTS*.

I can see two issues here:

(A) Is the list of exported symbols indeed available at program writing
    time, as the example seems to suggest?  I.e., does the programmer
    list the exported symbols by hand, as above, or is the list somehow
    computed (at compile time)?

    If it is the former (the programmer knows the list), then this can
    be done by DEFPACKAGE with just an exports clause.

    (How important is it that everything is exported at once at the
    very end, and not portion by portion?  Does the use of COMPILE etc.
    instead of :COMPILE-TOPLEVEL etc. suggest that this was written in
    pre-DEFPACKAGE days?)

    Trying to think of a manner in which the export list would be
    computed at compile time, I imagined for example something like
    DEFUN-EXPORT which is like

      (progn
        (defun foo ...)
        (eval-when <always>
          (export 'foo)))  ;or (PUSHNEW 'FOO *EXPORTS*)

(B) Is it a good idea to have the export list divided into parts,
    one for each file?  I am not sure there is a single answer,
    and I'd say it much depends on the overall principles of
    module organisation that have been adopted by the programmer.

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Juliusz Chroboczek
Subject: Re: Packages (?)
Date: 
Message-ID: <dh3iuaosa8a.fsf@iolla.dcs.ed.ac.uk>
Vassil Nikolov <········@poboxes.com>:

VN> (A) Is the list of exported symbols indeed available at program writing
VN>     time, as the example seems to suggest?

Yes.

VN>     (How important is it that everything is exported at once at the
VN>     very end, and not portion by portion?

Not at all.  I'd be quite happy to do an EXPORT in each file.  But
does this not have a `too dynamic' feel, in Kent's words?

VN>     Does the use of COMPILE etc.
VN>     instead of :COMPILE-TOPLEVEL etc. suggest that this was written in
VN>     pre-DEFPACKAGE days?)

No.  It means that it was written in days when I was not yet familiar
with the new EVAL-WHEN keywords, but already familiar with DEFPACKAGE.

VN>     I imagined for example something like DEFUN-EXPORT

Mhh...  Are you seriously advocating the use of such a macro?

VN> (B) Is it a good idea to have the export list divided into parts,
VN>     one for each file?  I am not sure there is a single answer,
VN>     and I'd say it much depends on the overall principles of
VN>     module organisation that have been adopted by the programmer.

Very much so.  I think that in this case I got the package granularity
wrong.  I started with a single package, then split into two, then
three.  Finally, it was to much of a mess, and so I returned to a
single package which only exported one symbol (the name of the
user-visible REPL).

(The previous paragraph contains a slight lie, as there actually was
another package that was used by the reader in the REPL (which used a
Lisp-like syntax); however, as this package was not used as a module,
it is irrelevant to this discussion.)

Another solution would have been a more fine-grained package
structure, but the program was very experimental, and changed too
often to make that practical.

Kent Pitman:

KP> I usually build a FOO-INTERNALS package and then defpackage a FOO
KP> package with (:export . #.*EXPORTS*) when this happens.

Does that mean that the (DEFPACKAGE FOO) form also has an :IMPORT
clause with the value of FOO-INTERNALS::*EXPORTS*?  Correct me if I'm
wrong, but I don't think that a package can export a symbol that it
doesn't import in the first place.

Still, it's an interesting way of structuring it.  I have to think it
over (expect more silly questions).

                                        J.
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfwn2001bvs.fsf@world.std.com>
Juliusz Chroboczek <···@dcs.ed.ac.uk> writes:

> VN>     I imagined for example something like DEFUN-EXPORT
> 
> Mhh...  Are you seriously advocating the use of such a macro?

People tried this and it was a *real* disaster semantically.
It's very easy to get situations where if you don't do your exports
all at once, the fasl file knows whether it expects to reference
FOO:BAR or FOO::BAR and it has decided it can say FOO:BAR because
BAR is exported. Let's suppose this is in some file A. Now file
B is compiled, so it also references FOO:BAR.  But later you go to
incrementally recompile some module C that needs B but not A, and
you end up with FOO::BAR being needed but FOO:BAR tried.  The problem
si that the file module dependencies must make sure you load all
symbols in just the right order for each other file to load, but no
one wants to declare that (that's why they are doing DEFUN-EXPORT
instead of a centralized export list--they want to be ultra modular),
but the utlra-modular style is incompatible with good load order.
I may not be explaining it very well, but this is associated with
a good deal of pain experienced by lots of indepenent people all
of whom were just ever-so-sure they had this all worked out and were
not going to have to write centralized export lists, but in the
end it was just too painful.

Vassil, in particular, should be advocating NOT doing this because it
means he has to "redundantly" load all the files just so the exports
are right. ;-)

> Kent Pitman:
> 
> KP> I usually build a FOO-INTERNALS package and then defpackage a FOO
> KP> package with (:export . #.*EXPORTS*) when this happens.
> 
> Does that mean that the (DEFPACKAGE FOO) form also has an :IMPORT
> clause with the value of FOO-INTERNALS::*EXPORTS*?  Correct me if I'm
> wrong, but I don't think that a package can export a symbol that it
> doesn't import in the first place.

Instead of "doesn't import" you mean "doesn't have accessible" (since
either being locally present or imported works), but you're ok on that
I think.  But yes, it does have to :import.  Usually I don't actually
use a variable, actually.  Instead I may do:
(defpackage "FOO"
 (:use)
 (:import . #1=#.(let ((list '()))
                   (do-external-symbols (symbol "FOO-INTERNALS")
                      (push symbol list))
                   list))
 (:export . #1#))
or whatever is needed to find the relevant symbols. I'm usually careful
to use only variable names that are CL symbols so as not to "pollute"
the bootstrap namespace with new symbols that aren't needed.  Symbols
like LIST, SYMBOL, and STRING make good variable names here. 

I've sometimes been known to do:
(progn
(defpackage "FOO-INTERNALS"
  (:use)
 (:export 
   ;; "private" exports
   "*FOO-INTERNALS-EXPORTS*"
   ;; "shared" exports
   . #1=("FOO" "BAR" "BAZ")))
(defpackage "FOO"
 (:import . #1#)
 (:export . #1#))
);ngorp

[Sometimes, btw, this is an ok place for MAKE-PACKAGE if the package is
going to be totally automatically created anyway and not used in the
system defining it, since the package is basically a data product and
not a declarative glue part of the program.]

> Still, it's an interesting way of structuring it.  I have to think it
> over (expect more silly questions).

Doubtless the above examples will give you some questions.

Stylistically someone might say those are marginal, but the importance
of good style is to be flexible to need, and though that code may
seem impenetrable, it's not very hard, and most people will just edit
the constant lists of symbols without reading the junk around it.  That
said, the dominant problem to solve is not getting things inconsistent,
and that code keeps it from being the case that someone edits one part
without remembering to edit another...  

The biz with
(progn
...
);ngorp

is because some text editors get confused if definitions are not in column
0.  Whenever I have to put definitions in column 0, I always name
the containing brackets that way.  Random, I suppose...
From: Vassil Nikolov
Subject: Re: Packages (?)
Date: 
Message-ID: <7fqhro$ejc$1@nnrp1.dejanews.com>
In article <···············@world.std.com>,
  Kent M Pitman <······@world.std.com> wrote:
> Juliusz Chroboczek <···@dcs.ed.ac.uk> writes:
>
> > VN>     I imagined for example something like DEFUN-EXPORT
> >
> > Mhh...  Are you seriously advocating the use of such a macro?
>
> People tried this and it was a *real* disaster semantically.
(...)
> Vassil, in particular, should be advocating NOT doing this because it
> means he has to "redundantly" load all the files just so the exports
> are right. ;-)

:-)

Absolutely.

If anything I wrote sounded like such advocating, that was my mistake.
I was looking for a quick and dirty illustration of what I had in
mind as constructing the export list from pieces by side effect,
and was willing to live with that which, being a silly example,
I did not bother to check for sanity.  I should have mentioned
that in my post.

(...)
> I've sometimes been known to do:
> (progn
> (defpackage "FOO-INTERNALS"
>   (:use)
>  (:export
>    ;; "private" exports
>    "*FOO-INTERNALS-EXPORTS*"
>    ;; "shared" exports
>    . #1=("FOO" "BAR" "BAZ")))
> (defpackage "FOO"
>  (:import . #1#)
>  (:export . #1#))
> );ngorp

Not that you need my praise, but this is the Right Thing if
I ever saw one.

> [Sometimes, btw, this is an ok place for [a maker function] if the
> [entity] is going to be totally automatically created anyway and not
> used in the system defining it, since the [entity] is basically a data
> product and not a declarative glue part of the program.]

I knew there was a way to express my compile-time/run-time/defmacro/etc.
point from the other thread in just four lines...

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfw1zhg3hwa.fsf@world.std.com>
Juliusz Chroboczek <···@dcs.ed.ac.uk> writes:

> Kent M Pitman <······@world.std.com>:
> 
> KMP> DEFPACKAGE is related to MAKE-PACKAGE functionally, but the difference
> KMP> is really about "when" not "what" (again repeating my remarks about
> KMP> DEFMACRO vs functions not evaluating arguments).
> 
> KMP> The best uses of DEFPACKAGE are to statically declare a package in a
> KMP> source file in a way that is easy to read and not changing.
> 
> And what when you have a statically declared package the exports list
> of which is maintained programmatically?  Would you advise DEFPACKAGE
> followed by EXPORT, or MAKE-PACKAGE followed by EXPORT?
> 
> The concrete example is as follows: a large system in which a number
> of files do something like
> 
>   (eval-when (compile load eval)
>     (dolist (s '(foo bar baz))
>       (pushnew s *exports*)))
> 
> and the very last file exports all the symbols in *EXPORTS*.

I usually build a FOO-INTERNALS package and then defpackage a FOO
package with (:export . #.*EXPORTS*) when this happens.

This is for two reasons--one is to get around the problem above.
The other is philosophical--I really do believe that the exports
should not "vary"--if you are *really* dynamically changing the export list
of a package, I am skeptical that the export list has meaning to other
packages.  If you are only using that as an implementation device for a
modularly constructed system, then the FOO-INTERNALS => FOO methodology
expresses that pretty well.

My greater annoyance personally--and everyone's views on this are very 
personal because the process of package definition is about how we view
the connectivity of the world, and that's a lot based on experience--is
that there's no simple way to export things based on what you imported,
or vice versa.  It is here, more than any other place, that I use both
#. and #n= and #n# to make sure I don't actually make a typo.  That
hints to me that something is wrong in the syntax of DEFPACAKGE.  But
I still prefer those reader mechanism for enforcing consistency over
falling back to MAKE-PACKAGE because that feels "too dynamic".

Keep in mind that "style rules", even strong ones, are reminders to
understand the issues and then choose wisely more than they are claims
that you should always believe the person issuing the style rule.
When I say  you should *really* do a certain thing, what I'm saying is
"you should *really* understand this issue well if you want to deviate".
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <3718DDF2.D19F8614@mindless.com>
Tim Bradshaw wrote:
> 
> * Dobes Vandermeer wrote:
> > I would disagree; in most languages that provide some kind of module
> > system that I have had experience with (C, C++, Ada, E, Java, and
> > Objective-C) export lists are generally not maintained carefully,
> > instead naming conventions are established that not only help you
> > identify the source of a name but also distinguish it from a "similar"
> > name from anotehr module.
> 
> Is this really true?  If so it must mean that the module systems for
> these things have essentially failed.  The whole point of the package
> system (which isn't a module system in the sense people who want
> module systems think of them) is to avoid the kind of nightmare you
> had in interlisp, and today in elisp where big subsystems have to name
> everything like gnus-xxx or vm-xxx.

Well I actually forgot about JAVA and ADA, which do have a hierachal
package system, and you can access functions & classes directly through
the hierarchy (e.g. Java.Lang.Object) or by importing a node form the
hierarchy (import Java.Lang).  These package systems are "safe" in that
they only provide a search path to a name, as opposed to importing all
those names into your package, and definitions are scoped so that your
local functions never interfere with the other package's functions.

> I don't find maintaining export lists burdensome, once I realised that
> the symbols you export are essentially the API to my packages.  If I
> change the exports I'm changing the API.

OK, I can live with that.

> > Not really.. THAT kind of ("defxxx" and "setf symbol-xxx") duality is
> > common and provides differing functionality, but make-package and
> > defpackage only appear to differ in the number of keywords they support.
> 
> DEFPACKAGE is equivalent to a MAKE-PACKAGE followed by a bunch of the
> other package functions.  It also happens at the correct time when
> you're compiling, which you'd have to arrange to happen with
> MAKE-PACKAGE & friends.

Hmm... I dont entirely understand what you mean by "at the correct time
when you're compiling", but I do now understand that make-package is
more low-level than defpackage, and somewhat deprecated.

CU
Dobes
From: Tim Bradshaw
Subject: Re: Packages (?)
Date: 
Message-ID: <ey3pv539bxe.fsf@lostwithiel.tfeb.org>
* Dobes Vandermeer wrote:
>> DEFPACKAGE is equivalent to a MAKE-PACKAGE followed by a bunch of the
>> other package functions.  It also happens at the correct time when
>> you're compiling, which you'd have to arrange to happen with
>> MAKE-PACKAGE & friends.

> Hmm... I dont entirely understand what you mean by "at the correct time
> when you're compiling", but I do now understand that make-package is
> more low-level than defpackage, and somewhat deprecated.

I don't think it's deprecated, I think it serves a different purpose.
If you want to do a lot of package-manipulation type things,
especially programmatically, you probably want to use the functional
interface. If you just want to declare a package once, then DEFPACKAGE
is what you want.  As an example I have some code which creates
packages which are `just like' another package (usually the CL
package), apart from a few symbols, which is useful if you want to
define slightly variant versions of CL.  To do that you need to use
the functional interface (because you need to be able to enumerate all
the symbols in a package).

The issue of things happening at the correct time matters because
MAKE-PACKAGE is a function.  So if you are compiling a file which has
in it, at the top level, (MAKE-PACKAGE ...), the compiler will not
call that function at compile time, so the package will not exist when
you are compiling and this is a bad thing.  Without a DEFPACKAGE macro
you either need lots of EVAL-WHENs, or the compiler needs special
knowledge of the package forms (which is what it had I think).

--tim
From: Vassil Nikolov
Subject: Re: Packages (?)
Date: 
Message-ID: <7fc0a9$hr5$1@nnrp1.dejanews.com>
In article <···············@lostwithiel.tfeb.org>,
  Tim Bradshaw <···@tfeb.org> wrote:
(...)
> Without a DEFPACKAGE macro
> you either need lots of EVAL-WHENs, or the compiler needs special
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
> knowledge of the package forms (which is what it had I think).
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
That used to be in the 1st edition of CLtL and was changed in
CLtL2 and ANSI Common Lisp, so that the compiler now is required
to treat only special forms specially.

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Vassil Nikolov
Subject: Re: Packages (?)
Date: 
Message-ID: <7fbvd8$ha3$1@nnrp1.dejanews.com>
In article <·················@mindless.com>,
  Dobes Vandermeer <·····@mindless.com> wrote:
(...)
> Well I actually forgot about JAVA and ADA, which do have a hierachal
> package system, and you can access functions & classes directly through
> the hierarchy (e.g. Java.Lang.Object) or by importing a node form the
> hierarchy (import Java.Lang).  These package systems are "safe" in that
> they only provide a search path to a name, as opposed to importing all
> those names into your package, and definitions are scoped so that your
> local functions never interfere with the other package's functions.

Apart from the hierarchy, you can do similarly in Common Lisp:
<Java package>.<thing> is similar to <Common Lisp package>:<thing>.

You can also scope definitions if necessary, not only by the package
system, but by FLET and friends.

(...)
> > DEFPACKAGE is equivalent to a MAKE-PACKAGE followed by a bunch of the
> > other package functions.  It also happens at the correct time when
> > you're compiling, which you'd have to arrange to happen with
> > MAKE-PACKAGE & friends.
>
> Hmm... I dont entirely understand what you mean by "at the correct time
> when you're compiling", but I do now understand that make-package is
> more low-level than defpackage, and somewhat deprecated.

`Correct time during compilation' here means that the effect of
DEFPACKAGE is felt by the file compiler so that when it reads the
rest of the file, all symbols get in the right package.  In this
respects DEFPACKAGE saves you from having to wrap MAKE-PACKAGE^1
in EVAL-WHEN (with :COMPILE-TOPLEVEL).
__________
^1 as well as other package operations

DEFPACKAGE can be implemented in Common Lisp by EVAL-WHEN plus
MAKE-PACKAGE, SHADOW, IMPORT, EXPORT, etc., but it would be rather
painful and error-prone if it were absent from the language.

MAKE-PACKAGE is _not_ deprecated in any way.  It is the package
constructor, and essential to the functionality of the package
system.

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Christopher R. Barry
Subject: Re: Packages (?)
Date: 
Message-ID: <87n1zysuaa.fsf@2xtreme.net>
Tim Bradshaw <···@tfeb.org> writes:

> The whole point of the package system (which isn't a module system
> in the sense people who want module systems think of them) is to
> avoid the kind of nightmare you had in interlisp, and today in elisp
> where big subsystems have to name everything like gnus-xxx or
> vm-xxx.

They don't _have_ to. The Franz Emacs Lisp Interface does everything
in the "fi" package so you for example start a process with
fi:common-lisp.

The facility exists but most code out there predates it or the authors
don't wish to break anything I would guess.

Christopher
From: Valeriy E. Ushakov
Subject: Re: Packages (?)
Date: 
Message-ID: <7fs5ot$eee$1@news.ptc.spbu.ru>
Christopher R. Barry <······@2xtreme.net> wrote:

>> avoid the kind of nightmare you had in interlisp, and today in elisp
>> where big subsystems have to name everything like gnus-xxx or
>> vm-xxx.

> They don't _have_ to. The Franz Emacs Lisp Interface does everything
> in the "fi" package so you for example start a process with
> fi:common-lisp.

That's just a symbol with name "fi:common-lisp", the colon being part
of the name.  They just choose to write more CL'ish fi:xxx instead of
more elispish fi-xxx.

SY, Uwe
-- 
···@ptc.spbu.ru                         |       Zu Grunde kommen
http://www.ptc.spbu.ru/~uwe/            |       Ist zu Grunde gehen
From: Tim Bradshaw
Subject: Re: Packages (?)
Date: 
Message-ID: <ey3pv4uuzng.fsf@lostwithiel.tfeb.org>
* Christopher R Barry wrote:
> Tim Bradshaw <···@tfeb.org
> They don't _have_ to. The Franz Emacs Lisp Interface does everything
> in the "fi" package so you for example start a process with
> fi:common-lisp.

No it doesn't.  It uses a prefix `fi:' on symbol names rather than the
more traditional `fi-', to make it look like there are packages.
Elisp has no package system.

--tim
From: Christopher R. Barry
Subject: Re: Packages (?)
Date: 
Message-ID: <873e1psusv.fsf@2xtreme.net>
Tim Bradshaw <···@tfeb.org> writes:

> * Christopher R Barry wrote:
> > Tim Bradshaw <···@tfeb.org
> > They don't _have_ to. The Franz Emacs Lisp Interface does everything
> > in the "fi" package so you for example start a process with
> > fi:common-lisp.
> 
> No it doesn't.  It uses a prefix `fi:' on symbol names rather than the
> more traditional `fi-', to make it look like there are packages.
> Elisp has no package system.

My bad. There are "obarrays", but they are different and not as
powerful. I thought, in error, the newer Emacsen had a CL-style symbol
package system and variables like "info::toolbar" kind of reinforced
my thinking. Oops.

Christopher
From: Marco Antoniotti
Subject: Re: Packages (?)
Date: 
Message-ID: <lweml8g9ml.fsf@copernico.parades.rm.cnr.it>
······@2xtreme.net (Christopher R. Barry) writes:

> Tim Bradshaw <···@tfeb.org> writes:
> 
> > * Christopher R Barry wrote:
> > > Tim Bradshaw <···@tfeb.org
> > > They don't _have_ to. The Franz Emacs Lisp Interface does everything
> > > in the "fi" package so you for example start a process with
> > > fi:common-lisp.
> > 
> > No it doesn't.  It uses a prefix `fi:' on symbol names rather than the
> > more traditional `fi-', to make it look like there are packages.
> > Elisp has no package system.
> 
> My bad. There are "obarrays", but they are different and not as
> powerful. I thought, in error, the newer Emacsen had a CL-style symbol
> package system and variables like "info::toolbar" kind of reinforced
> my thinking. Oops.

Not only Elisp only has OBARRAYs, but, last time I heard (things may
have changed since), Guile has a very messed up version of packages
and libraries and other things like those.  I'd like to be contradicted.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: thi
Subject: Re: Packages (?)
Date: 
Message-ID: <m2ryaje8uak.fsf@netcom10.netcom.com>
Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:

> Not only Elisp only has OBARRAYs, but, last time I heard (things may
> have changed since), Guile has a very messed up version of packages
> and libraries and other things like those.  I'd like to be
> contradicted.

guile is undergoing development of a module system.  until then, the
current module system is implemented such that a module basically has
two obarrays, one private one public.  one can export symbols to the
public interface, and to use a module means to have access to its public
interface.

whether or not this is messed up is a matter of opinion.  for the same
reason, the only contradiction possible is mu, sorry.

thi
-- 
________________________________________________________________________
thien-thi nguyen                   ^                   san jose, ca, usa
···@netcom.com           it's a balance thing.           +1 408 314 3470
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfwn207l6c6.fsf@world.std.com>
Dobes Vandermeer <·····@mindless.com> writes:

> > As for MAKE-PACKAGE vs. DEFPACKAGE, that's just the way Lisp is.  It often
> > provides low-level and high-level interfaces into the same feature.  It's
> > analogous to SETF of SYMBOL-FUNCTION vs. DEFUN.
> 
> Not really.. THAT kind of ("defxxx" and "setf symbol-xxx") duality is
> common and provides differing functionality, but make-package and
> defpackage only appear to differ in the number of keywords they support.

You have to take MAKE-PACKAGE as short-hand for MAKE-PACKAGE + the host
of functions like IMPORT, EXPORT, etc.  That is, DEFPACKAGE is the declarative
equivalent of the set of functional package manipulators.

The number of keywords seems to me irrrelevant.
 (DEFPACKAGE ...)
 is to
 {(MAKE-PACKAGE ...), (IMPORT ...), (EXPORT ...), ...etc.}
 as
 (DEFUN ....)
 is to
 (SETF (SYMBOL-FUNCTION ...) #'(LAMBDA ...))

Also, you are strongly encouraged stylistically to have only ONE 
DEFPACKAGE form, not to litter them all over the place, just as you
are strongly encouraged to have only one DEFUN for a given function.
It works to put them in various places (both function and package
definitions) but most compilers will rightly give you dire warnings 
about how you've defined the thing in two places.

On the other hand, there is no meaningful way in which the compiler
could nor does it even try to warn you about MAKE-PACKAGE uses being
done in more than one place, just as it doesn't try to warn you about
SETF of SYMBOL-FUNCTION being done in more than one place.  What is
done dynamically at runtime is up to the programmer to maintain.

Personally, I think all this discussion of "what do packages do"
nad "is it good enough" is misguided.  Lots of people have used packges
for about 20 years now and they mostly work under some pretty difficult
stress.  You should say what you are trying to do that you don't know
how to do with packages, and then when someone tells you how they
would do it, you should say what makes you nervous about the proposed
approach.  You're not going to get to any kind of feeling of comfort
about them as long as you just speak in abstracts and take a random walk
poking at this or that random  corner of the package system with no 
examples to talk about.
From: Vassil Nikolov
Subject: Re: Packages (?)
Date: 
Message-ID: <7fadv3$9hc$1@nnrp1.dejanews.com>
In article <···············@world.std.com>,
  Kent M Pitman <······@world.std.com> wrote:
(...)
> You have to take MAKE-PACKAGE as short-hand for MAKE-PACKAGE + the host
                   ^^^^^^^^^^^^
DEFPACKAGE you mean, of course.

> of functions like IMPORT, EXPORT, etc.  That is, DEFPACKAGE is the declarative
> equivalent of the set of functional package manipulators.
(...)

For me, packages are explained sufficiently well in CLtL[2] and
in the HyperSpec.  But I did have to read them a few times to
get the idea.  (Knowing the concepts of Modula-2 also helped
some.)

But maybe _textbooks_ don't explain packages well?

Does the world need a textbook just on packages, interacting
with a typical Lisp system, program organisation, etc.?

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfwvhevf24l.fsf@world.std.com>
Vassil Nikolov <········@poboxes.com> writes:

> In article <···············@world.std.com>,
>   Kent M Pitman <······@world.std.com> wrote:
> (...)
> > You have to take MAKE-PACKAGE as short-hand for MAKE-PACKAGE + the host
>                    ^^^^^^^^^^^^
> DEFPACKAGE you mean, of course.

No, in the context (now lost) I meant make-package.

It had been asserted that defpackage was to make-package as defun was
to setf of symbol-function.  And that's not entirely true.  In that
equation, you must assume "make-package" is shorthand for "make-package
+ several things" exactly so that it balances DEFPACKAGE.  I am prone to
make the error you thought you caught me on here more often than I should,
but this is one case where I was actually not goofing.

> > of functions like IMPORT, EXPORT, etc.  That is, DEFPACKAGE is the declarative
> > equivalent of the set of functional package manipulators.
> (...)
> 
> For me, packages are explained sufficiently well in CLtL[2] and
> in the HyperSpec.  But I did have to read them a few times to
> get the idea.  (Knowing the concepts of Modula-2 also helped
> some.)
> 
> But maybe _textbooks_ don't explain packages well?
> 
> Does the world need a textbook just on packages, interacting
> with a typical Lisp system, program organisation, etc.?

I'll add it to the list for mine.  various people have suggested there's
no reason for another lisp textbook, so I at least wanna catch some of
these less-covered areas.
From: Vassil Nikolov
Subject: Re: Packages (?)---and textbooks
Date: 
Message-ID: <7fc00l$ho1$1@nnrp1.dejanews.com>
In article <···············@world.std.com>,
  Kent M Pitman <······@world.std.com> wrote:
> Vassil Nikolov <········@poboxes.com> writes:
>
> > In article <···············@world.std.com>,
> >   Kent M Pitman <······@world.std.com> wrote:
> > (...)
> > > You have to take MAKE-PACKAGE as short-hand for MAKE-PACKAGE + the host
> >                    ^^^^^^^^^^^^
> > DEFPACKAGE you mean, of course.
>
> No, in the context (now lost) I meant make-package.
>
> It had been asserted that defpackage was to make-package as defun was
> to setf of symbol-function.  And that's not entirely true.  In that
> equation, you must assume "make-package" is shorthand for "make-package
> + several things" exactly so that it balances DEFPACKAGE.  I am prone to
> make the error you thought you caught me on here more often than I should,
> but this is one case where I was actually not goofing.

I missed your meaning in that post.  I am sorry.  Thanks for explaining.

(...)
> > But maybe _textbooks_ don't explain packages well?
> >
> > Does the world need a textbook just on packages, interacting
> > with a typical Lisp system, program organisation, etc.?
>
> I'll add it to the list for mine.  various people have suggested there's
> no reason for another lisp textbook, so I at least wanna catch some of
> these less-covered areas.

Let me add that, besides explaining how packages (or whatever) work,
and how to use them, it is _important_ to explain _why_ they are the
way they are, and what the _purposes_ of their designers were.  This
helps, sometimes a lot.  (I am also thinking of the `Rationale' notes
in CLtL, but extended.  I am also thinking of Feynman's story of how
he explained his programmers at Los Alamos the purpose of their
endeavour, and how that helped, though the analogy here is only with
respect to the usefulness of not treating people like beings that
only receive instruction, be it commands or education.)

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <3718D6AF.65EE9D47@mindless.com>
Kent M Pitman wrote:
> 
> Dobes Vandermeer <·····@mindless.com> writes:
> 
> > > As for MAKE-PACKAGE vs. DEFPACKAGE, that's just the way Lisp is.  It often
> > > provides low-level and high-level interfaces into the same feature.  It's
> > > analogous to SETF of SYMBOL-FUNCTION vs. DEFUN.
> >
> > Not really.. THAT kind of ("defxxx" and "setf symbol-xxx") duality is
> > common and provides differing functionality, but make-package and
> > defpackage only appear to differ in the number of keywords they support.
> 
> You have to take DEFPACKAGE as short-hand for MAKE-PACKAGE + the host
> of functions like IMPORT, EXPORT, etc.  That is, DEFPACKAGE is the declarative
> equivalent of the set of functional package manipulators.

OK, I see what you are saying.  So make-package and friends you might
use instead of defpackage to give you slightly finer-tuned control.

> Also, you are strongly encouraged stylistically to have only ONE
> DEFPACKAGE form, not to litter them all over the place

How could you litter them all over the place?  

You mean to have one defpackage in each file that is part of the
package?

> On the other hand, there is no meaningful way in which the compiler
> could nor does it even try to warn you about MAKE-PACKAGE uses being
> done in more than one place, just as it doesn't try to warn you about
> SETF of SYMBOL-FUNCTION being done in more than one place.  What is
> done dynamically at runtime is up to the programmer to maintain.

Actually, as someone mentioned before, it does mention it if you define
a function in two different files, at least in Allegro, so perhaps its
not so bad.

> Personally, I think all this discussion of "what do packages do"
> nad "is it good enough" is misguided.  Lots of people have used packges
> for about 20 years now and they mostly work under some pretty difficult
> stress.  

I dont think thats a legitimate argument, in ANY context.  Lots of
people have been using 2-digit dates for about 20 years, and their time
is up.  Lots of people have been using COBOL for about 20 years, and it
too has died.

> You should say what you are trying to do that you don't know
> how to do with packages, and then when someone tells you how they
> would do it, you should say what makes you nervous about the proposed
> approach.  

Well, this would help if I was trying to actually do something with
packages.  Unfortunately, I am not; I am just trying to evaluate how and
if I would use them.  So far I have yet to engage in a LISP project
large enough that the risk of duplicate names between systems grows to
the point that packages would be needed; this may change soon.

> You're not going to get to any kind of feeling of comfort
> about them as long as you just speak in abstracts and take a random walk
> poking at this or that random  corner of the package system with no
> examples to talk about.

Well, I am just learning about packages, and when I see an inconsistency
or likely problem, I of course want to find out why I am seeing it, and
if its fixable.

CU
Dobes
From: Tim Bradshaw
Subject: Re: Packages (?)
Date: 
Message-ID: <ey3ogkn9bi8.fsf@lostwithiel.tfeb.org>
* Dobes Vandermeer wrote:

> I dont think thats a legitimate argument, in ANY context.  Lots of
> people have been using 2-digit dates for about 20 years, and their time
> is up.  Lots of people have been using COBOL for about 20 years, and it
> too has died.

But they died (did cobol die?  I don't think so) because people came
across stuff they wanted to do that they really couldn't, or it was
ridiculously hard.  Not because someone made a claim that it was hard
to do x based on not having tried.

If you're willing to put effort into understanding it (and willing to
end up restarting your Lisp lots of times after you've fouled up the
namespace by fiddling with the package system!), you can do quite a
lot of things people claim are hard or impossible with it.  The best
example I have is the one I mentioned earlier in this thread -- people
claimed you couldn't do `variant CL's with packages in a way that
wasn't painful to use (because of name clashes).  But actually you can
do that.  But it wasn't obvious to me that you could until I tried
doing it.

--tim
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <37194731.4B71D376@mindless.com>
Tim Bradshaw wrote:
> 
> * Dobes Vandermeer wrote:
> 
> > I dont think thats a legitimate argument, in ANY context.  Lots of
> > people have been using 2-digit dates for about 20 years, and their time
> > is up.  Lots of people have been using COBOL for about 20 years, and it
> > too has died.
> 
> But they died (did cobol die?  I don't think so) because people came
> across stuff they wanted to do that they really couldn't, or it was
> ridiculously hard.  Not because someone made a claim that it was hard
> to do x based on not having tried.

OK, fair enough.

I have tried casually to use packages before, but I just got confused
and had to scrap it completely; I couldn't figure anything out, and I
kept getting unexpected problems and so forth.  Perhaps now with a
better understanding they will become more useful to me one day.

CU
Dobes
From: Kent M Pitman
Subject: Re: Packages (?)
Date: 
Message-ID: <sfwu2uff0p1.fsf@world.std.com>
Dobes Vandermeer <·····@mindless.com> writes:

> > Personally, I think all this discussion of "what do packages do"
> > nad "is it good enough" is misguided.  Lots of people have used packges
> > for about 20 years now and they mostly work under some pretty difficult
> > stress.  
> 
> I dont think thats a legitimate argument, in ANY context.

It's not an argument.  It's a truth about my opinion, and about my
observations of usage patterns throughout that time.  I'm saying I
don't have the energy to explain on a newsgroup why the package system
is right to you, one person.  People are bad about looking up compiled
answers on newsgroups and the info would get lost.  I might write it
in a book or if you paid me I might take the time to explain it to y
ou.  But it's beyond the scope of what I am personally willing to do
here and you may exhaust the patience of others to do it, too.  That
isn't an argument.  But you aren't a priori entitled to anything from
a newsgroup--just the hope someone will answer you.  Newsgroups are
filled with trolls and we can spend forever justifying to each
individual's taste whether something is worth it.  In the end, we just
all die not having done anything with our lives, and the trolls have
not contributed anything either. On the other hand, if you are having
trouble *using* the system, most of us are more willing to help you
with that.  This is not to accuse you of being a troll.  But the line
between being one and not is blurred, and is not always an issue of
intent.  Sometimes a person can consume undue resources from a group
without offering anything in return and that can be just as unjust
whether they intend to do this or not.  The fact is that we are all
here just a little bit prone at one time or another to sense arguments
that won't terminate or that will require more resources to win than
we have the time to spend.  If you aren't willing to trust the system
to work, you needn't use it.  If you are willing to trust that it
works, try USING it.  One way I personally sort out who are the good
risks to have long discussions with is by inspecting how much energy
they have invested themselves into things.  When you say you won't use
it until it's proven to work, or that you're only looking at this one
aspect of the system and at no other, you make people--certainly
me--skeptical that you are a good risk.  I/we could go on for weeks
with detailed answers to questions and still never satisfy you.
Meanwhile, other people making legitimate attempts to trust and use
the language might be getting ignored.

When I see some evidence that you've tried to build a system that uses
packages and you're having problems, I'll be happy to chime in with
help.  But I don't have the time to spend on an academic discussion.
My time is valuable, and this is not personally to me a good use of
it.  It's not important to me that some people don't like or
appreciate Lisp; I've long since come to grips with that.  Even the
world's best writers, artists, and so on have people who don't
appreciate them; it doesn't make them wrong.  I'm more personally
interested in supporting those who do like and appreciate Lisp, and
learning about the problems they legitimately encounter through use
than hearing some theoretical concern from someone who is not a user.

Just my opinions here.  You're welcome to seek those of others.
Perhaps they'll be more helpful.
From: Dobes Vandermeer
Subject: Re: Packages (?)
Date: 
Message-ID: <371946D9.D92830CF@mindless.com>
Kent M Pitman wrote:
> 
> Dobes Vandermeer <·····@mindless.com> writes:
> 
> > > Personally, I think all this discussion of "what do packages do"
> > > nad "is it good enough" is misguided.  Lots of people have used packges
> > > for about 20 years now and they mostly work under some pretty difficult
> > > stress.
> >
> > I dont think thats a legitimate argument, in ANY context.
> 
> When I see some evidence that you've tried to build a system that uses
> packages and you're having problems, I'll be happy to chime in with
> help.

OK, I'll sign off about this until then.. you've actually invested a
fair bit of time into my questions, and I appreciate it!

Thanks
Dobes
From: Vassil Nikolov
Subject: Re: Packages (?)
Date: 
Message-ID: <7fc0r2$i9m$1@nnrp1.dejanews.com>
In article <·················@mindless.com>,
  Dobes Vandermeer <·····@mindless.com> wrote:
(...)
> So make-package and friends you might
> use instead of defpackage to give you slightly finer-tuned control.

No.  DEFPACKAGE is compile-time and MAKE-PACKAGE and the rest of them
functions are run-time.

DEFPACKAGE is redundant if you happen to be willing to take the
pain of doing it yourself, taking care of proper order, etc.

> > Also, you are strongly encouraged stylistically to have only ONE
> > DEFPACKAGE form, not to litter them all over the place
>
> How could you litter them all over the place?

You can have one DEFPACKAGE form that establishes the package
and does shadowing; then a few forms down you could have another
that does exporting; then later on another that does more exporting,
and so on.  Hard to read, hard to maintain, error-prone.

> You mean to have one defpackage in each file that is part of the
> package?

No.  You have a single DEFPACKAGE form, perhaps by itself in a file
you load to establish the package, and before loading any other file,
you make sure that package-defining file is loaded.

(...)

Good luck,
Vassil.

--
Vassil Nikolov <········@poboxes.com> www.poboxes.com/vnikolov
(You may want to cc your posting to me if I _have_ to see it.)
   LEGEMANVALEMFVTVTVM  (Ancient Roman programmers' adage.)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
From: Tim Bradshaw
Subject: Re: Packages (?)
Date: 
Message-ID: <ey3lnfq9rro.fsf@lostwithiel.tfeb.org>
* Vassil Nikolov wrote:

> No.  You have a single DEFPACKAGE form, perhaps by itself in a file
> you load to establish the package, and before loading any other file,
> you make sure that package-defining file is loaded.

Incidentally, I found quite an interesting thing about this.  I used
to have a DEFPACKAGE (well, probably a MAKE-PACKAGE / IN-PACKAGE as
this was a while ago) somewhere, then each file of my package would
define some exports.  This is nice because it means I don't have to
keep maintaining this once-and-for-all definition of my exports.  But
it's not nice, because there *is* no once-and-for-all definition of
the exports, which means (if, like me, you treat the exported things
as the interface to whatever functionality you want) that the
definition of the interface is scattered throughout n files, and it's
really hard to keep it coherent.

I got half way through writing a DEFsomething macro which would define
a package and allow rather elaborate export descriptions which would
include some documentation, & `type' (variable, function) information,
but I don't think I ever finished it.  In any case I'm not sure it was
the right way to do this.

--tim
From: Chuck Fry
Subject: Re: Packages (?)
Date: 
Message-ID: <7fib9d$elb$1@shell5.ba.best.com>
In article <·················@mindless.com>,
Dobes Vandermeer  <·····@mindless.com> wrote:
>How often do people actually use packages?  

I construct specific packages for every project I do that's more than a
quick hack.

>Just in passing, they seem to be solving the right problem in possibly
>the wrong way.  You can never be completely sure what symbols you are
>sharing with what package, and there seems to be a few different ways to
>achieve the same ends in some cases (make-package vs. defpackage).

Using packages correctly takes some practice and a fair bit of
discipline.  It's unclear to me whether a simpler way would also provide
the necessary features.

Think of MAKE-PACKAGE as a primitive, to be used in higher level
constructs, while DEFPACKAGE is clearly intended as a user tool.  This
is consistent with other features in Common Lisp (e.g. MAKE-SYMBOL
vs. INTERN).

 -- Chuck
-- 
	    Chuck Fry -- Jack of all trades, master of none
 ······@chucko.com (text only please)  ········@home.com (MIME enabled)
Lisp bigot, mountain biker, car nut, sometime guitarist and photographer
The addresses above are real.  All spammers will be reported to their ISPs.
From: Thomas A. Russ
Subject: Re: Packages (?)
Date: 
Message-ID: <ymik8v8muff.fsf@sevak.isi.edu>
OK, I'll jump into the fray with my take on an explanation.

[Ignore the comments in square brackets.  They are just there to try to
 forestall having a certain other list contributor complain about how I
 am confusing you by leaving out certain exceptions.]

Dobes Vandermeer <·····@mindless.com> writes:

> I am having difficulty understanding the mechanism and uses of packages.

First off, let us start with SYMBOLS.

Symbols are lisp objects that have a number of attributes.  Among other
things, they have value and function cells and a name.  Any particular
symbol is a single object.

As a convenience to the user, Lisp provides a means for finding [most]
symbols by using their NAME.  The process of setting up a mapping from
the name (a STRING) to the SYMBOL is called interning.  There is a Lisp
function, INTERN, which will do this programmatically.  In addition the
Lisp reader will intern symbols while it reads them.
   [Don't worry about uninterned symbols and the reader's treatment of
    them for now]

The process of interning a symbol, however, involves more than just the
name of the symbol.  It also involves a PACKAGE.  At its core, a package
is a data structure that provides a mapping from names to symbols.  By
introducing separate packages, different symbols can have the same name
as long as they are in different packages.
   [or if they aren't interned at all]

The main service that packages provide is just this mapping.

There are other functions for manipulating symbols and their
relationship to packages.  EXPORTing symbols from a package gives them
special status.  This affects the reader and other packages that USE the
package in question.

The Lisp reader provides a means by which you can refer to symbols in
other packages.  That is by the use of names that include the package
prefix.  The package prefix is separated from the symbol name by the use
of one or two colon (":") characters.  Any interned symbol can be
refered to by using two colons to separate the package name from the
symbol name.  Exported symbols [and symbols in the keyword package] can
be referred to using only a single colon.

The whole issue of USEing another package is again mainly a convenience,
since it allows you to refer to the exported symbols of another package
(the one you are using) without having to type the package prefix.
   [Shadowing and Shadowing-import can affect this]

Importing symbols is similar to USEing, but operates at a more
fine-grained level.  Instead of getting all of the exported symbols of a
package, IMPORTing provides only the symbols specified.
   [Also, the imported symbols do not need to have been exported.]



Summary:
  The purpose of the package system is provide a means for avoiding name
conflicts by establishing multiple mappings from names to symbols.  That
is all that packages do for you.  They do not hide information.  They do
not control access.  Once you have mapped a name to a symbol, you have
an object that can be manipulated.  Everyone who has the same object
will see any changes you make to that object.


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