From: Ron Garret
Subject: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-2A9DC1.08210005122008@news.gha.chartermi.net>
I am happy to announce a new version of my lexicons code.  This version 
fixes a rather serious bug in the previous version, and adds new 
features, most notably semi-hygienic lexical macros and lexical classes 
and methods.  The implementation is also significantly cleaned up (it 
consists of a single file of portable ANSI Common Lisp) and is more 
seamlessly integrated into Common Lisp (lexicons are now implemented 
using packages).

Code is here:

http://www.flownet.com/ron/lisp/lexicons.lisp

Documentation is here:

http://www.flownet.com/ron/lisp/lexicons.pdf

Lexicons are first-class lexical environments for Common Lisp, what in 
other languages would be called modules or namespaces.  They are 
designed to be an adjunct, or potentially a replacement (depending on 
your needs) for packages.  Packages map strings on to symbols at 
read-time.  Lexicons map symbols onto bindings at compile-time.  For 
writing modular code, lexicons can be significantly more convenient than 
packages.  In particular, lexicons are unaffected by read-time 
side-effects, and there is no need to manually maintain lists of 
exported symbols.

This version has been tested only on Clozure Common Lisp, but it is 
written in portable ANSI Common Lisp so it should run under any 
conforming implementation.

Comments and feedback are welcome.

rg

From: budden
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <54b8cf3e-3bf9-47e4-a46a-c307ba53ce4b@j35g2000yqh.googlegroups.com>
Hi!
   I can not pay much attention for lexicons now. I think they
introduce too many new constructs to lisp, and that's why I think I
won't use it. I too tried to solve package problems. I developed a
rather minimalistic approach. This approach produced some dispute
here. It is the time to give a link here: http://norvig.com/python-lisp.html
Piter Norvig says that package system is hard to use and says it is a
disadvantage of CL. I agree completely to this.
   My solution is to add macro
(in-packages package &rest more-packages) which acts as following:
- when this macro is in effect, reader behaviour changes. When
reading, unqualified symbol is sought for in all
packages listed. It can be found as internal symbol in first package
and as external symbol only in the rest of the packages. If it is
found once, it is used. If it is found more than once, error is
produced. If it is not found, it it interned into package. Maybe (I
think) one more rule is needed: if this symbol is in shadowing symbols
list of the "package", it can be used without qualifier even if it is
external in some of other packages.
- you may use qualified symbols to specify exactly what you mean.
- optionally, package locks are imposed to some packages (syntax not
shown).
  Additionally, read-macro of kind
#with-packages (package &rest packages) form
  is added so that next form is read in scope of (with-packages) form.

  This approach allows minimize both import and use-package operations
and it is relatively safe. It does not remove the need to export some
symbols manually when you want, say, have a custom + or - in your
package. Idea is borrowed from sql syntax:

select t1.id, t2.id, t1.unique_field_of_t1 from t1, t2 where
t1.id=t2.t1_id

  Which proved in my practice to be fairly reliable and convinient.
  I say it just in case you didn't read the topic with keywords
"symbol clashes - how to avoid them"

  For this to work we need either to change implementation's "find-
package" function (which is not portable), or use portable lisp reader
written in CL (it can be done rather easily based on some of open-
source implementations, there is such a reader already, written by
Pascal J. Bourguignon, but it is under GPL and it has bugs). I managed
to substitute lisp reader completely with other lisp reader, for all
activity including compiler. So, for now all what is left to do is to
take some open-source reader and replace implementation-specific
reading primitives with CL ones. Don't know when I get time for this.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-4E7CA2.12532205122008@news.gha.chartermi.net>
In article 
<····································@j35g2000yqh.googlegroups.com>,
 budden <········@gmail.com> wrote:

> Hi!
>    I can not pay much attention for lexicons now. I think they
> introduce too many new constructs to lisp, and that's why I think I
> won't use it.

I don't know what you consider a "new" construct, but lexicons only 
introduce lexical equivalents of existing CL defining forms (defun, 
defvar, defmacro, defclass and defmethod).  The lexical equivalent of 
each of these has the same name but preceded by an L (ldefun, ldefvar, 
ldefmacro, ldefclass and ldefmethod).  One could easily shadow the 
existing defining forms so that programming with lexicons is no 
different from programming in regular CL, but I wasn't going to do this 
until I had time to do some really thorough testing.

> I too tried to solve package problems. I developed a
> rather minimalistic approach. This approach produced some dispute
> here. It is the time to give a link here: http://norvig.com/python-lisp.html
> Piter Norvig says that package system is hard to use and says it is a
> disadvantage of CL. I agree completely to this.

Which is in fact the primary motivation for lexicons.

>  My solution is to add macro
> (in-packages package &rest more-packages) which acts as following:

[snip]

IMHO, the central problem with packages is that they try to resolve 
namespaces at read time, when this ought to be done at compile-time.  
The appropriate information for resolving namespaces is simply not 
available at read-time.  So the problems with packages cannot be solved 
by changing the reader.

Note that this issue is in some sense the converse of the one 
investigated by Kent Pitman a long time ago:

http://www.nhplace.com/kent/PS/Ambitious.html

rg
From: budden
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <cbe188e9-a2d4-4db3-81c7-0d6b6424b363@l42g2000yqe.googlegroups.com>
Well, maybe I'll take a look at it later, but it is too much.
Some packages overwrite defun too. One of them is ap5 which is very
cool.
Other is screamer which is cool to. I afraid there will be
problems...
And, say, I want to make a wrapper for defclass with standard names of
accessors, initargs, etc.
If I accept lexicons, I need to redefine ldefclass too.

Anyway, I think I'll take a closer look at them in a short just to
find what ideas are there.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-430708.13190505122008@news.gha.chartermi.net>
In article 
<····································@l42g2000yqe.googlegroups.com>,
 budden <········@gmail.com> wrote:

> Well, maybe I'll take a look at it later, but it is too much.
> Some packages overwrite defun too. One of them is ap5 which is very
> cool.
> Other is screamer which is cool to. I afraid there will be
> problems...

It depends on what the shadowing forms in these other packages expand 
into.  If, for example, AP5:DEFUN expands into CL:DEFUN then you can 
just muck with the package system to have it expand into LEXICONS:DEFUN 
instead.  It should Just Work.  But this is the sort of thing I want to 
actually try before unleashing it on the world.

> And, say, I want to make a wrapper for defclass with standard names of
> accessors, initargs, etc.
> If I accept lexicons, I need to redefine ldefclass too.

Nope, you'll just need to change your wrapper to expand into ldefclass 
instead of defclass.  All the LDEF* forms have the exact same syntax as 
their corresponding non-lexical forms.  Alternatively you can shadow 
DEF* and just run your (unchanged) wrapper definition in the package 
with the shadowed symbols.

The ultimate goal is to be able to take existing code, remove (nearly) 
all the package-related stuff, move everything into the (not yet 
implemented) LEXICONS package, and have it all Just Work.  This may be a 
pipe dream, but the fact that there is now a very close correspondence 
between lexicons and packages makes me optimistic.

rg
From: Kenny
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <49399e18$0$14280$607ed4bc@cv.net>
budden wrote:
> Hi!
>    I can not pay much attention for lexicons now. I think they
> introduce too many new constructs to lisp, and that's why I think I
> won't use it. I too tried to solve package problems. I developed a
> rather minimalistic approach. This approach produced some dispute
> here. It is the time to give a link here: http://norvig.com/python-lisp.html
> Piter Norvig says that package system is hard to use and says it is a
> disadvantage of CL. I agree completely to this.

Well then I do believe it is time to go shopping.

Only there is nothing hard about the package system unless your cup is 
full and you want it to be like some other thing but everything is like 
that.

>    My solution is to add macro
> (in-packages package &rest more-packages) which acts as following:
> - when this macro is in effect, reader behaviour changes. When
> reading, unqualified symbol is sought for in all
> packages listed. It can be found as internal symbol in first package
> and as external symbol only in the rest of the packages. If it is
> found once, it is used. If it is found more than once, error is
> produced. If it is not found, it it interned into package. Maybe (I
> think) one more rule is needed: if this symbol is in shadowing symbols
> list of the "package", it can be used without qualifier even if it is
> external in some of other packages.
> - you may use qualified symbols to specify exactly what you mean.
> - optionally, package locks are imposed to some packages (syntax not
> shown).
>   Additionally, read-macro of kind
> #with-packages (package &rest packages) form
>   is added so that next form is read in scope of (with-packages) form.
> 
>   This approach allows minimize both import and use-package operations
> and it is relatively safe. It does not remove the need to export some
> symbols manually when you want, say, have a custom + or - in your
> package. Idea is borrowed from sql syntax:
> 
> select t1.id, t2.id, t1.unique_field_of_t1 from t1, t2 where
> t1.id=t2.t1_id
> 
>   Which proved in my practice to be fairly reliable and convinient.
>   I say it just in case you didn't read the topic with keywords
> "symbol clashes - how to avoid them"
> 
>   For this to work we need either to change implementation's "find-
> package" function (which is not portable), or use portable lisp reader
> written in CL (it can be done rather easily based on some of open-
> source implementations, there is such a reader already, written by
> Pascal J. Bourguignon, but it is under GPL and it has bugs). I managed
> to substitute lisp reader completely with other lisp reader, for all
> activity including compiler. So, for now all what is left to do is to
> take some open-source reader and replace implementation-specific
> reading primitives with CL ones. Don't know when I get time for this.

Good lord, don't you have any application programming to do?

kxo
From: Kaz Kylheku
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <20081220195225.214@gmail.com>
On 2008-12-05, Ron Garret <·········@flownet.com> wrote:
> http://www.flownet.com/ron/lisp/lexicons.lisp

Not a proper DOS or Unix text file. Lines separated by carriage returns only,
no linefeeds.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-F16535.11354905122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-05, Ron Garret <·········@flownet.com> wrote:
> > http://www.flownet.com/ron/lisp/lexicons.lisp
> 
> Not a proper DOS or Unix text file. Lines separated by carriage returns only,
> no linefeeds.

Sorry, that's the (old) Mac end-of-line convention.  (I was editing the 
file using MCL.)  I've uploaded a new version that uses linefeeds 
instead.

rg
From: David Golden
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <ghc6i2$v5d$1@aioe.org>
Ron Garret wrote:


> The implementation is also significantly cleaned up (it
> consists of a single file of portable ANSI Common Lisp) and is more
> seamlessly integrated into Common Lisp (lexicons are now implemented
> using packages).
> 

I'm not sure I like this, at least not the way a lexicon named "l1" now
seems to "use up" a package named l1.  Haven't really played with it
enough yet to judge if it's all that much of an issue, but maybe
packages used for the implementation should be called %lex-l1 or
something.

> They are
> designed to be an adjunct, or potentially a replacement (depending on
> your needs) for packages.  Packages map strings on to symbols at
> read-time.  Lexicons map symbols onto bindings at compile-time.  For
> writing modular code, lexicons can be significantly more convenient
> than packages.

Yeah, I'm one of the people who uses packages for stuff other than
writing modular code - they're independently useful for sorting 
symbols, so it'd be nice if both lexicons and packages would work with 
minimal interference with eachother...
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-4182D3.15073505122008@news.gha.chartermi.net>
In article <············@aioe.org>,
 David Golden <············@oceanfree.net> wrote:

> Ron Garret wrote:
> 
> 
> > The implementation is also significantly cleaned up (it
> > consists of a single file of portable ANSI Common Lisp) and is more
> > seamlessly integrated into Common Lisp (lexicons are now implemented
> > using packages).
> > 
> 
> I'm not sure I like this, at least not the way a lexicon named "l1" now
> seems to "use up" a package named l1.  Haven't really played with it
> enough yet to judge if it's all that much of an issue, but maybe
> packages used for the implementation should be called %lex-l1 or
> something.

That would be very easy to change.

> > They are
> > designed to be an adjunct, or potentially a replacement (depending on
> > your needs) for packages.  Packages map strings on to symbols at
> > read-time.  Lexicons map symbols onto bindings at compile-time.  For
> > writing modular code, lexicons can be significantly more convenient
> > than packages.
> 
> Yeah, I'm one of the people who uses packages for stuff other than
> writing modular code - they're independently useful for sorting 
> symbols, so it'd be nice if both lexicons and packages would work with 
> minimal interference with eachother...

Lexicons have always been orthogonal to (and therefore compatible with) 
packages from the beginning.  It's just that now packages are used in 
the implementation whereas before they weren't.

Out of curiosity, what kind of "symbol sorting" are you using packages 
for?

rg
From: David Golden
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <ghcm5j$4bg$1@aioe.org>
Ron Garret wrote:

 
> That would be very easy to change.
> 

I assumed as much, but you did ask for feedback... :-)
 
> Out of curiosity, what kind of "symbol sorting" are you using packages
> for?
> 

If you're actually programming with symbols as pseudo-objects 
(hey, they are first-class in lisp), then it's just handy to be able to
stash them into separate packages so that ones with the same name have
separate identities but are easy to refer to. 

You have symbols with the same symbol-name. You want them to be
different objects still, and you don't want the emacs lisp "solution"
(um, make them have different names...). I mean, not much more to it.

Personally, I've used it for an (unreleased and half-assed) glsl and c
translators usable in one image, in combination, that used e.g.
glsl:main and c:main.  Probably more stuff.

Mostly convenience for humans writing/reading code, not for the
computer - Nothing you _couldn't_ do with a different implementation
strategy, without packages (or even first-class symbols), just a naming
convention or a bunch of hashtables you look up different things in in
different contexts. But you wind up implementing half a package system
anyway, shrug.  OTOH, people wouldn't go around calling your
(non-performance-critical, simple, short, works) code "old
fashioned"...
From: Leslie P. Polzer
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <c92308a2-7b39-4f65-bb8c-39a6556ffae5@y1g2000pra.googlegroups.com>
I have a minor gripe with the function MAKE-LEXICON:

It modifies some global object (i.e. the list of lexicons).

This is not consistent with the usual semantics of MAKE-* functions
and should probably be called DEFLEXICON instead.

  Leslie
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-B9638D.14043106122008@news.gha.chartermi.net>
In article 
<····································@y1g2000pra.googlegroups.com>,
 "Leslie P. Polzer" <·············@gmx.net> wrote:

> I have a minor gripe with the function MAKE-LEXICON:
> 
> It modifies some global object (i.e. the list of lexicons).
> 
> This is not consistent with the usual semantics of MAKE-* functions
> and should probably be called DEFLEXICON instead.
> 
>   Leslie

I agree with you that this is a bit of a wart in the design, but there's 
a reason for it.  The design of the lexicons API was intended to mirror 
the API for packages as much as possible while still achieving the 
design goals.  Accordingly, MAKE-LEXICON is intended to be the 
counterpart to MAKE-PACKAGE, which also modifies a global.  DEFLEXICON, 
if it were to exist, would be the counterpart to DEFPACKAGE.  But the 
whole point of lexicons is to get rid of all the complexity that makes 
DEFPACKAGE necessary, so DEFLEXICON would in some sense be an oxymoron.

In an ideal world, MAKE-LEXICON would not modify a global.  It would 
also allow you to make anonymous lexicons, and multiple lexicons with 
the same name.  But it is not possible to make anonymous packages, nor 
is it possible to make multiple packages with the same name, since both 
of these would undermine the whole point of having packages.  (Note that 
these features would not necessarily undermine the utility of lexicons, 
which is IMHO another indication that lexicons are the Right Way to 
achieve modularity.)

I did it this way because I thought that it would make package fans feel 
warmer and fuzzier about lexicons to know that the binding of a symbol S 
in lexicon L was invariably the symbol L::S.  It would be easy enough to 
abandon this invariant and just use uninterned symbols for the bindings 
instead.  But personally, although I am no fan of packages, the current 
design has kind of grown on me.  It's far from clear that enforcing the 
global uniqueness of lexicon names is a bad idea, even if it may not be 
logically necessary.

rg
From: David Golden
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <ghfilk$lb5$1@aioe.org>
Ron Garret wrote:

 
> I did it this way because I thought that it would make package fans
> feel warmer and fuzzier about lexicons to know that the binding of a
> symbol S
> in lexicon L was invariably the symbol L::S. 

Hmm. I guess that does sound handy. Perhaps my clash complaint is
adequately addressed by the user just adopting some explicit naming
convention for lexicons, rather than lexicon code doing any
name-munging. i.e. a lexicon named =lyekka=  with an implementation
package named =lyekka= isn't going to clash with a package named
lyekka.
From: Slobodan Blazeski
Subject: why cl packages are hard to use ?
Date: 
Message-ID: <2c967dc5-a2f7-482d-9f45-b9ad85c8bbdd@j11g2000yqg.googlegroups.com>
May somebody please explain me with simple words why cl packages are
hard to use, 'couse I really don't get it?
The best is probably to hear from somebody who just learned lisp or
somebody who teaches lisp (do such people exist anymore?) and his/her
students has problems with packages.

bobi
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-D3A535.09500707122008@news.gha.chartermi.net>
In article 
<····································@j11g2000yqg.googlegroups.com>,
 Slobodan Blazeski <·················@gmail.com> wrote:

> May somebody please explain me with simple words why cl packages are
> hard to use, 'couse I really don't get it?
> The best is probably to hear from somebody who just learned lisp or
> somebody who teaches lisp (do such people exist anymore?) and his/her
> students has problems with packages.
> 
> bobi

Packages aren't "hard to use", they just do the Wrong Thing ;-)  
Packages operate at read-time, but most programmer's intuitions about 
modularity relate to global bindings, which is a compile-time concept.

The biggest practical problem with packages, and the central motivation 
for lexicons, is that exported symbol lists have to be maintained 
manually.  This violates the DRY principle, and makes maintenance more 
difficult than it needs to be, rather like the burden imposed by C on 
the programmer to maintain the .c file and the .h files in parallel.  
Lexicons let you write modular code without manually maintaining an 
export list.

A secondary problem with packages is that because they do what they do 
at read time, merely parsing the program has potential side-effects 
(interning symbols).  If you attempt to parse a program in an 
environment where your packages have not been set up properly, these 
side effects can end up messing up your environment to the point where 
recovery is very difficult because you suddenly have a zillion symbol 
interned in a package where they should not be interned.  Lexicons avoid 
this problem because they operate at compile time, not read time.  They 
also have a deferred binding mechanism that allows recovery from 
unresolved bindings cause by missing libraries to be done at run-time, 
so if you don't have your libraries set up properly you can recover by 
simply importing the right library.  You don't have to recompile the 
client code.

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6q2iu8Fai50gU1@mid.individual.net>
Ron Garret wrote:
> In article 
> <····································@j11g2000yqg.googlegroups.com>,
>  Slobodan Blazeski <·················@gmail.com> wrote:
> 
>> May somebody please explain me with simple words why cl packages are
>> hard to use, 'couse I really don't get it?
>> The best is probably to hear from somebody who just learned lisp or
>> somebody who teaches lisp (do such people exist anymore?) and his/her
>> students has problems with packages.
>>
>> bobi
> 
> Packages aren't "hard to use", they just do the Wrong Thing ;-)  
> Packages operate at read-time, but most programmer's intuitions about 
> modularity relate to global bindings, which is a compile-time concept.

And therein lies the answer: Only people who stick to their intuition 
and try to use packages as if they were about bindings will find it hard 
to use packages. You have to adjust your expectations, and then packages 
become very easy. (Some people don't need this kind of adjustment, 
because the view packages provide comes natural to them.)

IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
the problem better than modules, i.e. managing the mapping from 
identifiers to concepts. So I wouldn't agree that they do the wrong 
thing, to the contrary, I think they do the right thing. But it's good 
that you put a smiley there... ;)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-C42F62.10540807122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
> the problem better than modules, i.e. managing the mapping from 
> identifiers to concepts.

Why?

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6q2m50Fai6kjU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
>> the problem better than modules, i.e. managing the mapping from 
>> identifiers to concepts.
> 
> Why?

Because they can make distinctions that you cannot make with module 
systems. For example, if you had only a module system, a class would not 
be able to inherit from two different classes with slots of the same 
name and be able to keep them as two different slots (unless you come up 
with funky renaming mechanisms, like in the R6RS module system, for 
example).

With a CL-style package system, the choice is always unambiguous: If you 
use the same symbol as somebody else, you definitely mean the same 
concept. If you want to denote a different concept, you have to use a 
different symbol. It's much harder to make such distinctions with module 
systems.

[Maybe having both packages and modules, like your lexicons, in the same 
system is beneficial in that it provides the functionalities of both 
worlds - but I cannot tell because I haven't tried this.]


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-E12F43.13295407122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
> >> the problem better than modules, i.e. managing the mapping from 
> >> identifiers to concepts.
> > 
> > Why?
> 
> Because they can make distinctions that you cannot make with module 
> systems. For example, if you had only a module system, a class would not 
> be able to inherit from two different classes with slots of the same 
> name and be able to keep them as two different slots (unless you come up 
> with funky renaming mechanisms, like in the R6RS module system, for 
> example).

That's true, but how often do you actually do multiple inheritance from 
two different classes that were separately developed?

BTW, because the current implementation of lexicons is tightly coupled 
with packages it is fairly straightforward to "fix" this.  I put "fix" 
in scare quotes because it's not at all clear to me that this is 
actually a problem, but if it really is then you can just have LDEFCLASS 
lexify the slot names along with the superclasses, e.g.:

(defmacro ldefclass (name superclasses slots &rest stuff &environment 
env)
  `(progn
     (lexify ,name)
     (defclass ,(lbind name (env-lexicon env))
       ,(mapcar (lambda (c) (or (find-cell (env-lexicon env) c)
                                (error "There is no class named ~S in 
the current lexical environment." c)))
                superclasses)
       ,(mapcar (lambda (s) (lbind s (env-lexicon env))) slots)
       ,@stuff)))

(defmacro lslot-value (instance slot-name &optional lexicon &environment 
env)
  `(slot-value ,instance ,(ref-form slot-name (or (find-lexicon lexicon) 
(env-lexicon env)))))

> With a CL-style package system, the choice is always unambiguous: If you 
> use the same symbol as somebody else, you definitely mean the same 
> concept. If you want to denote a different concept, you have to use a 
> different symbol. It's much harder to make such distinctions with module 
> systems.

That is not quite a fair argument.  It's true, but only because CL uses 
symbols as slot names.  That stacks the deck in favor of packages.  One 
could easily envision a minor variation on CLOS that used abstract slot 
identifier objects instead of symbols as slot names, and had lexically 
scoped bindings of identifiers onto abstract slot identifiers.  This 
would provide the exact same functionality but with the slot-identifier 
bindings taking place at compile time rather than read time.

But there's a more serious critique of your argument as well:  It's true 
that "If you use the same symbol as somebody else, you definitely mean 
the same concept."  However, because *package* is a global resource 
which can be manipulated in various ways, then unless you fully qualify 
every single symbol in your code (which no one ever does) you have to 
carefully manage *package* in order to insure that all the references to 
FOO that are supposed to be the same are in fact the same, and 
vice-versa.  This is certainly doable, but I would claim that it's a 
non-trivial burden on the programmer, particularly an inexperienced one.

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qcnfpFbpmeoU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>
>>>> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
>>>> the problem better than modules, i.e. managing the mapping from 
>>>> identifiers to concepts.
>>> Why?
>> Because they can make distinctions that you cannot make with module 
>> systems. For example, if you had only a module system, a class would not 
>> be able to inherit from two different classes with slots of the same 
>> name and be able to keep them as two different slots (unless you come up 
>> with funky renaming mechanisms, like in the R6RS module system, for 
>> example).
> 
> That's true, but how often do you actually do multiple inheritance from 
> two different classes that were separately developed?

The question is not how often this happens, but what you can do if and 
when it happens. I am aware of situations in Java, for example, where 
this can lead to a situation where you have to restart to write 
considerable portions of your software from scratch. It's good that this 
danger doesn't exist in Common Lisp.

>> With a CL-style package system, the choice is always unambiguous: If you 
>> use the same symbol as somebody else, you definitely mean the same 
>> concept. If you want to denote a different concept, you have to use a 
>> different symbol. It's much harder to make such distinctions with module 
>> systems.
> 
> That is not quite a fair argument.  It's true, but only because CL uses 
> symbols as slot names.  That stacks the deck in favor of packages.  One 
> could easily envision a minor variation on CLOS that used abstract slot 
> identifier objects instead of symbols as slot names, and had lexically 
> scoped bindings of identifiers onto abstract slot identifiers.  This 
> would provide the exact same functionality but with the slot-identifier 
> bindings taking place at compile time rather than read time.

...module figuring out all the fine details. ;)

> But there's a more serious critique of your argument as well:  It's true 
> that "If you use the same symbol as somebody else, you definitely mean 
> the same concept."  However, because *package* is a global resource 
> which can be manipulated in various ways, then unless you fully qualify 
> every single symbol in your code (which no one ever does) you have to 
> carefully manage *package* in order to insure that all the references to 
> FOO that are supposed to be the same are in fact the same, and 
> vice-versa.  This is certainly doable, but I would claim that it's a 
> non-trivial burden on the programmer, particularly an inexperienced one.

Indeed, that part of CL's package system is not ideal. I would prefer 
something like in Modula-2's or Oberon's module system, where you are 
required to import each and every identifier, or use fully qualified 
names. Especially Oberon's approach is extremely good, IMHO. That would 
be a great improvement for CL's packages.

But that's not a reason to throw the baby out with the bathwater...


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-8E2CD1.13010911122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >> Ron Garret wrote:
> >>> In article <··············@mid.individual.net>,
> >>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>
> >>>> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
> >>>> the problem better than modules, i.e. managing the mapping from 
> >>>> identifiers to concepts.
> >>> Why?
> >> Because they can make distinctions that you cannot make with module 
> >> systems. For example, if you had only a module system, a class would not 
> >> be able to inherit from two different classes with slots of the same 
> >> name and be able to keep them as two different slots (unless you come up 
> >> with funky renaming mechanisms, like in the R6RS module system, for 
> >> example).
> > 
> > That's true, but how often do you actually do multiple inheritance from 
> > two different classes that were separately developed?
> 
> The question is not how often this happens, but what you can do if and 
> when it happens. I am aware of situations in Java, for example, where 
> this can lead to a situation where you have to restart to write 
> considerable portions of your software from scratch. It's good that this 
> danger doesn't exist in Common Lisp.

The same thing can happen in CL.  Unless you can guarantee that package 
names are globally unique there's always the possibility of wanting to 
combine two code bases that use the same package name.  Such name 
clashes (for packages called "UTILITIES" for example) are not unheard of.

> >> With a CL-style package system, the choice is always unambiguous: If you 
> >> use the same symbol as somebody else, you definitely mean the same 
> >> concept. If you want to denote a different concept, you have to use a 
> >> different symbol. It's much harder to make such distinctions with module 
> >> systems.
> > 
> > That is not quite a fair argument.  It's true, but only because CL uses 
> > symbols as slot names.  That stacks the deck in favor of packages.  One 
> > could easily envision a minor variation on CLOS that used abstract slot 
> > identifier objects instead of symbols as slot names, and had lexically 
> > scoped bindings of identifiers onto abstract slot identifiers.  This 
> > would provide the exact same functionality but with the slot-identifier 
> > bindings taking place at compile time rather than read time.
> 
> ...module figuring out all the fine details. ;)
> 
> > But there's a more serious critique of your argument as well:  It's true 
> > that "If you use the same symbol as somebody else, you definitely mean 
> > the same concept."  However, because *package* is a global resource 
> > which can be manipulated in various ways, then unless you fully qualify 
> > every single symbol in your code (which no one ever does) you have to 
> > carefully manage *package* in order to insure that all the references to 
> > FOO that are supposed to be the same are in fact the same, and 
> > vice-versa.  This is certainly doable, but I would claim that it's a 
> > non-trivial burden on the programmer, particularly an inexperienced one.
> 
> Indeed, that part of CL's package system is not ideal. I would prefer 
> something like in Modula-2's or Oberon's module system, where you are 
> required to import each and every identifier, or use fully qualified 
> names.

How would that work if I wanted to make a package and have the Common 
Lisp language available in that package?  Would I have to explicitly 
import every one of the 700 or so exported symbols in the COMMON-LISP 
package? Or would I have to write code like this:

(common-lisp:defun fact (n)
  (common-lisp:if (common-lisp:<= n 1)
    0
    (common-lisp:* n (fact (commmon-lisp:1- n)))))

rg
From: Rob Warnock
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <NsSdnYR1YdtDZNzUnZ2dnUVZ_oPinZ2d@speakeasy.net>
Ron Garret  <·········@flownet.com> wrote:
+---------------
|  Pascal Costanza <··@p-cos.net> wrote:
| > The question is not how often this happens, but what you can do if and 
| > when it happens. I am aware of situations in Java, for example, where 
| > this can lead to a situation where you have to restart to write 
| > considerable portions of your software from scratch. It's good that this 
| > danger doesn't exist in Common Lisp.
| 
| The same thing can happen in CL.  Unless you can guarantee that package 
| names are globally unique there's always the possibility of wanting to 
| combine two code bases that use the same package name.  Such name 
| clashes (for packages called "UTILITIES" for example) are not unheard of.
+---------------

The good news is tha most people have started naming their packages
with names constructed to be globally unique, such as "NET.P-COS.UTILITIES"
and "COM.FLOWNET.UTILITIES" and "ORG.RPW3.UTILS".

The bad news, of course, is that people are still distributing packages
with short non-globally-unique *nicknames* such as "UTILS", so some
conflicts still need to be fixed, either manually or with RENAME-PACKAGE
hacks to de-conflict the nicknames.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-E02541.00532512122008@news.gha.chartermi.net>
In article <································@speakeasy.net>,
 ····@rpw3.org (Rob Warnock) wrote:

> Ron Garret  <·········@flownet.com> wrote:
> +---------------
> |  Pascal Costanza <··@p-cos.net> wrote:
> | > The question is not how often this happens, but what you can do if and 
> | > when it happens. I am aware of situations in Java, for example, where 
> | > this can lead to a situation where you have to restart to write 
> | > considerable portions of your software from scratch. It's good that this 
> | > danger doesn't exist in Common Lisp.
> | 
> | The same thing can happen in CL.  Unless you can guarantee that package 
> | names are globally unique there's always the possibility of wanting to 
> | combine two code bases that use the same package name.  Such name 
> | clashes (for packages called "UTILITIES" for example) are not unheard of.
> +---------------
> 
> The good news is tha most people have started naming their packages
> with names constructed to be globally unique, such as "NET.P-COS.UTILITIES"
> and "COM.FLOWNET.UTILITIES" and "ORG.RPW3.UTILS".
> 
> The bad news, of course, is that people are still distributing packages
> with short non-globally-unique *nicknames* such as "UTILS", so some
> conflicts still need to be fixed, either manually or with RENAME-PACKAGE
> hacks to de-conflict the nicknames.

The problem is not so much the packages themselves, it's all the client 
code that has explicit references to things like UTILS::FOO.  All that 
code will need to be changed too.

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qem9hFc2opaU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>
>>>> Ron Garret wrote:
>>>>> In article <··············@mid.individual.net>,
>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>
>>>>>> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
>>>>>> the problem better than modules, i.e. managing the mapping from 
>>>>>> identifiers to concepts.
>>>>> Why?
>>>> Because they can make distinctions that you cannot make with module 
>>>> systems. For example, if you had only a module system, a class would not 
>>>> be able to inherit from two different classes with slots of the same 
>>>> name and be able to keep them as two different slots (unless you come up 
>>>> with funky renaming mechanisms, like in the R6RS module system, for 
>>>> example).
>>> That's true, but how often do you actually do multiple inheritance from 
>>> two different classes that were separately developed?
>> The question is not how often this happens, but what you can do if and 
>> when it happens. I am aware of situations in Java, for example, where 
>> this can lead to a situation where you have to restart to write 
>> considerable portions of your software from scratch. It's good that this 
>> danger doesn't exist in Common Lisp.
> 
> The same thing can happen in CL.  Unless you can guarantee that package 
> names are globally unique there's always the possibility of wanting to 
> combine two code bases that use the same package name.  Such name 
> clashes (for packages called "UTILITIES" for example) are not unheard of.

Yes, but that's a different discussion. The same can happen for module 
systems (and lexicons) as well. The only solutions in that part of the 
problem space are pragmatic ones, like the globally unique names that 
are used by convention (!) in Java. (But see below for a more 
comprehensive solution.)

>>> But there's a more serious critique of your argument as well:  It's true 
>>> that "If you use the same symbol as somebody else, you definitely mean 
>>> the same concept."  However, because *package* is a global resource 
>>> which can be manipulated in various ways, then unless you fully qualify 
>>> every single symbol in your code (which no one ever does) you have to 
>>> carefully manage *package* in order to insure that all the references to 
>>> FOO that are supposed to be the same are in fact the same, and 
>>> vice-versa.  This is certainly doable, but I would claim that it's a 
>>> non-trivial burden on the programmer, particularly an inexperienced one.
>> Indeed, that part of CL's package system is not ideal. I would prefer 
>> something like in Modula-2's or Oberon's module system, where you are 
>> required to import each and every identifier, or use fully qualified 
>> names.
> 
> How would that work if I wanted to make a package and have the Common 
> Lisp language available in that package?  Would I have to explicitly 
> import every one of the 700 or so exported symbols in the COMMON-LISP 
> package? Or would I have to write code like this:
> 
> (common-lisp:defun fact (n)
>   (common-lisp:if (common-lisp:<= n 1)
>     0
>     (common-lisp:* n (fact (commmon-lisp:1- n)))))

Here is what Modula-2 and Oberon do: They both define a core language 
that is accessible by everyone. After all, they are languages that 
distinguish strongly between language constructs and library procedures, 
so the language constructs are always available unqualified and can 
never clash with any procedure or variable names.

In Modula-2, you import identifiers from other modules by explicitly 
listing them all:

FROM SomeModule IMPORT doThis, doThat, Type1, Type2;

There is no way of getting all identifiers implicitly from another 
module, like with Common Lisp's :use / use-package. It is rather only 
possible to do the equivalent of Common Lisp's :import-from / import.

Advantage: In Common Lisp, it can happen that package p1 export foo, 
package p2 doesn't, and you use both p1 and p2 in another package p3. If 
later on, package p1 removes foo from its export list, but p2 adds foo 
to its export list, the programmer maintaining p3 will not easily notice 
the change because p3 silently still refers to a foo, just a different 
one. In Modula-2 this problem cannot arise.

In Modula-2 the import declaration would look like this:

MODULE M3;

FROM M1 IMPORT foo, bar;
FROM M2 IMPORT baz;

If M1 stops exporting foo, but M2 starts exporting it, module M3 would 
still not compile, and thus the maintainer of M3 would notice that 
something has changed.


Having to list all identifiers from other packages all the time is very 
inconvenient, though, especially for large-scale programs. That's why 
Wirth changed the import declaration in Oberon. In Oberon, which is 
largely like Modula-2 with a couple of changes in detail, the only way 
to import identifiers is by importing complete modules:

IMPORT SomeModule;

This allows you to use identifiers from that module _qualified_, so 
inside a module that has that import declaration, you can say this:

SomeModule.foo := SomeModule.bar + baz;
(* where baz is guaranteed to be from the current module *)


It is not possible to refer to any other module within such a module, 
unless such other modules are imported as well. Say, if you want to use 
the module SYSTEM in the same module as well, you have to change the 
import declaration to this, otherwise you cannot use it:

IMPORT SomeModule, SYSTEM;

Now there is still the inconvenience that you have to use lengthy module 
names all the time. That's why Oberon also provides something similar to 
nicknames, with an important difference though: The nicknames can be 
chose by the client modules, not by the provider modules. Here is an 
example:

IMPORT SM := SomeModule, SYSTEM;

Now, inside this module you can refer to identifiers of SomeModule like 
this:

SM.foo := SM.bar + baz;

Having used all of Modula-2, Oberon, Java and Common Lisp for quite a 
while, I am convinced that Oberon's approach is the most elegant one, 
the most convenient to use, while guaranteeing the highest degree of 
clash freeness - except that it should handle import and export of 
symbols like in Common Lisp, not of bindings.

The added benefit of Oberon's approach is that it's very easy to replace 
modules that some module uses. In the above example, it's very easy to 
say this:

IMPORT SM := SomeOtherVersionOfSomeModule, SYSTEM;

...and then just recompile. Very nice for testing, very nice for dealing 
with different versions of the same library.


We wouldn't be able to blindly reuse Oberon's module system in an 
imaginary new version of the Common Lisp standard. But if I were to make 
decisions for how to change Common Lisp's package system, I would try to 
change the following:

+ There shouldn't be an option anymore to import all symbols from some 
other package by just saying :use or use-package. (I totally agree with 
Kaz here.)

+ The common-lisp package should have special status. It may be a good 
idea that not all 700, or so, symbols are exported from common-lisp as 
is the case in current ANSI Common Lisp, but the size should rather be 
something along the lines of ISLISP, and everything else should be put 
in some standard library package. But that's a detail and not immensely 
important. What's important is that common-lisp should be a privileged 
package whose symbols I can just use without qualifying them. (:use / 
use-package could be allowed for common-lisp, for example, but 
restricted to that one package.)

+ There should be a new option to import all symbols from some other 
package :import-package / import-package, which allows you to use all 
those symbols _qualified_. So after an (import-package :some-package), 
you can say both some-package:foo and some-package::internal-foo, but 
not otherwise. There should be a way to assign a package-local nickname 
for that other package. So after an (import-package :some-package :sp), 
you can say sp:foo and sp::internal-foo, but not otherwise. References 
to some-other-package:bar or some-other-package::bar without a 
corresponding :import-package / import-package should be disallowed, or 
at least deprecated (with a warning).

+ For backwards compatibility, :import-from / import should still be 
supported, which allows for Modula-2-style imports.


The advantages would be:

+ Name clashes are minimized even further.

+ There cannot be clashes anymore because of carelessly chosen 
nicknames. Nicknames are strictly local and not global anymore. 
Nicknames announced using the current package system could be deprecated.

+ It is always clear where a symbol comes from either directly from the 
source code, or by looking at the package declaration. No ambiguities 
anymore, as is currently still possible.

+ The usefulness of the current package system, to make very 
fine-grained distinctions using symbols, is still maintained. No need to 
throw the baby out with the bathwater.

+ An added benefit is that system definition utilities could now be 
based on (or use information from) package declarations, since the 
relationships between packages become unambiguous.


The disadvantages would be:

+ Existing code has to be modified: If there are "wild" qualified 
references to symbols from other packages (like in some-package:foo), 
corresponding :import-package declarations have to be added to the 
corresponding packages. The overhead should be very mild, since this can 
be supported by Common Lisp compilers with the appropriate warnings / 
error messages.

+ If there are unqualified references to symbols implicitly imported by 
:use / use-package declarations, the workload for upgrading existing 
libraries is higher. That's why it may be a good idea to only deprecate 
:use / use-package, and not just suddenly completely remove it. (There 
is a potential for political tension here, because vendors may want to 
have similar privileged status for their implementation-specific 
extensions like Common Lisp would provide for the common-lisp package. I 
don't immediately see a good solution here.)


Just my 0.02� (a much better currency these days... ;)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-F8A57F.09191612122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >> Ron Garret wrote:
> >>> In article <··············@mid.individual.net>,
> >>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>
> >>>> Ron Garret wrote:
> >>>>> In article <··············@mid.individual.net>,
> >>>>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>>>
> >>>>>> IMHO, packages, i.e. managing the mapping from strings to symbols, 
> >>>>>> solve 
> >>>>>> the problem better than modules, i.e. managing the mapping from 
> >>>>>> identifiers to concepts.
> >>>>> Why?
> >>>> Because they can make distinctions that you cannot make with module 
> >>>> systems. For example, if you had only a module system, a class would not 
> >>>> be able to inherit from two different classes with slots of the same 
> >>>> name and be able to keep them as two different slots (unless you come up 
> >>>> with funky renaming mechanisms, like in the R6RS module system, for 
> >>>> example).
> >>> That's true, but how often do you actually do multiple inheritance from 
> >>> two different classes that were separately developed?
> >> The question is not how often this happens, but what you can do if and 
> >> when it happens. I am aware of situations in Java, for example, where 
> >> this can lead to a situation where you have to restart to write 
> >> considerable portions of your software from scratch. It's good that this 
> >> danger doesn't exist in Common Lisp.
> > 
> > The same thing can happen in CL.  Unless you can guarantee that package 
> > names are globally unique there's always the possibility of wanting to 
> > combine two code bases that use the same package name.  Such name 
> > clashes (for packages called "UTILITIES" for example) are not unheard of.
> 
> Yes, but that's a different discussion. The same can happen for module 
> systems (and lexicons) as well.

No, lexicons are (at least potentially) immune from this because 
lexicons are not tightly bound to their names the way packages are.  The 
current implementation has a global lexicon namespace, but that would be 
easy to change.  There's no reason why you couldn't have two lexicons 
with the same name.

> Advantage: In Common Lisp, it can happen that package p1 export foo, 
> package p2 doesn't, and you use both p1 and p2 in another package p3. If 
> later on, package p1 removes foo from its export list, but p2 adds foo 
> to its export list, the programmer maintaining p3 will not easily notice 
> the change because p3 silently still refers to a foo, just a different 
> one. In Modula-2 this problem cannot arise.

I would argue that this is no different than if a module changes the 
definition of some exported functionality in some 
non-backwards-compatible way.  If you blindly use a new version of a 
library without reading the docs there are problems that you will 
encounter that no namespacing system will save you from.

The form of this argument is strikingly similar to the arguments that 
people put forth in support of static typing.  "Just declare your types 
and the compiler will save you from all these potential errors."  <==> 
"Just explicitly import all your identifiers and the compiler will save 
you..." etc. etc.  Will you next be advocating adding static typing to 
CL?

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qhnekFck34iU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>
>>>> Ron Garret wrote:
>>>>> In article <··············@mid.individual.net>,
>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>
>>>>>> Ron Garret wrote:
>>>>>>> In article <··············@mid.individual.net>,
>>>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>>>
>>>>>>>> IMHO, packages, i.e. managing the mapping from strings to symbols, 
>>>>>>>> solve 
>>>>>>>> the problem better than modules, i.e. managing the mapping from 
>>>>>>>> identifiers to concepts.
>>>>>>> Why?
>>>>>> Because they can make distinctions that you cannot make with module 
>>>>>> systems. For example, if you had only a module system, a class would not 
>>>>>> be able to inherit from two different classes with slots of the same 
>>>>>> name and be able to keep them as two different slots (unless you come up 
>>>>>> with funky renaming mechanisms, like in the R6RS module system, for 
>>>>>> example).
>>>>> That's true, but how often do you actually do multiple inheritance from 
>>>>> two different classes that were separately developed?
>>>> The question is not how often this happens, but what you can do if and 
>>>> when it happens. I am aware of situations in Java, for example, where 
>>>> this can lead to a situation where you have to restart to write 
>>>> considerable portions of your software from scratch. It's good that this 
>>>> danger doesn't exist in Common Lisp.
>>> The same thing can happen in CL.  Unless you can guarantee that package 
>>> names are globally unique there's always the possibility of wanting to 
>>> combine two code bases that use the same package name.  Such name 
>>> clashes (for packages called "UTILITIES" for example) are not unheard of.
>> Yes, but that's a different discussion. The same can happen for module 
>> systems (and lexicons) as well.
> 
> No, lexicons are (at least potentially) immune from this because 
> lexicons are not tightly bound to their names the way packages are.  The 
> current implementation has a global lexicon namespace, but that would be 
> easy to change.  There's no reason why you couldn't have two lexicons 
> with the same name.

Maybe. But you have to find them. ("would be easy to change" - that's a 
good one... ;)

>> Advantage: In Common Lisp, it can happen that package p1 export foo, 
>> package p2 doesn't, and you use both p1 and p2 in another package p3. If 
>> later on, package p1 removes foo from its export list, but p2 adds foo 
>> to its export list, the programmer maintaining p3 will not easily notice 
>> the change because p3 silently still refers to a foo, just a different 
>> one. In Modula-2 this problem cannot arise.
> 
> I would argue that this is no different than if a module changes the 
> definition of some exported functionality in some 
> non-backwards-compatible way.  If you blindly use a new version of a 
> library without reading the docs there are problems that you will 
> encounter that no namespacing system will save you from.

People are doing this all the time. I regularly update the libraries 
that my own libraries depend on, and most of the time, I don't encounter 
such problems. Welcome to the real world.

> The form of this argument is strikingly similar to the arguments that 
> people put forth in support of static typing.  "Just declare your types 
> and the compiler will save you from all these potential errors."  <==> 
> "Just explicitly import all your identifiers and the compiler will save 
> you..." etc. etc.  Will you next be advocating adding static typing to 
> CL?

Don't worry, I stopped beating my wife.

(I was happy that your back in c.l.l. initially, because we're finally 
having discussions about Lisp again, which is rare in c.l.l. these days. 
But you're now getting silly, which is unfortunate. It is well known 
what my stance about static typing is. So please don't get silly, that 
would be very helpful. Thank you.)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-4966E5.12595813122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >> Ron Garret wrote:
> >>> In article <··············@mid.individual.net>,
> >>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>
> >>>> Ron Garret wrote:
> >>>>> In article <··············@mid.individual.net>,
> >>>>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>>>
> >>>>>> Ron Garret wrote:
> >>>>>>> In article <··············@mid.individual.net>,
> >>>>>>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>>>>>
> >>>>>>>> IMHO, packages, i.e. managing the mapping from strings to symbols, 
> >>>>>>>> solve 
> >>>>>>>> the problem better than modules, i.e. managing the mapping from 
> >>>>>>>> identifiers to concepts.
> >>>>>>> Why?
> >>>>>> Because they can make distinctions that you cannot make with module 
> >>>>>> systems. For example, if you had only a module system, a class would 
> >>>>>> not 
> >>>>>> be able to inherit from two different classes with slots of the same 
> >>>>>> name and be able to keep them as two different slots (unless you come 
> >>>>>> up 
> >>>>>> with funky renaming mechanisms, like in the R6RS module system, for 
> >>>>>> example).
> >>>>> That's true, but how often do you actually do multiple inheritance from 
> >>>>> two different classes that were separately developed?
> >>>> The question is not how often this happens, but what you can do if and 
> >>>> when it happens. I am aware of situations in Java, for example, where 
> >>>> this can lead to a situation where you have to restart to write 
> >>>> considerable portions of your software from scratch. It's good that this 
> >>>> danger doesn't exist in Common Lisp.
> >>> The same thing can happen in CL.  Unless you can guarantee that package 
> >>> names are globally unique there's always the possibility of wanting to 
> >>> combine two code bases that use the same package name.  Such name 
> >>> clashes (for packages called "UTILITIES" for example) are not unheard of.
> >> Yes, but that's a different discussion. The same can happen for module 
> >> systems (and lexicons) as well.
> > 
> > No, lexicons are (at least potentially) immune from this because 
> > lexicons are not tightly bound to their names the way packages are.  The 
> > current implementation has a global lexicon namespace, but that would be 
> > easy to change.  There's no reason why you couldn't have two lexicons 
> > with the same name.
> 
> Maybe. But you have to find them. ("would be easy to change" - that's a 
> good one... ;)

(defun make-lexicon (name &optional package)
  (when (null package)
    (setf package (make-package (gensym (format nil "~A" name)))
  (let ( (l (%make-lexicon :name name :parent (current-lexicon)
                           :package package)) )
    (push l *lexicons*)
    l))

? (make-lexicon "L")
#<Lexicon L>
? (make-lexicon "L")
#<Lexicon L>
? *lexicons*
(#<Lexicon L> #<Lexicon L> #<Lexicon ROOT>)
? (in-lexicon (first *lexicons*))
#<Lexicon L>
? (ldefvar x 1)
L490::X
? x
1
? (in-lexicon (second *lexicons*))
#<Lexicon L>
? (ldefvar x 2)
L489::X
? x
2
? (in-lexicon (first *lexicons*))
#<Lexicon L>
? x
1
? 

Is that easy enough for you?

> 
> >> Advantage: In Common Lisp, it can happen that package p1 export foo, 
> >> package p2 doesn't, and you use both p1 and p2 in another package p3. If 
> >> later on, package p1 removes foo from its export list, but p2 adds foo 
> >> to its export list, the programmer maintaining p3 will not easily notice 
> >> the change because p3 silently still refers to a foo, just a different 
> >> one. In Modula-2 this problem cannot arise.
> > 
> > I would argue that this is no different than if a module changes the 
> > definition of some exported functionality in some 
> > non-backwards-compatible way.  If you blindly use a new version of a 
> > library without reading the docs there are problems that you will 
> > encounter that no namespacing system will save you from.
> 
> People are doing this all the time. I regularly update the libraries 
> that my own libraries depend on, and most of the time, I don't encounter 
> such problems. Welcome to the real world.
> 
> > The form of this argument is strikingly similar to the arguments that 
> > people put forth in support of static typing.  "Just declare your types 
> > and the compiler will save you from all these potential errors."  <==> 
> > "Just explicitly import all your identifiers and the compiler will save 
> > you..." etc. etc.  Will you next be advocating adding static typing to 
> > CL?
> 
> Don't worry, I stopped beating my wife.
> 
> (I was happy that your back in c.l.l. initially, because we're finally 
> having discussions about Lisp again, which is rare in c.l.l. these days. 
> But you're now getting silly, which is unfortunate.

*YOU* are the one comparing an advocacy of static typing with wife 
beating and *I* am the one being silly?  And you wonder why I don't hang 
our here much any more?

> It is well known what my stance about static typing is.

Not to me it isn't.

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qiuv2Fcmmq2U1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>
>>>> Ron Garret wrote:
>>>>> In article <··············@mid.individual.net>,
>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>
>>>>>> Ron Garret wrote:
>>>>>>> In article <··············@mid.individual.net>,
>>>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>>>
>>>>>>>> Ron Garret wrote:
>>>>>>>>> In article <··············@mid.individual.net>,
>>>>>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>>>>>
>>>>>>>>>> IMHO, packages, i.e. managing the mapping from strings to symbols, 
>>>>>>>>>> solve 
>>>>>>>>>> the problem better than modules, i.e. managing the mapping from 
>>>>>>>>>> identifiers to concepts.
>>>>>>>>> Why?
>>>>>>>> Because they can make distinctions that you cannot make with module 
>>>>>>>> systems. For example, if you had only a module system, a class would 
>>>>>>>> not 
>>>>>>>> be able to inherit from two different classes with slots of the same 
>>>>>>>> name and be able to keep them as two different slots (unless you come 
>>>>>>>> up 
>>>>>>>> with funky renaming mechanisms, like in the R6RS module system, for 
>>>>>>>> example).
>>>>>>> That's true, but how often do you actually do multiple inheritance from 
>>>>>>> two different classes that were separately developed?
>>>>>> The question is not how often this happens, but what you can do if and 
>>>>>> when it happens. I am aware of situations in Java, for example, where 
>>>>>> this can lead to a situation where you have to restart to write 
>>>>>> considerable portions of your software from scratch. It's good that this 
>>>>>> danger doesn't exist in Common Lisp.
>>>>> The same thing can happen in CL.  Unless you can guarantee that package 
>>>>> names are globally unique there's always the possibility of wanting to 
>>>>> combine two code bases that use the same package name.  Such name 
>>>>> clashes (for packages called "UTILITIES" for example) are not unheard of.
>>>> Yes, but that's a different discussion. The same can happen for module 
>>>> systems (and lexicons) as well.
>>> No, lexicons are (at least potentially) immune from this because 
>>> lexicons are not tightly bound to their names the way packages are.  The 
>>> current implementation has a global lexicon namespace, but that would be 
>>> easy to change.  There's no reason why you couldn't have two lexicons 
>>> with the same name.
>> Maybe. But you have to find them. ("would be easy to change" - that's a 
>> good one... ;)
> 
> (defun make-lexicon (name &optional package)
>   (when (null package)
>     (setf package (make-package (gensym (format nil "~A" name)))
>   (let ( (l (%make-lexicon :name name :parent (current-lexicon)
>                            :package package)) )
>     (push l *lexicons*)
>     l))
> 
> ? (make-lexicon "L")
> #<Lexicon L>
> ? (make-lexicon "L")
> #<Lexicon L>
> ? *lexicons*
> (#<Lexicon L> #<Lexicon L> #<Lexicon ROOT>)
> ? (in-lexicon (first *lexicons*))
> #<Lexicon L>
> ? (ldefvar x 1)
> L490::X
> ? x
> 1
> ? (in-lexicon (second *lexicons*))
> #<Lexicon L>
> ? (ldefvar x 2)
> L489::X
> ? x
> 2
> ? (in-lexicon (first *lexicons*))
> #<Lexicon L>
> ? x
> 1
> ? 
> 
> Is that easy enough for you?

You showed how to do the trivial part. That's not impressive. You have 
to find those modules. You have to organize a way how programmer A can 
say that he wants library L from provider B. You need to organize a 
global naming convention for that, there is no real way around that. If 
that global naming convention is easy to follow, like in Java, you have 
an effective solution. If it's too ad hoc, like in Common Lisp, you can 
have nameclashes between packages or modules. This is orthogonal to how 
you organize the namespaces.

>>>> Advantage: In Common Lisp, it can happen that package p1 export foo, 
>>>> package p2 doesn't, and you use both p1 and p2 in another package p3. If 
>>>> later on, package p1 removes foo from its export list, but p2 adds foo 
>>>> to its export list, the programmer maintaining p3 will not easily notice 
>>>> the change because p3 silently still refers to a foo, just a different 
>>>> one. In Modula-2 this problem cannot arise.
>>> I would argue that this is no different than if a module changes the 
>>> definition of some exported functionality in some 
>>> non-backwards-compatible way.  If you blindly use a new version of a 
>>> library without reading the docs there are problems that you will 
>>> encounter that no namespacing system will save you from.
>> People are doing this all the time. I regularly update the libraries 
>> that my own libraries depend on, and most of the time, I don't encounter 
>> such problems. Welcome to the real world.
>>
>>> The form of this argument is strikingly similar to the arguments that 
>>> people put forth in support of static typing.  "Just declare your types 
>>> and the compiler will save you from all these potential errors."  <==> 
>>> "Just explicitly import all your identifiers and the compiler will save 
>>> you..." etc. etc.  Will you next be advocating adding static typing to 
>>> CL?
>> Don't worry, I stopped beating my wife.
>>
>> (I was happy that your back in c.l.l. initially, because we're finally 
>> having discussions about Lisp again, which is rare in c.l.l. these days. 
>> But you're now getting silly, which is unfortunate.
> 
> *YOU* are the one comparing an advocacy of static typing with wife 
> beating and *I* am the one being silly?

Blabla. You have drawn weird conclusions what I would advocate or not. 
This is very insulting.

>> It is well known what my stance about static typing is.
> 
> Not to me it isn't.

Well, I guess you know how to use google.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-93748B.23210513122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> > 
> > Is that easy enough for you?
> 
> You showed how to do the trivial part. That's not impressive. You have 
> to find those modules. You have to organize a way how programmer A can 
> say that he wants library L from provider B. You need to organize a 
> global naming convention for that, there is no real way around that.

You are mistaken.  Python is an existence proof that a global naming 
convention is NOT necessary.  Python's modules are named locally.  You 
and I can use the same module, and I can call that module FOO and you 
can call it BAZ.  Not only that, but you can write code that refers to 
that module as BAZ and I can use your code without modification simply 
by creating a symlink in my local file system, or by adding a single 
line of code ("import foo as baz").

> >>>> Advantage: In Common Lisp, it can happen that package p1 export foo, 
> >>>> package p2 doesn't, and you use both p1 and p2 in another package p3. If 
> >>>> later on, package p1 removes foo from its export list, but p2 adds foo 
> >>>> to its export list, the programmer maintaining p3 will not easily notice 
> >>>> the change because p3 silently still refers to a foo, just a different 
> >>>> one. In Modula-2 this problem cannot arise.
> >>> I would argue that this is no different than if a module changes the 
> >>> definition of some exported functionality in some 
> >>> non-backwards-compatible way.  If you blindly use a new version of a 
> >>> library without reading the docs there are problems that you will 
> >>> encounter that no namespacing system will save you from.
> >> People are doing this all the time. I regularly update the libraries 
> >> that my own libraries depend on, and most of the time, I don't encounter 
> >> such problems. Welcome to the real world.
> >>
> >>> The form of this argument is strikingly similar to the arguments that 
> >>> people put forth in support of static typing.  "Just declare your types 
> >>> and the compiler will save you from all these potential errors."  <==> 
> >>> "Just explicitly import all your identifiers and the compiler will save 
> >>> you..." etc. etc.  Will you next be advocating adding static typing to 
> >>> CL?
> >> Don't worry, I stopped beating my wife.
> >>
> >> (I was happy that your back in c.l.l. initially, because we're finally 
> >> having discussions about Lisp again, which is rare in c.l.l. these days. 
> >> But you're now getting silly, which is unfortunate.
> > 
> > *YOU* are the one comparing an advocacy of static typing with wife 
> > beating and *I* am the one being silly?
> 
> Blabla. You have drawn weird conclusions what I would advocate or not. 
> This is very insulting.

I have done no such thing.  All I did was ask a question (and a 
rhetorical one at that).

> >> It is well known what my stance about static typing is.
> > 
> > Not to me it isn't.
> 
> Well, I guess you know how to use google.

You are missing the point.  I don't care what your position on static 
typing is.  The point is: Lisp doesn't have static typing, so any 
argument for packages (or any Lisp feature) that follows the form of the 
arguments that people make for static typing (and yours did) is 
self-defeating.  That static typing is better than latent typing is 
*axiomatically* false in the context of a discussion of Lisp.

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qk9qmFd188tU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>>> Is that easy enough for you?
>> You showed how to do the trivial part. That's not impressive. You have 
>> to find those modules. You have to organize a way how programmer A can 
>> say that he wants library L from provider B. You need to organize a 
>> global naming convention for that, there is no real way around that.
> 
> You are mistaken.  Python is an existence proof that a global naming 
> convention is NOT necessary.  Python's modules are named locally.  You 
> and I can use the same module, and I can call that module FOO and you 
> can call it BAZ.  Not only that, but you can write code that refers to 
> that module as BAZ and I can use your code without modification simply 
> by creating a symlink in my local file system, or by adding a single 
> line of code ("import foo as baz").

At some stage, there was a reference to the same thing. At that stage, 
we had to agree on some name, and if it was only the same website we 
downloaded the library from. This is inevitable, and orthogonal to 
whether we use modules or packages.

>>>>>> Advantage: In Common Lisp, it can happen that package p1 export foo, 
>>>>>> package p2 doesn't, and you use both p1 and p2 in another package p3. If 
>>>>>> later on, package p1 removes foo from its export list, but p2 adds foo 
>>>>>> to its export list, the programmer maintaining p3 will not easily notice 
>>>>>> the change because p3 silently still refers to a foo, just a different 
>>>>>> one. In Modula-2 this problem cannot arise.
>>>>> I would argue that this is no different than if a module changes the 
>>>>> definition of some exported functionality in some 
>>>>> non-backwards-compatible way.  If you blindly use a new version of a 
>>>>> library without reading the docs there are problems that you will 
>>>>> encounter that no namespacing system will save you from.
>>>> People are doing this all the time. I regularly update the libraries 
>>>> that my own libraries depend on, and most of the time, I don't encounter 
>>>> such problems. Welcome to the real world.
>>>>
>>>>> The form of this argument is strikingly similar to the arguments that 
>>>>> people put forth in support of static typing.  "Just declare your types 
>>>>> and the compiler will save you from all these potential errors."  <==> 
>>>>> "Just explicitly import all your identifiers and the compiler will save 
>>>>> you..." etc. etc.  Will you next be advocating adding static typing to 
>>>>> CL?
>>>> Don't worry, I stopped beating my wife.
>>>>
>>>> (I was happy that your back in c.l.l. initially, because we're finally 
>>>> having discussions about Lisp again, which is rare in c.l.l. these days. 
>>>> But you're now getting silly, which is unfortunate.
>>> *YOU* are the one comparing an advocacy of static typing with wife 
>>> beating and *I* am the one being silly?
>> Blabla. You have drawn weird conclusions what I would advocate or not. 
>> This is very insulting.
> 
> I have done no such thing.  All I did was ask a question (and a 
> rhetorical one at that).

Whatever.

>>>> It is well known what my stance about static typing is.
>>> Not to me it isn't.
>> Well, I guess you know how to use google.
> 
> You are missing the point.  I don't care what your position on static 
> typing is.  The point is: Lisp doesn't have static typing, so any 
> argument for packages (or any Lisp feature) that follows the form of the 
> arguments that people make for static typing (and yours did) is 
> self-defeating.

That's nonsense.



Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-1BEBE7.09070114122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >>> Is that easy enough for you?
> >> You showed how to do the trivial part. That's not impressive. You have 
> >> to find those modules. You have to organize a way how programmer A can 
> >> say that he wants library L from provider B. You need to organize a 
> >> global naming convention for that, there is no real way around that.
> > 
> > You are mistaken.  Python is an existence proof that a global naming 
> > convention is NOT necessary.  Python's modules are named locally.  You 
> > and I can use the same module, and I can call that module FOO and you 
> > can call it BAZ.  Not only that, but you can write code that refers to 
> > that module as BAZ and I can use your code without modification simply 
> > by creating a symlink in my local file system, or by adding a single 
> > line of code ("import foo as baz").
> 
> At some stage, there was a reference to the same thing.

That's not true.  We could be referring to two different things.  As 
long as they have the same API we can treat them *as if* they were the 
same thing even though in fact they are not the same thing.  For 
example, "Common Lisp" is ambiguous (since there are many 
implementations) but we don't have to resolve that ambiguity in order to 
have a useful discussion about it, or even to use it in a real system.

> At that stage, we had to agree on some name

That's not true either.  There is, for example, a Python package that is 
sometimes called "MySQLdb" and sometimes called "MySQL-Python".  So even 
in those cases where you *are* talking about the same thing it is not 
necessary to agree on a name.

> and if it was only the same website we 
> downloaded the library from.

Neither is that.  The package that I referred to above is available from 
multiple web sites.

> This is inevitable,

Since it is not true, it is clearly not inevitable.

> and orthogonal to whether we use modules or packages.

That's not true either.  *IF* we are going to use names (and they are 
undeniably convenient, even if not strictly necessary) then the choice 
of whether to consider a word that appears to be the same but has 
potentially two different meanings to be in fact two different words has 
important practical consequences.

Consider the word "Venus" which in common usage can designate both a 
planet and a Roman goddess.  Are "Venus" the planet and "Venus" the 
goddess two different words, or are they the same word that can take on 
two different meanings depending on the context?  How about Venus the 
tennis player?  This is not a trivial problem.  It has an extensive 
literature.  It has been debated for centuries.  (I wrote my master's 
thesis on it.)  Getting in to the technical details would take us far 
afield.  I'll just point out that I am able to refer to both Venus the 
planet and Venus the Roman goddess in the same sentence without having 
to disambiguate them as planet::venus and roman-mythology::venus.

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qktsmFd15efU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>
>>>>> Is that easy enough for you?
>>>> You showed how to do the trivial part. That's not impressive. You have 
>>>> to find those modules. You have to organize a way how programmer A can 
>>>> say that he wants library L from provider B. You need to organize a 
>>>> global naming convention for that, there is no real way around that.
>>> You are mistaken.  Python is an existence proof that a global naming 
>>> convention is NOT necessary.  Python's modules are named locally.  You 
>>> and I can use the same module, and I can call that module FOO and you 
>>> can call it BAZ.  Not only that, but you can write code that refers to 
>>> that module as BAZ and I can use your code without modification simply 
>>> by creating a symlink in my local file system, or by adding a single 
>>> line of code ("import foo as baz").
>> At some stage, there was a reference to the same thing.
> 
> That's not true.  We could be referring to two different things.  As 
> long as they have the same API we can treat them *as if* they were the 
> same thing even though in fact they are not the same thing.  For 
> example, "Common Lisp" is ambiguous (since there are many 
> implementations) but we don't have to resolve that ambiguity in order to 
> have a useful discussion about it, or even to use it in a real system.
> 
>> At that stage, we had to agree on some name
> 
> That's not true either.  There is, for example, a Python package that is 
> sometimes called "MySQLdb" and sometimes called "MySQL-Python".  So even 
> in those cases where you *are* talking about the same thing it is not 
> necessary to agree on a name.
> 
>> and if it was only the same website we 
>> downloaded the library from.
> 
> Neither is that.  The package that I referred to above is available from 
> multiple web sites.

But at some stage, it emanated from the same source, and it's ultimately 
possible to trace it back. To repeat: At some stage, there was a 
reference to the same thing.

>> This is inevitable,
> 
> Since it is not true, it is clearly not inevitable.
> 
>> and orthogonal to whether we use modules or packages.
> 
> That's not true either.  *IF* we are going to use names (and they are 
> undeniably convenient, even if not strictly necessary) then the choice 
> of whether to consider a word that appears to be the same but has 
> potentially two different meanings to be in fact two different words has 
> important practical consequences.
> 
> Consider the word "Venus" which in common usage can designate both a 
> planet and a Roman goddess.  Are "Venus" the planet and "Venus" the 
> goddess two different words, or are they the same word that can take on 
> two different meanings depending on the context?  How about Venus the 
> tennis player?  This is not a trivial problem.  It has an extensive 
> literature.  It has been debated for centuries.  (I wrote my master's 
> thesis on it.)  Getting in to the technical details would take us far 
> afield.  I'll just point out that I am able to refer to both Venus the 
> planet and Venus the Roman goddess in the same sentence without having 
> to disambiguate them as planet::venus and roman-mythology::venus.

You are funny.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-B9803A.10421514122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >> Ron Garret wrote:
> >>> In article <··············@mid.individual.net>,
> >>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>
> >>>>> Is that easy enough for you?
> >>>> You showed how to do the trivial part. That's not impressive. You have 
> >>>> to find those modules. You have to organize a way how programmer A can 
> >>>> say that he wants library L from provider B. You need to organize a 
> >>>> global naming convention for that, there is no real way around that.
> >>> You are mistaken.  Python is an existence proof that a global naming 
> >>> convention is NOT necessary.  Python's modules are named locally.  You 
> >>> and I can use the same module, and I can call that module FOO and you 
> >>> can call it BAZ.  Not only that, but you can write code that refers to 
> >>> that module as BAZ and I can use your code without modification simply 
> >>> by creating a symlink in my local file system, or by adding a single 
> >>> line of code ("import foo as baz").
> >> At some stage, there was a reference to the same thing.
> > 
> > That's not true.  We could be referring to two different things.  As 
> > long as they have the same API we can treat them *as if* they were the 
> > same thing even though in fact they are not the same thing.  For 
> > example, "Common Lisp" is ambiguous (since there are many 
> > implementations) but we don't have to resolve that ambiguity in order to 
> > have a useful discussion about it, or even to use it in a real system.
> > 
> >> At that stage, we had to agree on some name
> > 
> > That's not true either.  There is, for example, a Python package that is 
> > sometimes called "MySQLdb" and sometimes called "MySQL-Python".  So even 
> > in those cases where you *are* talking about the same thing it is not 
> > necessary to agree on a name.
> > 
> >> and if it was only the same website we 
> >> downloaded the library from.
> > 
> > Neither is that.  The package that I referred to above is available from 
> > multiple web sites.
> 
> But at some stage, it emanated from the same source, and it's ultimately 
> possible to trace it back. To repeat: At some stage, there was a 
> reference to the same thing.

No.  You're refuting the wrong example.  It is true that "MySQLdb" and 
"MySQL-python" refer to the same source.  But "Common Lisp" (which in 
certain circumstances can be referred to as "CL" without being 
misunderstood) arises from multiple sources.  There are many other 
examples: gray streams.  HTTP servers.  In fact, anything that conforms 
to a standard can be referred to by multiple names and arise from 
multiple sources.  Your claim that "You have to organize a way how 
programmer A can say that he wants library L from provider B. You need 
to organize a global naming convention for that, there is no real way 
around that." is simply false.

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qlaitFd6numU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>
>>>> Ron Garret wrote:
>>>>> In article <··············@mid.individual.net>,
>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>
>>>>>>> Is that easy enough for you?
>>>>>> You showed how to do the trivial part. That's not impressive. You have 
>>>>>> to find those modules. You have to organize a way how programmer A can 
>>>>>> say that he wants library L from provider B. You need to organize a 
>>>>>> global naming convention for that, there is no real way around that.
>>>>> You are mistaken.  Python is an existence proof that a global naming 
>>>>> convention is NOT necessary.  Python's modules are named locally.  You 
>>>>> and I can use the same module, and I can call that module FOO and you 
>>>>> can call it BAZ.  Not only that, but you can write code that refers to 
>>>>> that module as BAZ and I can use your code without modification simply 
>>>>> by creating a symlink in my local file system, or by adding a single 
>>>>> line of code ("import foo as baz").
>>>> At some stage, there was a reference to the same thing.
>>> That's not true.  We could be referring to two different things.  As 
>>> long as they have the same API we can treat them *as if* they were the 
>>> same thing even though in fact they are not the same thing.  For 
>>> example, "Common Lisp" is ambiguous (since there are many 
>>> implementations) but we don't have to resolve that ambiguity in order to 
>>> have a useful discussion about it, or even to use it in a real system.
>>>
>>>> At that stage, we had to agree on some name
>>> That's not true either.  There is, for example, a Python package that is 
>>> sometimes called "MySQLdb" and sometimes called "MySQL-Python".  So even 
>>> in those cases where you *are* talking about the same thing it is not 
>>> necessary to agree on a name.
>>>
>>>> and if it was only the same website we 
>>>> downloaded the library from.
>>> Neither is that.  The package that I referred to above is available from 
>>> multiple web sites.
>> But at some stage, it emanated from the same source, and it's ultimately 
>> possible to trace it back. To repeat: At some stage, there was a 
>> reference to the same thing.
> 
> No.  You're refuting the wrong example.  It is true that "MySQLdb" and 
> "MySQL-python" refer to the same source.  But "Common Lisp" (which in 
> certain circumstances can be referred to as "CL" without being 
> misunderstood) arises from multiple sources.  There are many other 
> examples: gray streams.  HTTP servers.  In fact, anything that conforms 
> to a standard can be referred to by multiple names and arise from 
> multiple sources.  Your claim that "You have to organize a way how 
> programmer A can say that he wants library L from provider B. You need 
> to organize a global naming convention for that, there is no real way 
> around that." is simply false.

"Everything that conforms to a standard" must name the one standard that 
it claims to conform to.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-114677.15312814122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >> Ron Garret wrote:
> >>> In article <··············@mid.individual.net>,
> >>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>
> >>>> Ron Garret wrote:
> >>>>> In article <··············@mid.individual.net>,
> >>>>>  Pascal Costanza <··@p-cos.net> wrote:
> >>>>>
> >>>>>>> Is that easy enough for you?
> >>>>>> You showed how to do the trivial part. That's not impressive. You have 
> >>>>>> to find those modules. You have to organize a way how programmer A can 
> >>>>>> say that he wants library L from provider B. You need to organize a 
> >>>>>> global naming convention for that, there is no real way around that.
> >>>>> You are mistaken.  Python is an existence proof that a global naming 
> >>>>> convention is NOT necessary.  Python's modules are named locally.  You 
> >>>>> and I can use the same module, and I can call that module FOO and you 
> >>>>> can call it BAZ.  Not only that, but you can write code that refers to 
> >>>>> that module as BAZ and I can use your code without modification simply 
> >>>>> by creating a symlink in my local file system, or by adding a single 
> >>>>> line of code ("import foo as baz").
> >>>> At some stage, there was a reference to the same thing.
> >>> That's not true.  We could be referring to two different things.  As 
> >>> long as they have the same API we can treat them *as if* they were the 
> >>> same thing even though in fact they are not the same thing.  For 
> >>> example, "Common Lisp" is ambiguous (since there are many 
> >>> implementations) but we don't have to resolve that ambiguity in order to 
> >>> have a useful discussion about it, or even to use it in a real system.
> >>>
> >>>> At that stage, we had to agree on some name
> >>> That's not true either.  There is, for example, a Python package that is 
> >>> sometimes called "MySQLdb" and sometimes called "MySQL-Python".  So even 
> >>> in those cases where you *are* talking about the same thing it is not 
> >>> necessary to agree on a name.
> >>>
> >>>> and if it was only the same website we 
> >>>> downloaded the library from.
> >>> Neither is that.  The package that I referred to above is available from 
> >>> multiple web sites.
> >> But at some stage, it emanated from the same source, and it's ultimately 
> >> possible to trace it back. To repeat: At some stage, there was a 
> >> reference to the same thing.
> > 
> > No.  You're refuting the wrong example.  It is true that "MySQLdb" and 
> > "MySQL-python" refer to the same source.  But "Common Lisp" (which in 
> > certain circumstances can be referred to as "CL" without being 
> > misunderstood) arises from multiple sources.  There are many other 
> > examples: gray streams.  HTTP servers.  In fact, anything that conforms 
> > to a standard can be referred to by multiple names and arise from 
> > multiple sources.  Your claim that "You have to organize a way how 
> > programmer A can say that he wants library L from provider B. You need 
> > to organize a global naming convention for that, there is no real way 
> > around that." is simply false.
> 
> "Everything that conforms to a standard" must name the one standard that 
> it claims to conform to.

No, it doesn't.  It just has to conform.

Even if it were necessary to name the standard (as opposed to merely 
describing it) that name would not have to be globally unique.

In fact, one can make an argument that naming things *at all* is the 
Wrong Thing to do, that the Right Thing is always to describe what you 
want (and what you provide), and that binding should be done by matching 
descriptions rather than names.  This is not my argument; this is a 
position taken by Richard Gabriel at the 2002 ILC.  In fact, I can 
vividly recall Gabriel predicting with a surprising level of vehemence 
that Lisp would win big on the Web because "the Java people are too 
stupid" (his exact words) to realize that trying to bind web services by 
name was not going to work very well.

Quite a prescient observation in retrospect.

rg
From: Matthew D Swank
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <YTc1l.2988$cL7.600@newsfe22.iad>
On Sun, 14 Dec 2008 18:25:42 +0100, Pascal Costanza wrote:

> Ron Garret wrote:
>> In article <··············@mid.individual.net>,
>>  Pascal Costanza <··@p-cos.net> wrote:
>> 
>>> Ron Garret wrote:
>>>> In article <··············@mid.individual.net>,
>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>
> You are funny.
> 
> 
> Pascal

Though Pascal has defended the orthodox view of packages ably in previous 
posts, this particular thread seems to be in danger of turning into Kenny 
v. Pascal: http://tinyurl.com/57dwh5  

I don't understand the amount of defensive invective being spewed from 
the traditional packages w/interning reader side.  The side effecting 
reader is a compromise solution designed to make property list on symbols 
usable.  

I don't think the common lisp package system is as serendipitous to 
namespace management as lisp-2.  However, I think it is fair to say that 
the lispy habit of attaching meaning to eql symbols would have to change 
under a more traditional modules system.

Sometimes I'm not sure common-lisp can evolve much more.  There are a 
bunch of very smart, motivated people on comp.lang.lisp that have an 
implacable "get off my lawn" mentality. 

There are also some smart, thoughtful people who have to decide if it is 
worth the energy to change common-lisp.  If you've drunk enough of the 
lisp kool-aid why would you want anything different.


Matt
-- 
Reply hazy, ask again later.
From: D Herring
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <49459880$0$17067$6e1ede2f@read.cnntp.org>
Matthew D Swank wrote:
> Sometimes I'm not sure common-lisp can evolve much more.  There are a 
> bunch of very smart, motivated people on comp.lang.lisp that have an 
> implacable "get off my lawn" mentality. 

Somehow, the following made it into my set of "lisp" bookmarks.
http://www.shirky.com/writings/group_enemy.html

- Daniel
From: Pascal J. Bourguignon
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <877i6245x2.fsf@informatimago.com>
Matthew D Swank <··················@gmail.com> writes:

> On Sun, 14 Dec 2008 18:25:42 +0100, Pascal Costanza wrote:
>
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>> 
>>>> Ron Garret wrote:
>>>>> In article <··············@mid.individual.net>,
>>>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>>>
>> You are funny.
>> 
>> 
>> Pascal
>
> Though Pascal has defended the orthodox view of packages ably in previous 
> posts, this particular thread seems to be in danger of turning into Kenny 
> v. Pascal: http://tinyurl.com/57dwh5  
>
> I don't understand the amount of defensive invective being spewed from 
> the traditional packages w/interning reader side.  The side effecting 
> reader is a compromise solution designed to make property list on symbols 
> usable.  
>
> I don't think the common lisp package system is as serendipitous to 
> namespace management as lisp-2.  However, I think it is fair to say that 
> the lispy habit of attaching meaning to eql symbols would have to change 
> under a more traditional modules system.
>
> Sometimes I'm not sure common-lisp can evolve much more.  There are a 
> bunch of very smart, motivated people on comp.lang.lisp that have an 
> implacable "get off my lawn" mentality. 
>
> There are also some smart, thoughtful people who have to decide if it is 
> worth the energy to change common-lisp.  If you've drunk enough of the 
> lisp kool-aid why would you want anything different.

You and we should be writting the strong AI we've been waiting for 50
years.  Then we'll be able to ask it to design the perfect language.
But in the meantime, CL is perfect in my book for we can indeed modify
it easily when it lacks in some part.   When it doesn't lack, indeed
"get off my lawn".

-- 
__Pascal Bourguignon__
From: Bob Felts
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <1iryew1.3117if1qy8sb2N%wrf3@stablecross.com>
Ron Garret <·········@flownet.com> wrote:

[...]

> 
> Consider the word "Venus" which in common usage can designate both a 
> planet and a Roman goddess.  Are "Venus" the planet and "Venus" the 
> goddess two different words, or are they the same word that can take on
> two different meanings depending on the context?  How about Venus the
> tennis player?  This is not a trivial problem.  It has an extensive 
> literature.  It has been debated for centuries.  (I wrote my master's
> thesis on it.)  Getting in to the technical details would take us far
> afield.  I'll just point out that I am able to refer to both Venus the
> planet and Venus the Roman goddess in the same sentence without having
> to disambiguate them as planet::venus and roman-mythology::venus.
> 

Yes, you can make such a reference, but that means that the sentence has
to have enough extra information so that the reader can disambiguate
each usage the way you intended it.

We know that it's terribly easy to construct sentences so that such
extra information isn't available to the reader.  In Greek, for example,
"gyne" can mean either woman or wife.  There are a number of places in
the Bible where it isn't clear which one the author meant, even with the
surrounding context.  

Since extra information is embedded in a sentence where the meaning of
Venus can be determined, doesn't it make sense to standardize how this
meta-information is embedded, so that there is no room for ambiguity?
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-C39CA1.17222414122008@news.gha.chartermi.net>
In article <···························@stablecross.com>,
 ····@stablecross.com (Bob Felts) wrote:

> Ron Garret <·········@flownet.com> wrote:
> 
> [...]
> 
> > 
> > Consider the word "Venus" which in common usage can designate both a 
> > planet and a Roman goddess.  Are "Venus" the planet and "Venus" the 
> > goddess two different words, or are they the same word that can take on
> > two different meanings depending on the context?  How about Venus the
> > tennis player?  This is not a trivial problem.  It has an extensive 
> > literature.  It has been debated for centuries.  (I wrote my master's
> > thesis on it.)  Getting in to the technical details would take us far
> > afield.  I'll just point out that I am able to refer to both Venus the
> > planet and Venus the Roman goddess in the same sentence without having
> > to disambiguate them as planet::venus and roman-mythology::venus.
> > 
> 
> Yes, you can make such a reference, but that means that the sentence has
> to have enough extra information so that the reader can disambiguate
> each usage the way you intended it.
> 
> We know that it's terribly easy to construct sentences so that such
> extra information isn't available to the reader.  In Greek, for example,
> "gyne" can mean either woman or wife.  There are a number of places in
> the Bible where it isn't clear which one the author meant, even with the
> surrounding context.  
> 
> Since extra information is embedded in a sentence where the meaning of
> Venus can be determined, doesn't it make sense to standardize how this
> meta-information is embedded, so that there is no room for ambiguity?

Absolutely.  The dispute is not over whether extra information should be 
used to disambiguate references.  The dispute is over whether this 
information should be applied during parsing (which is what packages do) 
or during compilation (which is what lexicons do) or at run-time (which 
is what Python does).

rg
From: Bob Felts
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <1iryhez.mchq8d1tojos2N%wrf3@stablecross.com>
Ron Garret <·········@flownet.com> wrote:

> In article <···························@stablecross.com>,
>  ····@stablecross.com (Bob Felts) wrote:
> 
[...]

> 
> Absolutely.  The dispute is not over whether extra information should be
> used to disambiguate references.  The dispute is over whether this 
> information should be applied during parsing (which is what packages do)
> or during compilation (which is what lexicons do) or at run-time (which
> is what Python does).
> 

That's what I get for reading a thread through a peep-hole.  Thanks for
the summary.

It's an easy dispute to settle.  Provide all three and let the
implementor choose what fits his/her needs best.  In thirty years we
might have an answer.  ;-)
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-01AEE3.21330014122008@news.gha.chartermi.net>
In article <···························@stablecross.com>,
 ····@stablecross.com (Bob Felts) wrote:

> Ron Garret <·········@flownet.com> wrote:
> 
> > In article <···························@stablecross.com>,
> >  ····@stablecross.com (Bob Felts) wrote:
> > 
> [...]
> 
> > 
> > Absolutely.  The dispute is not over whether extra information should be
> > used to disambiguate references.  The dispute is over whether this 
> > information should be applied during parsing (which is what packages do)
> > or during compilation (which is what lexicons do) or at run-time (which
> > is what Python does).
> > 
> 
> That's what I get for reading a thread through a peep-hole.  Thanks for
> the summary.
> 
> It's an easy dispute to settle.  Provide all three and let the
> implementor choose what fits his/her needs best.  In thirty years we
> might have an answer.  ;-)

Sound like a fine plan to me.

rg
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081230163646.407@gmail.com>
On 2008-12-14, Ron Garret <·········@flownet.com> wrote:
> Consider the word "Venus" which in common usage can designate both a 
> planet and a Roman goddess.

Also consider the quoted word '"Venus"' that appears in a sentence
when we're discussing the word itself, and the double-quoted word
`'"Venus"'` when we're discussing sentences about quoting.
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081230075931.968@gmail.com>
On 2008-12-14, Ron Garret <·········@flownet.com> wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
>
>> > 
>> > Is that easy enough for you?
>> 
>> You showed how to do the trivial part. That's not impressive. You have 
>> to find those modules. You have to organize a way how programmer A can 
>> say that he wants library L from provider B. You need to organize a 
>> global naming convention for that, there is no real way around that.
>
> You are mistaken.  Python is an existence proof that a global naming 
> convention is NOT necessary.  Python's modules are named locally.  You 
> and I can use the same module, and I can call that module FOO and you 
> can call it BAZ.  Not only that, but you can write code that refers to 
> that module as BAZ and I can use your code without modification simply 
> by creating a symlink in my local file system, or by adding a single 
> line of code ("import foo as baz").

So there could be two or more FOO::X identifiers in the codebase
that refer to completely different things. But FOO::X and BAR::X,
on the other hand, are exactly the same thing.

Have fun surfing that codebase with tags.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-D0C379.10464514122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-14, Ron Garret <·········@flownet.com> wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> >
> >> > 
> >> > Is that easy enough for you?
> >> 
> >> You showed how to do the trivial part. That's not impressive. You have 
> >> to find those modules. You have to organize a way how programmer A can 
> >> say that he wants library L from provider B. You need to organize a 
> >> global naming convention for that, there is no real way around that.
> >
> > You are mistaken.  Python is an existence proof that a global naming 
> > convention is NOT necessary.  Python's modules are named locally.  You 
> > and I can use the same module, and I can call that module FOO and you 
> > can call it BAZ.  Not only that, but you can write code that refers to 
> > that module as BAZ and I can use your code without modification simply 
> > by creating a symlink in my local file system, or by adding a single 
> > line of code ("import foo as baz").
> 
> So there could be two or more FOO::X identifiers in the codebase
> that refer to completely different things. But FOO::X and BAR::X,
> on the other hand, are exactly the same thing.
> 
> Have fun surfing that codebase with tags.

This one of those things that could be abused but generally isn't.  The 
fact of the matter is that people write large systems in Python and it 
mostly Just Works.

rg
From: Pascal J. Bourguignon
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <7c7i65vi2e.fsf@pbourguignon.anevia.com>
Pascal Costanza <··@p-cos.net> writes:
> [...]
> Having to list all identifiers from other packages all the time is
> very inconvenient, though, especially for large-scale programs. 

Yes, but this inconvenience gives a good incentive to the programmers
to keep the module interfaces small.


> That's
> why Wirth changed the import declaration in Oberon.  In Oberon, which
> is largely like Modula-2 with a couple of changes in detail, the only
> way to import identifiers is by importing complete modules:
>
> IMPORT SomeModule;
>
> This allows you to use identifiers from that module _qualified_, so
> inside a module that has that import declaration, you can say this:
>
> SomeModule.foo := SomeModule.bar + baz;
> (* where baz is guaranteed to be from the current module *)

This is also possible in Modula-2. 
It has always been a little disturbing for me that the syntax included both:

     FROM <module> IMPORT <symbol>{,<symbol>};
and  
                   IMPORT <module>{,<module>};

> Now there is still the inconvenience that you have to use lengthy
> module names all the time. That's why Oberon also provides something
> similar to nicknames, with an important difference though: The
> nicknames can be chose by the client modules, not by the provider
> modules. Here is an example:
>
> IMPORT SM := SomeModule, SYSTEM;

I assume  you mean:

  IMPORT SM := SomeModule;

> Now, inside this module you can refer to identifiers of SomeModule
> like this:
>
> SM.foo := SM.bar + baz;



Having to declare all the module imports at the beginning of the
source files allows to implement dependency analysis tools without a
need to parse the whole source.  I tried to do the same in CL by
defining a declaration and declaring the packages I use at the
beginning of my lisp files.  This works as long as the package used
are not determined dynamically at run-time, but then no
compilation-time dependency analysis tool can help there.

I may also add a nickname there, but it would probably be better to
declare the need for a package with such a name, and the symbols used,
and  connect the packages  adding nicknames in a separate
configuration file.


(IN-PACKAGE "COMMON-LISP-USER")
(DECLAIM (DECLARATION ALSO-USE-PACKAGES)
         (ALSO-USE-PACKAGES "COM.INFORMATIMAGO.COMMON-LISP.BSET"))
(EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE)
  (COM.INFORMATIMAGO.COMMON-LISP.PACKAGE:ADD-NICKNAME
   "COM.INFORMATIMAGO.COMMON-LISP.BSET" "BSET"))
(DEFPACKAGE "COM.INFORMATIMAGO.COMMON-LISP.BRELATION"
  (:USE "COMMON-LISP")
  (:EXPORT "PROJECT-2" "PROJECT-1" "WRITE-BRELATION" "READ-BRELATION"
           "FOR-ALL-DO" "EXISTS-1" "EXISTS" "FOR-ALL" "EXTRACT" "SELECT" "CARDINAL"
           "IS-EMPTY" "IS-NOT-EQUAL" "IS-EQUAL" "IS-STRICT-SUBSET" "IS-SUBSET"
           "COMPLEMENT" "SYM-DIFF" "INTERSECTION" "DIFFERENCE" "UNION" "ASSIGN"
           "ASSIGN-ELEMENT" "ASSIGN-EMPTY" "CLOSURE" "GET-CYCLICS" "IS-CYCLIC"
           "HAS-REFLEXIVE" "IS-EQUIVALENCE" "IS-TRANSITIVE" "IS-SYMMETRIC"
           "IS-REFLEXIVE" "IS-TRANSITIVE-1" "IS-REFLEXIVE-1" "IS-RELATED" "IS-ELEMENT"
           "EXCLUDE" "INCLUDE" "MAKE-BRELATION" "BRELATION")
  (:SHADOW "COMPLEMENT" "INTERSECTION" "UNION")
  (:IMPORT-FROM "COM.INFORMATIMAGO.COMMON-LISP.UTILITY" "VECTOR-INIT" "FOR")
  (:DOCUMENTATION
   "This package implements a relation abstract data type
    based on an array of bset.
    It can represent only relations between two positive
    and bounded integers.

    Copyright Pascal J. Bourguignon 2004 - 2004
    This package is provided under the GNU General Public License.
    See the source file for details."))
(IN-PACKAGE "COM.INFORMATIMAGO.COMMON-LISP.BRELATION")


(DEFSTRUCT (BRELATION (:CONSTRUCTOR %MAKE-BRELATION))
  (ADJSETS (MAKE-ARRAY '(0) :ELEMENT-TYPE 'BSET:BSET
                       :initial-element (bset:make-bset 0))
           :TYPE (ARRAY BSET:BSET (*)))
  (SIZE-1 0 :TYPE (INTEGER 0))
  (SIZE-2 0 :TYPE (INTEGER 0)))

...


> Having used all of Modula-2, Oberon, Java and Common Lisp for quite a
> while, I am convinced that Oberon's approach is the most elegant one,
> the most convenient to use, while guaranteeing the highest degree of
> clash freeness - except that it should handle import and export of
> symbols like in Common Lisp, not of bindings.
>
> The added benefit of Oberon's approach is that it's very easy to
> replace modules that some module uses. In the above example, it's very
> easy to say this:
>
> IMPORT SM := SomeOtherVersionOfSomeModule, SYSTEM;
>
> ...and then just recompile. Very nice for testing, very nice for
> dealing with different versions of the same library.


It would be even easier if the binding SM <-> ActualModule
wasn't done in the source, but in the configuration.


> We wouldn't be able to blindly reuse Oberon's module system in an
> imaginary new version of the Common Lisp standard. But if I were to
> make decisions for how to change Common Lisp's package system, I would
> try to change the following:
>
> + There shouldn't be an option anymore to import all symbols from some
> other package by just saying :use or use-package. (I totally agree
> with Kaz here.)
>
> + The common-lisp package should have special status. It may be a good
> idea that not all 700, or so, symbols are exported from common-lisp as
> is the case in current ANSI Common Lisp, but the size should rather be
> something along the lines of ISLISP, and everything else should be put
> in some standard library package. But that's a detail and not
> immensely important. What's important is that common-lisp should be a
> privileged package whose symbols I can just use without qualifying
> them. (:use / use-package could be allowed for common-lisp, for
> example, but restricted to that one package.)

Ok, IF you allow the programmer to define his own "priviledged" packages.
I want to be able to write:

(defpackage "PGM"
  (:use "PJB-LISP"))

and use PJB-LISP instead of COMMON-LISP.

  
> + There should be a new option to import all symbols from some other
> package :import-package / import-package, which allows you to use all
> those symbols _qualified_. So after an (import-package :some-package),
> you can say both some-package:foo and some-package::internal-foo, but
> not otherwise. There should be a way to assign a package-local
> nickname for that other package. So after an (import-package
> :some-package :sp), you can say sp:foo and sp::internal-foo, but not
> otherwise. References to some-other-package:bar or
> some-other-package::bar without a corresponding :import-package /
> import-package should be disallowed, or at least deprecated (with a
> warning).
>
> + For backwards compatibility, :import-from / import should still be
> supported, which allows for Modula-2-style imports.
>
>
> The advantages would be:
>
> + Name clashes are minimized even further.
>
> + There cannot be clashes anymore because of carelessly chosen
> nicknames. Nicknames are strictly local and not global
> anymore. Nicknames announced using the current package system could be
> deprecated.


(defpackage P1
  (:from-package DD :need (S1 S3 S5))
  ...)

(defpackage P2
  (:from-package DD :need (S1 S2 S3))
  ...)

(defpackage D1
  (:export S1 S2 S3 S4 S5))

(defpackage D2
  (:export S1 S2 S3 S4))

(declare-nickname :in P1 :use D1 :as DD)
(declare-nickname :in P2 :use D2 :as DD)

(load "p1.lisp")
(load "p2.lisp")


Checks could also be done to match needed vs. exported symbol lists,
and trying to read a DD:SYMBOL-NOT-DECLARED-NEEDED would signal a
continuable error.


> + It is always clear where a symbol comes from either directly from
> the source code, or by looking at the package declaration. No
> ambiguities anymore, as is currently still possible.
>
> + The usefulness of the current package system, to make very
> fine-grained distinctions using symbols, is still maintained. No need
> to throw the baby out with the bathwater.
>
> + An added benefit is that system definition utilities could now be
> based on (or use information from) package declarations, since the
> relationships between packages become unambiguous.
>
>
> The disadvantages would be:
>
> + Existing code has to be modified: If there are "wild" qualified
> references to symbols from other packages (like in some-package:foo),
> corresponding :import-package declarations have to be added to the
> corresponding packages. The overhead should be very mild, since this
> can be supported by Common Lisp compilers with the appropriate
> warnings / error messages.
>
> + If there are unqualified references to symbols implicitly imported
> by :use / use-package declarations, the workload for upgrading
> existing libraries is higher. That's why it may be a good idea to only
> deprecate :use / use-package, and not just suddenly completely remove
> it. (There is a potential for political tension here, because vendors
> may want to have similar privileged status for their
> implementation-specific extensions like Common Lisp would provide for
> the common-lisp package. I don't immediately see a good solution
> here.)

Yes, see above, we would need a way to declare a priviledged package.


+ There's some level of over-engineering here.

+ It's good only as long as all the symbols are statically determined.

+ We still need to think it out, read-time wise.  Consider the
  declare-nickname example above.  Should (defpackage (:from-package
  :need)) impact the readtable so we can read the defined package
  right away, before declaring the nickname / package binding?

+ I remember passing a lot of time establising the lists of imported
  symbols when programming in Modula-2... Current defpackage :use
  option is not so bad.


> Just my 0.02� (a much better currency these days... ;)
>
>
> Pascal

-- 
__Pascal Bourguignon__
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081227031023.751@gmail.com>
On 2008-12-07, Ron Garret <·········@flownet.com> wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
>
>> Ron Garret wrote:
>> > In article <··············@mid.individual.net>,
>> >  Pascal Costanza <··@p-cos.net> wrote:
>> > 
>> >> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
>> >> the problem better than modules, i.e. managing the mapping from 
>> >> identifiers to concepts.
>> > 
>> > Why?
>> 
>> Because they can make distinctions that you cannot make with module 
>> systems. For example, if you had only a module system, a class would not 
>> be able to inherit from two different classes with slots of the same 
>> name and be able to keep them as two different slots (unless you come up 
>> with funky renaming mechanisms, like in the R6RS module system, for 
>> example).
>
> That's true, but how often do you actually do multiple inheritance from 
> two different classes that were separately developed?

It's not a problem only for multiple inheritance (base-base clash) but also for
single inheritance (base-derived clash).   And it doesn't involve just
immediate superclasses.

Remember that in CLOS, slots of the same name override each other (a damn
useful behavior). If the superclass has a slot FOO, and the subclass has a slot
FOO, there is only one slot FOO.  You can change the :allocation of a slot
under inheritance, too. Perhaps in the base class, assigning to a slot FOO only
changs FOO in that instance. The derived one spcifies :ALLOCATION :CLASS, so
changing FOO mutates it in every instance of that class. Or vice versa.

Think this is only a potential problem for someone writing a new derived
class? Think again.

Suppose that I have a base class which is widely inherited already in a large
program.  I would like to add a slot to this class, so I pick the name FOO.
Now I have to search the entire class hierarchy subclasses from my class
to see if someone is already using that slot name.

Solution: name the slot using the private symbol MYPACKAGE::FOO.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-4FDCC6.12321711122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> Suppose that I have a base class which is widely inherited already in a large
> program.  I would like to add a slot to this class, so I pick the name FOO.
> Now I have to search the entire class hierarchy subclasses from my class
> to see if someone is already using that slot name.

No you don't.  All you have to do is call CLASS-SLOTS.

> Solution: name the slot using the private symbol MYPACKAGE::FOO.

There is no guarantee that this slot does not already exist unless you 
have complete control over the contents of MYPACKAGE.  By extension, for 
this solution to be effective, every Lisp programmer in the world who 
ever collaborates with someone else needs their own private package (and 
probably a different private package for each project they work on).  
And because the package namespace is global you need a planet-wide 
mechanism for managing package names.  So you can't use a package named 
MYPACKAGE and expect that to work because sooner or later you'll collide 
with someone else's MYPACKAGE.  It would have to be 
com.gmail.kkylheku.mypackage or something like that.  To really be sure, 
every package anyone uses anywhere in the world would need to have a 
GUID.

There is effectively no difference between that and just choosing a 
naming convention that forces all programmers to only use symbols with a 
unique prefix in a totally flat namespace, particularly since you are an 
advocate of explicit importation of every symbol you want to use from 
another package.  Instead of

(import com.gmail.kkylheku.mypackage::foo *package*)

(slot-value thing 'foo)

you would do:

(symbol-macrolet ((foo 'com.gmail.kkylheku.mypackage-foo))
  ...
  (slot-value thing foo)  ; Note foo is unquoted here
  ...
)

Now you have the exact same effect without packages, just a single, flat 
global namespace.  Instead of having "foo" mapped onto 
com.gmail.kkylheku.mypackage::foo by the reader, you have foo mapped 
into com.gmail.kkylheku.mypackage-foo by the compiler.  But the net 
effect is exactly the same in both cases, both in terms of avoiding name 
clashes, and in terms of how much typing you have to do.

BTW, I was going to mention this earlier but I'll do it now: since you 
believe that USE-PACKAGE is a Bad Thing, how exactly am I supposed to 
make my own package and still be able to use Common Lisp?  Do I have to 
explicitly import all of the 700 or so symbols in the common-lisp 
package into my package every time?  That seems like quite a burden.

rg
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081227093456.86@gmail.com>
On 2008-12-11, Ron Garret <·········@flownet.com> wrote:
> In article <··················@gmail.com>,
>  Kaz Kylheku <········@gmail.com> wrote:
>
>> Suppose that I have a base class which is widely inherited already in a large
>> program.  I would like to add a slot to this class, so I pick the name FOO.
>> Now I have to search the entire class hierarchy subclasses from my class
>> to see if someone is already using that slot name.
>
> No you don't.  All you have to do is call CLASS-SLOTS.

You don't necessarily have the source code to the entire class hirearchy.
Suppose you're shipping a class library. Add a slot, and some users
may experience a clash when they try your next release.

> BTW, I was going to mention this earlier but I'll do it now: since you 
> believe that USE-PACKAGE is a Bad Thing, how exactly am I supposed to 
> make my own package and still be able to use Common Lisp?

I don't re-iterate everything when this comes up. USE-PACKAGE is okay if you
are inheriting from a stable namespace. The danger is that the namespace is a
moving target.

I wonder what will happen to the CL namespace when one day there is a new ANSI
Lisp standard.

I will firmly advocate the position that the "COMMON-LISP" namespace and its
nickname "CL" should always provide only those symbols defined in the 1994
standard.

Anything new should be in a package called "COMMON-LISP-<year>".

> Do I have to 
> explicitly import all of the 700 or so symbols in the common-lisp 
> package into my package every time?  That seems like quite a burden.

USE-PACKAGE is okay for CL.

But even so, it's not hard to loop over the symbols exported from CL to create
a list, which you can then cut and paste into a :USE clause in your defpackage.

Weren't you just advocating the use of CLASS-SLOTS in a similar way?

At least this is generally feasible, since you actually have the entire package
that you're thinking of using.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-28C9DA.00505912122008@news.gha.chartermi.net>
In article <·················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-11, Ron Garret <·········@flownet.com> wrote:
> > In article <··················@gmail.com>,
> >  Kaz Kylheku <········@gmail.com> wrote:
> >
> >> Suppose that I have a base class which is widely inherited already in a 
> >> large
> >> program.  I would like to add a slot to this class, so I pick the name 
> >> FOO.
> >> Now I have to search the entire class hierarchy subclasses from my class
> >> to see if someone is already using that slot name.
> >
> > No you don't.  All you have to do is call CLASS-SLOTS.
> 
> You don't necessarily have the source code to the entire class hirearchy.
> Suppose you're shipping a class library. Add a slot, and some users
> may experience a clash when they try your next release.

Ah, good point.  Hadn't thought of that.  I'm pretty sure this has a 
straightforward solution though.  (General strategy is to rewrite slot 
names like Pascal suggested.  I don't believe it's very difficult.  I'd 
do it on the spot if it weren't 1 AM.)

> > BTW, I was going to mention this earlier but I'll do it now: since you 
> > believe that USE-PACKAGE is a Bad Thing, how exactly am I supposed to 
> > make my own package and still be able to use Common Lisp?
> 
> I don't re-iterate everything when this comes up. USE-PACKAGE is okay if you
> are inheriting from a stable namespace. The danger is that the namespace is a
> moving target.

That seems to be at odds with what you said before:

"USE-PACKAGE is a braindamaged concept borrowed from other languages. 
The proper engineering solution is to maintain explicit import lists..."

> I wonder what will happen to the CL namespace when one day there is a new 
> ANSI Lisp standard.

I don't know what will happen to the namespace, but I'll wager that when 
there is a new ANSI Lisp standard, pigs will fly.

> I will firmly advocate the position that the "COMMON-LISP" namespace and its
> nickname "CL" should always provide only those symbols defined in the 1994
> standard.
> 
> Anything new should be in a package called "COMMON-LISP-<year>".

That sort of slavish devotion to backwards-compatibility is the reason 
that Windows (and the x86 architecture for that matter) is the mess that 
it currently is.

> > Do I have to 
> > explicitly import all of the 700 or so symbols in the common-lisp 
> > package into my package every time?  That seems like quite a burden.
> 
> USE-PACKAGE is okay for CL.

Your position on this is a bit of a moving target.

> But even so, it's not hard to loop over the symbols exported from CL to 
> create
> a list, which you can then cut and paste into a :USE clause in your 
> defpackage.

That only works because the symbols exported from CL don't change.  The 
list of symbols exported from libraries that are not moribund may change.

> Weren't you just advocating the use of CLASS-SLOTS in a similar way?

No, I don't think so.  But it's a moot point since what I was advocating 
doesn't work.

rg
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081227033656.614@gmail.com>
On 2008-12-07, Ron Garret <·········@flownet.com> wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
>
>> Ron Garret wrote:
>> > In article <··············@mid.individual.net>,
>> >  Pascal Costanza <··@p-cos.net> wrote:
>> > 
>> >> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
>> >> the problem better than modules, i.e. managing the mapping from 
>> >> identifiers to concepts.
>> > 
>> > Why?
>> 
>> Because they can make distinctions that you cannot make with module 
>> systems. For example, if you had only a module system, a class would not 
>> be able to inherit from two different classes with slots of the same 
>> name and be able to keep them as two different slots (unless you come up 
>> with funky renaming mechanisms, like in the R6RS module system, for 
>> example).
>
> That's true, but how often do you actually do multiple inheritance from 
> two different classes that were separately developed?
>
> BTW, because the current implementation of lexicons is tightly coupled 
> with packages it is fairly straightforward to "fix" this.  I put "fix" 
> in scare quotes because it's not at all clear to me that this is 
> actually a problem, but if it really is then you can just have LDEFCLASS 
> lexify the slot names along with the superclasses, e.g.:
>
> (defmacro ldefclass (name superclasses slots &rest stuff &environment 
> env)
>   `(progn
>      (lexify ,name)
>      (defclass ,(lbind name (env-lexicon env))
>        ,(mapcar (lambda (c) (or (find-cell (env-lexicon env) c)
>                                 (error "There is no class named ~S in 
> the current lexical environment." c)))
>                 superclasses)
>        ,(mapcar (lambda (s) (lbind s (env-lexicon env))) slots)
>        ,@stuff)))
>
> (defmacro lslot-value (instance slot-name &optional lexicon &environment 
> env)
>   `(slot-value ,instance ,(ref-form slot-name (or (find-lexicon lexicon) 
> (env-lexicon env)))))
>
>> With a CL-style package system, the choice is always unambiguous: If you 
>> use the same symbol as somebody else, you definitely mean the same 
>> concept. If you want to denote a different concept, you have to use a 
>> different symbol. It's much harder to make such distinctions with module 
>> systems.
>
> That is not quite a fair argument.  It's true, but only because CL uses 
> symbols as slot names.  That stacks the deck in favor of packages.

Yeah, if Lisp used dumb strings for naming things, that would stack
the deck in the favor of related dumb hacks like modules, wouldn't it.

> One 
> could easily envision a minor variation on CLOS that used abstract slot 
> identifier objects instead of symbols as slot names, and had lexically 

Although any object can be exploited for its EQ equality in order
to identify, not all objects in Lisp have useful interning semantics
under the reader.

> scoped bindings of identifiers onto abstract slot identifiers. 

This already exists in the form of the widely used WITH-SLOTS macro.

  (with-slots ((f foo) (b bar))) obj
    ;; now we have lexical F and B representing
    ;; slots FOO and BAR of obj.
    )

But the above relies on the interning of FOO and BAR.

If slots were named by any objects whatsoever, how would you actually write the
code to map some lexical identifier to the abstract slot?

> But there's a more serious critique of your argument as well:  It's true 
> that "If you use the same symbol as somebody else, you definitely mean 
> the same concept."  However, because *package* is a global resource 
> which can be manipulated in various ways, then unless you fully qualify 

COMPILE-FILE and LOAD take care to save and restore *package*.

> every single symbol in your code (which no one ever does) you have to 
> carefully manage *package* in order to insure that all the references to 

Only read-time or compile-time manipulation of *package* can change 
where your code is interning symbols.

In your module of code, just write the (in-package ...) top-level form
somewhere near the top. Then things are read against the package.

It's conceivable that some nasty macro could change the value or contents 
of *package* (i.e. nasty because the documented purpose of that macro
is not related to doing anything with packages).

Oh well!

Since Lisp gives us full power of the language at macro-expansion time, no
scoping system with exposed data structures is immune to such interference.

> FOO that are supposed to be the same are in fact the same, and 
> vice-versa.  This is certainly doable, but I would claim that it's a 
> non-trivial burden on the programmer, particularly an inexperienced one.
>
> rg
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-CB0DE1.12523311122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> > That is not quite a fair argument.  It's true, but only because CL uses 
> > symbols as slot names.  That stacks the deck in favor of packages.
> 
> Yeah, if Lisp used dumb strings for naming things, that would stack
> the deck in the favor of related dumb hacks like modules, wouldn't it.

Just calling something dumb doesn't make it so.

> 
> > One 
> > could easily envision a minor variation on CLOS that used abstract slot 
> > identifier objects instead of symbols as slot names, and had lexically 
> 
> Although any object can be exploited for its EQ equality in order
> to identify, not all objects in Lisp have useful interning semantics
> under the reader.

So what?  Why is it so important that the reader do the work?

Note by the way that the Lisp reader can produce some surprising 
results, e.g.:

P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
T
P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
NIL

How this can happen is left as an exercise for the reader (no pun 
intended).

> 
> > scoped bindings of identifiers onto abstract slot identifiers. 
> 
> This already exists in the form of the widely used WITH-SLOTS macro.
> 
>   (with-slots ((f foo) (b bar))) obj
>     ;; now we have lexical F and B representing
>     ;; slots FOO and BAR of obj.
>     )
> 
> But the above relies on the interning of FOO and BAR.
> 
> If slots were named by any objects whatsoever, how would you actually write 
> the
> code to map some lexical identifier to the abstract slot?

(let ((identifier (find-slot-identifier class slot-description)))
  (slot-value instance identifier))

You can actually do this in standard CL by using uninterned symbols for 
slot names, and using e.g.

(defun find-slot-identifier (class description)
  (find description (class-slots class) :test 'string-equal :key 
'slot-name))

or something like that.

> > But there's a more serious critique of your argument as well:  It's true 
> > that "If you use the same symbol as somebody else, you definitely mean 
> > the same concept."  However, because *package* is a global resource 
> > which can be manipulated in various ways, then unless you fully qualify 
> 
> COMPILE-FILE and LOAD take care to save and restore *package*.
> 
> > every single symbol in your code (which no one ever does) you have to 
> > carefully manage *package* in order to insure that all the references to 
> 
> Only read-time or compile-time manipulation of *package* can change 
> where your code is interning symbols.
> 
> In your module of code, just write the (in-package ...) top-level form
> somewhere near the top. Then things are read against the package.
> 
> It's conceivable that some nasty macro could change the value or contents 
> of *package* (i.e. nasty because the documented purpose of that macro
> is not related to doing anything with packages).
> 
> Oh well!
> 
> Since Lisp gives us full power of the language at macro-expansion time, no
> scoping system with exposed data structures is immune to such interference.


You think too much like a C++ programmer.  In Lisp it is not necessarily 
the case that all code is contained in files and compiled all at once 
before the program is run.  In fact, code can be and often is compiled 
at run-time, at which time the reader may be used to parse not only code 
but data as well.  Run-time manipulation of *package* (and *readtable* 
for that matter) are not "nasty", they are standard (albeit advanced) 
coding techniques in Lisp.

rg
From: Rob Warnock
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <NsSdnYd1YdulYNzUnZ2dnUVZ_oPinZ2d@speakeasy.net>
Ron Garret  <·········@flownet.com> wrote:
+---------------
| Note by the way that the Lisp reader can produce some surprising 
| results, e.g.:
| 
| P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
| T
| P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
| NIL
| 
| How this can happen is left as an exercise for the reader
| (no pun intended).
+---------------

O.k, I give up. How?!?  [Assuming that those *are* indeed
successive REPL commands with no intervening operations...]


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081227175406.535@gmail.com>
On 2008-12-12, Rob Warnock <····@rpw3.org> wrote:
> Ron Garret  <·········@flownet.com> wrote:
> +---------------
>| Note by the way that the Lisp reader can produce some surprising 
>| results, e.g.:
>| 
>| P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
>| T
>| P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
>| NIL
>| 
>| How this can happen is left as an exercise for the reader
>| (no pun intended).
> +---------------
>
> O.k, I give up. How?!?  [Assuming that those *are* indeed
> successive REPL commands with no intervening operations...]

Ditto. I have not been able to solve the puzzle of how there can be a
read-print inconsistency over FOO, but not over BAR (short of some very dirty
readtable manipulation or something).

There is no manipulation of *package*, *readtable*, or the objects
they point to.

Some combination of *print-case* and readtable-case will probably
do it, but for both BAZ and FOO alike.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-08277D.00174012122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-12, Rob Warnock <····@rpw3.org> wrote:
> > Ron Garret  <·········@flownet.com> wrote:
> > +---------------
> >| Note by the way that the Lisp reader can produce some surprising 
> >| results, e.g.:
> >| 
> >| P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
> >| T
> >| P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
> >| NIL
> >| 
> >| How this can happen is left as an exercise for the reader
> >| (no pun intended).
> > +---------------
> >
> > O.k, I give up. How?!?  [Assuming that those *are* indeed
> > successive REPL commands with no intervening operations...]
> 
> Ditto. I have not been able to solve the puzzle of how there can be a
> read-print inconsistency over FOO, but not over BAR (short of some very dirty
> readtable manipulation or something).
> 
> There is no manipulation of *package*, *readtable*, or the objects
> they point to.
> 
> Some combination of *print-case* and readtable-case will probably
> do it, but for both BAZ and FOO alike.

[···@mickey:~]$ clisp
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2006

[1]> (make-package :p1)
#<PACKAGE P1>
[2]> (make-package :p2)
#<PACKAGE P2>
[3]> (setf s '#:foo)
#:FOO
[4]> (import s :p1)
T
[5]> (import s :p2)
T
[6]> (unintern s :p1)
T
[7]> (in-package :p2)
#<PACKAGE P2>
P2[8]> 'foo
#:FOO
P2[9]> 'baz
BAZ
P2[10]>
From: Rob Warnock
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <studnU3FrN0JtN_UnZ2dnUVZ_vednZ2d@speakeasy.net>
Ron Garret  <·········@flownet.com> wrote:
+---------------
|  Kaz Kylheku <········@gmail.com> wrote:
| > Rob Warnock <····@rpw3.org> wrote:
| > > Ron Garret  <·········@flownet.com> wrote:
| > >| P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
| > >| T
| > >| P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
| > >| NIL
| > >| 
| > >| How this can happen is left as an exercise for the reader
| > >| (no pun intended).
| > >
| > > O.k, I give up. How?!?  [Assuming that those *are* indeed
| > > successive REPL commands with no intervening operations...]
| > 
| > Ditto. I have not been able to solve the puzzle of how there can be a
| > read-print inconsistency over FOO, but not over BAR (short of some
| > very dirty readtable manipulation or something).
...
| [···@mickey:~]$ clisp
...
| [1]> (make-package :p1)
| #<PACKAGE P1>
| [2]> (make-package :p2)
| #<PACKAGE P2>
| [3]> (setf s '#:foo)
| #:FOO
| [4]> (import s :p1)
| T
| [5]> (import s :p2)
| T
| [6]> (unintern s :p1)
| T
| [7]> (in-package :p2)
| #<PACKAGE P2>
| P2[8]> 'foo
| #:FOO
| P2[9]> 'baz
| BAZ
| P2[10]>
+---------------

Wow!! That's *really* nasty!!  Worse, now that you've shown the
basic pattern, I find that I can duplicate it[1] *much* more simply:

    cmu> (make-package :p1)

    #<The P1 package, 0/9 internal, 0/9 external>
    cmu> (import 'p1::foo)

    T
    cmu> (unintern 'p1::foo :p1)

    T
    cmu> 'foo

    #:FOO
    cmu> 

Ugh.


-Rob

[1] In CMUCL, at least. Neither your example nor mine works in
    the really ancient CLISP-2.29 I have handy (probably because
    recent versions are more ANSI compatible).

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qeoetFc8f39U1@mid.individual.net>
Rob Warnock wrote:
> Ron Garret  <·········@flownet.com> wrote:
> +---------------
> |  Kaz Kylheku <········@gmail.com> wrote:
> | > Rob Warnock <····@rpw3.org> wrote:
> | > > Ron Garret  <·········@flownet.com> wrote:
> | > >| P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
> | > >| T
> | > >| P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
> | > >| NIL
> | > >| 
> | > >| How this can happen is left as an exercise for the reader
> | > >| (no pun intended).
> | > >
> | > > O.k, I give up. How?!?  [Assuming that those *are* indeed
> | > > successive REPL commands with no intervening operations...]
> | > 
> | > Ditto. I have not been able to solve the puzzle of how there can be a
> | > read-print inconsistency over FOO, but not over BAR (short of some
> | > very dirty readtable manipulation or something).
> ...
> | [···@mickey:~]$ clisp
> ...
> | [1]> (make-package :p1)
> | #<PACKAGE P1>
> | [2]> (make-package :p2)
> | #<PACKAGE P2>
> | [3]> (setf s '#:foo)
> | #:FOO
> | [4]> (import s :p1)
> | T
> | [5]> (import s :p2)
> | T
> | [6]> (unintern s :p1)
> | T
> | [7]> (in-package :p2)
> | #<PACKAGE P2>
> | P2[8]> 'foo
> | #:FOO
> | P2[9]> 'baz
> | BAZ
> | P2[10]>
> +---------------
> 
> Wow!! That's *really* nasty!!  Worse, now that you've shown the
> basic pattern, I find that I can duplicate it[1] *much* more simply:
> 
>     cmu> (make-package :p1)
> 
>     #<The P1 package, 0/9 internal, 0/9 external>
>     cmu> (import 'p1::foo)
> 
>     T
>     cmu> (unintern 'p1::foo :p1)
> 
>     T
>     cmu> 'foo
> 
>     #:FOO
>     cmu> 
> 
> Ugh.

The wording in the HyperSpec doesn't exactly promote the use of unintern 
as a regular tool to be used extensively in Lisp programs.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rob Warnock
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <Zd2dnXy-PKhfsN_UnZ2dnUVZ_jKdnZ2d@speakeasy.net>
Pascal Costanza  <··@p-cos.net> wrote:
+---------------
| Rob Warnock wrote:
| > Wow!! That's *really* nasty!!  Worse, now that [RonG has] shown the
| > basic pattern, I find that I can duplicate it *much* more simply:
...
| The wording in the HyperSpec doesn't exactly promote the use of
| unintern as a regular tool to be used extensively in Lisp programs.
+---------------

Yes, well, as the saying goes, it wasn't so much that the pig could
sing well; it was that it could sing at all.

And as long as we're misusing aphorisms: If only fools use UNINTERN,
then it *will* get used, and when you least expect it...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qhmaoFcjq84U1@mid.individual.net>
Rob Warnock wrote:
> Pascal Costanza  <··@p-cos.net> wrote:
> +---------------
> | Rob Warnock wrote:
> | > Wow!! That's *really* nasty!!  Worse, now that [RonG has] shown the
> | > basic pattern, I find that I can duplicate it *much* more simply:
> ...
> | The wording in the HyperSpec doesn't exactly promote the use of
> | unintern as a regular tool to be used extensively in Lisp programs.
> +---------------
> 
> Yes, well, as the saying goes, it wasn't so much that the pig could
> sing well; it was that it could sing at all.
> 
> And as long as we're misusing aphorisms: If only fools use UNINTERN,
> then it *will* get used, and when you least expect it...

I think you're overrating the potential for real problems here...


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-EB0867.08305212122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> The wording in the HyperSpec doesn't exactly promote the use of unintern 
> as a regular tool to be used extensively in Lisp programs.

How else would you recover from a situation where a typo at the REPL 
caused a symbol to be interned that you didn't want to have interned?

rg
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qhn5dFcivhkU1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> The wording in the HyperSpec doesn't exactly promote the use of unintern 
>> as a regular tool to be used extensively in Lisp programs.
> 
> How else would you recover from a situation where a typo at the REPL 
> caused a symbol to be interned that you didn't want to have interned?

When you're trying to recover from a typo, you haven't exported/imported 
that one symbol yet to/from other packages. So no harm done.


Aside: The nameclashes caused by module systems are real problems in 
other languages that can cause real headaches, as experienced by 
programmers in such languages. The problems you describe with the CL 
package system are transient, it's always possible to resolve them, 
without compromising elegance. On top of that, we don't have extensive 
knowledge with lexicons in Common Lisp, so we cannot judge yet how well 
it really works. However, what we can tell is that there have been a lot 
of proposals for module systems in Scheme, with no clear winner and a 
lot of arguing among Schemers what the best approach is. The current 
agreement seems to be the one suggested in R6RS, and that one is a mess.

I am not opposing lexicons, it's good that there is experimentation with 
alternative approaches. But I think it's good that we have something 
that works reasonably well, with no serious deficiencies, with 
admittedly some not-so-perfect corner cases, which however don't seem to 
be serious show stoppers.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-6EA788.13485713122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Ron Garret wrote:
> > In article <··············@mid.individual.net>,
> >  Pascal Costanza <··@p-cos.net> wrote:
> > 
> >> The wording in the HyperSpec doesn't exactly promote the use of unintern 
> >> as a regular tool to be used extensively in Lisp programs.
> > 
> > How else would you recover from a situation where a typo at the REPL 
> > caused a symbol to be interned that you didn't want to have interned?
> 
> When you're trying to recover from a typo, you haven't exported/imported 
> that one symbol yet to/from other packages. So no harm done.

No, but you have created a potential name conflict.

Actually, "typo" wasn't really the right word.  The real problems arise 
when you load some code that is supposed to use a package before that 
package is loaded.  Now you have a bunch of (conflicting) symbols 
interned in the client package.  For example:

? (make-package :p1)
#<Package "P1">
? (in-package :p1)
#<Package "P1">
? (defun library-function () 'p1-lib-result)
LIBRARY-FUNCTION
? (export 'library-function)
T
? (make-package :p2)
#<Package "P2">
? (in-package :p2)
#<Package "P2">
? (defun foo () (library-function))
;Compiler warnings :
;   Undefined function LIBRARY-FUNCTION, in FOO.
FOO
? (use-package :p1)
> Error: Using #<Package "P1"> in #<Package "P2"> 
>        would cause name conflicts with symbols already present in that package: 
>        LIBRARY-FUNCTION  P1:LIBRARY-FUNCTION


> Aside: The nameclashes caused by module systems are real problems in 
> other languages that can cause real headaches, as experienced by 
> programmers in such languages.

So what?  That just means that all those other languages are broken too.

BTW, I've been doing a lot of Python programming lately.  Python has a 
very unsophisticated module system, but I've never encountered a 
nameclash problem.  Not once.  In fact, I've never seen a report of a 
nameclash problem on c.l.python.

By way of contrast, there is a steady stream of newbies having problems 
with packages in c.l.l.  When you do a Google search for "Python 
modules" the first result is the global module index, but when you 
search for "lisp packages" the first result is 
http://www.flownet.com/ron/packages.pdf .  It's hard to explain the 
popularity of a paper entitled "The Complete Idiot's Guide to Common 
Lisp Packages" if no one is having any problems with them.

> The problems you describe with the CL 
> package system are transient, it's always possible to resolve them, 
> without compromising elegance.

That depends on your definition of "elegance."  Having a parser with 
global side-effects strikes me as horribly inelegant (to say nothing of 
a language that boasts about having user-modifiable syntax, but lets you 
change everything *except* the part that introduces those global 
side-effects).

> On top of that, we don't have extensive 
> knowledge with lexicons in Common Lisp, so we cannot judge yet how well 
> it really works. However, what we can tell is that there have been a lot 
> of proposals for module systems in Scheme, with no clear winner and a 
> lot of arguing among Schemers what the best approach is. The current 
> agreement seems to be the one suggested in R6RS, and that one is a mess.

All of R6RS is a mess.  So what?  Just because the Scheme community is 
screwed up does not mean that better solutions are impossible.

> I am not opposing lexicons, it's good that there is experimentation with 
> alternative approaches. But I think it's good that we have something 
> that works reasonably well, with no serious deficiencies, with 
> admittedly some not-so-perfect corner cases, which however don't seem to 
> be serious show stoppers.

One could make the exact same argument for *any* programming language 
with a large code base, including C++ and Java.  Whatever problems those 
languages may have, manifestly none of them are show-stoppers since the 
show has manifestly not been stopped.  Whether or not a language 
deficiency is "serious" (or even a deficiency) is to some extent a 
matter of personal taste.

It does not follow that Lexicons are not an improvement by some 
reasonable quality metric, even though you may not find that quality 
metric to your personal liking.

rg
From: Raffael Cavallaro
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <2008121318031843658-raffaelcavallaro@pasespamsilvousplaitmaccom>
On 2008-12-13 16:48:57 -0500, Ron Garret <·········@flownet.com> said:

> Having a parser with
> global side-effects strikes me as horribly inelegant (to say nothing of
> a language that boasts about having user-modifiable syntax, but lets you
> change everything *except* the part that introduces those global
> side-effects).

Absolutely. Rich Hickey's Clojure has a reader that does *not* have 
side effects. I.e., it is generally recognized by lisp users who don't 
want to spend time pulling their hair out in frustration that if we 
were starting over from scratch today (which luxury Rich Hickey has) 
that we would design the lisp reader to be side effect free.



-- 
Raffael Cavallaro, Ph.D.
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081229160905.773@gmail.com>
On 2008-12-13, Raffael Cavallaro <················@pas.espam.s.il.vous.plait.mac.com> wrote:
> On 2008-12-13 16:48:57 -0500, Ron Garret <·········@flownet.com> said:
>
>> Having a parser with
>> global side-effects strikes me as horribly inelegant (to say nothing of
>> a language that boasts about having user-modifiable syntax, but lets you
>> change everything *except* the part that introduces those global
>> side-effects).
>
> Absolutely. Rich Hickey's Clojure has a reader that does *not* have 
> side effects. I.e., it is generally recognized by lisp users who don't 

I don't believe it. A reader requires side effects. Without the side effect of
interning a symbol, two occurences of X won't be recognized as the same object.

You can localize some of the effects so that they are scoped within
a form. I se that Clojure has some NAME# notation, where the # makes gensyms
for you in a backquote so that multiple occurences of X# are the same symbol,
but the X is forgotten when that form is read.

We can do this in CL by setting up an anonymous package around a form,
setting up some default contents, letting the reader spew into it, and then
analyzing the package to pick and choose what we want to promote.

This is what my PKG read macro does. We can get the effect of Clojure's
gensyms like this:

·@((keep while)(intern top end))

(defmacro while ((guard &body finally-body) &body loop-body)
  `(block nil
     (tagbody
      top
       (unless ,guard (go end))
       (progn ,@loop-body)
       (go top)
      end
       (return (progn ,@finally-body)))))

(keep while) means that out of the set of newly interned
symbols in the defmacro form, only the symbol named "WHILE"
will be propagated back to the parent. If a symbol WHILE
is already inherited from the surrounding package,
it will stay as that symbol.

(intern top end) means that the symbols called "TOP" and "END"
are installed into the anonymous package as present symbols.  Any conflicting
symbols (i.e. imported or inherited from the outside) are uninterned first, and
if it's a case of inheritance, then shadowing is applied.
Thus TOP and END are unique to the form. They are not named in
the KEEP directive, and so they stay that way.

There is still a possible side effect, namely that WHILE
ends up being interned. I can hardly see how we can do without
that side effect, otherwise how would anyone be able to
call WHILE?

> were starting over from scratch today (which luxury Rich Hickey has) 
> that we would design the lisp reader to be side effect free.

I don't like pulling my hair out, yet I'd hardly change a thing.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-367628.21482513122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-13, Raffael Cavallaro 
> <················@pas.espam.s.il.vous.plait.mac.com> wrote:
> > On 2008-12-13 16:48:57 -0500, Ron Garret <·········@flownet.com> said:
> >
> >> Having a parser with
> >> global side-effects strikes me as horribly inelegant (to say nothing of
> >> a language that boasts about having user-modifiable syntax, but lets you
> >> change everything *except* the part that introduces those global
> >> side-effects).
> >
> > Absolutely. Rich Hickey's Clojure has a reader that does *not* have 
> > side effects. I.e., it is generally recognized by lisp users who don't 
> 
> I don't believe it. A reader requires side effects. Without the side effect 
> of
> interning a symbol, two occurences of X won't be recognized as the same 
> object.

One can adopt a theoretical model where all possible symbols have been 
interned ahead of time.  Of course, no real implementation can implement 
this model with perfect fidelity, but even "purely functional" programs 
have side-effects like using memory.  It's just that these side-effects 
are (mostly) hidden from the user.

rg
From: Raffael Cavallaro
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <200812132231028930-raffaelcavallaro@pasespamsilvousplaitmaccom>
On 2008-12-13 22:00:33 -0500, Kaz Kylheku <········@gmail.com> said:

> I don't believe it. A reader requires side effects. Without the side effect of
> interning a symbol, two occurences of X won't be recognized as the same object.

Forms *evaluated* by the reader may have side effects but the mere act 
of reading input does not. For example, defining a variable or a 
function has the side effect of interning the symbol referring to that 
var or function but simply using a symbol in a form does not intern it. 
This is what is meant by having a side effect free reader.

In common lisp:

? (find-symbol "FUJIGABAH")
NIL
NIL
? (let ((fujigabah 10)) fujigabah)
10
? (find-symbol "FUJIGABAH")
FUJIGABAH
:INTERNAL
?

i.e., merely using fujigabah as a local causes this symbol to be interned.

In Clojure, merely using a symbol does not cause it to be interned. You 
have to evaluate a form that explicitly interns a symbol, for example 
defining a function using that symbol or a var:

user> (def foo 10)
#'user/foo
user> (resolve 'foo)
#'user/foo
user> (resolve 'fujigabah) ;; no such symbol interned
nil
user> (let [fujigabah 10] fujigabah)
10
user> (resolve 'fujigabah) ;; still not interned
nil
user> (def fujigabah 10)
#'user/fujigabah
user> (resolve 'fujigabah) ;; eval of def has interned it
#'user/fujigabah
user> fujigabah
10
-- 
Raffael Cavallaro, Ph.D.
From: Pascal J. Bourguignon
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <87oczf3ssn.fsf@informatimago.com>
Kaz Kylheku <········@gmail.com> writes:

> On 2008-12-13, Raffael Cavallaro <················@pas.espam.s.il.vous.plait.mac.com> wrote:
>> On 2008-12-13 16:48:57 -0500, Ron Garret <·········@flownet.com> said:
>>
>>> Having a parser with
>>> global side-effects strikes me as horribly inelegant (to say nothing of
>>> a language that boasts about having user-modifiable syntax, but lets you
>>> change everything *except* the part that introduces those global
>>> side-effects).
>>
>> Absolutely. Rich Hickey's Clojure has a reader that does *not* have 
>> side effects. I.e., it is generally recognized by lisp users who don't 
>
> I don't believe it. A reader requires side effects. Without the side effect of
> interning a symbol, two occurences of X won't be recognized as the same object.

You don't need interning if you redefine EQ and EQL to be EQUAL.

Notice that immutability of values allow the functionnal compiler to
collapse EQUAL values at will, so indeed EQUAL is also EQL and EQ.


Then INTERN == MAKE-SYMBOL (modulo package management).

-- 
__Pascal Bourguignon__
From: Raffael Cavallaro
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <2008121410424711272-raffaelcavallaro@pasespamsilvousplaitmaccom>
On 2008-12-14 06:22:32 -0500, ···@informatimago.com (Pascal J. 
Bourguignon) said:

> You don't need interning if you redefine EQ and EQL to be EQUAL.

In particular, Clojure uses Baker's EGAL:

<http://home.pipeline.com/~hbaker1/ObjectIdentity.html>


-- 
Raffael Cavallaro, Ph.D.
From: Tamas K Papp
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qipqtFco1q7U2@mid.individual.net>
On Sat, 13 Dec 2008 13:48:57 -0800, Ron Garret wrote:

> BTW, I've been doing a lot of Python programming lately.  Python has a
> very unsophisticated module system, but I've never encountered a
> nameclash problem.  Not once.  In fact, I've never seen a report of a
> nameclash problem on c.l.python.
> 
> By way of contrast, there is a steady stream of newbies having problems
> with packages in c.l.l.  When you do a Google search for "Python
> modules" the first result is the global module index, but when you
> search for "lisp packages" the first result is
> http://www.flownet.com/ron/packages.pdf . It's hard to explain the
> popularity of a paper entitled "The Complete Idiot's Guide to Common
> Lisp Packages" if no one is having any problems with them.

This does not imply that packages are problematic, just that they are 
different, compared to concepts in other languages people are used to.  
Many new things are difficult to understand when people first encounter 
them, so what?

As a newbie, I encountered some things in CL I couldn't understand, I 
read the aforementioned tutorial and some others, and since then I have 
been fine.  Frankly, I don't see what you are trying to fix with 
lexicons, but I guess it is nice to experiment.  I keep my eyes open if 
anything worthwhile results from this effort, but so far I am not really 
convinced (1) that  there is any significant practical problem with 
packages, and (2) lexicons are better.

Best,

Tamas
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-DDCB06.23004513122008@news.gha.chartermi.net>
In article <··············@mid.individual.net>,
 Tamas K Papp <······@gmail.com> wrote:

> On Sat, 13 Dec 2008 13:48:57 -0800, Ron Garret wrote:
> 
> > BTW, I've been doing a lot of Python programming lately.  Python has a
> > very unsophisticated module system, but I've never encountered a
> > nameclash problem.  Not once.  In fact, I've never seen a report of a
> > nameclash problem on c.l.python.
> > 
> > By way of contrast, there is a steady stream of newbies having problems
> > with packages in c.l.l.  When you do a Google search for "Python
> > modules" the first result is the global module index, but when you
> > search for "lisp packages" the first result is
> > http://www.flownet.com/ron/packages.pdf . It's hard to explain the
> > popularity of a paper entitled "The Complete Idiot's Guide to Common
> > Lisp Packages" if no one is having any problems with them.
> 
> This does not imply that packages are problematic, just that they are 
> different, compared to concepts in other languages people are used to.  
> Many new things are difficult to understand when people first encounter 
> them, so what?

All else being equal, something that is easier to understand is better 
than something that is more difficult to understand.  IMHO.

> As a newbie, I encountered some things in CL I couldn't understand, I 
> read the aforementioned tutorial and some others, and since then I have 
> been fine.  Frankly, I don't see what you are trying to fix with 
> lexicons

I am trying to make a system for managing libraries in CL that Just 
Works.  Python's library system is an existence proof that this is 
possible.  No one has ever written "The Complete Idiot's Guide to Python 
Modules" and no one ever will because such a document is not necessary 
because Python's module system Just Works.

rg
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081229204759.187@gmail.com>
On 2008-12-14, Ron Garret <·········@flownet.com> wrote:
> All else being equal, something that is easier to understand is better 
> than something that is more difficult to understand.  IMHO.

Ah, blessed be those who manage to find all else equal.

>> As a newbie, I encountered some things in CL I couldn't understand, I 
>> read the aforementioned tutorial and some others, and since then I have 
>> been fine.  Frankly, I don't see what you are trying to fix with 
>> lexicons
>
> I am trying to make a system for managing libraries in CL that Just 
> Works.  Python's library system is an existence proof that this is 
> possible.

Python's library system is proof that it's possible in Python, where we drop
requirements like symbol as a data type, quoting code as data, programs
expressing new special forms. Or slots in one object that actually belong to
different libraries.

What does it mean for a name to refer to something in Python,
and to what extent is that extensible?

So, maybe all else is not equal, I guess! 

If all else was equal, then you could just implement exactly the same
library system in CL. Existence proved, QED.

I suspect that less brainpower (or brain struggle) went into the Python library
system than what you've put into Lexicons. Why is that?

So far you've had to fix things that don't even map into Python concepts.

> No one has ever written "The Complete Idiot's Guide to Python 
> Modules" 

Because that would be redundant for "The Guide to Python Modules".
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-41B30D.09230014122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-14, Ron Garret <·········@flownet.com> wrote:
> > All else being equal, something that is easier to understand is better 
> > than something that is more difficult to understand.  IMHO.
> 
> Ah, blessed be those who manage to find all else equal.

Indeed.

> >> As a newbie, I encountered some things in CL I couldn't understand, I 
> >> read the aforementioned tutorial and some others, and since then I have 
> >> been fine.  Frankly, I don't see what you are trying to fix with 
> >> lexicons
> >
> > I am trying to make a system for managing libraries in CL that Just 
> > Works.  Python's library system is an existence proof that this is 
> > possible.
> 
> Python's library system is proof that it's possible in Python, where we drop
> requirements like symbol as a data type, quoting code as data, programs
> expressing new special forms.

It is possible to quote code as data in Python, it's just that the data 
type used to represent code in Python is the string, not the cons cell.

That symbols are not first-class data types is a consequence of that 
decision.  It is easy to add a symbol type to Python, it's just that the 
Python compiler wouldn't make use of it (since programs are strings).

BTW, the exact same thing is true of Scheme.  Scheme programs are 
strings too (at least they were in r5rs.  Maybe things have changed.)

> Or slots in one object that actually belong to
> different libraries.

*That* is the trick.  This is the one thing that packages do that I have 
not yet figured out how to reproduce in lexicons.

> What does it mean for a name to refer to something in Python,
> and to what extent is that extensible?

Oh, that's easy.  For a name to refer to something means that the name 
is a key in an environment, which is a first-class data structure, 
usually a dictionary, but occasionally some other dictionary-like data 
structure like a module.  This mechanism is actually quite powerful and 
flexible (some argue it is too powerful and flexible).

> So, maybe all else is not equal, I guess!

Not yet.  I'm working on it.

> If all else was equal, then you could just implement exactly the same
> library system in CL. Existence proved, QED.

That's right.  Python serves merely as an inspiration for lexicons, not 
a design.

> I suspect that less brainpower (or brain struggle) went into the Python 
> library system than what you've put into Lexicons. Why is that?

Actually I'm not sure that's true.  Although Lexicons have been a work 
in progress for a long time, I don't actually work on them all that 
much.  They are a side project, and I only get to work on them when I'm 
not busy with something else more important.

> So far you've had to fix things that don't even map into Python concepts.

Of course, because Lisp has things that Python doesn't (like 
multimethods and macros).

> > No one has ever written "The Complete Idiot's Guide to Python 
> > Modules" 
> 
> Because that would be redundant for "The Guide to Python Modules".

Which also doesn't exist.

rg
From: Rob Warnock
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <f7-dncgzOZ1mWtjUnZ2dnUVZ_gmdnZ2d@speakeasy.net>
Ron Garret  <·········@flownet.com> wrote:
+---------------
| It is possible to quote code as data in Python, it's just that the data 
| type used to represent code in Python is the string, not the cons cell.
| 
| That symbols are not first-class data types is a consequence of that 
| decision.  It is easy to add a symbol type to Python, it's just that the 
| Python compiler wouldn't make use of it (since programs are strings).
| 
| BTW, the exact same thing is true of Scheme.  Scheme programs are 
| strings too (at least they were in r5rs.  Maybe things have changed.)
+---------------

Actually, IMHO that's a sort of (unhealthy) community myth the Schemers
[and their standards] adhere to. You can't even read the introductory
section on syntax in R5RS without realizing they're not actually serious
about that "Scheme programs are strings" thing:

    1.2 Syntax

    Scheme, like most dialects of Lisp, employs a fully parenthesized
    prefix notation for programs and (other) data; the grammar of Scheme
    generates a sublanguage of the language used for data. An important
    consequence of this simple, uniform representation is the susceptibility
    of Scheme programs and data to uniform treatment by other Scheme
    programs. For example, the eval procedure evaluates a Scheme program
    expressed as data.

    The read procedure performs syntactic as well as lexical decomposition
    of the data it reads. The read procedure parses its input as data
    (section 7.1.2), not as program.

    The formal syntax of Scheme is described in section 7.1. 

To emphasize the point: THE EVAL PROCEDURE EVALUATES A SCHEME PROGRAM
EXPRESSED AS DATA. *Not* as a string!!! See for yourself, in any R5RS
Scheme implementation that you have access to:

    > (eval "(+ 1 2)" (scheme-report-environment 5))
    "(+ 1 2)"
    > 

What? It didn't evaluate the string? Nope. You need an s-expr for that:

    > (eval '(+ 1 2) (scheme-report-environment 5))
    3
    > 

And "6.5 Eval" reaffirms that EVAL takes Scheme data, not strings:

    6.5 Eval

    [[procedure]] (eval expression environment-specifier)

    Evaluates expression in the specified environment and returns
    its value. Expression must be a valid Scheme expression
    represented as data, and environment-specifier must be a value
    returned by one of the three procedures described below.
    ...

As far as I can tell, the "Scheme programs are strings" myth was
introduced only to make Chapter 7 "Formal syntax and semantics"
easier to write, but IMHO it only ends up obfuscating the true
nature of the language by not providing an interpretation of Scheme
data constructed by any means *other* than the rreader. Consider:

    7.1.2 External representations

    <Datum> is what the read procedure (section 6.6.2) successfully
    parses. Note that any string that parses as an <expression> will
    also parse as a <datum>. 

Yes, <datum> is a description of an external string, but once *parsed*
it is no longer a <datum>, but merely "Scheme data" -- "the objects
themselves" which READ returns.

    6.6.2 Input

    [[library procedure]] (read)
    [[library procedure]] (read port)

    Read converts external representations of Scheme objects into the
    objects themselves. That is, it is a parser for the nonterminal
    <datum> (see sections 7.1.2 and 6.3.2). Read returns the next
    object parsable from the given input port, updating port to point
    to the first character past the end of the external representation
    of the object. 

By pushing the BNF for <datum> -- and by extension, <expression> --
onto external string representations, they've make it absolutely
impossible to rigorously specify the structure of Scheme objects
created ab initio as data by Scheme procedures *other* than the
built-in READ procedure!! Hint: You can build all the "Scheme objects"
you want (by consing & such) which are legal arguments to EVAL,
but they won't be <expression>s!! Madness!

Yes, those who criticize Scheme for this myth have it right.
Common Lisp took the sane path: In CL a <datum> is a CL object,
*not* a string. And <expression> [or, rather, a <form> which
is a conforming program] is a subset of <datum>. The CL reader
is just *one* way [albeit a standarized way] to contruct a
<datum> from an external string.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: George Neuner
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6q3dk45fh1rhgbrnf3mfu2ie8rtgu5jgam@4ax.com>
On Sun, 14 Dec 2008 20:59:07 -0600, ····@rpw3.org (Rob Warnock) wrote:

>Ron Garret  <·········@flownet.com> wrote:
>+---------------
>| It is possible to quote code as data in Python, it's just that the data 
>| type used to represent code in Python is the string, not the cons cell.
>| 
>| That symbols are not first-class data types is a consequence of that 
>| decision.  It is easy to add a symbol type to Python, it's just that the 
>| Python compiler wouldn't make use of it (since programs are strings).
>| 
>| BTW, the exact same thing is true of Scheme.  Scheme programs are 
>| strings too (at least they were in r5rs.  Maybe things have changed.)
>+---------------
>
>Actually, IMHO that's a sort of (unhealthy) community myth the Schemers
>[and their standards] adhere to. You can't even read the introductory
>section on syntax in R5RS without realizing they're not actually serious
>about that "Scheme programs are strings" thing:
>
>    1.2 Syntax
>
>    Scheme, like most dialects of Lisp, employs a fully parenthesized
>    prefix notation for programs and (other) data; the grammar of Scheme
>    generates a sublanguage of the language used for data. An important
>    consequence of this simple, uniform representation is the susceptibility
>    of Scheme programs and data to uniform treatment by other Scheme
>    programs. For example, the eval procedure evaluates a Scheme program
>    expressed as data.
>
>    The read procedure performs syntactic as well as lexical decomposition
>    of the data it reads. The read procedure parses its input as data
>    (section 7.1.2), not as program.
>
>    The formal syntax of Scheme is described in section 7.1. 
>
>To emphasize the point: THE EVAL PROCEDURE EVALUATES A SCHEME PROGRAM
>EXPRESSED AS DATA. *Not* as a string!!! See for yourself, in any R5RS
>Scheme implementation that you have access to:
>
>    > (eval "(+ 1 2)" (scheme-report-environment 5))
>    "(+ 1 2)"
>    > 
>
>What? It didn't evaluate the string? Nope. You need an s-expr for that:
>
>    > (eval '(+ 1 2) (scheme-report-environment 5))
>    3
>    > 
>
>And "6.5 Eval" reaffirms that EVAL takes Scheme data, not strings:
>
>    6.5 Eval
>
>    [[procedure]] (eval expression environment-specifier)
>
>    Evaluates expression in the specified environment and returns
>    its value. Expression must be a valid Scheme expression
>    represented as data, and environment-specifier must be a value
>    returned by one of the three procedures described below.
>    ...
>
>As far as I can tell, the "Scheme programs are strings" myth was
>introduced only to make Chapter 7 "Formal syntax and semantics"
>easier to write, but IMHO it only ends up obfuscating the true
>nature of the language by not providing an interpretation of Scheme
>data constructed by any means *other* than the rreader. Consider:
>
>    7.1.2 External representations
>
>    <Datum> is what the read procedure (section 6.6.2) successfully
>    parses. Note that any string that parses as an <expression> will
>    also parse as a <datum>. 
>
>Yes, <datum> is a description of an external string, but once *parsed*
>it is no longer a <datum>, but merely "Scheme data" -- "the objects
>themselves" which READ returns.
>
>    6.6.2 Input
>
>    [[library procedure]] (read)
>    [[library procedure]] (read port)
>
>    Read converts external representations of Scheme objects into the
>    objects themselves. That is, it is a parser for the nonterminal
>    <datum> (see sections 7.1.2 and 6.3.2). Read returns the next
>    object parsable from the given input port, updating port to point
>    to the first character past the end of the external representation
>    of the object. 
>
>By pushing the BNF for <datum> -- and by extension, <expression> --
>onto external string representations, they've make it absolutely
>impossible to rigorously specify the structure of Scheme objects
>created ab initio as data by Scheme procedures *other* than the
>built-in READ procedure!! Hint: You can build all the "Scheme objects"
>you want (by consing & such) which are legal arguments to EVAL,
>but they won't be <expression>s!! Madness!
>
>Yes, those who criticize Scheme for this myth have it right.
>Common Lisp took the sane path: In CL a <datum> is a CL object,
>*not* a string. And <expression> [or, rather, a <form> which
>is a conforming program] is a subset of <datum>. The CL reader
>is just *one* way [albeit a standarized way] to contruct a
><datum> from an external string.
>
>
>-Rob


It's more the point that (R5) Scheme doesn't define the internal
representation that eval is defined to work on - the report only
alludes to its existence in 7.1.2.  I agree that, strictly speaking,
"programs are strings" is a myth - but since, by the report, only read
can create this mysterious IR, there is no real distinction to be
drawn between the program and it's external textual representation.

[IMO, R6 confused the issue even more by droning on about the creation
and manipulation of "syntactic datums" without actually addressing
whether they constitute a first level of IR or are to be considered
parser tokens ahead of IR construction.]

George
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-AE740F.10324515122008@news.gha.chartermi.net>
In article <··································@4ax.com>,
 George Neuner <········@comcast.net> wrote:

> On Sun, 14 Dec 2008 20:59:07 -0600, ····@rpw3.org (Rob Warnock) wrote:
> 
> >Ron Garret  <·········@flownet.com> wrote:
> >+---------------
> >| It is possible to quote code as data in Python, it's just that the data 
> >| type used to represent code in Python is the string, not the cons cell.
> >| 
> >| That symbols are not first-class data types is a consequence of that 
> >| decision.  It is easy to add a symbol type to Python, it's just that the 
> >| Python compiler wouldn't make use of it (since programs are strings).
> >| 
> >| BTW, the exact same thing is true of Scheme.  Scheme programs are 
> >| strings too (at least they were in r5rs.  Maybe things have changed.)
> >+---------------
> >
> >Actually, IMHO that's a sort of (unhealthy) community myth the Schemers
> >[and their standards] adhere to.

Just for the record (since I'm the one who started this) I do not 
believe that the Scheme community actually adheres to this "myth".  I 
think if you make the claim that "Scheme programs are stings" in c.l.s 
you will encounter plentiful opposition.  (This experiment was actually 
tried a few years back.  If you're interested in the results do a Google 
Groups search on "Scheme programs are strings.")

But IMO it's not a myth because:

> >By pushing the BNF for <datum> -- and by extension, <expression> --
> >onto external string representations, they've make it absolutely
> >impossible to rigorously specify the structure of Scheme objects
> >created ab initio as data by Scheme procedures *other* than the
> >built-in READ procedure!! Hint: You can build all the "Scheme objects"
> >you want (by consing & such) which are legal arguments to EVAL,
> >but they won't be <expression>s!! Madness!

and:

> It's more the point that (R5) Scheme doesn't define the internal
> representation that eval is defined to work on - the report only
> alludes to its existence in 7.1.2.  I agree that, strictly speaking,
> "programs are strings" is a myth - but since, by the report, only read
> can create this mysterious IR, there is no real distinction to be
> drawn between the program and it's external textual representation.

I believe this confusion is no accident.  Hygienic macros are easier to 
implement if EVAL is NOT required to accept the data type produced by a 
call to CONS, and instead only accepts some kind of "abstract syntax 
object" which can keep track of the lexical environment in which it was 
created.  This view seems to be supported by:

> [IMO, R6 confused the issue even more by droning on about the creation
> and manipulation of "syntactic datums" without actually addressing
> whether they constitute a first level of IR or are to be considered
> parser tokens ahead of IR construction.]

But again, I can't speak authoritatively on this as I have not 
thoroughly studied R6Rs.

rg
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081231133105.921@gmail.com>
On 2008-12-15, Ron Garret <·········@flownet.com> wrote:
> Just for the record (since I'm the one who started this) I do not 
> believe that the Scheme community actually adheres to this "myth".  I 
> think if you make the claim that "Scheme programs are stings" in c.l.s 
> you will encounter plentiful opposition.

You will be labeled as a troll, I suspect. :)
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081231100451.437@gmail.com>
On 2008-12-15, George Neuner <········@comcast.net> wrote:
> It's more the point that (R5) Scheme doesn't define the internal
> representation that eval is defined to work on - the report only
> alludes to its existence in 7.1.2. 

Is that really true? The counterexample would be code which
constructs a list at run time and then evaluates it.

There is definitely a symbol datatype (6.3.3).

The following R5RS Scheme expression would appear
to construct an expresion:

  (list 'define (list 'foo 'x 'y) (list '+ 'x 'y))

  -> (define (foo x y) (+ x y))

Surely we can eval the output of that expression.

Section 6.5 (Eval) says that ``[The] [E]xpression must be a valid Scheme
expression represented as data.''  Now data could be anything,
but they probably don't mean a character string like "(define ...)".

I see what you guys are getting at. I suppose that at text-based representation
is possible. It's not required that lists be made up of atoms and conses.
The list function itself could actually compute a representation that is
internally a character string.  That fits the definition of a <datum>, which is
what what the read function parses.

So the data produced by:

  (list 'define (list 'foo 'x 'y) (list '+ 'x 'y))

could actually be text-based, and so the facts that it's tagged as a list type
and that we can eval it doesn't prove that it's not a string.

Of course, it wouldn't have a string type. Its type would still be list, but
the memory representation could just be a flat piece of text, just like the
PATH list in Unix, which must always be parsed for its colons.

I.e. a conforming implementation of R5RS Scheme---code and data---could be
implemented using the same text-munging techniques as, say, the POSIX shell.

Nevertheless, this would be an obtuse and actually a very cumbersome
and difficult way to implement Scheme.

I guess it's the consequence of being very abstract. The visible external
inputs and visible outputs of a Scheme system are character data.  If that can
be represented in /any/ way whatsoever inside the system, then it can't be
ruled out that the text representation can be used.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-7A1B45.13290715122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-15, George Neuner <········@comcast.net> wrote:
> > It's more the point that (R5) Scheme doesn't define the internal
> > representation that eval is defined to work on - the report only
> > alludes to its existence in 7.1.2. 
> 
> Is that really true? The counterexample would be code which
> constructs a list at run time and then evaluates it.
> 
> There is definitely a symbol datatype (6.3.3).
> 
> The following R5RS Scheme expression would appear
> to construct an expresion:
> 
>   (list 'define (list 'foo 'x 'y) (list '+ 'x 'y))
> 
>   -> (define (foo x y) (+ x y))
> 
> Surely we can eval the output of that expression.

On a strict reading of the standard, no, you can't, at least not 
directly.  You have to render that list as string, run that string 
through the Scheme parser, and then EVAL the result.  Scheme has the 
same surface syntax for code and data, but the standard takes great care 
NOT to require that code and data actually have the same internal 
representation.

Of course, the standard *allows* them to have the same internal 
representation, and most (but not all) Scheme implementations actually 
use the same internal representation.  But you can't count on it.  This 
is done deliberately in order to make it easier to implement hygienic 
macros.

rg
From: Tamas K Papp
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qkmf6Fd2i9tU1@mid.individual.net>
On Sat, 13 Dec 2008 23:00:45 -0800, Ron Garret wrote:

> In article <··············@mid.individual.net>,
>  Tamas K Papp <······@gmail.com> wrote:
> 
>> This does not imply that packages are problematic, just that they are
>> different, compared to concepts in other languages people are used to.
>> Many new things are difficult to understand when people first encounter
>> them, so what?
> 
> All else being equal, something that is easier to understand is better
> than something that is more difficult to understand.  IMHO.

But the point is that things are not equal.  CL is a different language 
with different capabilities.

> I am trying to make a system for managing libraries in CL that Just
> Works.  Python's library system is an existence proof that this is
> possible.  No one has ever written "The Complete Idiot's Guide to Python
> Modules" and no one ever will because such a document is not necessary
> because Python's module system Just Works.

For me, CL packages Just Work.  I had to devote about an afternoon to 
reading the tutorials and browsing the Hyperspec, but I think it was 
worth it.  I don't see the problem with devoting time to learning 
powerful concepts.

Tamas
From: alien_guy
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <pan.2008.12.14.17.01.15@l.org>
On Sat, 13 Dec 2008 23:00:45 -0800, Ron Garret wrote:
> I am trying to make a system for managing libraries in CL that Just
> Works.  Python's library system is an existence proof that this is
> possible.  No one has ever written "The Complete Idiot's Guide to Python
> Modules" and no one ever will because such a document is not necessary
> because Python's module system Just Works.

Yes, I suppose that's why just yesterday a guy came to #lisp saying that 
he switched to CL because he had problems with Python's modules and that 
he liked the flexibility that CL's packages allowed him.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-19070D.10431214122008@news.gha.chartermi.net>
In article <·······················@l.org>, alien_guy <·@l.org> wrote:

> On Sat, 13 Dec 2008 23:00:45 -0800, Ron Garret wrote:
> > I am trying to make a system for managing libraries in CL that Just
> > Works.  Python's library system is an existence proof that this is
> > possible.  No one has ever written "The Complete Idiot's Guide to Python
> > Modules" and no one ever will because such a document is not necessary
> > because Python's module system Just Works.
> 
> Yes, I suppose that's why just yesterday a guy came to #lisp saying that 
> he switched to CL because he had problems with Python's modules and that 
> he liked the flexibility that CL's packages allowed him.

News to me.  What was the problem?

rg
From: Kenny
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <49457d07$0$20283$607ed4bc@cv.net>
Ron Garret wrote:
> In article <·······················@l.org>, alien_guy <·@l.org> wrote:
> 
> 
>>On Sat, 13 Dec 2008 23:00:45 -0800, Ron Garret wrote:
>>
>>>I am trying to make a system for managing libraries in CL that Just
>>>Works.  Python's library system is an existence proof that this is
>>>possible.  No one has ever written "The Complete Idiot's Guide to Python
>>>Modules" and no one ever will because such a document is not necessary
>>>because Python's module system Just Works.
>>
>>Yes, I suppose that's why just yesterday a guy came to #lisp saying that 
>>he switched to CL because he had problems with Python's modules and that 
>>he liked the flexibility that CL's packages allowed him.
> 
> 
> News to me.  What was the problem?

Possibly the same thing that led me to punt on my port of Cells to 
Python. And there is lies a meta-punt: the query to c.l.python led to 
precisely one respondent who had nothing to offer after checking all my 
code except that "it should work". Contrasted with the c.l.l community, 
I understood in a flash that I was reaching out to a herd of so many 
heiffers and shut down the effort.

Probably you do not do anything interesting enough to break Python's 
module system. Like Costanza you are not actually programming, you are 
just hawking a library. And a boring one at that if it cannot break the 
Python module joke.

kny
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qivj5Fck3u8U1@mid.individual.net>
Ron Garret wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
> 
>> Ron Garret wrote:
>>> In article <··············@mid.individual.net>,
>>>  Pascal Costanza <··@p-cos.net> wrote:
>>>
>>>> The wording in the HyperSpec doesn't exactly promote the use of unintern 
>>>> as a regular tool to be used extensively in Lisp programs.
>>> How else would you recover from a situation where a typo at the REPL 
>>> caused a symbol to be interned that you didn't want to have interned?
>> When you're trying to recover from a typo, you haven't exported/imported 
>> that one symbol yet to/from other packages. So no harm done.
> 
> No, but you have created a potential name conflict.

I am not interested about potential conflicts, I am interested about 
conflict that actually occur in practice.

> Actually, "typo" wasn't really the right word.  The real problems arise 
> when you load some code that is supposed to use a package before that 
> package is loaded.  Now you have a bunch of (conflicting) symbols 
> interned in the client package.  For example:
> 
> ? (make-package :p1)
> #<Package "P1">
> ? (in-package :p1)
> #<Package "P1">
> ? (defun library-function () 'p1-lib-result)
> LIBRARY-FUNCTION
> ? (export 'library-function)
> T
> ? (make-package :p2)
> #<Package "P2">
> ? (in-package :p2)
> #<Package "P2">
> ? (defun foo () (library-function))
> ;Compiler warnings :
> ;   Undefined function LIBRARY-FUNCTION, in FOO.
> FOO
> ? (use-package :p1)
>> Error: Using #<Package "P1"> in #<Package "P2"> 
>>        would cause name conflicts with symbols already present in that package: 
>>        LIBRARY-FUNCTION  P1:LIBRARY-FUNCTION

Since you came up with the "nice" analogy to static typing: Yeah, they 
also talk about potential type errors at runtime, and they can also 
construct examples where you actually get unwanted type errors at runtime.

Doesn't prove anything, though.

>> The problems you describe with the CL 
>> package system are transient, it's always possible to resolve them, 
>> without compromising elegance.
> 
> That depends on your definition of "elegance."  Having a parser with 
> global side-effects strikes me as horribly inelegant (to say nothing of 
> a language that boasts about having user-modifiable syntax, but lets you 
> change everything *except* the part that introduces those global 
> side-effects).

You can achieve elegance even with imperfect systems.

>> On top of that, we don't have extensive 
>> knowledge with lexicons in Common Lisp, so we cannot judge yet how well 
>> it really works. However, what we can tell is that there have been a lot 
>> of proposals for module systems in Scheme, with no clear winner and a 
>> lot of arguing among Schemers what the best approach is. The current 
>> agreement seems to be the one suggested in R6RS, and that one is a mess.
> 
> All of R6RS is a mess.  So what?  Just because the Scheme community is 
> screwed up does not mean that better solutions are impossible.

Sure.

>> I am not opposing lexicons, it's good that there is experimentation with 
>> alternative approaches. But I think it's good that we have something 
>> that works reasonably well, with no serious deficiencies, with 
>> admittedly some not-so-perfect corner cases, which however don't seem to 
>> be serious show stoppers.
> 
> One could make the exact same argument for *any* programming language 
> with a large code base, including C++ and Java.

Indeed.

> Whatever problems those 
> languages may have, manifestly none of them are show-stoppers since the 
> show has manifestly not been stopped.  Whether or not a language 
> deficiency is "serious" (or even a deficiency) is to some extent a 
> matter of personal taste.

Indeed.

> It does not follow that Lexicons are not an improvement by some 
> reasonable quality metric, even though you may not find that quality 
> metric to your personal liking.

The same can be said about packages. Packages allow you to make more 
fine-grained distinctions than module systems. That's an objective 
statement. It doesn't seem to be important to you, and you seem to 
dislike some of the consequences, but it is important to me, and I can 
live with the consequences.


This would be a good point to stop the discussion.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081229133903.609@gmail.com>
On 2008-12-13, Ron Garret <·········@flownet.com> wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
>
>> Ron Garret wrote:
>> > In article <··············@mid.individual.net>,
>> >  Pascal Costanza <··@p-cos.net> wrote:
>> > 
>> >> The wording in the HyperSpec doesn't exactly promote the use of unintern 
>> >> as a regular tool to be used extensively in Lisp programs.
>> > 
>> > How else would you recover from a situation where a typo at the REPL 
>> > caused a symbol to be interned that you didn't want to have interned?
>> 
>> When you're trying to recover from a typo, you haven't exported/imported 
>> that one symbol yet to/from other packages. So no harm done.
>
> No, but you have created a potential name conflict.

Enter PKG:

@((keep foo)) ;; from the following form, retain only FOO
(defun foo (x)
  (let ((b (creaet-widget))) ;; typo
    ...))

--> FOO

(find-symbol "CREAET-WIDGET") 

---> NIL; NIL
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081229162221.548@gmail.com>
On 2008-12-13, Ron Garret <·········@flownet.com> wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
>
>> Ron Garret wrote:
>> > In article <··············@mid.individual.net>,
>> >  Pascal Costanza <··@p-cos.net> wrote:
>> > 
>> >> The wording in the HyperSpec doesn't exactly promote the use of unintern 
>> >> as a regular tool to be used extensively in Lisp programs.
>> > 
>> > How else would you recover from a situation where a typo at the REPL 
>> > caused a symbol to be interned that you didn't want to have interned?
>> 
>> When you're trying to recover from a typo, you haven't exported/imported 
>> that one symbol yet to/from other packages. So no harm done.
>
> No, but you have created a potential name conflict.
>
> Actually, "typo" wasn't really the right word.  The real problems arise 
> when you load some code that is supposed to use a package before that 
> package is loaded.  Now you have a bunch of (conflicting) symbols 
> interned in the client package.  For example:
>
> ? (make-package :p1)
> #<Package "P1">
> ? (in-package :p1)
> #<Package "P1">
> ? (defun library-function () 'p1-lib-result)
> LIBRARY-FUNCTION
> ? (export 'library-function)
> T
> ? (make-package :p2)
> #<Package "P2">
> ? (in-package :p2)
> #<Package "P2">
> ? (defun foo () (library-function))
> ;Compiler warnings :
> ;   Undefined function LIBRARY-FUNCTION, in FOO.
> FOO
> ? (use-package :p1)

PKG:

  (defpackage :p1 (:export library-function))
  (defpackage :p2 (:export foo))

  ·@(in p1)
  (defun library-function () 'lib-result)
  -> P1:LIBRARY-FUNCTION

  ·@((in p2)(keep))
  (defun foo () (library-function))
  -> P2::FOO

  ;; NOTE: FOO survives in spite of (KEEP) because
  ;; it's already present in P2.

  ;; Now discover that function P2::LIBRARY-FUNCTION is undefined
  ;; try again:

  ·@((in p2)(use p1)(keep))
  (defun foo () (library-function)
    (library-function)) ;; P1:LIBRRARY-FUNCTION, no problem.
  -> P2::FOO

Note that P2 doesn't use P1.  P1 is never on the package use list of P2.
It only functionally appears that way over the scope of the form.

The form is not really in P2 either; it's in an anonymous package
which is reconciled against P2 after the form is read.
From: Pascal J. Bourguignon
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <7c3agtvb73.fsf@pbourguignon.anevia.com>
Pascal Costanza <··@p-cos.net> writes:
>> Wow!! That's *really* nasty!!  Worse, now that you've shown the
>> basic pattern, I find that I can duplicate it[1] *much* more simply:
>>     cmu> (make-package :p1)
>>     #<The P1 package, 0/9 internal, 0/9 external>
>>     cmu> (import 'p1::foo)
>>     T
>>     cmu> (unintern 'p1::foo :p1)
>>     T
>>     cmu> 'foo
>>     #:FOO
>>     cmu> Ugh.
>
> The wording in the HyperSpec doesn't exactly promote the use of
> unintern as a regular tool to be used extensively in Lisp programs.

That's no excuse >:-}
-- 
__Pascal Bourguignon__
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081227204207.395@gmail.com>
On 2008-12-12, Ron Garret <·········@flownet.com> wrote:
> In article <··················@gmail.com>,
>  Kaz Kylheku <········@gmail.com> wrote:
>
>> On 2008-12-12, Rob Warnock <····@rpw3.org> wrote:
>> > Ron Garret  <·········@flownet.com> wrote:
>> > +---------------
>> >| Note by the way that the Lisp reader can produce some surprising 
>> >| results, e.g.:
>> >| 
>> >| P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
>> >| T
>> >| P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
>> >| NIL
>> >| 
>> >| How this can happen is left as an exercise for the reader
>> >| (no pun intended).
>> > +---------------
>> >
>> > O.k, I give up. How?!?  [Assuming that those *are* indeed
>> > successive REPL commands with no intervening operations...]
>> 
>> Ditto. I have not been able to solve the puzzle of how there can be a
>> read-print inconsistency over FOO, but not over BAR (short of some very dirty
>> readtable manipulation or something).
>> 
>> There is no manipulation of *package*, *readtable*, or the objects
>> they point to.
>> 
>> Some combination of *print-case* and readtable-case will probably
>> do it, but for both BAZ and FOO alike.
>
> [···@mickey:~]$ clisp
>   i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
>   I I I I I I I      8     8   8           8     8     o  8    8
>   I  \ `+' /  I      8         8           8     8        8    8
>    \  `-+-'  /       8         8           8      ooooo   8oooo
>     `-__|__-'        8         8           8           8  8
>         |            8     o   8           8     o     8  8
>   ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8
>
> Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
> Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
> Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
> Copyright (c) Bruno Haible, Sam Steingold 1999-2000
> Copyright (c) Sam Steingold, Bruno Haible 2001-2006
>
> [1]> (make-package :p1)
> #<PACKAGE P1>
> [2]> (make-package :p2)
> #<PACKAGE P2>
> [3]> (setf s '#:foo)
> #:FOO
> [4]> (import s :p1)
> T
> [5]> (import s :p2)
> T
> [6]> (unintern s :p1)
> T
> [7]> (in-package :p2)
> #<PACKAGE P2>
> P2[8]> 'foo
> #:FOO
> P2[9]> 'baz
> BAZ

I tried following this route, but somehow didn't hit upon how to make it work,
probably due to not believing in it sufficiently.

(I too read Erann's paper where you got your little piece of humor about the
``exercise for the reader'', so I'm familiar with the fate of the
#:WEIRD-SYMBOL thing).

Is this portable across Lisps? 

Since FOO is in fact present in P2, it's strange that it doesn't get
printed as FOO.

If it had a home package, it would be printed as FOO relative to P2, in spite
of home package being something other than P2.

Discrimination against the homeless?

The #: comes off with a good bath and shave, you know!

Proof:

P2[12]> 'foo
#:FOO
P2[13]> (progn (unintern 'foo) (import 'foo))
T
P2[14]> 'foo
FOO

Clean symbol with a home, ready to work!

All we did was boot it out of the package and then re-import it. A homeless
symbol acquires the package as a home when imported into it.
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qejf6Fc70c5U1@mid.individual.net>
Kaz Kylheku wrote:
> On 2008-12-12, Rob Warnock <····@rpw3.org> wrote:
>> Ron Garret  <·········@flownet.com> wrote:
>> +---------------
>> | Note by the way that the Lisp reader can produce some surprising 
>> | results, e.g.:
>> | 
>> | P2[19]> (eq 'baz (read-from-string (format nil "~S" 'baz)))
>> | T
>> | P2[20]> (eq 'foo (read-from-string (format nil "~S" 'foo)))
>> | NIL
>> | 
>> | How this can happen is left as an exercise for the reader
>> | (no pun intended).
>> +---------------
>>
>> O.k, I give up. How?!?  [Assuming that those *are* indeed
>> successive REPL commands with no intervening operations...]
> 
> Ditto. I have not been able to solve the puzzle of how there can be a
> read-print inconsistency over FOO, but not over BAR (short of some very dirty
> readtable manipulation or something).
> 
> There is no manipulation of *package*, *readtable*, or the objects
> they point to.
> 
> Some combination of *print-case* and readtable-case will probably
> do it, but for both BAZ and FOO alike.

Here is one solution for the puzzle:

(defpackage :my-package
   (:shadow :read-from-string))

(in-package :my-package)

(defun read-from-string (&rest args)
   (let ((result (apply #'cl:read-from-string args)))
     (if (eq result 'foo)
       'baz
       result)))

And then perform the above in the package :my-package. :-P

Try to do that with modules. ;) [1]


Pascal

[1] Note the smiley.

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Didier Verna
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <muxoczmzt86.fsf@uzeb.lrde.epita.fr>
Pascal Costanza wrote:

> Because they can make distinctions that you cannot make with module
> systems. For example, if you had only a module system, a class would
> not be able to inherit from two different classes with slots of the
> same name and be able to keep them as two different slots (unless you
> come up with funky renaming mechanisms, like in the R6RS module
> system, for example).

  I'm not sure I follow you.

#include <iostream>

struct foo1
{
  foo1 () { slot = 1; };
  int slot;
};

struct foo2
{
  foo2 () { slot = 2; };
  int slot;
};

struct mystruct : public foo1, foo2
{
  mystruct () { slot = 0; };
  int slot;
};


int main (int argc, char *argv[])
{
  mystruct ms;
  std::cout << ms.slot << ms.foo2::slot << ms.foo1::slot << std::endl;
}

./test => 021

-- 
Resistance is futile. You will be jazzimilated.

Scientific site:   http://www.lrde.epita.fr/~didier
Music (Jazz) site: http://www.didierverna.com

EPITA/LRDE, 14-16 rue Voltaire, 94276 Le Kremlin-Bic�tre, France
Tel. +33 (0)1 44 08 01 85       Fax. +33 (0)1 53 14 59 22
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081208095423.235@gmail.com>
On 2008-12-08, Didier Verna <······@lrde.epita.fr> wrote:
> Pascal Costanza wrote:
>
>> Because they can make distinctions that you cannot make with module
>> systems. For example, if you had only a module system, a class would
>> not be able to inherit from two different classes with slots of the
>> same name and be able to keep them as two different slots (unless you
>> come up with funky renaming mechanisms, like in the R6RS module
>> system, for example).
>
>   I'm not sure I follow you.

Hi Didier, allow someone with more C++ kung fu.

> #include <iostream>
>
> struct foo1
> {
>   foo1 () { slot = 1; };
>   int slot;
> };
>
> struct foo2
> {
>   foo2 () { slot = 2; };
>   int slot;
> };
>
> struct mystruct : public foo1, foo2

Note that public doesn't apply to foo2, which is inherited privately. Syntax
bites!

> {
>   mystruct () { slot = 0; };
>   int slot;
> };

Your test case is flawed. Although you have demonstrated that multiple classes
in the hiearchy can have a separate definition for slot, what is missing is
this:

1. The observation that this is a semantic feature of C++ which makes it
ipossible to override "slot". In other words, C++ fails to provide virtual data
members, instead giving us something that resembles C structs.

2. The observation that C++ does provide overrideable functions, for which the
example would behave quite differently.

So, let's whip out my pet example:

  // two completely different meanings of draw()

  class lottery { public: virtual void draw(); };
  class graphic { public: virtual void draw(); };

  class graphic_lottery : public lottery, public graphic 
  { public: void draw(); };

Because draw is a virtual function everywhere, with the same type signature,
it's considered the same function. 

Lexically, the name graphic_lotter::draw still shadows the base class
definition. But semantically, draw overrides both functions!

If you pass the object to some module that only knows about lotteries, and
which treats it via a lottery & reference, and that module calls draw, it will
call the override! Likewise, of course, if you pass it to some graphic subystem
that treats is as a graphic, the call to draw also calls the override.

So Pascal's basic thesis is correct: if you have a class system with
overrideable members, and you only have a module system for global bindings,
you get clashes like this.

C++ doesn't effectively have a module system at the class level, because it
treats "lottery::draw" and "graphic::draw" as the same item under inheritance.
C++ namespaces can't fix the problem either because they don't work inside
classes. (Equivalent as Pascal's observation).
From: Didier Verna
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <muxskoxv2wr.fsf@uzeb.lrde.epita.fr>
Kaz Kylheku <········@gmail.com> wrote:

> Your test case is flawed. Although you have demonstrated that multiple
> classes in the hiearchy can have a separate definition for slot, what
> is missing is this:
>
> 1. The observation that this is a semantic feature of C++ which makes
> it impossible to override "slot". In other words, C++ fails to provide
> virtual data members, instead giving us something that resembles C
> structs.

  Pascal didn't seem to refer to slot overriding; only having different
slots with the same name kept separate. But I agree that virtual data
members is missing from C++. Not sure this has anything to do with the
original discussion though.

> 2. The observation that C++ does provide overrideable functions, for
> which the example would behave quite differently.

  The situation is even more complex than that:

- virtual functions can be overridden provided that the return value
  type is covariant and the arguments types are INVARIANT (not even just
contravariant as would only be required to guarantee type safety),
- non-virtual functions can be overloaded (same name but different
  prototypes will be considered as different functions),

- and (and this is were the fun begins): virtual functions not complying
with the covariance/invariance rule will be considered different
(overloadable) ones; so for instance

virtual void lottery::draw (int wireframep)

and later

virtual void graphic_lottery::draw () // oops, forgot the argument

are different functions (you don't even get a warning). Then, if you

lottery *mylot = new graphic_lottery;
mylot->draw (1);

you miss the overridden method.


> So, let's whip out my pet example:
>
>   // two completely different meanings of draw()
>
>   class lottery { public: virtual void draw(); };
>   class graphic { public: virtual void draw(); };
>
>   class graphic_lottery : public lottery, public graphic 
>   { public: void draw(); };
>
> Because draw is a virtual function everywhere, with the same type
> signature, it's considered the same function.
>
> Lexically, the name graphic_lotter::draw still shadows the base class
> definition. But semantically, draw overrides both functions!

  Well, yeah, that's the definition of virtual methods.

> If you pass the object to some module that only knows about lotteries,
> and which treats it via a lottery & reference, and that module calls
> draw, it will call the override!

  Well, yeah, that's the definition of virtual methods :-) But on the
other hand, if draw is a virtual method and your module doesn't want to
use the override, it will go

lot_or_subclass->lottery::draw ();

instead of just 

lot_or_subclass->draw ();

So you still have a separation between different implementations of the
same virtual method.

I still fail to see how all this is relevant to either Pascal's
argument, or to the original point, which was that CL packages operate
at read time instead of at a later stage.

-- 
Resistance is futile. You will be jazzimilated.

Scientific site:   http://www.lrde.epita.fr/~didier
Music (Jazz) site: http://www.didierverna.com

EPITA/LRDE, 14-16 rue Voltaire, 94276 Le Kremlin-Bic�tre, France
Tel. +33 (0)1 44 08 01 85       Fax. +33 (0)1 53 14 59 22
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081225045913.537@gmail.com>
On 2008-12-09, Didier Verna <······@lrde.epita.fr> wrote:
> Kaz Kylheku <········@gmail.com> wrote:
>
>> Your test case is flawed. Although you have demonstrated that multiple
>> classes in the hiearchy can have a separate definition for slot, what
>> is missing is this:
>>
>> 1. The observation that this is a semantic feature of C++ which makes
>> it impossible to override "slot". In other words, C++ fails to provide
>> virtual data members, instead giving us something that resembles C
>> structs.
>
>   Pascal didn't seem to refer to slot overriding; only having different
> slots with the same name kept separate.

Which C++ does by making them a different slot, but which it doesn't
do for functions.

The inconsistency itself perfectly illustrate's Pascal's point.

Namespacing rules are shoehorned into reference semantics.

> But I agree that virtual data
> members is missing from C++. Not sure this has anything to do with the
> original discussion though.

It has everything to do with it, because of C++ had virtual
data members, you'd have a problem under inheritance.

>> 2. The observation that C++ does provide overrideable functions, for
>> which the example would behave quite differently.
>
>   The situation is even more complex than that:
>
> - virtual functions can be overridden provided that the return value
>   type is covariant and the arguments types are INVARIANT (not even just
> contravariant as would only be required to guarantee type safety),
> - non-virtual functions can be overloaded (same name but different
>   prototypes will be considered as different functions),
>
> - and (and this is were the fun begins): virtual functions not complying
> with the covariance/invariance rule will be considered different
> (overloadable) ones; so for instance
>
> virtual void lottery::draw (int wireframep)
>
> and later
>
> virtual void graphic_lottery::draw () // oops, forgot the argument
>
> are different functions (you don't even get a warning). Then, if you
>
> lottery *mylot = new graphic_lottery;
> mylot->draw (1);
>
> you miss the overridden method.
>
>
>> So, let's whip out my pet example:
>>
>>   // two completely different meanings of draw()
>>
>>   class lottery { public: virtual void draw(); };
>>   class graphic { public: virtual void draw(); };
>>
>>   class graphic_lottery : public lottery, public graphic 
>>   { public: void draw(); };
>>
>> Because draw is a virtual function everywhere, with the same type
>> signature, it's considered the same function.
>>
>> Lexically, the name graphic_lotter::draw still shadows the base class
>> definition. But semantically, draw overrides both functions!
>
>   Well, yeah, that's the definition of virtual methods.

Well, the point is that this is a stupid definition. C++ has
a jumble of confused lookup rules.  Sometimes two class members
which have the same name are considered to be defining the
same thing, sometimes they are completely unrelated.

>> If you pass the object to some module that only knows about lotteries,
>> and which treats it via a lottery & reference, and that module calls
>> draw, it will call the override!
>
>   Well, yeah, that's the definition of virtual methods :-) But on the
> other hand, if draw is a virtual method and your module doesn't want to
> use the override, it will go
>
> lot_or_subclass->lottery::draw ();

That's no good, because you have defeated virtual dispatch.

The code here must not assume that it has a lottery
object.

> So you still have a separation between different implementations of the
> same virtual method.

But if I access them that way, they cease to be virtual.

There is still the fact that my graphic_lottery::draw overrides
both lottery drawing and graphical drawing. That's the function
that is reached by virtual dispatch on either base class.

> I still fail to see how all this is relevant to either Pascal's
> argument, or to the original point, which was that CL packages operate
> at read time instead of at a later stage.

The point is that with symbol packaging, we would have LOTTERY::DRAW
and GRAPHIC::DRAW generic functions. They are different symbols.

For the multiply-derived class, we could independently define methods for
these, so we could customize the drawing and the lottery picking.

(And no, this doesn't really have anything to with method and class separation,
because the same reasoning applies to slots).

C++ doesn't have symbol packaging, so namespace issues are entangled into a
confusing mess of lookup rules that involve semantics of type matching and
whatnot.

These two instances of draw /are/ considered the same symbol because of type
signatures and return value of coinheritance. These two are not the same symbol
because they are data members in different classes. Etc.

C++ illustrate's Pascal's points very well:

P> IMHO, packages, i.e. managing the mapping from strings to symbols, solve
P> the problem better than modules, i.e. managing the mapping from
P> identifiers to concepts.
P> [ ... ]
P>Because they can make distinctions that you cannot make with module systems.
P>For example, if you had only a module system, a class would not be able to
P>inherit from two different classes with slots of the same name and be able to
P>keep them as two different slots (unless you come up with funky renaming
P>mechanisms, like in the R6RS module system, for example).

The clash between the unrelated draw virtual functions shows how you are not
able to inherit from two classes and keep two different draw functions.  They
are considered the same, and the proof is that you can write a single draw that
overrides both. There is in fact only one draw symbol, which is why those
functions can be connected together through that name.  Scope resolution
doesn't help because it defeats virtual dispatch.

This is the consequence of handling namespace issues at the module (i.e. in
this case class) level. The consequence is that class_a::foo and class_b::foo
are different things, only not really.

The symbols GRAPHIC::DRAW and LOTTERY::DRAW would never be connected
together, except by some devious mechanism that looks at SYMBOL-NAME
equivalence.
From: Pascal Costanza
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <6qcnr1FbpmeoU2@mid.individual.net>
Didier Verna wrote:
> Pascal Costanza wrote:
> 
>> Because they can make distinctions that you cannot make with module
>> systems. For example, if you had only a module system, a class would
>> not be able to inherit from two different classes with slots of the
>> same name and be able to keep them as two different slots (unless you
>> come up with funky renaming mechanisms, like in the R6RS module
>> system, for example).
> 
>   I'm not sure I follow you.
> 
> #include <iostream>
> 
> struct foo1
> {
>   foo1 () { slot = 1; };
>   int slot;
> };
> 
> struct foo2
> {
>   foo2 () { slot = 2; };
>   int slot;
> };
> 
> struct mystruct : public foo1, foo2
> {
>   mystruct () { slot = 0; };
>   int slot;
> };
> 
> 
> int main (int argc, char *argv[])
> {
>   mystruct ms;
>   std::cout << ms.slot << ms.foo2::slot << ms.foo1::slot << std::endl;
> }
> 
> ./test => 021

Right. I wasn't precise enough.

You wouldn't be able to keep the slots separate without support from the 
language construct that you're dealing with (here structs). In C, 
structs are forced to come up with a semantics for dealing with 
nameclashes, and as Kaz pointed out, the resolutions are different 
depending on whether you deal with slots or methods.

For every new language construct with similar characteristics, you would 
have to do this exercise again and again, with the danger that different 
language constructs may have slightly different semantics. For example, 
Common Lisp may have resulted in a language where defstruct, defclass 
and define-condition have different resolution mechanisms for such 
nameclashes, and if I wanted to add a new kind of data structure (using 
macros, etc.), I would have to think about this again.

Packages solve this ones, and it's orthogonal to other constructs in the 
language. I don't have to think about such things anymore. I think 
that's a big advantage.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081223003443.688@gmail.com>
On 2008-12-07, Ron Garret <·········@flownet.com> wrote:
> In article <··············@mid.individual.net>,
>  Pascal Costanza <··@p-cos.net> wrote:
>
>> IMHO, packages, i.e. managing the mapping from strings to symbols, solve 
>> the problem better than modules, i.e. managing the mapping from 
>> identifiers to concepts.
>
> Why?

Because we have symbols as a first-class data type. So we need packages to work
everywhere, including in data:

  (setf foo::y 42)

  (quote foo::x)

Lis packages have to work they way they do because in general, you do not know
what symbols in a form are evaluated normally, which symbols are evaluated
according to special rules, and which ones not at all.

Packaging symbols provides the right separation of concerns, for instance in OO
programming.

We can define a class in which the slots belong to different packages. We can
write methods that are named by symbols in different packages, yet specialize
on the same object.

This is very nice; given some existing class, I can extend that class in my own
module, using identifiers from my namespace.

  (in 'my-namespace)

  (defclass my-class (other-namespace:base)
    ((my-slot :accessor my-slot ...)))

All of the slots of other-namespace:base are named using other-namespace
symbols, and so are the existing generic functions.

I can make my own slots and generic functions in my own namespace.

This does not cause a problem when we are referencing slots:

  (slot-value instance 'my-slot)
  (slot-value instance 'other-namespace:foo)

The alternative solution would be to make namespacing a part of slot lookup
(i.e. the mapping of the symbol to the concept). If symbols don't have
namespaces, you have to invent qualified identifiers to deal with this:

Suppose that you inherit from two base classes A and B that both define a slot
FOO.  Compound identifier would have to be introduced to solve the
disambiguation problem:

 (slot-value instance '(a foo)) ;; the foo from base A

 (slot-value instance '(b foo)) ;; the foo from base B

Also keep in mind that slot-value is a function, not a special operator, so it
cannot pull a namespace context from lexical scope. Suppose that in some scope
you want you want (slot-value instance 'foo) to behave like (slot-value
instance '(a foo)).  You need now need a dynamically scoped mapping of
unqualified identifiers to qualified ones.  It smells like big-time suckage!
From: Mark Wooding
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <slrngke415.k2f.mdw@metalzone.distorted.org.uk>
Pascal Costanza <··@p-cos.net> wrote:

> IMHO, packages, i.e. managing the mapping from strings to symbols,
> solve the problem better than modules, i.e. managing the mapping from
> identifiers to concepts.

Certainly in a Lisp-2+, like Common Lisp, it makes a lot of sense
putting the `namespace control' at the string-to-symbol stage, as CL
does, rather than at the (multiple) symbol-to-think stages.  This makes
the namespace control entirely orthogonal to the namespaces themselves:
functions, variables, macros, types, class names, method combinations,
method qualifiers, slot names, block names, catch tags, go labels, (yes,
in the presence of a powerful macro system, the package system is useful
with all of these) all handled in the same elegant way.

It also lets you do some valuable things which, as far as I know, no
other language can.  For example, the names for the slots defined by a
class form a little namespace in most languages.  Unfortunately, this
namespace is usually shared with the class's subclasses and descendants,
which makes adding new slots later a dicey business, and can make
multiple inheritance an utter nightmare.  (C++ users will use this as an
excuse for their utterly broken MI.)  Lisp users, with their package
system, will almost certainly have stashed the slot names in distinct
packages in the first place and never notice that there was a problem.

-- [mdw]
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081223010136.451@gmail.com>
On 2008-12-07, Ron Garret <·········@flownet.com> wrote:
> In article 
><····································@j11g2000yqg.googlegroups.com>,
>  Slobodan Blazeski <·················@gmail.com> wrote:
>
>> May somebody please explain me with simple words why cl packages are
>> hard to use, 'couse I really don't get it?
>> The best is probably to hear from somebody who just learned lisp or
>> somebody who teaches lisp (do such people exist anymore?) and his/her
>> students has problems with packages.
>> 
>> bobi
>
> Packages aren't "hard to use", they just do the Wrong Thing ;-)  
> Packages operate at read-time, but most programmer's intuitions about 
> modularity relate to global bindings, which is a compile-time concept.
>
> The biggest practical problem with packages, and the central motivation 
> for lexicons, is that exported symbol lists have to be maintained 
> manually.

Exporting symbols is braindamaged. The solution is: don't manage exported lists.

What is the purpose of exporting symbols?

One purpose is documentary: by exporting certain symbols, you are asserting
that they are yoru public interface.

But exported symbols are not just documentary. What does the machine actually
let us do with exported symbols?

It lets us apply USE-PACKAGE, (or the :USE clause in DEFPACKAGE). This is
called package inheritance: all of the exported symbols of another package
become visible in this one.

USE-PACKAGE is a braindamaged concept borrowed from other languages.

The proper engineering solution is to maintain explicit import lists: pick
every single identifier from a foreign package that you wish to use locally as
an unqualified name, and explicitly install it into your current scope.

Can you come up with a hack that lets me choose exactly which identifiers I
pull in from some namespace (regardless of what that namespace says it
exports), without having to maintain import lists?

That would be useful. But I don't see how; thep roblem implicitly calls for
list maintenance. I mean, you have to write down the symbols that you want.
That's a list.

Now as far as export lists go, the difficulty of maintaining them isn't due to
any fundamental property of Lisp packages. The automation of export lists could
be added to Lisp packages without changing the design.

Like with import lists, the programmer ultimately has to indicate to the
machine that he wants certain symbols exported. And that constitutes a list!
Your complaint is that you have to write down this list in some place (like
your DEFPACKAGE) in addition to all the other definitions elsewhere that assign
meaning to those symbols (like DEFMETHOD-s, DEFUN-s, DEFCLASS-es, etc).

One way to solve that might be to have some kind of special state in a package
so that you could do this:

  ;; top level
  (in-package 'foo)

  (public)

  (defun foo ...)

  (private)

  (defun bar ...)

PUBLIC and PRIVATE would set and reset some flag, and defining constructs could
use it to export or not export the name which they are defining.

The problem with this is that a package definition is often put into a separate
file which is loaded by everyone. That file has to do the complete job of
establishing what is exported and what isn't. You cannot leave it to a bunch of
load-time side effects.

With the above mechanism, if module A depends on B, B has to be loaded first,
so that all of these effects in its toplevel forms are elaborated before
anything is done with A.

In other words, mantaining export lists is simply a consequence of  applying ad
ependency inversion to decouple module dependencies.

> This violates the DRY principle, and makes maintenance more 
> difficult than it needs to be, rather like the burden imposed by C on 
> the programmer to maintain the .c file and the .h files in parallel.  

If you do not maintain an interface and implementation separately (either as
separate files or as sections of the same file, as is the case with some
langauges), it means that in before processing module B that depends on A, the
language implementation has to process all of A, so that it could pull out the
interface information that is implicitly distributed throughout B.

C header files, crude as the mechanism is, do allow us to compile some foo.c
that uses bar.h, without having access bar.c, or any representation of it.

In order to have an efficient interface/implementation mechanim (i.e. not like
that of C) you'd need some kind of special support. I.e. there wuold have to be
a way of processing a file, similar to COMPILE-FILE, which would digest all of
the interface information and spit it into some kind of efficient form: perhaps
some special interface file: like a fasl, but with no code. Or maybe a special
section of a fasl.

When a module B uses A, the compiler would pull out A's digested interface info
(refreshing it first, if the source of A is newer).  In this way, B could be
compiled without doing a complete compilation of A.

You know, you could develop an annotation system for Lisp modules which would
allow such processing. Code is data right?

Let's say we have this syntax:

  (module foo)

  :public

  (defun x ...)

  :private

  (defun y ...)

You could cob together a Lisp build system which will munge source code and
generate the defpackage definitions, with export lists and all.

The above would result in there being a (DEFPACKAGE FOO ...) somewhere
which exports the symbol X.
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-5A53A1.14202207122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> Can you come up with a hack that lets me choose exactly which identifiers I
> pull in from some namespace (regardless of what that namespace says it
> exports), without having to maintain import lists?
> 
> That would be useful. But I don't see how; thep roblem implicitly calls for
> list maintenance. I mean, you have to write down the symbols that you want.
> That's a list.

Yes, but it does not follow that those lists need to be generated by 
manually writing down all of their members.  For example, I might want 
to be able to say, "I want to use class C1" and automatically get all of 
the symbols (slot names, associated methods, etc.) associated with that 
class without having to manually list them all.

> Now as far as export lists go, the difficulty of maintaining them isn't due 
> to
> any fundamental property of Lisp packages. The automation of export lists 
> could
> be added to Lisp packages without changing the design.

Really?  How?  In particular, how do you distinguish between those 
symbols in the package that actually have functionality associated with 
them versus those that got interned there as a side-effect of some other 
process (like someone mistyping something into an interactive session)?

> One way to solve that might be to have some kind of special state in a 
> package
> so that you could do this:
> 
>   ;; top level
>   (in-package 'foo)
> 
>   (public)
> 
>   (defun foo ...)
> 
>   (private)
> 
>   (defun bar ...)
> 
> PUBLIC and PRIVATE would set and reset some flag, and defining constructs 
> could
> use it to export or not export the name which they are defining.

How would this work if I'm doing interactive development?

How would it know to export my slot names and accessor function names?

What if I defined a macro that defined other things, how would those 
things get exported?

> > This violates the DRY principle, and makes maintenance more 
> > difficult than it needs to be, rather like the burden imposed by C on 
> > the programmer to maintain the .c file and the .h files in parallel.  
> 
> If you do not maintain an interface and implementation separately (either as
> separate files or as sections of the same file, as is the case with some
> langauges), it means that in before processing module B that depends on A, 
> the
> language implementation has to process all of A, so that it could pull out 
> the
> interface information that is implicitly distributed throughout B.

Yes.  So?


> C header files, crude as the mechanism is, do allow us to compile some foo.c
> that uses bar.h, without having access bar.c, or any representation of it.

Yes.  So the programmer has to do a lot of work to make the compiler's 
work easier.  I thought computers were supposed to make our lives 
easier, not vice-versa.


> In order to have an efficient interface/implementation mechanim (i.e. not 
> like
> that of C) you'd need some kind of special support. I.e. there wuold have to 
> be
> a way of processing a file, similar to COMPILE-FILE, which would digest all 
> of
> the interface information and spit it into some kind of efficient form: 
> perhaps
> some special interface file: like a fasl, but with no code. Or maybe a 
> special
> section of a fasl.

Not necessarily.  Lexicons are implemented so that bindings can be 
resolved at run-time if needed.  The bindings are cached so the overhead 
is only incurred once (and it's only a hash-table lookup, so it's pretty 
minimal overhead anyway).


> When a module B uses A, the compiler would pull out A's digested interface 
> info
> (refreshing it first, if the source of A is newer).  In this way, B could be
> compiled without doing a complete compilation of A.
> 
> You know, you could develop an annotation system for Lisp modules which would
> allow such processing. Code is data right?
> 
> Let's say we have this syntax:
> 
>   (module foo)
> 
>   :public
> 
>   (defun x ...)
> 
>   :private
> 
>   (defun y ...)
> 
> You could cob together a Lisp build system which will munge source code and
> generate the defpackage definitions, with export lists and all.
> 
> The above would result in there being a (DEFPACKAGE FOO ...) somewhere
> which exports the symbol X.

The problem is that in the presence of macros there's no way to know 
what all is being defined without actually running the code.

rg
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081223035936.954@gmail.com>
On 2008-12-07, Ron Garret <·········@flownet.com> wrote:
> In article <··················@gmail.com>,
>  Kaz Kylheku <········@gmail.com> wrote:
>> In order to have an efficient interface/implementation mechanim (i.e. not 
>> like
>> that of C) you'd need some kind of special support. I.e. there wuold have to 
>> be
>> a way of processing a file, similar to COMPILE-FILE, which would digest all 
>> of
>> the interface information and spit it into some kind of efficient form: 
>> perhaps
>> some special interface file: like a fasl, but with no code. Or maybe a 
>> special
>> section of a fasl.
>
> Not necessarily.  Lexicons are implemented so that bindings can be 
> resolved at run-time if needed.  The bindings are cached so the overhead 
> is only incurred once (and it's only a hash-table lookup, so it's pretty 
> minimal overhead anyway).

Compilers need to know about bindings. For instance, an inline function cannot
be procedurally integrated by a compiler, if it's called through a binding that
is resolved at run-time.

it's nice to be able to defer bindings to run time, but you can't use that
to solve problems at the cost of interfering with compilation.

>> When a module B uses A, the compiler would pull out A's digested interface 
>> info
>> (refreshing it first, if the source of A is newer).  In this way, B could be
>> compiled without doing a complete compilation of A.
>> 
>> You know, you could develop an annotation system for Lisp modules which would
>> allow such processing. Code is data right?
>> 
>> Let's say we have this syntax:
>> 
>>   (module foo)
>> 
>>   :public
>> 
>>   (defun x ...)
>> 
>>   :private
>> 
>>   (defun y ...)
>> 
>> You could cob together a Lisp build system which will munge source code and
>> generate the defpackage definitions, with export lists and all.
>> 
>> The above would result in there being a (DEFPACKAGE FOO ...) somewhere
>> which exports the symbol X.
>
> The problem is that in the presence of macros there's no way to know 
> what all is being defined without actually running the code.

But you have that problem regardless. For instance, Lexicons provides
alternatives to some some well-known defining macros, but not all.

The build system for the above modules could hack it with some simple guesses.
here are some heuristics that would work ``99%'' of the time:

1. Any symbol that is at the immediate level of a toplevel compound form, and
   that is interned in the module's package, is being defined.

   Example:

      (module :goop
        (:uses :blorg))

      :public

      (define-blorg zorch (squiggle ..))


   Here, the package in effect is GOOP. (DEFINE-BLORG ...) is a toplevel
   form, with two symbols at the highest nesting level: DEFINE-BLORG
   and ZORCH. DEFINE-BLORG comes from the BLORG package. ZORCH is interned
   in GOOP. It's in a :PUBLIC section, so we add it to the list of 
   exported symbols.  We know nothing about what DEFINE-BLORG does,
   only that it's a form appearing in the :EXPORT section.
   The symbol SQUIGGLE is ignored by this analysis, even though it's
   in the BLORG package.

2. A toplevel form is understood properly, with regard for PROGN, EVAL-WHEN
   and the rest:

     :public

     (eval-when (... situations ...)
       (define-blorg zorch ...)) ;; zorch exported


You know, maybe even having an explicit export construct would help. Experience
in the Linux kernel, for instance, tells me that it's not much of a bother to
do:

  void some_function(...)
  {
  }
  EXPORT_SYMBOL(some_function)

In spite of the repetition, there is value in the exporting being locate near
the function rather than in some list somewhere else.  If you decide to delete
the function or move it elsewhere, all you have to do is extend the scope of
your edit over one additional line.

So for the cases where the simple heuristic doesn't work, the programmer could
use an explicit export directive.

Also, there could be an API into the system that would allow the programmer to
teach it where the defined symbols are in particular forms.

Suppose you have a 

  (DEFINE-ZARK (:OP (STRANGE-ZARK) ...))

The name STRANGE-ZARK is embedded in the list. Using some interface, you could
associate the symbol DEFINE-ZARK with a ``name extractor'' hook. The module
system, seeing that DEFINE-ZARK appears in a :PUBLIC section, would then run
this test: (GET-NAME-EXTRACTOR-P 'DEFINE-ZARK). If this returns a function, it
is invoked like this (FUNCALL EXTRACTOR '(DEFINE-ZARK (:OP (STRANGE-ZARK)
...))) and it returns a list of names, namely (STRANGE-ZARK). These are then
added to the list of exported symbols.

The entire project is scanned this way and ther results are automatically
compiled into a repository of generated files containing DEFPACKAGE forms.

The build system arranges for everything to be loaded in the right order,
and the (MODULE ...) construct in each file expands to some forms like
(IN-PACKAGE) and whatnot.

The defining of name extractors would be in the (MODULE ...) syntax, of course.

  ;;; module ZARK: provides ZARK:DEFINE-ZARK, with an
  ;;; associated name extractor.

  (module :zark
    (:name-extractors
      (define-zark ((form)
                    (second (second form)))))
    ...)

  :public
 
  (defmacro define-zark ...)
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-508306.23350607122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-07, Ron Garret <·········@flownet.com> wrote:
> > In article <··················@gmail.com>,
> >  Kaz Kylheku <········@gmail.com> wrote:
> >> In order to have an efficient interface/implementation mechanim (i.e. not 
> >> like
> >> that of C) you'd need some kind of special support. I.e. there wuold have 
> >> to 
> >> be
> >> a way of processing a file, similar to COMPILE-FILE, which would digest 
> >> all 
> >> of
> >> the interface information and spit it into some kind of efficient form: 
> >> perhaps
> >> some special interface file: like a fasl, but with no code. Or maybe a 
> >> special
> >> section of a fasl.
> >
> > Not necessarily.  Lexicons are implemented so that bindings can be 
> > resolved at run-time if needed.  The bindings are cached so the overhead 
> > is only incurred once (and it's only a hash-table lookup, so it's pretty 
> > minimal overhead anyway).
> 
> Compilers need to know about bindings. For instance, an inline function 
> cannot
> be procedurally integrated by a compiler, if it's called through a binding 
> that
> is resolved at run-time.
> 
> it's nice to be able to defer bindings to run time, but you can't use that
> to solve problems at the cost of interfering with compilation.

There's no difference in this respect between lexicons and packages.  In 
both cases, if you know the binding at compile time the compiler can use 
it.  If you don't, it can't.

> >> When a module B uses A, the compiler would pull out A's digested interface 
> >> info
> >> (refreshing it first, if the source of A is newer).  In this way, B could 
> >> be
> >> compiled without doing a complete compilation of A.
> >> 
> >> You know, you could develop an annotation system for Lisp modules which 
> >> would
> >> allow such processing. Code is data right?
> >> 
> >> Let's say we have this syntax:
> >> 
> >>   (module foo)
> >> 
> >>   :public
> >> 
> >>   (defun x ...)
> >> 
> >>   :private
> >> 
> >>   (defun y ...)
> >> 
> >> You could cob together a Lisp build system which will munge source code 
> >> and
> >> generate the defpackage definitions, with export lists and all.
> >> 
> >> The above would result in there being a (DEFPACKAGE FOO ...) somewhere
> >> which exports the symbol X.
> >
> > The problem is that in the presence of macros there's no way to know 
> > what all is being defined without actually running the code.
> 
> But you have that problem regardless. For instance, Lexicons provides
> alternatives to some some well-known defining macros, but not all.

What's missing?

rg
From: Kenny
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <493c0b0b$0$14309$607ed4bc@cv.net>
Slobodan Blazeski wrote:
> May somebody please explain me with simple words why cl packages are
> hard to use, 'couse I really don't get it?
> The best is probably to hear from somebody who just learned lisp or
> somebody who teaches lisp (do such people exist anymore?) and his/her
> students has problems with packages.
> 
> bobi


Sure!:

http://smuglispweeny.blogspot.com/2008/12/why-lisp-packages-are-so-easy-hard.html

hth, kzo
From: Brian Adkins
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <m2d4g3dg10.fsf@gmail.com>
Kenny <·········@gmail.com> writes:

> Slobodan Blazeski wrote:
>> May somebody please explain me with simple words why cl packages are
>> hard to use, 'couse I really don't get it?
>> The best is probably to hear from somebody who just learned lisp or
>> somebody who teaches lisp (do such people exist anymore?) and his/her
>> students has problems with packages.
>>
>> bobi
>
>
> Sure!:
>
> http://smuglispweeny.blogspot.com/2008/12/why-lisp-packages-are-so-easy-hard.html
>
> hth, kzo

Also, http://gigamonkeys.com/book/programming-in-the-large-packages-and-symbols.html

-- 
Brian Adkins
http://www.lojic.com/
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-55DF5D.10105707122008@news.gha.chartermi.net>
In article <··············@gmail.com>,
 Brian Adkins <···········@gmail.com> wrote:

> Kenny <·········@gmail.com> writes:
> 
> > Slobodan Blazeski wrote:
> >> May somebody please explain me with simple words why cl packages are
> >> hard to use, 'couse I really don't get it?
> >> The best is probably to hear from somebody who just learned lisp or
> >> somebody who teaches lisp (do such people exist anymore?) and his/her
> >> students has problems with packages.
> >>
> >> bobi
> >
> >
> > Sure!:
> >
> > http://smuglispweeny.blogspot.com/2008/12/why-lisp-packages-are-so-easy-hard
> > .html
> >
> > hth, kzo
> 
> Also, 
> http://gigamonkeys.com/book/programming-in-the-large-packages-and-symbols.html

Ah what the hell.

http://www.flownet.com/ron/packages.pdf

rg
From: Pascal J. Bourguignon
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <8763lwrtwo.fsf@informatimago.com>
Slobodan Blazeski <·················@gmail.com> writes:

> May somebody please explain me with simple words why cl packages are
> hard to use, 'couse I really don't get it?

Well, I'd say you're the best placed to explain with simple words why CL
packages are hard to use, because for us they are not hard to use.

But if you cannot explaint it with simple words, you may also use
complicated words, we've got good dictionaries.


> The best is probably to hear from somebody who just learned lisp or
> somebody who teaches lisp (do such people exist anymore?) and his/her
> students has problems with packages.



I don't find CL packages hard to use.  On the contrary, they're a very
simple concept, and at the same time they're very powerful.


Let's start without packages, and try to solve some simple practical
problems.

Assume we create two symbols with the same name, "ABC", and "bind" them
to different values:

[11]> (list (list (make-symbol "ABC") 1) (list (make-symbol "ABC") 2))
((#:ABC 1) (#:ABC 2))


Then we can find a symbol from a name, for example when we read the
string "ABC" from the user, we wan to find what symbol it corresponds
to, and retrieve its value:

[12]> (let ((syms (list (list (make-symbol "ABC") 1) (list (make-symbol "ABC") 2))))
        (second (find "ABC" syms :key (function first) :test (function string=))))
1

But how could we find instead the other symbol named "ABC", with value
2?  The solution proposed is to put the symbols in different
lists, named "packages", having different names.  So now, we can find a
symbol named "ABC" in a current 'package' refered to by *pack*, or a
symbol named "ABC" qualified by a package name such as "YOUR::ABC".

[14]> (let ((packs (list (list "MINE" (list (make-symbol "ABC") 1))
                         (list "YOUR" (list (make-symbol "ABC") 2))))
            (*pack* "MINE"))
  (list (second (find "ABC" (rest (find *pack* packs
                                        :key (function first) :test (function string=)))
                      :key (function first) :test (function string=)))
        (second (find "ABC" (rest (find "YOUR" packs
                                        :key (function first) :test (function string=)))
                      :key (function first) :test (function string=)))))
(1 2)


CL:IMPORT puts a symbol on the list of symbols of a package.
CL:FIND-SYMBOL finds a symbol in the list of symbols of a package.
CL:FIND-PACKAGE finds a package in the list of packages.

CL:INTERN does both CL:FIND-SYMBOL, and if not found, CL:MAKE-SYMBOL and CL:IMPORT.


With CL:USE-PACKAGE, there's a little technicality,  in that the symbols
from the used packages are not really "interned" or "imported" into the
using package, but it works most of the time exactly the same.



Each package maintains also a list of "exported" symbols, and this is
used only to signal an error when you try to read a qualified symbol
that is not exported with only one colon.

              SYMB is exported from PACK    SYMB is not exported from PACK
PACK:SYMB              ok                             error
PACK::SYMB             ok                               ok



-- 
__Pascal Bourguignon__
From: Ron Garret
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <rNOSPAMon-A49420.10083107122008@news.gha.chartermi.net>
In article <··············@informatimago.com>,
 ···@informatimago.com (Pascal J. Bourguignon) wrote:

> I don't find CL packages hard to use.  On the contrary, they're a very
> simple concept, and at the same time they're very powerful.

That's true, but...

> Let's start without packages, and try to solve some simple practical
> problems.
> 
> Assume we create two symbols with the same name, "ABC", and "bind" them
> to different values:
> 
> [11]> (list (list (make-symbol "ABC") 1) (list (make-symbol "ABC") 2))
> ((#:ABC 1) (#:ABC 2))

With all due respect, this is not the kind of "practical problem" that 
most programmers deal with on a day-to-day basis, particularly not when 
they are starting out.  Using MAKE-SYMBOL is a pretty advanced concept, 
and using it to make multiple symbols with the same name is a pretty 
esoteric technique.  In fact, the whole concept of an uninterned symbol 
is pretty advanced.  Peter Seibel's book, for example, doesn't even 
mention them until chapter 21, and then only in passing.  MAKE-SYMBOL is 
not mentioned at all.

The vast majority of symbols that beginning and work-a-day Lispers deal 
with are interned by the reader, and most non-advanced Lisp programmers 
think about modular programming in terms of exporting functions, 
classes, macros, and methods, not symbols.  If you doubt this, do a 
Google search in c.l.l. for "How do I export a function?" and see how 
many hits you get.

rg
From: Pascal J. Bourguignon
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <7c8wqr9gcc.fsf@pbourguignon.anevia.com>
Ron Garret <·········@flownet.com> writes:

> In article <··············@informatimago.com>,
>  ···@informatimago.com (Pascal J. Bourguignon) wrote:
>
>> I don't find CL packages hard to use.  On the contrary, they're a very
>> simple concept, and at the same time they're very powerful.
>
> That's true, but...
>
>> Let's start without packages, and try to solve some simple practical
>> problems.
>> 
>> Assume we create two symbols with the same name, "ABC", and "bind" them
>> to different values:
>> 
>> [11]> (list (list (make-symbol "ABC") 1) (list (make-symbol "ABC") 2))
>> ((#:ABC 1) (#:ABC 2))
>
> With all due respect, this is not the kind of "practical problem" that 
> most programmers deal with on a day-to-day basis, particularly not when 
> they are starting out.  Using MAKE-SYMBOL is a pretty advanced concept, 
> and using it to make multiple symbols with the same name is a pretty 
> esoteric technique.  In fact, the whole concept of an uninterned symbol 
> is pretty advanced.  Peter Seibel's book, for example, doesn't even 
> mention them until chapter 21, and then only in passing.  MAKE-SYMBOL is 
> not mentioned at all.
>
> The vast majority of symbols that beginning and work-a-day Lispers deal 
> with are interned by the reader, and most non-advanced Lisp programmers 
> think about modular programming in terms of exporting functions, 
> classes, macros, and methods, not symbols.  If you doubt this, do a 
> Google search in c.l.l. for "How do I export a function?" and see how 
> many hits you get.

Sorry, I didn't explain well enough what I was doing and what problems
were being solved.  I took the point of view of the implementor or
language designer, and starting from the simple notion of symbol, how
do we implement a reader and some system to be able to have different
symbols with the same name.  That is, how do we defined different
namespaces. 

Introducing named packages that can contain a set of symbol, we can
qualify our symbols with the name of some package, and therefore we
can access two symbols with the same name by prefixing them with the
package name.  Q&D but effective namespaces.  



Actually since we didn't consider anything else than symbols, symbol
names and package names to build the notion of package, this is
totally orthogonal to the rest of the language, and can therefore be
applied very effectively and modularly to any namespace problem.


For example, in CL you can very easily add methods to be applied to
pre-defined classes (either built-in or coming from libraries) without
any risk of method name clash, because method names are symbols, and
symbols in different packages can be different symbols.




To contrast with the situation in Ruby, where you can effectively add
a method to a predefined class:

(class Array
  (def find(element , options = {:key => (function :identity,0), :test (function :==,1),
                                 :start => 0, :end => nil})
      ...
   end)
end)

but unfortunately, this is done in the namespace of the Array class,
and since Ruby is not Lisp, Greenspuning happends everywhere and some
other library will defined a find method too.  Name collision, breakage.

So you have to use modules, but then you still cannot include modules,
since when you do so, the methods defined in the module latest
included override any method previously defined in the class or
included from another module.

Therefore you cannot define methods, but you have to define functions
in modules if you want to use namespace separation in Ruby.  Lame.


-- 
__Pascal Bourguignon__
From: Kaz Kylheku
Subject: Re: why cl packages are hard to use ?
Date: 
Message-ID: <20081223002805.959@gmail.com>
On 2008-12-07, Pascal J. Bourguignon <···@informatimago.com> wrote:
> Slobodan Blazeski <·················@gmail.com> writes:
>
>> May somebody please explain me with simple words why cl packages are
>> hard to use, 'couse I really don't get it?
>
> Well, I'd say you're the best placed to explain with simple words why CL
> packages are hard to use, because for us they are not hard to use.
>
> But if you cannot explaint it with simple words, you may also use
> complicated words, we've got good dictionaries.

I.e. we have lexicons to deal with hard-to-use packages of verbiage. :)
From: David Golden
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <ghha9u$fmh$1@aioe.org>
Ron Garret wrote:


> I did it this way because I thought that it would make package fans
> feel warmer and fuzzier about lexicons to know that the binding of a
> symbol S
> in lexicon L was invariably the symbol L::S.


No, wait. This isn't good.

CL-USER> (defpackage :a)
#<PACKAGE "A">
CL-USER> (defpackage :b)
#<PACKAGE "B">
CL-USER> (make-lexicon :=l=)
#<Lexicon =L=>
CL-USER> (in-lexicon :=l=)
#<Lexicon =L=>
CL-USER> (ldefun a::x () "one")
=L=::X
CL-USER> (ldefun b::x () "two")
STYLE-WARNING: redefining =L=::X in DEFUN
=L=::X
CL-USER> (a::x)
"two"

a::x and b::x are different symbols supporting
different bindings absent lexicons, IMO lexicons should
just allow them to be lexical, not merge them, if lexicons
are truly on another axis to packages.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-0FCCAF.14070907122008@news.gha.chartermi.net>
In article <············@aioe.org>,
 David Golden <············@oceanfree.net> wrote:

> Ron Garret wrote:
> 
> 
> > I did it this way because I thought that it would make package fans
> > feel warmer and fuzzier about lexicons to know that the binding of a
> > symbol S
> > in lexicon L was invariably the symbol L::S.
> 
> 
> No, wait. This isn't good.
> 
> CL-USER> (defpackage :a)
> #<PACKAGE "A">
> CL-USER> (defpackage :b)
> #<PACKAGE "B">
> CL-USER> (make-lexicon :=l=)
> #<Lexicon =L=>
> CL-USER> (in-lexicon :=l=)
> #<Lexicon =L=>
> CL-USER> (ldefun a::x () "one")
> =L=::X
> CL-USER> (ldefun b::x () "two")
> STYLE-WARNING: redefining =L=::X in DEFUN
> =L=::X
> CL-USER> (a::x)
> "two"
> 
> a::x and b::x are different symbols supporting
> different bindings absent lexicons, IMO lexicons should
> just allow them to be lexical, not merge them, if lexicons
> are truly on another axis to packages.

The design intention was that for global bindings one would use either 
packages or lexicons but not both, particularly now that lexicons are 
closely coupled with packages.  Don't forget that every lexicon now has 
a package associated with it, and that the binding of a symbol in a 
lexicon is the symbol with the same name interned in the lexicon's 
package.  So binding P1::FOO and P2::FOO into the same lexicon under the 
current design would require two different symbols named FOO to be 
interned in the same package, which is not possible.

I could "fix" this (fix in scare quotes because it's not clear that this 
is actually a problem) by munging symbol names to include their 
packages, but I fear this would undermine one of the principal design 
goals of lexicons which is to keep things simple and appeal to 
programmers who are used to e.g. Python.

rg
From: David Golden
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <ghhnc2$qsm$1@aioe.org>
Ron Garret wrote:

> In article <············@aioe.org>,


> I could "fix" this (fix in scare quotes because it's not clear that
> this is actually a problem) by munging symbol names to include their
> packages,

Or perhaps it'd be easier to do it in the package name, so that

a:b --> l.a:b

?

The existing hierarchical.package.support in several popular
implementations would handle that easily, though you maybe don't want
to rely on that being present, the subset needed would probably be
straightforward to include locally.

> but I fear this would undermine one of the principal design
> goals of lexicons which is to keep things simple and appeal to
> programmers who are used to e.g. Python.

Shrug.  Well, I'm used to common lisp, and used to package*symbol, not
symbol, being unique.  It just seems an avoidable limitation.  Means
e.g. ldefun etc. aren't transparently substitutable for defun etc.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-797CF3.23370707122008@news.gha.chartermi.net>
In article <············@aioe.org>,
 David Golden <············@oceanfree.net> wrote:

> Shrug.  Well, I'm used to common lisp, and used to package*symbol, not
> symbol, being unique.  It just seems an avoidable limitation.  Means
> e.g. ldefun etc. aren't transparently substitutable for defun etc.

They are (or at least they should be) as long as you are not defining 
symbols with an explicit package qualifier.  I suspect this is the case 
for the vast majority of actual Lisp code.

rg
From: Helmut Eller
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <m2vdtvnl4l.fsf@gmail.com>
* Ron Garret [2008-12-05 17:21+0100] writes:

> Comments and feedback are welcome.

Are lexicons supposed to work with compiled code or only with
interpreted code?

For instance I tried this:

CL-USER> (load "lexicons.lisp")
#P"/home/helmut/lisp/lexicons/lexicons.lisp"                                   CL-USER> (make-lexicon :l1)
#<Lexicon L1>                                                                  CL-USER> (ldefun foo () (bar))
;Compiler warnings :
;   In ROOT::FOO: Undefined function BAR
ROOT::FOO                               
CL-USER> (compile 'foo)
FOO                                                                            NIL                                                                            NIL                                                                            CL-USER> (ldefun bar () (print 'bar))
ROOT::BAR                                                                      CL-USER> (foo)
> Special operator or global macro-function BAR can't be FUNCALLed or APPLYed
   [Condition of type CCL::CALL-SPECIAL-OPERATOR-OR-MACRO]


Helmut.

PS: lexicons.lisp can't be compiled because the function ENV-LEXICON is
needed during compilation.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-BDA96B.08460408122008@news.gha.chartermi.net>
In article <··············@gmail.com>,
 Helmut Eller <············@gmail.com> wrote:

> * Ron Garret [2008-12-05 17:21+0100] writes:
> 
> > Comments and feedback are welcome.
> 
> Are lexicons supposed to work with compiled code or only with
> interpreted code?
> 
> For instance I tried this:
> 
> CL-USER> (load "lexicons.lisp")
> #P"/home/helmut/lisp/lexicons/lexicons.lisp"                                  
>  CL-USER> (make-lexicon :l1)
> #<Lexicon L1>                                                                 
>  CL-USER> (ldefun foo () (bar))
> ;Compiler warnings :
> ;   In ROOT::FOO: Undefined function BAR
> ROOT::FOO                               
> CL-USER> (compile 'foo)
> FOO                                                                           
>  NIL                                                                          
>   NIL                                                                         
>    CL-USER> (ldefun bar () (print 'bar))
> ROOT::BAR                                                                     
>  CL-USER> (foo)
> > Special operator or global macro-function BAR can't be FUNCALLed or APPLYed
>    [Condition of type CCL::CALL-SPECIAL-OPERATOR-OR-MACRO]

This is a known limitation of the current implementation, and is 
described in the documentation in section 3.2.  In brief, you can't 
LDEFUN something after you've refer to it because by then it has already 
been compiled as a call to an unknown function whereas it needs to be 
compiled as a deferred lexical reference.  To fix this requires a code 
walker.

> PS: lexicons.lisp can't be compiled because the function ENV-LEXICON is
> needed during compilation.

They are supposed to work compiled, so this is a bug.  (I use CCL which 
compiles everything by default, so I hardly ever use compile-file.)  I 
don't see offhand what's causing it, and the quick fix I tried didn't 
work, but you can work around this problem by loading the file before 
compiling it.

rg
From: Helmut Eller
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <m28wqqo5sp.fsf@gmail.com>
* Ron Garret [2008-12-08 17:46+0100] writes:

> This is a known limitation of the current implementation, and is 
> described in the documentation in section 3.2.  In brief, you can't 
> LDEFUN something after you've refer to it because by then it has already 
> been compiled as a call to an unknown function whereas it needs to be 
> compiled as a deferred lexical reference.  To fix this requires a code 
> walker.

In section 3.3 you are talking about mutually recursive functions and I
naively expected that LDEFUN was supposed to handle that.  Apparently
that refers to something else.

Well, I guess something like DEFDEFERRED would be easy to add.  A code
walker would still be good to avoid calls to undefined functions.

Helmut.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-AEA418.14562208122008@news.gha.chartermi.net>
In article <··············@gmail.com>,
 Helmut Eller <············@gmail.com> wrote:

> * Ron Garret [2008-12-08 17:46+0100] writes:
> 
> > This is a known limitation of the current implementation, and is 
> > described in the documentation in section 3.2.  In brief, you can't 
> > LDEFUN something after you've refer to it because by then it has already 
> > been compiled as a call to an unknown function whereas it needs to be 
> > compiled as a deferred lexical reference.  To fix this requires a code 
> > walker.
> 
> In section 3.3 you are talking about mutually recursive functions and I
> naively expected that LDEFUN was supposed to handle that.

It is supposed to.  And it does, it's just a bit awkward at the moment.  
Tokens have to be lexified in order to be handled properly (otherwise 
they get CL's normal semantics).  But they *don't* have to be bound.

> Well, I guess something like DEFDEFERRED would be easy to add.

It's already there.  It's called LEXIFY.

> A code
> walker would still be good to avoid calls to undefined functions.

Yep.

rg
From: Kaz Kylheku
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <20081208121035.-230@gmail.com>
On 2008-12-08, Helmut Eller <············@gmail.com> wrote:
> * Ron Garret [2008-12-08 17:46+0100] writes:
>
>> This is a known limitation of the current implementation, and is 
>> described in the documentation in section 3.2.  In brief, you can't 
>> LDEFUN something after you've refer to it because by then it has already 
>> been compiled as a call to an unknown function whereas it needs to be 
>> compiled as a deferred lexical reference.  To fix this requires a code 
>> walker.
>
> In section 3.3 you are talking about mutually recursive functions and I
> naively expected that LDEFUN was supposed to handle that.  Apparently
> that refers to something else.
>
> Well, I guess something like DEFDEFERRED would be easy to add.  A code
> walker would still be good to avoid calls to undefined functions.

I think I will stick to Lisp's packaging system.

Handling it at the token -> symbol conversion level is the smart design.

It's one of those good ideas in computing, like abstracting files at the
operating system level. It's good to be able to use the same function to write
to a socket or file.

Handling identifier namespaces at the symbol -> reference level is wrong.
It's like having separate functions for writing to sockets and files.

Now you need a way to handle namespacing in global bindings, a way to handle
namespacing in class slot lookup, and who knows what else. Any data structure
that supports symbol lookup needs to now be equipped with namespace rules.  And
that includes user-defined data structures that haven't even been written yet.

There is a kind of Fourier effect in programming. If you are working in the
right Fourier transform space, you implement something once and it fixes a
problem everywhere. If you work in a different space, you not only replicate
effort but create future effort.

I like this analogy: a simple spike in the time domain is a big mess in the
frequency domain requiring infinite bandwidth.
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-B83523.15121908122008@news.gha.chartermi.net>
In article <···················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-08, Helmut Eller <············@gmail.com> wrote:
> > * Ron Garret [2008-12-08 17:46+0100] writes:
> >
> >> This is a known limitation of the current implementation, and is 
> >> described in the documentation in section 3.2.  In brief, you can't 
> >> LDEFUN something after you've refer to it because by then it has already 
> >> been compiled as a call to an unknown function whereas it needs to be 
> >> compiled as a deferred lexical reference.  To fix this requires a code 
> >> walker.
> >
> > In section 3.3 you are talking about mutually recursive functions and I
> > naively expected that LDEFUN was supposed to handle that.  Apparently
> > that refers to something else.
> >
> > Well, I guess something like DEFDEFERRED would be easy to add.  A code
> > walker would still be good to avoid calls to undefined functions.
> 
> I think I will stick to Lisp's packaging system.
> 
> Handling it at the token -> symbol conversion level is the smart design.

It is indeed, but that's not what CL does.  CL translates *program text* 
directly into symbols.  There are no "tokens."  That is precisely the 
problem.

rg
From: Kaz Kylheku
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <20081224053758.479@gmail.com>
On 2008-12-08, Ron Garret <·········@flownet.com> wrote:
> In article <···················@gmail.com>,
>  Kaz Kylheku <········@gmail.com> wrote:
>
>> On 2008-12-08, Helmut Eller <············@gmail.com> wrote:
>> > * Ron Garret [2008-12-08 17:46+0100] writes:
>> >
>> >> This is a known limitation of the current implementation, and is 
>> >> described in the documentation in section 3.2.  In brief, you can't 
>> >> LDEFUN something after you've refer to it because by then it has already 
>> >> been compiled as a call to an unknown function whereas it needs to be 
>> >> compiled as a deferred lexical reference.  To fix this requires a code 
>> >> walker.
>> >
>> > In section 3.3 you are talking about mutually recursive functions and I
>> > naively expected that LDEFUN was supposed to handle that.  Apparently
>> > that refers to something else.
>> >
>> > Well, I guess something like DEFDEFERRED would be easy to add.  A code
>> > walker would still be good to avoid calls to undefined functions.
>> 
>> I think I will stick to Lisp's packaging system.
>> 
>> Handling it at the token -> symbol conversion level is the smart design.
>
> It is indeed, but that's not what CL does.  CL translates *program text* 
> directly into symbols.  There are no "tokens."  That is precisely the 
> problem.

ANSI CL:

  2.3 Interpretation of Tokens

  2.3.1 Numbers as Tokens

  2.3.2 Constructing Numbers from Tokens

  2.3.3 The Consing Dot

  2.3.4 Symbols as Tokens

  2.3.5 Valid Patterns for Tokens

  2.3.6 Package System Consistency Rules

I usually know what I'm token about. :)
From: Ron Garret
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <rNOSPAMon-876FB4.18505508122008@news.gha.chartermi.net>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2008-12-08, Ron Garret <·········@flownet.com> wrote:
> > In article <···················@gmail.com>,
> >  Kaz Kylheku <········@gmail.com> wrote:
> >
> >> On 2008-12-08, Helmut Eller <············@gmail.com> wrote:
> >> > * Ron Garret [2008-12-08 17:46+0100] writes:
> >> >
> >> >> This is a known limitation of the current implementation, and is 
> >> >> described in the documentation in section 3.2.  In brief, you can't 
> >> >> LDEFUN something after you've refer to it because by then it has 
> >> >> already 
> >> >> been compiled as a call to an unknown function whereas it needs to be 
> >> >> compiled as a deferred lexical reference.  To fix this requires a code 
> >> >> walker.
> >> >
> >> > In section 3.3 you are talking about mutually recursive functions and I
> >> > naively expected that LDEFUN was supposed to handle that.  Apparently
> >> > that refers to something else.
> >> >
> >> > Well, I guess something like DEFDEFERRED would be easy to add.  A code
> >> > walker would still be good to avoid calls to undefined functions.
> >> 
> >> I think I will stick to Lisp's packaging system.
> >> 
> >> Handling it at the token -> symbol conversion level is the smart design.
> >
> > It is indeed, but that's not what CL does.  CL translates *program text* 
> > directly into symbols.  There are no "tokens."  That is precisely the 
> > problem.
> 
> ANSI CL:
> 
>   2.3 Interpretation of Tokens
> 
>   2.3.1 Numbers as Tokens
> 
>   2.3.2 Constructing Numbers from Tokens
> 
>   2.3.3 The Consing Dot
> 
>   2.3.4 Symbols as Tokens
> 
>   2.3.5 Valid Patterns for Tokens
> 
>   2.3.6 Package System Consistency Rules
> 
> I usually know what I'm token about. :)

OK, let me rephrase: the problem is that tokens as defined in section 
2.3 are not first-class data structures.

The whole point of Lisp -- the main thing that differentiates it from 
other languages -- is that program semantics are defined on a 
first-class intermediate data type (forms) rather than directly on 
program text.  This has a number of advantages which I hope I don't have 
to enumerate here.  But the interpretation of *symbols* is defined 
directly on program text, not on an intermediate first-class data 
structure (which is what I thought you meant by the word "token", but I 
guess I'll have to find some other term since token is taken).

rg
From: D Herring
Subject: Re: ANNOUNCE: Lexicons 2.0 (beta) released
Date: 
Message-ID: <ghn073$vjk$1@aioe.org>
Ron Garret wrote:
...
> The whole point of Lisp -- the main thing that differentiates it from 
> other languages -- is that program semantics are defined on a 
> first-class intermediate data type (forms) rather than directly on 
> program text.  This has a number of advantages which I hope I don't have 
> to enumerate here.  But the interpretation of *symbols* is defined 
> directly on program text, not on an intermediate first-class data 
> structure (which is what I thought you meant by the word "token", but I 
> guess I'll have to find some other term since token is taken).

Clojure introduced a useful view of how this could work.  IIRC, it 
uses text->symbol->resolution instead of interning everything straight 
away.

Evaluation
http://clojure.org/evaluation?responseToken=d25a462a7b80271f95464457123e5d63

Differences with Lisps
http://clojure.org/lisps?responseToken=d9edfe17ab0592cbb7f873eb6326aa34
...
# Keywords are not Symbols
# Symbols are not storage locations (see Var)
# nil is not a Symbol
...
# syntax-quote does symbol resolution, so `x is not the same as 'x.
...


- Daniel