Now that a mere:
(progn
(defparameter *system-loaded* '())
(defparameter *system-errors* '())
(flet ((got-error (system error)
(push (cons system error) *system-errors*))
(success (system result)
(push (cons system result) *system-loaded*)))
(dolist (system (ql:system-list))
(handler-case
(restart-case (handler-bind
((error (lambda (err)
(got-error system (princ-to-string err))
(compute-restarts)
(invoke-restart (find-restart 'try-next-one err)))))
(success system (ql:quickload (ql-dist:name system))))
(try-next-one () nil))
#+clisp (SYSTEM::SIMPLE-STORAGE-CONDITION (err)
(got-error system (princ-to-string err)))
(error (err)
;; should not occur...
(got-error system (princ-to-string err))))))
(format t "Total systems: ~5D~%" (length (ql:system-list)))
(format t "Installed systems: ~5D~%" (length *system-loaded*))
(format t "Errors: ~5D~%" (length *system-error*))
(finish-output))
let you load all the lisp libraries at once, thanks to quicklisp, it is
somewhat regreatable that so few packages be documented on-line:
C/USER[580]> (values (length (remove-if-not (lambda (p) (documentation p 't)) (list-all-packages)))
(length (list-all-packages)))
263 ;
1340
Library authors, please add docstrings!
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
> Now that a mere:
[snip load code]
> let you load all the lisp libraries at once, thanks to quicklisp, it is
> somewhat regreatable that so few packages be documented on-line:
Unfortunately it's not easy to load everything because of package name
conflicts. So depending on which one you load first you'll skew your
results. It would be interesting to see each one independently loaded
for statistics.
Until I started working on Quicklisp, I didn't realize that
:documentation was even available as an option to defpackage.
Zach
> Unfortunately it's not easy to load everything because of package name
> conflicts.
I don't have the energy to dig out messages to CLL from ten years or so
ago suggesting that it might be a good idea to use the obvious
"org.tfeb.xml.parser"-style names for packages to avoid this kind of
problem. Maybe in another ten years we'll get to where Java was in the
mid 90s (in this respect).
I'm glad more people don't do this. It's replacing one problem with a
worse one.
Zach
> I'm glad more people don't do this. It's replacing one problem with a
> worse one.
Why?
> "Pascal J. Bourguignon" <p...@informatimago.com> writes:
>
>> Now that a mere:
> [snip load code]
>> let you load all the lisp libraries at once, thanks to quicklisp, it is
>> somewhat regreatable that so few packages be documented on-line:
>
> Unfortunately it's not easy to load everything because of package name
> conflicts. So depending on which one you load first you'll skew your
> results. It would be interesting to see each one independently loaded
> for statistics.
Yes, that would be another request I'd have; but for now, I tried to
load them only on clisp, where there are unfortunately a lot of systems
that cannot work (often for trivial questions, or for conforming
problems rather than only for unfulfilled dependencies).
> Until I started working on Quicklisp, I didn't realize that
> :documentation was even available as an option to defpackage.
--
> Zach Beane <xa...@xach.com> writes:
>
> > Tim Bradshaw <t...@tfeb.org> writes:
> >
> >> On 2011-01-16 15:12:00 +0000, Zach Beane said:
> >>
> >>> Unfortunately it's not easy to load everything because of package name
> >>> conflicts.
> >>
> >> I don't have the energy to dig out messages to CLL from ten years or
> >> so ago suggesting that it might be a good idea to use the obvious
> >> "org.tfeb.xml.parser"-style names for packages to avoid this kind of
> >> problem. Maybe in another ten years we'll get to where Java was in
> >> the mid 90s (in this respect).
> >
> > I'm glad more people don't do this. It's replacing one problem with a
> > worse one.
>
> What problem does "org.tfeb.xml.parser" offer?
Verbosity. Also, it doesn't even guarantee uniqueness because domains
can change ownership.
rg
You are free to add a nickname of your liking:
(rename-package
'org.tfeb.xml.parser
'org.tfeb.xml.parser
(cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
> Also, it doesn't even guarantee uniqueness because domains can change
> ownership.
It also doesn't exclude malice. Guess we have to choose between strong
cryptography and nothing, right?
--
A change in perspective is worth 80 IQ points. --- Alan Kay
> RG <rNOS...@flownet.com> writes:
>
> > In article <87aaj07...@kuiper.lan.informatimago.com>,
> > "Pascal J. Bourguignon" <p...@informatimago.com> wrote:
> >
> >>
> >> What problem does "org.tfeb.xml.parser" offer?
> >
> > Verbosity.
>
> You are free to add a nickname of your liking:
>
> (rename-package
> 'org.tfeb.xml.parser
> 'org.tfeb.xml.parser
> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
If you're willing to do that then you don't need uniqueness at all.
(load-something-in-package-foo)
(rename-package 'foo 'my-foo1)
(load-something-else-into-package-foo)
(rename-package 'foo 'my-foo2)
That's even simpler.
> > Also, it doesn't even guarantee uniqueness because domains can change
> > ownership.
>
> It also doesn't exclude malice. Guess we have to choose between strong
> cryptography and nothing, right?
That's a little extreme. GUIDs are probably sufficient.
But what one really ought to do IMHO is to pop up a level and ask
whether a mechanism intended to provide read-print consistency for
symbols is really the right tool for the job of modularizing code.
rg
> In article <m2lj2ky...@host-10-5-17-33.vaih.selfnet.de>,
> Edmunds Cers <edm...@laivas.lv> wrote:
>
>> You are free to add a nickname of your liking:
>>
>> (rename-package
>> 'org.tfeb.xml.parser
>> 'org.tfeb.xml.parser
>> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
>
> If you're willing to do that then you don't need uniqueness at all.
>
> (load-something-in-package-foo)
> (rename-package 'foo 'my-foo1)
> (load-something-else-into-package-foo)
> (rename-package 'foo 'my-foo2)
>
> That's even simpler.
Simpler, how? This has to be integrated in a system loader and can
backfire spectacularly on some later read or if the package does some
creation and interning of symbols at runtime.
> But what one really ought to do IMHO is to pop up a level and ask
> whether a mechanism intended to provide read-print consistency for
> symbols is really the right tool for the job of modularizing code.
What other tools do we got?
> rg
> You are free to add a nickname of your liking:
>
> (rename-package
> 'org.tfeb.xml.parser
> 'org.tfeb.xml.parser
> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
The above code could cause errors if org.tfeb.xml.parser were a
nickname. A corrected version:
(defun add-nickname (package nickname)
(rename-package
package
(package-name package)
(cons nickname (package-nicknames package))))
(add-nickname 'org.tfeb.xml.parser 'parser)
> In article <m2lj2ky...@host-10-5-17-33.vaih.selfnet.de>,
> Edmunds Cers <edm...@laivas.lv> wrote:
>
>> RG <rNOS...@flownet.com> writes:
>>
>> > In article <87aaj07...@kuiper.lan.informatimago.com>,
>> > "Pascal J. Bourguignon" <p...@informatimago.com> wrote:
>> >
>> >>
>> >> What problem does "org.tfeb.xml.parser" offer?
>> >
>> > Verbosity.
>>
>> You are free to add a nickname of your liking:
>>
>> (rename-package
>> 'org.tfeb.xml.parser
>> 'org.tfeb.xml.parser
>> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
>
> If you're willing to do that then you don't need uniqueness at all.
>
> (load-something-in-package-foo)
> (rename-package 'foo 'my-foo1)
> (load-something-else-into-package-foo)
> (rename-package 'foo 'my-foo2)
>
> That's even simpler.
Actually, this is too verbose. It also has the problem that you can do
that only in the ultimate integration. If you publish your code, you
cannot be sure that nobody won't want to integrate it with another body
of code that already use those nicknames.
There should be no nickname pre-defined on published packages.
Long package names are not a problem in practice, because either you
mention them once in the defpackage :use clause, or you use them to
qualify symbols only a very small number of occurences in a source file.
If you observe the opposite, then you have another problem: your cross
package dependencies are too wide. Solve this problem instead.
>> > Also, it doesn't even guarantee uniqueness because domains can change
>> > ownership.
This is nto a problem either, because:
1- this doesn't occur often,
2- you can easily distribute a different library with other package
names.
Point 2 is even what you should do if you plan to distribute discrete
versions of your libraries, like ALEXANDRIA.0.DEV.
>> It also doesn't exclude malice. Guess we have to choose between strong
>> cryptography and nothing, right?
>
> That's a little extreme. GUIDs are probably sufficient.
(21EC2020-3AEA-1069-A2DD-08002B30309D:WITH-GENSYMS
(wall door window roof) ...)
(COM.INFORMATIMAGO.COMMON-LISP.CESARUM.UTILITY:WITH-GENSYMS
(wall door window roof) ...)
Granted, GUIDs may be shorter, but I still prefer the reversed domain
name.
> But what one really ought to do IMHO is to pop up a level and ask
> whether a mechanism intended to provide read-print consistency for
> symbols is really the right tool for the job of modularizing code.
It won't be bad to think about it, but IMO packages solve 90% of the
modularization needs, and if you want to solve the modularization
problem, in the scope of Internet and open software, you will find that
you have to solve this same problem.
There's already the notion of relative packages (which requires reader
extensions). I think packages + relative packages cover 100% of what
solution hypothetical modules could solve.
We could introduce modules, and optionally qualify packages with a
module name. This would only change the last dot by a colon:
(COM.INFORMATIMAGO.COMMON-LISP.CESARUM:UTILITY:WITH-GENSYMS
(wall door window roof) ...)
It's simplier to use relative package names, when the facility is/will
be available.
(COM.INFORMATIMAGO.COMMON-LISP.CESARUM.UTILITY:WITH-GENSYMS
(wall door window roof) ...)
is future-compatible with them.
> Edmunds Cers <edm...@laivas.lv> writes:
>
>> You are free to add a nickname of your liking:
>>
>> (rename-package
>> 'org.tfeb.xml.parser
>> 'org.tfeb.xml.parser
>> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
>
> The above code could cause errors if org.tfeb.xml.parser were a
> nickname. A corrected version:
>
> (defun add-nickname (package nickname)
> (rename-package
> package
> (package-name package)
> (cons nickname (package-nicknames package))))
Actually, this is undefined behavior. The correct implementation is in
COM.INFORMATIMAGO.COMMON-LISP.CESARUM.PACKAGE.
> RG <rNOS...@flownet.com> writes:
>
> > In article <m2lj2ky...@host-10-5-17-33.vaih.selfnet.de>,
> > Edmunds Cers <edm...@laivas.lv> wrote:
> >
> >> RG <rNOS...@flownet.com> writes:
> >>
> >> > In article <87aaj07...@kuiper.lan.informatimago.com>,
> >> > "Pascal J. Bourguignon" <p...@informatimago.com> wrote:
> >> >
> >> >>
> >> >> What problem does "org.tfeb.xml.parser" offer?
> >> >
> >> > Verbosity.
> >>
> >> You are free to add a nickname of your liking:
> >>
> >> (rename-package
> >> 'org.tfeb.xml.parser
> >> 'org.tfeb.xml.parser
> >> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
> >
> > If you're willing to do that then you don't need uniqueness at all.
> >
> > (load-something-in-package-foo)
> > (rename-package 'foo 'my-foo1)
> > (load-something-else-into-package-foo)
> > (rename-package 'foo 'my-foo2)
> >
> > That's even simpler.
>
> Actually, this is too verbose.
I don't dispute this. But it's less verbose than EC's original proposal.
> It also has the problem that you can do
> that only in the ultimate integration.
That's also true of the original. This is a fundamental problem with
packages: within a given CL instance, they share a global namespace.
You can either manage this namespace yourself, or you can delegate that
management to some other entity (like the W3C). But you have to manage
it.
> Long package names are not a problem in practice, because either you
> mention them once in the defpackage :use clause, or you use them to
> qualify symbols only a very small number of occurences in a source file.
>
> If you observe the opposite, then you have another problem: your cross
> package dependencies are too wide. Solve this problem instead.
What is a "cross-package dependency"? And what does it mean for one of
those to be "too wide"?
> >> > Also, it doesn't even guarantee uniqueness because domains can change
> >> > ownership.
>
> This is nto a problem either, because:
> 1- this doesn't occur often,
It will occur more and more often as time goes on.
> 2- you can easily distribute a different library with other package
> names.
>
> Point 2 is even what you should do if you plan to distribute discrete
> versions of your libraries, like ALEXANDRIA.0.DEV.
How well that works depends on how often client code uses package:symbol
syntax. That's really what this whole debate is about. If you don't
use that syntax, you don't really need packages at all. But if you do
use that syntax and the name of a package that you use changes then you
have a problem. Perhaps not the most difficult problem you will ever
face in your coding career, but a problem nonetheless.
> >> It also doesn't exclude malice. Guess we have to choose between strong
> >> cryptography and nothing, right?
> >
> > That's a little extreme. GUIDs are probably sufficient.
>
>
> (21EC2020-3AEA-1069-A2DD-08002B30309D:WITH-GENSYMS
> (wall door window roof) ...)
>
> (COM.INFORMATIMAGO.COMMON-LISP.CESARUM.UTILITY:WITH-GENSYMS
> (wall door window roof) ...)
>
>
> Granted, GUIDs may be shorter, but I still prefer the reversed domain
> name.
Somehow I find myself agreeing. :-)
> > But what one really ought to do IMHO is to pop up a level and ask
> > whether a mechanism intended to provide read-print consistency for
> > symbols is really the right tool for the job of modularizing code.
>
> It won't be bad to think about it, but IMO packages solve 90% of the
> modularization needs
On the consumer side I agree. On the producer side I personally find
packages to be extremely annoying because of the need to manually
maintain export lists. Reasonable people could disagree (and they do).
> and if you want to solve the modularization
> problem, in the scope of Internet and open software, you will find that
> you have to solve this same problem.
That depends on what you mean by "this same problem." Maintaining a
global namespace is not a requirement for solving the modularization
problem, even on a global scale.
> There's already the notion of relative packages (which requires reader
> extensions). I think packages + relative packages cover 100% of what
> solution hypothetical modules could solve.
That's a step in the right direction.
> We could introduce modules
Another step in the right direction.
> and optionally qualify packages with a module name.
How would that help? The fundamental problem is that packages
necessarily share a global namespace. If you force modules to also
share a global namespace you have made zero progress.
There is a fundamental tradeoff to be made. You can either have a world
where the semantics of FOO:BAZ are independent of context, or one where
they are not. In the first world you have a global namespace you have
to manage. In the second world you have local contexts you have to
manage. Which world is better is ultimately a matter of taste, but one
can make the unqualified observation that local contexts are invariably
easier to manage than global ones. But let's not make the problem any
more complicated than it needs to be. There are really only two
decisions to make: 1) maintain a global namespace or not, and 2) resolve
identifiers at read time, macroexpand/compile time, or run-time, or some
combination of the three. That's really all there is to it.
rg
> RG <rNOS...@flownet.com> writes:
>
> > In article <m2lj2ky...@host-10-5-17-33.vaih.selfnet.de>,
> > Edmunds Cers <edm...@laivas.lv> wrote:
> >
> >> You are free to add a nickname of your liking:
> >>
> >> (rename-package
> >> 'org.tfeb.xml.parser
> >> 'org.tfeb.xml.parser
> >> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
> >
> > If you're willing to do that then you don't need uniqueness at all.
> >
> > (load-something-in-package-foo)
> > (rename-package 'foo 'my-foo1)
> > (load-something-else-into-package-foo)
> > (rename-package 'foo 'my-foo2)
> >
> > That's even simpler.
>
> Simpler, how? This has to be integrated in a system loader and can
> backfire spectacularly on some later read or if the package does some
> creation and interning of symbols at runtime.
Yes, but you would have these problem regardless. For any X you can
only have one package named X. If you have two packages that want to be
called X and code that assumes that they are both called X then there is
no way to run that code in a single Lisp image that guarantees that you
won't lose.
> > But what one really ought to do IMHO is to pop up a level and ask
> > whether a mechanism intended to provide read-print consistency for
> > symbols is really the right tool for the job of modularizing code.
>
> What other tools do we got?
My personal favorite is this:
http://rondam.blogspot.com/2010/02/new-and-improved-lexicons-now-50-lexie
r.html
But I'm slightly biased.
rg
... stuff deleted ...
>
> Until I started working on Quicklisp, I didn't realize that
> :documentation was even available as an option to defpackage.
>
> Zach
And I didn't realize it until I saw it in your package :-)
Mirko
> Edmunds Cers <edm...@laivas.lv> writes:
>
>> (defun add-nickname (package nickname)
>> (rename-package
>> package
>> (package-name package)
>> (cons nickname (package-nicknames package))))
>
> Actually, this is undefined behavior.
If I understand you correctly, you refer to "consequences are undefined
if _new-name_ or any _new-nickname_ conflicts with any existing package
names" from the CLHS description of rename-package. To make the behavior
defined in all cases then, one needs to check if the nickname is already
used. Like this:
(defun add-nickname (package nickname)
(let ((package (find-package package))
(nick-package (find-package nickname)))
(if (eq package nick-package)
package
(if (null nick-package)
(rename-package
package
(package-name package)
(cons nickname (package-nicknames package)))
(error "Nickname ~S already in use." nickname)))))
> The correct implementation is in
> COM.INFORMATIMAGO.COMMON-LISP.CESARUM.PACKAGE.
This solves the above and adds some more bells and whistles.
> In article <m2hbd8y...@host-10-5-17-33.vaih.selfnet.de>,
> Edmunds Cers <edm...@laivas.lv> wrote:
>
>> RG <rNOS...@flownet.com> writes:
>>
>> > In article <m2lj2ky...@host-10-5-17-33.vaih.selfnet.de>,
>> > Edmunds Cers <edm...@laivas.lv> wrote:
>> >
>> >> You are free to add a nickname of your liking:
>> >>
>> >> (rename-package
>> >> 'org.tfeb.xml.parser
>> >> 'org.tfeb.xml.parser
>> >> (cons 'parser (package-nicknames 'org.tfeb.xml.parser)))
>> >
>> > If you're willing to do that then you don't need uniqueness at all.
>> >
>> > (load-something-in-package-foo)
>> > (rename-package 'foo 'my-foo1)
>> > (load-something-else-into-package-foo)
>> > (rename-package 'foo 'my-foo2)
>> >
>> > That's even simpler.
>>
>> Simpler, how? This has to be integrated in a system loader and can
>> backfire spectacularly on some later read or if the package does some
>> creation and interning of symbols at runtime.
>
> Yes, but you would have these problem regardless.
I was answering to your complaint about org.tfeb.xml.parser being too
verbose. In your application code (not in library code, as pointed out
by Pascal J. Bourguignon) you can have short nicknames for the libraries
you use, so you can write parser:foo instead of
org.tfeb.xml.parser:foo. Adding a nickname to a package can not cause
the above problems, renaming the package can.
> For any X you can only have one package named X. If you have two
> packages that want to be called X and code that assumes that they are
> both called X then there is no way to run that code in a single Lisp
> image that guarantees that you won't lose.
That is why we need the reverse-domain-name prefixed package names. The
short nicknames make their appearance only in your application code.
>> > But what one really ought to do IMHO is to pop up a level and ask
>> > whether a mechanism intended to provide read-print consistency for
>> > symbols is really the right tool for the job of modularizing code.
>>
>> What other tools do we got?
>
> My personal favorite is this:
>
> http://rondam.blogspot.com/2010/02/new-and-improved-lexicons-now-50-lexie
> r.html
>
> But I'm slightly biased.
Could you elaborate just a bit? I did not manage to gather from the link
(and the pdf linked from the link) what lexicons really offer over
packages. In particular, how do they help solve the conflicting
namespace-name problem under discussion?
Shameless plug :)
http://within-parens.blogspot.com/2009/02/naming-packages.html
Cheers
--
Marco
> Verbosity.
Yes it is more verbose, if you don't use (in the use-package sense)
packages, or import symbols, but refer to symbols by their full names.
I guess a lot of people must do that, though I find it a weird
programming style - the only cases I do it are where I happen to want
some definition from a package in one place only, in which case the
additional verbosity is obviously minute as a fraction of the program.
(See below for more on this.)
I think that if you want names to be globally unique in the presence of
a large number of names and without making them incomprehensible, then
you require two things: longer names with some kind of structure, and
an authority for allocating parts of those names with the ability to
delegate authority for other parts. Pretty much every system which
needs to allocate names globally has come up against this and come to
the same solution. Both the authority and the delegation are
important, as witnessed by internet hostnames: there was essentially
always an authority (in the form of the central HOSTS.TXT file), but
quite early on people realised that that authority would have to be
able to delegate parts of the namespace because the single HOSTS.TXT
file has terrible scaling properties.
There are various things one could do to resolve namespace clashes in
CL: using something different (and better than) packages, using
non-portable package name tricks (see below again), or other things.
What people seem to be doing at present is just assuming that Lisp will
never be widely used (so we won't have many packages), and Lisp users
will never fall out in any bad way (so clashes can be amicably
resolved), so there is no need to worry: after all it's not a big
problem now, and it's painful to address. I think that's shortsighted:
some of us would like Lisp to be widely used, in which case there will
be a problem, and some of us are also notoriously fractious, so
amicable resolution may not work that well. Finally, although the
problem is indeed painful to address, the pain goes up as the number of
packages increases, so (assuming Lisp becomes more widely used) it will
never be less painful than it is now.
My suggestion is that the problem can be resolved within the existing
package system, by using DNS as the authority and delegation mechanism,
at the cost of longer package names.
> Also, it doesn't even guarantee uniqueness because domains
> can change ownership.
I find it hard to take this point seriously. Pretty much nothing
guarantees uniqueness, but we can make attempts to dramatically
increase the likelihood of it. That's all I'm suggesting.
* The verbosity problem. (This is the "see below" bit mentioned above.)
I'm probably not the best person to talk about this as I tend to not
use explicit package prefixes but construct packages which have direct
access to the symbols I need, using a tool I wrote to do this
(conduits, which is portable, I hope).
However there are a couple of other things which can make this better
as well. Franz support "relative package names" which allow packages
to use short names for other packages which are close to them in the
namespace. The implementation of this is in the public domain to my
knowledge. In order for it to work it requires anything that looks up
a package name to go through it, which requires (probably small)
changes to CL.
Based originally on that code I wrote some code which does something
slightly different: it allows a package to be associated with a map
from "mentioned package names" to "actual package names". So for
instance I might have a package "org.tfeb.grunge" in which the
mentioned package "xml" maps to "com.cley.horrible.xml", then, if I am
in org.tfeb.grunge, "xml:bog" will translate to
"com.cley.horrible.xml:bog". This obviously requires similar small
changes to CL to the Franz thing. I don't think this is actually very
well designed, but one of the neat thing you can do with it is to make
packages in which the "CL" package is something different, which is
quite interesting.
It turns out that conduits is all I ever use, but it did occur to me
that an interesting thing to do would be to persuade implementations to
provide a standard (substandard in the KMP sense, perhaps) way of
hooking the string->package lookup, so that then people would be able
to experiment with their own approaches to this. My sketch idea was
that there would be a variable *find-package-hook* which would by
default be nil. If it wasn't nil it should be bound to a function
which will be called with two arguments: a string and the
implementation's underlying package finding function (which does not go
through this hook). It can use this function to look up packages based
on the string, and can return a package, or nil. However I'm not
convinced this is a reasonable design: the idea of passing in the
standard finder is to avoid recursion problems where the hook function
needs to look up a package.
One question about that is how much it might hurt performance.
Obviously if the hook function is slow it will hurt, but my tests at
the time (this is quite a long time ago) is that there was not really a
noticable impact, assuming the hook function was not doing anything
silly.
> Based originally on that code I wrote some code which does something
> slightly different: it allows a package to be associated with a map
> from "mentioned package names" to "actual package names". So for
> instance I might have a package "org.tfeb.grunge" in which the
> mentioned package "xml" maps to "com.cley.horrible.xml", then, if I am
> in org.tfeb.grunge, "xml:bog" will translate to
> "com.cley.horrible.xml:bog".
Something along these lines sounds like a reasonable strategy. However
it's a bit unclear to me if the map of "mentioned package names" should
be associated with a package or a file.
For the file association, I'm thinking something similar to how
IN-PACKAGE in effect associates a default package with the file. Maybe
even the "mentioned package names" could be tacked on as extra arguments
to IN-PACKAGE.
--
Frode V. Fjeld
> Based originally on that code I wrote some code which does something
> slightly different: it allows a package to be associated with a map
> from "mentioned package names" to "actual package names". So for
> instance I might have a package "org.tfeb.grunge" in which the
> mentioned package "xml" maps to "com.cley.horrible.xml", then, if I am
> in org.tfeb.grunge, "xml:bog" will translate to
> "com.cley.horrible.xml:bog".
I think this is a great idea, except if this applies only to nicknames,
so that any package can still be accessed by its full name. In effect
you would add a nickname list for used packages that shadows any
nicknames that could be already defined by the packages
themselves. Calls to in-package would have to 1) restore the nickname
list for all packages as it were without any shadowing of nicknames, and
2) apply any shadowing defined by the new package.
The big win of this approach is that this would allow the use of
(possibly conflicting) nicknames in library code as well as in
application code.
OK, you're right, adding a nickname doesn't have the same problems as
renaming a package. But you still have the problem that package
nicknames live in the same global namespace as package names, so if you
use this trick you cannot safely release your code for other people to
use.
> >> > But what one really ought to do IMHO is to pop up a level and ask
> >> > whether a mechanism intended to provide read-print consistency for
> >> > symbols is really the right tool for the job of modularizing code.
> >>
> >> What other tools do we got?
> >
> > My personal favorite is this:
> >
> > http://rondam.blogspot.com/2010/02/new-and-improved-lexicons-now-50-lexie
> > r.html
> >
> > But I'm slightly biased.
>
> Could you elaborate just a bit? I did not manage to gather from the link
> (and the pdf linked from the link) what lexicons really offer over
> packages. In particular, how do they help solve the conflicting
> namespace-name problem under discussion?
Lexicons operate at macroexpand time, so they are not bound to syntax
the way packages are. Packages necessarily have to live in a global
namespace in order to do one of the things that they do, namely, provide
read-print consistency for symbols. But lexicons have nothing do do
with reading or printing, so they don't have to have a global namespace.
(They don't even have to have names.
NOTE: the current implementation of lexicons does have a global
namespace because each lexicon has a package associated with it as part
of its internal implementation. But this is just to aid in debugging,
and to help people feel a little warmer and fuzzier about lexicons.
It's not necessary, and this restriction is easily removed.
rg
Also, the undefined consequences includes also when the name is not
changed. So to be conforming, you have to rename the package to a
temporary name, before renaming it to its original name.
>> The correct implementation is in
>> COM.INFORMATIMAGO.COMMON-LISP.CESARUM.PACKAGE.
>
> This solves the above and adds some more bells and whistles.
But unfortunately, it doesn't do the double-rename required.
Happily, most implementations don't seem to care. But still, my
add-nickname is not conforming :-(
> Based originally on that code I wrote some code which does something
> slightly different: it allows a package to be associated with a map
> from "mentioned package names" to "actual package names". So for
> instance I might have a package "org.tfeb.grunge" in which the
> mentioned package "xml" maps to "com.cley.horrible.xml", then, if I am
> in org.tfeb.grunge, "xml:bog" will translate to
> "com.cley.horrible.xml:bog". This obviously requires similar small
> changes to CL to the Franz thing. I don't think this is actually very
> well designed, but one of the neat thing you can do with it is to make
> packages in which the "CL" package is something different, which is
> quite interesting.
Modula-2 has something like that.
When you import an module into another, you can rename it. So you can
have system-wide (internet-wide) module names, and just give it them
local names when using them:
MODULE MyApp;
IMPORT com.informatimago.modula_2.tree.BinaryTree AS bt;
... bt.makeTree(...); ...
END MyApp;
I tried to implement something like that in my early DEFINE-PACKAGE
macro, but in CL it wasn't very successful, having to add a nickname,
this conflicted with other IMPORT AS.
> It turns out that conduits is all I ever use, but it did occur to me
> that an interesting thing to do would be to persuade implementations
> to provide a standard (substandard in the KMP sense, perhaps) way of
> hooking the string->package lookup, so that then people would be able
> to experiment with their own approaches to this.
This is needed. This is one purpose of my implementation of a lisp
reader.
> My sketch idea was that there would be a variable *find-package-hook*
> which would by default be nil. If it wasn't nil it should be bound to
> a function which will be called with two arguments: a string and the
> implementation's underlying package finding function (which does not
> go through this hook). It can use this function to look up packages
> based on the string, and can return a package, or nil. However I'm
> not convinced this is a reasonable design: the idea of passing in the
> standard finder is to avoid recursion problems where the hook function
> needs to look up a package.
>
> One question about that is how much it might hurt performance.
> Obviously if the hook function is slow it will hurt, but my tests at
> the time (this is quite a long time ago) is that there was not really
> a noticable impact, assuming the hook function was not doing anything
> silly.
Once upon a time, I had a function to make system names in reverse-dns
name to pathnames to lookup for
#P"PACKAGES:COM;INFORMATIMAGO;COMMON-LISP;SYSTEM.ASD"
when loading the asdf system :com.informatimago.common-lisp
but for better integration with others' libraries, now I have
handwritten
/lisp/packages/com/informatimago/common-lisp/cesarum/com.informatimago.common-lisp.cesarum.asd files
(notice the redundancy...), instead of automatically generated
system.asd files...
This is more complex, because of run time calls to INTERN, FIND-SYMBOL,
FIND-PACKAGE, etc.
> > It turns out that conduits is all I ever use, but it did occur to me
> > that an interesting thing to do would be to persuade implementations
> > to provide a standard (substandard in the KMP sense, perhaps) way of
> > hooking the string->package lookup, so that then people would be able
> > to experiment with their own approaches to this.
>
> This is needed.
+1
rg
> In article <m2y66jx...@host-10-5-17-33.vaih.selfnet.de>,
> Edmunds Cers <edm...@laivas.lv> wrote:
>
> But you still have the problem that package nicknames live in the same
> global namespace as package names, so if you use this trick you cannot
> safely release your code for other people to use.
Did you see Tim's proposal? One could associate a list of nicknames for
packages wich will be used (by name) from a package foo with the package
foo itself. These nicknames would then shadow any existing nicknames of
some (potentially unrelated) packages when (in-package foo) is called.
This way every package can have its own set of nicknames for any other
packages it cares to use package:symbol style. Neat.
Try to formulate this as a CDR...
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/
Or in C++ (excepting that . cannot be part of a name):
namespace MyApp {
namespace bt = com.informatimago.modula_2.tree.BinaryTree ;
... bt.makeTree(...); ...
}
KHD
There does not seem to be a strategy for the manipulation of package
aliases which does not effect subsequent loads. Such scope issues are
usually solved in a language by using a lexical name-space. It would
have been nice if Common Lisp had chosen to use a lexical name-space for
package aliases. I think aliases now crowd the package name-space, and
ultimately just simplify the typing of application specific package
definitions.
--
Barry Fishman
Also Ada has something like this...
Cheers
--
Marco
> RG <rNOS...@flownet.com> writes:
>
> > In article <m2y66jx...@host-10-5-17-33.vaih.selfnet.de>,
> > Edmunds Cers <edm...@laivas.lv> wrote:
> >
> > But you still have the problem that package nicknames live in the same
> > global namespace as package names, so if you use this trick you cannot
> > safely release your code for other people to use.
>
> Did you see Tim's proposal? One could associate a list of nicknames for
> packages wich will be used (by name) from a package foo with the package
> foo itself. These nicknames would then shadow any existing nicknames of
> some (potentially unrelated) packages when (in-package foo) is called.
> This way every package can have its own set of nicknames for any other
> packages it cares to use package:symbol style. Neat.
Yep. Seems like a good solution if it can be effected. But it's a
non-compliant change, so I'm not optimistic.
rg
> Something along these lines sounds like a reasonable strategy. However
> it's a bit unclear to me if the map of "mentioned package names" should
> be associated with a package or a file.
Yes, that is not clear to me either. That was why I ultimately decided
the right approach would be to allow a hook into package lookup and let
time decide what the right approach was.
>
> Try to formulate this as a CDR...
What's that (sorry, I should know)?
Second entry in my footer.
For some time now, I have taken the habbit of starting every lisp file
with something like this:
(in-package :my-own-package-and-readtable-name)
(in-readtable :my-own-package-and-readtable-name)
So I have not tried it yet, but if I can tweak the readtable to
establish a set of correspondances between "nicknames" that *I* would
choose, and specific packages, then that would be all that I need. Of
course, provided that no two packages have the same name in the first
place, and that package authors stop providing nicknames which is evil.
In other words, getting back to the question above, it seems to me that
"mappings" should be associated with readtables, not with files or
packages.
--
Resistance is futile. You will be jazzimilated.
Scientific site: http://www.lrde.epita.fr/~didier
Music (Jazz) site: http://www.didierverna.com
> Yep. Seems like a good solution if it can be effected. But it's a
> non-compliant change, so I'm not optimistic.
Two unrelated replies to this:
First one is that what I am actually (now) proposing is that it would
be interesting to (sub-)standardize some way of hooking string->package
lookup. On top of this my original proposal could be implemented, but
also other ideas could be played with, including ones which are
probably better. Such a hooking interface obviously would require
extensions to CL confirmance at the implementation level (rather than
purely at user level which is where conduits and (I think?) lexicons
live, but so long as nothing appears in the CL package I think
implementations could still be conformant.
Given that such a hooking interface is not likely to be a massive
amount of implementational work I will have a go at specifying it and
implementing it in one implementation.
Second reply (not really a reply actually) is that I'm not trying to
argue in favour of packages and against anything else. We all know
that packages suck in many ways: I'm just trying to make them suck less.
> Second entry in my footer.
Doh
The problem with that is that they are _ugly_. Also, backwards.
There's a kinda reasonable purpose to having them backwards in Java, but
in CL why not at least have them be in normal order?
They'd still be hideous though.
--
Robert A. Uhl
> The problem with that is that they are _ugly_. Also, backwards.
> There's a kinda reasonable purpose to having them backwards in Java, but
> in CL why not at least have them be in normal order?
For the same reason that t...@aiai.ed.ac.uk was preferable to t...@uk.ac.ed.aiai
(This comment may only make sense to you if you used computers in the
UK in the late 80s).