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

Package System and new dialect

30 views
Skip to first unread message

Kelly Murray

unread,
Jul 17, 1998, 3:00:00 AM7/17/98
to
I'm having serious trouble trying to use the package system,
and was hoping someone else has figured out how to do what
I need to do.

Basically, a want to have a new dialect of CL, which redefines
(shadows) some symbols in the lisp package. No problem here.
The problem is that now I want other packages to be able to
just :use this package, but this doesn't work because it
creates conflicts with the lisp package. It seems I must
explicitly use :shadowing-import-from to enumerate EACH
conflicting symbol from the new-dialect package.
This is just plain bad, because now changing the new-dialect
package is useless, I must go edit all the other package definitions.
I suppose I can have the other packages not :use the lisp package,
but then I must enumerate all the lisp symbols in the new-dialect
package, which I suppose is better, but still lots of work,
and because of implementation specific extensions, I could
never know all the symbols that must be exported. Basically,
this solution just moves the problem back one more level,
but it still exists.

What i think I want is a what I might call :shadowing-use
that takes a package to use all exported symbols from, shadowing
any that conflict. Am I confused, is there a way to do this,
or is the package system as broken as I think it appears to be?

Kelly Murray k...@intellimarket.com

Jrm

unread,
Jul 17, 1998, 3:00:00 AM7/17/98
to

Kelly Murray wrote in message <35AFC5B6...@IntelliMarket.Com>...

>I'm having serious trouble trying to use the package system,


This is a tautology.

> Am I confused, is there a way to do this,
>or is the package system as broken as I think it appears to be?


You are not confused. The package system is a broken idea.


Kent M Pitman

unread,
Jul 18, 1998, 3:00:00 AM7/18/98
to
Kelly Murray <k...@franz.com> writes:

> It seems I must
> explicitly use :shadowing-import-from to enumerate EACH
> conflicting symbol from the new-dialect package.

I think it's not an error in the fundamental package system design but
a deficiency in the set of options you're offered. One ought to be
able to declare that the whole point of a certain package is to
override another, and that whenever it is used, it overrides the other.
For example:

(:exported-symbols-supersede
(symname1 packagename1 packagename2...)
(symname2 packagename1 packagename2...)
...)

There are several other similar kinds of operations that one might want.
For example, the ability to import and re-export a whole package of
symbols.

> This is just plain bad,

Yes.

> because now changing the new-dialect
> package is useless, I must go edit all the other package definitions.

No.

Heh. I agree it's bad. But it's false that you have to go re-edit the
definitions in the situations you describe--if you have to do that, you
haven't done all you can with Lisp's ability to introspect.

For example, I sometimes do things like:

(defpackage "FOO"
(:use "BAR" "BAZ")
(:shadowing-import-from "BAR"
. #1=#.(let ((syms '()))
(do-external-symbols (s "BAR")
(push (string s) syms))
syms))
(:export . #1#))

This is a simulated example; I don't have an actual example at my
fingertips. And I admit it's a little on the ugly side, but my point
is that it's pretty robust against later changes to BAR, provided
those changes are not hostile to the FOO or BAZ packages.

Don't take the fact that one can do this as meaning I don't advocate
language changes to support a more perspicuous syntax.

But my point is that as broken language features go, this one is still
pretty darned flexible. It's this kind of "low-tech automatic
programming" that makes Lisp win when other languages lose...

Kent M Pitman

unread,
Jul 18, 1998, 3:00:00 AM7/18/98
to
"Jrm" <emer...@eval-apply.com> writes:

You'll have to elaborate on that before I believe you. What the
package system teaches us is that multiple inheritance is hard and
that you need quite a number of very advanced naming systems for
describing the necessary patterns of inheritance.

There is, of course, also a fight ongoing forever by people who
mistake a package system for a module system (the two serve different
purposes but the advocates of module systems rarely realize this and
so rant on ad infinitum about why module systems are superior when
module systems don't address the issues the package system is intended
to). CL has no module system--not because we think a module system is
bad, but more because no one has ever created, used, debugged and
proposed one and because creating one out of thin air in a standards
meeting is known to be a bad idea.

I don't want to recreate the fight over packages systems vs module
systems here, but in brief I'll just say that a package system
partitions DATA and a module system partitions programs. Each has its
purpose. CL is full of data. But (again reinforcing my continual
claims that languages are ecosystems and you can't get rid of one
feature without harming another) to get rid of packages would mean to
get rid of GET, since GET cannot work usefully if symbols are shared
across packages. In languages like Scheme where there is only a
module system and no package system, you have no GET or you implement
it with hash tables, which may change its performance characteristic
and/or require largescale rewriting of existing code, much of which
uses GET heavily. Among other things, GET never has to stop to
re-hash a dirty hash table and so has more predictable performance.

Erik Naggum

unread,
Jul 18, 1998, 3:00:00 AM7/18/98
to
* Kelly Murray

| Basically, a want to have a new dialect of CL, which redefines (shadows)
| some symbols in the lisp package.

this certainly tells me that users of your package should _not_ :USE the
COMMON-LISP package.

| The problem is that now I want other packages to be able to just :use
| this package, but this doesn't work because it creates conflicts with the
| lisp package.

only if they they also :USE "COMMON-LISP". but _why_ would they do that
if they want your dialect?

| I suppose I can have the other packages not :use the lisp package,
| but then I must enumerate all the lisp symbols in the new-dialect
| package, which I suppose is better, but still lots of work,
| and because of implementation specific extensions, I could
| never know all the symbols that must be exported.

huh? there are 978 symbols in the COMMON-LISP package, all counted, none
forgotten, and an implementation is _not_ allowed to export more symbols
from the COMMON-LISP package.

if your package does :USE COMMON-LISP, you can compute the :EXPORT list
to re-export all of its symbols once and for all since you'll presumably
override any pre-existing bindings via :SHADOW, anyway, and then perhaps
remove symbols from the export list if you remove semantics. collecting
the list of external symbols does not appear to be "lots of work" to me.
the following should produce output that is reasonably pastable directly
into a DEFPACKAGE form:

(pprint (sort (loop for symbol being each external-symbol in "COMMON-LISP"
collect (symbol-name symbol))
#'string<))

I don't understand the point about implementation-specific extensions.
the symbols aren't even allowed to have bindings or associations apart
from those specified in the standard, so you know _exactly_ what to do
with all of these symbols, and it should even be eminently feasible to
know in advance that some symbols should not be shadowed, such as EQL,
which would screw up DEFMETHOD.

| Basically, this solution just moves the problem back one more level, but
| it still exists.

really? the "problem" is now one of being explicit about using your
dialect by specifying a :USE clause that does not include COMMON-LISP,
but instead your dialect. that doesn't seem unfair, does it?

#:Erik
--
http://www.naggum.no/spam.html is about my spam protection scheme and how
to guarantee that you reach me. in brief: if you reply to a news article
of mine, be sure to include an In-Reply-To or References header with the
message-ID of that message in it. otherwise, you need to read that page.

Barry Margolin

unread,
Jul 18, 1998, 3:00:00 AM7/18/98
to
In article <31097384...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:
> I don't understand the point about implementation-specific extensions.
> the symbols aren't even allowed to have bindings or associations apart
> from those specified in the standard, so you know _exactly_ what to do
> with all of these symbols, and it should even be eminently feasible to
> know in advance that some symbols should not be shadowed, such as EQL,
> which would screw up DEFMETHOD.

I think his point is that the user may be using the implementation's
default package, which includes their additions. And that package
presumably imports and exports the COMMON-LISP symbols. If the user tries
to use both that package and this dialect package, they'll encounter the
same conflicts he's complaining about.

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.

Erik Naggum

unread,
Jul 18, 1998, 3:00:00 AM7/18/98
to
* Barry Margolin

| I think his point is that the user may be using the implementation's
| default package, which includes their additions. And that package
| presumably imports and exports the COMMON-LISP symbols. If the user
| tries to use both that package and this dialect package, they'll
| encounter the same conflicts he's complaining about.

this appears to me to presuppose that this default package does the same
kind of trickery with :EXPORT that I proposed for the dialect package.
if it does, then it is _another_ "dialect" in the system that the user
wishes to use. trying to use two different dialects at once is not what
I would consider a high priority problem for the package system to solve.
supporting one should reasonably be doable, though.

now, I don't know how big this dialect is supposed to be, or whether it
is just a bunch of macros and slightly different functions, but this all
appears to me not to be a problem, but rather a question of wishing for a
less elaborate solution.

I have actually had a similar problem when looking at GNU Emacs Lisp
compatibility in a Common Lisp Emacs. my solution was to enumerate the
symbols that were semantically the same from Emacs Lisp to Common Lisp
and leverage off of the standard Common Lisp functions when possible. in
a few cases, however, I had to define a new function which merely called
the Common Lisp function of the same name because the symbol was used for
other things that shouldn't be exported.

however, and for what it's worth, even this doesn't appear "broken" to me
-- I'm still trying to figure out (on deeper and deeper levels) what the
language was designed to do, and there doesn't seem to be any broken
parts of the language relative to _some_ understanding of the intent. I
think it's important to find the intentions that make the language what
it became. different intentions must then implement their own ways,
rather than break what works in ways contrary to their desires.

Jrm

unread,
Jul 18, 1998, 3:00:00 AM7/18/98
to

Kent M Pitman wrote in message ...

>"Jrm" <emer...@eval-apply.com> writes:
>> The package system is a broken idea.
>
>You'll have to elaborate on that before I believe you.

Rather than dredge up the usual arguments, I'll just put
forth a few of the pragmatic problems I've seen.

1. The package system makes READ have side effects,
1a. thus READ is not idempotent.
1b. loading a file into a ZMACS buffer is not idempotent(!)

2. It looks like a module system, and people try to make
it one. (So the people are wrong, but it is still a problem.)

3. It is hard to model alternative package systems within
the system. For instance, suppose you are attempting to
port some code to a system with a different package topology.
It is impossible to model that new topology without screwing up
the existing one. Yes, this is rare, but I ran into it.

4. Some (most? all?) systems differentiate CL:IF from FOO:IF
when compiling. This means that macros that write code for
the compiler have to use the CL:IF. But you may not want
to have CL:IF in your package for other reasons. For example,
you may wish to put properties on it that conflict with other
peoples uses (like if you are writing a cross-compiler).

5. I've *never* been able to use the package system to my
benefit, but it has continually gotten in my way.

> a package system
>partitions DATA and a module system partitions programs.

I don't understand what you mean here. Do you mean that the
package system partitions the particular class of data called SYMBOLS?
Or something deeper?

>GET cannot work usefully if symbols are shared
>across packages.

Why not?

> [Argument that GET would suffer]
This sounds like a red herring. I'm sure that GET could easily be made
just as predictable and of high performance without having packages around.
Manipulating a PLIST can't be that much easier than hashing, and since the
symbols are at a fixed location, why would rehashing be necessary? Maybe
your experience is different than mine, but I haven't seen too much code
that depends upon the performance of GET. Experts tend not to use GET,
and naive people write code that performs so bad anyway that the GET
bottleneck is unimportant.

Lieven Marchand

unread,
Jul 18, 1998, 3:00:00 AM7/18/98
to
Kent M Pitman <pit...@world.std.com> writes:

> to). CL has no module system--not because we think a module system is
> bad, but more because no one has ever created, used, debugged and
> proposed one and because creating one out of thin air in a standards
> meeting is known to be a bad idea.
>
> I don't want to recreate the fight over packages systems vs module

> systems here, but in brief I'll just say that a package system
> partitions DATA and a module system partitions programs. Each has its

Is there an archive of the ANSI CL committee discussions? I've read one
file that comes with the CMU-CL distribution that has part of these.

It would be very interesting to be able to review some of the original
arguments with hindsight of how things are used now.

For Scheme the RNRS mailing list is archived.
--
Lieven Marchand <m...@bewoner.dma.be>
------------------------------------------------------------------------------
Few people have a talent for constructive laziness. -- Lazarus Long

Lieven Marchand

unread,
Jul 19, 1998, 3:00:00 AM7/19/98
to
Kent M Pitman <pit...@world.std.com> writes:

> There is, of course, also a fight ongoing forever by people who
> mistake a package system for a module system (the two serve different
> purposes but the advocates of module systems rarely realize this and
> so rant on ad infinitum about why module systems are superior when
> module systems don't address the issues the package system is intended

> to). CL has no module system--not because we think a module system is
> bad, but more because no one has ever created, used, debugged and
> proposed one and because creating one out of thin air in a standards
> meeting is known to be a bad idea.

One reason for this may be that people who want a module system only
agree about the vague idea that they want 'modules'. The CL package
system is already more powerful than the module system of Modula-3
and it is possible to write in that style in CL.

On the other end of the spectrum are the module system of ML with its
functors and signatures, in which the module system is for a large part
responsible for the static type safety of the program. About every time
I start thinking about more static typechecking in lisp I end up with the
thought that ML is already there for those who want it.

Various schemes have implemented module systems but a consensus there also
seems hard to find.

Barry Margolin

unread,
Jul 19, 1998, 3:00:00 AM7/19/98
to
In article <6ot90t$l1r$1...@xenon.inbe.net>,

Lieven Marchand <m...@bewoner.dma.be> wrote:
>Is there an archive of the ANSI CL committee discussions? I've read one
>file that comes with the CMU-CL distribution that has part of these.
>
>It would be very interesting to be able to review some of the original
>arguments with hindsight of how things are used now.

The minutes of X3J13 meetings are presumably available (but not online, I
don't think), but they generally didn't go into this level of detail. They
just said what was discussed and voted on.

Many subcommittee discussions took place on mailing lists, but I'm not sure
where those archives are these days.

Barry Margolin

unread,
Jul 19, 1998, 3:00:00 AM7/19/98
to
In article <31098670...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:
>* Lieven Marchand

>| Is there an archive of the ANSI CL committee discussions? I've read one
>| file that comes with the CMU-CL distribution that has part of these.
>
> you do know about the ISSUES that are available with the text of the
> draft and which are part of the HyperSpec, I hope?

The problem with using them as the answer to his question is that these
documents only explain the reasoning behind changes that were made between
CLtL and ANSI CL. They don't include much about things we talked and
emailed about but that didn't get voted in (except for competing proposals
within an ISSUE document).

In the context of Lieven's original question, I don't think there was much
discussion at all of a module system in X3J13. Most significant discussion
of package vs. module systems probably took place when Common Lisp was
originally being designed (i.e. before CLtL was published). Most recent
discussion of module systems for Lisp have been in the context of ISLisp
design.

Erik Naggum

unread,
Jul 19, 1998, 3:00:00 AM7/19/98
to
* Lieven Marchand
| Is there an archive of the ANSI CL committee discussions? I've read one
| file that comes with the CMU-CL distribution that has part of these.

you do know about the ISSUES that are available with the text of the
draft and which are part of the HyperSpec, I hope?

http://www.harlequin.com/books/HyperSpec/Issues/Issues-Categorized.html
http://www.harlequin.com/books/HyperSpec/Issues/Issues-Alphabetical.html

while being far from the whole story, they do contain a fair amount of
background information. in any case, I have found them inordinately
informative in understanding what proposal was trying to do.

Marco Antoniotti

unread,
Jul 19, 1998, 3:00:00 AM7/19/98
to

Hello,

Personally I don't quite get the subtle difference between "package"
system and "module" system.

Given that such difference exists, the question is: can I emulate a
module system with the package system and viceversa? (Please note
that I am not asking for comments on what is better - I am just asking
for clarifying examples and solutions)

Cheers

--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 80 79 23, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it

Kent M Pitman

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Lieven Marchand <m...@bewoner.dma.be> writes:

> Is there an archive of the ANSI CL committee discussions? I've read one
> file that comes with the CMU-CL distribution that has part of these.

Yes, somewhere. But I don't know where. I have a personal set of archives
on the disk at my house--I'm pretty sure I never intentionally deleted
any common-lisp-related e-mail. But I am pretty sure there are other
archives. I'm just not sure if they're public. It is not an offical
policy of ANSI to make such conversations public--indeed, they somewhat
seem to discourage it for fear it will stifle discussion. I took a slight
risk in publishing the cleanup issues along with the Common Lisp HyperSpec(TM)
but I figured they were at least publicly accessible (at parcftp.xerox.com:/pub/cl)
and so I wouldn't be putting out anything that anyone hadn't already made public.
I just made it a little easier to find.

> It would be very interesting to be able to review some of the original
> arguments with hindsight of how things are used now.

Some may have been made interactively at meetings.



> For Scheme the RNRS mailing list is archived.

Oh, I'm sure the bits are there. It's just a public/private thing.
When we call each other idiots or blame each other for bringing the
langauge down, we like to think we're not publicly slandering each
other. I'd put a smiley there, but you'd think I was kidding. Some
of the discussions did get a little heated, perhaps to the point where
that really would have mattered to a few people's careers. I think it
didn't, but it easily could have.... (No, I won't elaborate further on
who or how or when. Certain issues are better left vague. But
suffice it to say that none of us who've been in it for the long haul
take these design issues lightly.)

And anyway, as you noted in another message, no one has ever proposed a
module system for CL. The committee never voted on vague wishes of
people; only on specific proposals, and usually only accepted
proposals for solutions that were implemented and tested. I've never
even heard of a single Maclisp or Common Lisp family dialect
implementing a module system. So there wouldn't be any discussion
anyway.

I wasn't involved in the decisions that led specifically to the
creation of a package system but I was around at the time and my
impression was that the decision to partition systems by package
instead of module was made sometime around 1977 or 1978 since my
"second preliminary version" of the earliest Black Lisp Machine
Manuals (dubbed "Chinuals" because "chine" and "ual" were the part of
the name that wrapped onto the cover) referred mostly to packageless
functionality, but with only a few functions in the SI package. File
code was just file-xxx and (amusingly enough) package code was
pkg-xxx. The Red Chinual (March 1981) is pretty spartan in its number
of package references, but by the time of the Purple one (which I
think is the same as the Silver one, except the Silver one was
published at Symbolics and not MIT--bother are July 81, I think), you
start to see lots of uses of FS:xxx and SI:xxx as if it was finally
catching on. The Lisp Machines had no memory partition between
processes so critically relied on the package system to separate data
between users and system, and considering all the software systems
they were trying to have concurrently loaded, I'm sure that symbol
collisions would have been rampant. (I remember complaining that
Macsyma used symbols named with "%" prefixes and so did the low-level
system internal memory referencing primitives, and I asked to have those
not just have odd names but also be put in package SI where I couldn't
damage them accientally.)

Remember, too, that the project to create Common Lisp from the various
Maclisp/Lispm dialects began around 1980 and didn't finish until
the book went out in 1984. CL took a lot of its lead from the
Lisp Machine because it was a real success story in the area of
partitioning programs in the same environment so they could be
co-resident and yet conveniently cross-call each other.

As I recall, the original Scheme report is approximately concurrent
with this decision (1978, I think), so there was really no reason to
suppose there was any alternate wisdom to appeal to than partitioning
symbols. The practice of partitioning symbols (by uninterning them,
or remob'ing them as it was called in those days) goes back much
farther. The Maclisp compiler, which extends at least to the early
1970's used a separate 'obarray' (place in which to intern symbols,
predating packages; they were objects and had no 'name'). The package
system didn't invent the idea of separating symbols; it merely allowed
people to continue the practice conveniently by adding a naming scheme
to refer to what had previously felt like merely 'uninterned symbols
all over the place'.

The history of Common Lisp has been not to innovate but to try to
agree on common names and terms for things everyone was already doing.
In order to be a candidate for Common Lisp, someone needs to be
already doing the thing. In the case of a few important things, like
CLOS, there were divergent practices and you see innovation in order
to achieve compromise.

But standards making is NOT about design. And so the CL records are not
really as deficient as they seem in this regard. This is just a decision
that goes back a LONG, LONG way.

Also, there's a fundamental schism between Lisp and Scheme which I
sometimes call absolute-ism vs relative-ism. In Scheme, everything is
about "the initial place" of things--things don't have names--they have
places from which you pick them up. In Lisp, they really have names.
It's sort of like absolute filenames vs relative ones. The effectiveness
of relative filenames is easy to see if you are porting systems. If you
move a directory around, relative filenames work great. But the
effectiveness of absolute filenames is that you always know really where
something is--if you can't FIND the foo system, knowing the relative
pathname of foo's parts doesn't help. Lisp is sort of the same in my mind.
Yes, in Scheme modules it's very elegant that things can be remodularized with
no loss of meaning, BUT in CL I can sit down anywhere and know how to
gets started and where to find things because they can't easily be
placed in a place I can't find. Neither of these can clearly be said to
be better than the other--they are design trade-offs distilled to their
best... And in my mind, once something reduces to a design trade-off,
I cease to fuss over "which is better" except for grins at conference
debates since I've already proven that it's not a function of one's absolute
needs but rather a relative matter, dependent on one's values. Hmmm.
And there's that absolute vs relative thing again--I must be recursing...
or is it iterating? Ah, yes, the joys of endless debates.

Further, and finally, as you effectively alluded to also in your later
post, the CL package system is written in such a way that it does not
preclude a user-written module sytem. And I wouldn't be at all
surprised if other aspects of CL offer enough power that such a module
system could be entirely coded in portable CL ... if someone had a mind
to do it. (For example, in response to my claim that private slots
were not possible in CLOS, someone proposed on this newsgroup that one
could simulate the effect with gensymed slot names. Give people a
good powerful set of tools and it's fascinating what they can come up
with!)

Anyway, I know this is partly redundant with the points you made in your
other message but I hope the historical information above is of some
value, or if not, at least of some interest/amusement.

Barry Margolin

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
In article <lwd8b1b...@galvani.parades.rm.cnr.it>,

Marco Antoniotti <mar...@galvani.parades.rm.cnr.it> wrote:
>Personally I don't quite get the subtle difference between "package"
>system and "module" system.

A module system controls access to program elements, such as functions and
variables. The package system controls access to data elements,
specifically symbols.

>Given that such difference exists, the question is: can I emulate a
>module system with the package system and viceversa? (Please note
>that I am not asking for comments on what is better - I am just asking
>for clarifying examples and solutions)

The package system can be used to approximate a module system. You run
into problems if a symbol is used in multiple ways, and you want its
different functions to be shared differently. E.g. if you're using the
name MYPACKAGE:FOO as both a function name and an initarg for a CLOS class,
exporting the initarg also exports the function.

Patrick A. O'Donnell

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Kelly Murray <k...@franz.com> writes:
> I'm having serious trouble trying to use the package system,
> and was hoping someone else has figured out how to do what
> I need to do.
>
> Basically, a want to have a new dialect of CL, which redefines
> (shadows) some symbols in the lisp package. No problem here.

> The problem is that now I want other packages to be able to
> just :use this package, but this doesn't work because it
> creates conflicts with the lisp package.
...

> Am I confused, is there a way to do this,
> or is the package system as broken as I think it appears to be?
>
> Kelly Murray k...@intellimarket.com

No, it's not broken. It _is_ often confusing.

I have done what you are trying to do, and the approach I took is just
as Kent, Barry, and others have pointed out. The key is to not expect
the users of your package to also use the CL package. You are
creating a complete replacement for CL which defines your dialect.
Using do-exported-symbols, you can easily copy all the symbols you
need from CL, without the necessity of enumerating them in your
package definition.

I strongly recommend _not_ importing platform-specific extensions.
Keep those separate and refer to them with explicit package prefixes.
You may not expect your system to be portable -- today. If supplying
a package that does include platform-specific extensions is required,
then a simple solution is the same one that is required of vendors --
create the dialect package based on CL, and also one based on the
vendor-specific CL package.

- Patrick O'Donnell
p...@ai.mit.edu


Kent M Pitman

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Barry Margolin <bar...@bbnplanet.com> writes:

> In article <lwd8b1b...@galvani.parades.rm.cnr.it>,
> Marco Antoniotti <mar...@galvani.parades.rm.cnr.it> wrote:
> >Personally I don't quite get the subtle difference between "package"
> >system and "module" system.
>
> A module system controls access to program elements, such as functions and
> variables. The package system controls access to data elements,
> specifically symbols.

I like to think of a mdoule system as "attaching semantics". It permits
an identifier X to be promoted to a -particular- data flow path. The
result is another piece of data that is not manifest to the user but is
understood by the compiler in a way that becomes the essence of a lexical
variable--that it cannot be confused with someone else's X.

By contrast, a package system doesn't "attach semantics". It deals in
data structures that the user can see and touch. You can tell symbols
apart when they are packaged differently, and not unless. Holding just
FOO:X, you can't tell if it's a lexical variable or piece of data.

Macros in Lisp, for example, return data with no semantics attached .
Just data, not meta-data. THe "painting" that hygienic macros do in
Scheme is an example of attaching semantics. So is the--darn I don't
remember the greek letter (thank goodness lisp uses full-length
symbolic identifiers and not stupid little greek letters or i'd not
ever have gotten anywhere with the language)--beta(?) substitution
in lambda calculus though it's not as obvious--(the "semantics" in
that case is trickily captured through the ability to choose a unique
object, since the only info that needs to be conveyed is "differentness").

> >Given that such difference exists, the question is: can I emulate a
> >module system with the package system and viceversa? (Please note
> >that I am not asking for comments on what is better - I am just asking
> >for clarifying examples and solutions)

Sure. Just crawl into any package that you want to declare to be your
universe and start stressing the lexical environment system instead
of using any more packages. This is What Scheme compatibility packages
do. They make a Scheme package and then build everything else out
of lexical environments within that pacakge, doing nothing more
with packages.

> The package system can be used to approximate a module system. You run
> into problems if a symbol is used in multiple ways, and you want its
> different functions to be shared differently. E.g. if you're using the
> name MYPACKAGE:FOO as both a function name and an initarg for a CLOS class,
> exporting the initarg also exports the function.

Right. And for this reason, symbols can't be used as initarg names
in a dialect that has no package system. Because there is no way to
assure their uniqueness. You change
(make-instance 'foo 'bar 1 'baz 2)
to
(make-instance foo bar 1 baz 2)
But then you get into that absolutimsm vs relativeism thing I wrote
about last night.

Rob Warnock

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Kent M Pitman <pit...@world.std.com> wrote:
+---------------

| But standards making is NOT about design.
+---------------

(*sigh*) Oh, would that that were true! And indeed it used to be, but...

In the area of networking hardware & protocols, HP-IB (as IEEE-488)
and HIPPI were about the last standards which codified existing,
working practice more-or-less unchanged. Since then, all new networking
hardware/protocols have been "design by standards committee", by what
some cynics call the principle of "maximum mutual disadvantage". That is,
if something is already *working*, well then, the company that made it
work would have an "unfair" competitive advantage if the working system
got standardized, wouldn't it, and we can't have *that*, can we??!?
As a prime example, consider FDDI...

IEEE 802.3 *almost* left D-I-X Ethernet alone, but broke it by requiring
that only 802.2 LLC be used on top. Fortunately, Xerox helped the pragmatists
squeak by that one by relocating a few of the previously-assigned Ethernet
"types" that had the same values as IEEE 802.3 "lengths" [which fell in
the same bit positions on the wire], so that now all of the "types" are
disjoint from the legal values of "length", so classic D-I-X Ethernet can
co-exist on the same wire as 802.3. [*Whew!!* That was close!] And a similar
end-run snuck Ethernet types back into "pure" 802.2 media such as FDDI,
by using the "SNAPpy Xerox" hack (everyone agreeing that an LLC/SNAP frame
with OUI=0 implies that the two "reserved for organizational use" bytes
would be an Ethernet type). [Another close one!]

And so it goes. *All* of the ATM world has been "design by standards
committee". Even the "rebel" AAL5 (a radically simpler alternative
to AAL4) was proposed to the ANSI T1S1.5 before it was ever implemented.
[And don't even get me *started* about ATM flow-control...]


-Rob

-----
Rob Warnock, 7L-551 rp...@sgi.com http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
2011 N. Shoreline Blvd. FAX: 650-933-4392
Mountain View, CA 94043 PP-ASEL-IA

Lieven Marchand

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Erik Naggum <cle...@naggum.no> writes:

> you do know about the ISSUES that are available with the text of the
> draft and which are part of the HyperSpec, I hope?
>

Yes, I usually have the HyperSpec in a window when I'm programming in
Lisp and I'd hate to do without it.

> while being far from the whole story, they do contain a fair amount of
> background information. in any case, I have found them inordinately
> informative in understanding what proposal was trying to do.
>

There very useful but there only part of the story. Take for instance
one issue I've read today: DEFSTRUCT-COPIER:ARGUMENT-TYPE.

You get a very nice write up of four proposals. At the end you get the
opinions of a few people and the suggestion that COPY-STRUCTURE could
be added to the language. Now if you check the standard COPY-STRUCTURE
was added but of the original four proposals it would seem the least
desirable in Loosemore's ranking was taken. (It's not even stated very
explicitly in the standard what the behaviour is.)

So obviously some arguments/reasons are missing.

Lieven Marchand

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Kent M Pitman <pit...@world.std.com> writes:

> Oh, I'm sure the bits are there. It's just a public/private thing.
> When we call each other idiots or blame each other for bringing the
> langauge down, we like to think we're not publicly slandering each
> other. I'd put a smiley there, but you'd think I was kidding. Some
> of the discussions did get a little heated, perhaps to the point where
> that really would have mattered to a few people's careers. I think it

I can imagine ;-) Technical discussions with people who really care for
the subject can get interesting.

> But standards making is NOT about design. And so the CL records are not
> really as deficient as they seem in this regard. This is just a decision
> that goes back a LONG, LONG way.

Having used a language that has seen quite a bit of committee design (C++)
I think CL made the right decision.

> Yes, in Scheme modules it's very elegant that things can be remodularized with
> no loss of meaning, BUT in CL I can sit down anywhere and know how to

You seem to imply that Scheme has a module system. To the best of my
knowledge, even in R5RS it hasn't. It is true that most substantial
scheme implementations have developed a module system. Probably they
run into name clashes far earlier since scheme has only one namespace.


> Further, and finally, as you effectively alluded to also in your later
> post, the CL package system is written in such a way that it does not
> preclude a user-written module sytem. And I wouldn't be at all

Perhaps the people who don't like the current package system should come
up with a design? Or at least a requirements document ;-)

> Anyway, I know this is partly redundant with the points you made in your
> other message but I hope the historical information above is of some
> value, or if not, at least of some interest/amusement.

I at least find it quite interesting. Maybe this could become a column like
the Modula-3 one 'How the language got its spots.'

Tim Bradshaw

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to
* Kent M Pitman wrote:

> Further, and finally, as you effectively alluded to also in your later
> post, the CL package system is written in such a way that it does not
> preclude a user-written module sytem. And I wouldn't be at all
> surprised if other aspects of CL offer enough power that such a module
> system could be entirely coded in portable CL ... if someone had a mind
> to do it. (For example, in response to my claim that private slots
> were not possible in CLOS, someone proposed on this newsgroup that one
> could simulate the effect with gensymed slot names. Give people a
> good powerful set of tools and it's fascinating what they can come up
> with!)


Actually you only sort-of can because redefinition breaks horribly,
because the next time you evaluate DEFCLASS the slot names are
different. I actually tried to do this! Of course you can write a
defclass-wrapper that keeps the real slot names around somewhere and
reuses them, which is what I ended up doing.

--tim

Kelly Murray

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to
Patrick A. O'Donnell wrote:

>
> Kelly Murray <k...@franz.com> writes:
> > Basically, a want to have a new dialect of CL, which redefines
> > (shadows) some symbols in the lisp package. No problem here.
> > The problem is that now I want other packages to be able to
> > just :use this package, but this doesn't work because it
> > creates conflicts with the lisp package.
> ...
> I have done what you are trying to do, and the approach I took is just
> as Kent, Barry, and others have pointed out. The key is to not expect
> the users of your package to also use the CL package. You are
> creating a complete replacement for CL which defines your dialect.
> Using do-exported-symbols, you can easily copy all the symbols you
> need from CL, without the necessity of enumerating them in your
> package definition.

This appears to be a workable solution,
however, I believe it is defeating the purpose of exporting symbols
from a package if another package must manually enumerate all those
exported symbols when it wants to essentially "use" that package to
create a new one. Doing it programmatically using do-exported-symbols
is not really good, it violates the supposed declarative nature
of a DEFPACKAGE; defpackage should be powerful enough to
do what is needed. The fact its so cumbersome is certainly one
reason everyone hates the package system, its confusing and
doesn't do what you think it does.
BTW, what is the explaination for the word "shadow"?

Let me suggest an :extend keyword be defined
which imports and exports all symbols from a package.

(defpackage "NOT-COMMON-LISP"
(:extend "COMMON-LISP")
(:shadow "IF") ;; alternative syntax for IF
)

Now one could easily create new packages that extend other ones,
for example:

(defpackage "NFS"
(:extend "FS")
(:shadow "OPEN")
)

Just a thought.

-kelly murray k...@intellimarket.com

Kent M Pitman

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
Kelly Murray <k...@IntelliMarket.Com> writes:

> Let me suggest an :extend keyword be defined
> which imports and exports all symbols from a package.
>
> (defpackage "NOT-COMMON-LISP"
> (:extend "COMMON-LISP")
> (:shadow "IF") ;; alternative syntax for IF
> )

I mostly like this. Though I admit on second glance I do worry a
little about the fact that the "extension" is here of the
"negative" kind. Still, it's as good a name as I've heard suggested
so far.

Marco Antoniotti

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
Kent M Pitman <pit...@world.std.com> writes:

Too much Java programming lately? :)

Erik Naggum

unread,
Jul 22, 1998, 3:00:00 AM7/22/98
to
* Kelly Murray

| The fact its so cumbersome is certainly one reason everyone hates the
| package system, its confusing and doesn't do what you think it does.

count me out, please. I don't hate the package system. it also does
what I think it does.

I use the package system to partition both code and data in my current
project into fairly gross partitions, for which the package system seems
well suited (unlike the fine partitions frequently employed in namespaces
or module systems in other languages), such as a "substrate" package of
fairly low-level functions supporting the application code in its own
package, which does _not_ USE the substrate package, but references the
symbols therein explicitly. this avoids a lot of SHADOWING-IMPORT-FROM
for redefined CL functions (stuff like a generic OPEN that dispatches on
subclasses of PATHNAME -- not quite kosher) and also improves legibility
in that one is not confused by apparent references to the standard CL
functions. then there's the administration (or user) package which does
USE the application package, but not the COMMON-LISP package and is
intended as the user interface package. however, if I were to use a
module system, it would have had an order of magnitude more namespaces.

Tim Bradshaw

unread,
Jul 24, 1998, 3:00:00 AM7/24/98
to
For what its worth, here is something I wrote which provides a
reasonable syntax for providing `new dialect' packages. I only wrote
it to check I understood how to do this, I haven't used this in anger
(or at all, really). Apologies for the line lengths.

--tim

--cut for conduit-packages.lisp --
;;; -*- Mode: LISP; Base: 10; Syntax: Ansi-common-lisp; Package: CL-USER -*-

;;;; Conduit packages tfb 24-Jul-1998 00:41:02
;;; This generalises the stuff in VERIFY-FORM.LISP

(defmacro define-conduit-package (name &body clauses)
"Define a package that you can use as a `conduit' to extend existing packages.
This works by importing symbols from the existing packages and then reexporting them.
The syntax is as DEFPACKAGE, wiht the addition of three new clauses:
(:EXTENDS package) takes package and reexports all its symbols;
(:EXTENDS/INCLUDING package . syms/names) reexports only syms/names;
(:EXTENDS/EXCLUDING package . syms/names) reexports all *but* syms/names."
;; It would almost certainly be better if this compiled to something that did a
;; MAKE-PACKAGE and some loops over other packages at runtime, because the common
;; case of extending CL modulo a few symbols is horrendous.
`(defpackage ,name
(:use) ;use no other packages by default
,@(mapcan #'(lambda (c)
(case (first c)
(:extends
;; blindly extend a package.
(let ((package (find-package (second c)))
(symnames '()))
(do-external-symbols (s package)
(push (symbol-name s) symnames))
`((:import-from ,(package-name package)
,@symnames)
(:export ,@symnames))))
(:extends/including
;; ship out just a few symbols from a package.
(let ((package (find-package (second c)))
(symnames (mapcar #'(lambda (s)
(etypecase s
(symbol
(symbol-name s))
(string
s)))
(cddr c))))
`((:import-from ,(package-name package)
,@symnames)
(:export ,@symnames))))
(:extends/excluding
;; ship out all but the mentioned symbols.
(let ((package (find-package (second c)))
(excluded-names (mapcar #'(lambda (s)
(etypecase s
(symbol
(symbol-name s))
(string
s)))
(cddr c)))
(symnames '()))
;; don't care about speed here
(do-external-symbols (s package)
(let ((n (symbol-name s)))
(unless (member n excluded-names
:test #'string=)
(push n symnames))))
`((:import-from ,(package-name package)
,@symnames)
(:export ,@symnames))))
(otherwise
(list c))))
clauses)))


#||
(define-conduit-package "CL/MAGIC-IF"
(:extends/excluding "CL" "IF")
(:export "IF"))
||#

Kent M Pitman

unread,
Jul 27, 1998, 3:00:00 AM7/27/98
to
Tim Bradshaw <t...@aiai.ed.ac.uk> writes:

> For what its worth, here is something I wrote which provides a [...]

Gee, if I was doing it, I'd have made a NEW-DEFPACKAGE package, put the
symbol in there under the name DEFPACKAGE, and then defined a package
KMP-LISP (you might prefer TFB-LISP, of course) as a conduit package
which imports and exports CL with that one extra change... At least
then you'd always be sure you had at least one user. :-)

Seriously, I think something like this is a good approach in that it
shows that CL is powerful enough for users to help themselves out of
problems in the language design. Since I can pretty much guarantee
you it will never be designed importantly, the ability to override
things in a flexible way seems more important than the actual chosen
functionality.

Oddly, Richard Stallman once said this about Emacs. I made a stripped
down editor with just a basic Emacs command set and he said it shouldn't
be called Emacs (or even MinEmacs, which I think is what I called it)
because the defining characteristic of the editor was its redefinability,
not its initial command set. I guess I think that's a generally
applicable design principle of large systems that I feel I can really
use.

0 new messages