|
From: Richard M Kreuter on 17 Dec 2006 17:03 Hello, Some of the recent Lisp code and documentation available on the net encourage or require the employment package-delimited symbol names in source code, and some library packages are being written that can't be USEd (in the sense of use-package, or a bunch of imports) in packages that also use the CL package. Examples: * (From the asdf manual; note that the asdf package is USEable alongside CL) | The system foo is loaded (and compiled, if necessary) by evaluating | the following form in your Lisp implementation: | | (asdf:operate 'asdf:load-op 'foo) * (From the asdf-install tutorial) | ... you can download and install the library directly by providing | the download URL of the package like so: | | (asdf-install:install "http://weitz.de/files/cl-ppcre.tar.gz") * (From SBCL's SB-POSIX README; SB-POSIX is /not/ USEable alongside CL) | The user is encouraged not to (USE-PACKAGE :SB-POSIX) but instead to | use the SB-POSIX: prefix on all references, as some of our symbols | have the same name as CL symbols (OPEN, CLOSE, SIGNAL etc). What are people's opinions about this way of employing the package system, as opposed to making USEable packages and USEing them? For my part, I think this is an unfortunate practice for library code, for the following reason: when a package is intentionally unUSEable or customarily unUSEd, the package name becomes de facto interface in the /source text/, where Lisp can't do much with it. To switch existing programs from using one implementation of an API that encourages or requires package-qualified symbol names in source code to another implementation of the same API (modulo package names, of course), it's necessary either to audit code, or else to play tricky games with the package namespace around compilation and loading. By contrast, when a package is USEable and customarily USEd, switching between compatible implementations of an interface normally involves editing some defpackage forms (in case package A exports symbols not exported from package B, switching from USEing B to A may require some shadowing or shadowing-import-froms, I suppose). Concrete examples where there could be practical advantages to multiply-implementable interfaces aren't hard to imagine: an implementation might provide POSIX, sockets, or database APIs that are compatible with some implementation-independent libraries, but optimized in ways that implementation-independent libraries can't or wouldn't be (e.g., taking advantage of some imeplementation specific memory management features, or operating system specific features of the range of operating systems where the implementation runs). Programs that employ USEable packages can then take advantage of implementation-optimized libraries relatively easily, in principle. Anyhow, I'm curious what people's thoughts are about this. -- RmK P.S. It might save time for me to concede up front that unUSEable packages can have symbols with shorter symbol-names. However, this only helps people who are writing code in such packages, and there are a variety of means available for people who are really desparate for short names in their own code: shadowing CL symbols and defining symbol macros, using reader macros, etc.
From: Pascal Bourguignon on 17 Dec 2006 17:16 Richard M Kreuter <kreuter(a)progn.net> writes: > [...] > For my part, I think this is an unfortunate practice for library code, > for the following reason: when a package is intentionally unUSEable or > customarily unUSEd, the package name becomes de facto interface in the > /source text/, where Lisp can't do much with it. > [...] You're right. But we live in the hope for relative package names or local package nicknames extensions... Have a look at: http://www.franz.com/support/tech_corner/hierpackuser.lhtml -- __Pascal Bourguignon__ http://www.informatimago.com/ READ THIS BEFORE OPENING PACKAGE: According to certain suggested versions of the Grand Unified Theory, the primary particles constituting this product may decay to nothingness within the next four hundred million years.
From: joswig on 17 Dec 2006 18:10 On 17 Dez., 23:03, Richard M Kreuter <kreu...(a)progn.net> wrote: > Hello, > > Some of the recent Lisp code and documentation available on the net > encourage or require the employment package-delimited symbol names in > source code, and some library packages are being written that can't be > USEd (in the sense of use-package, or a bunch of imports) in packages > that also use the CL package. Examples: > > * (From the asdf manual; note that the asdf package is USEable > alongside CL) > > | The system foo is loaded (and compiled, if necessary) by evaluating > | the following form in your Lisp implementation: > | > | (asdf:operate 'asdf:load-op 'foo) > > * (From the asdf-install tutorial) > > | ... you can download and install the library directly by providing > | the download URL of the package like so: > | > | (asdf-install:install "http://weitz.de/files/cl-ppcre.tar.gz") > > * (From SBCL's SB-POSIX README; SB-POSIX is /not/ USEable alongside > CL) > > | The user is encouraged not to (USE-PACKAGE :SB-POSIX) but instead to > | use the SB-POSIX: prefix on all references, as some of our symbols > | have the same name as CL symbols (OPEN, CLOSE, SIGNAL etc). > > What are people's opinions about this way of employing the package > system, as opposed to making USEable packages and USEing them? Often I like to have the package name in the source code, since it will remind me when I'm reading the source where the symbol comes from. Also using a package can have all kinds of unwanted side effects and you can have lots of conflicts in some situations. As an example: Consider this code: Package p1: (defclass foo () ((bar))) (defun bar ()) Now you export BAR from package P1 (probably to have the function BAR accessible there). If you use package P1 in package P2, the symbol BAR from package P1 will be visible. That means all uses of BAR will refer to that symbol. And you have exported the symbol BAR, which is used as a slot name AND as a function. In package P2: (defclass baz () ((bar))) Again this BAR is the one from the other package, even though you might only wanted to export a function. But you can't export functions. You can only export symbols and symbols can be used to name many things (class names, slot names, functions, variables, ...). > > For my part, I think this is an unfortunate practice for library code, > for the following reason: when a package is intentionally unUSEable or > customarily unUSEd, the package name becomes de facto interface in the > /source text/, where Lisp can't do much with it. > > To switch existing programs from using one implementation of an API > that encourages or requires package-qualified symbol names in source > code to another implementation of the same API (modulo package names, > of course), it's necessary either to audit code, or else to play > tricky games with the package namespace around compilation and > loading. By contrast, when a package is USEable and customarily USEd, > switching between compatible implementations of an interface normally > involves editing some defpackage forms (in case package A exports > symbols not exported from package B, switching from USEing B to A may > require some shadowing or shadowing-import-froms, I suppose). > > Concrete examples where there could be practical advantages to > multiply-implementable interfaces aren't hard to imagine: an > implementation might provide POSIX, sockets, or database APIs that are > compatible with some implementation-independent libraries, but > optimized in ways that implementation-independent libraries can't or > wouldn't be (e.g., taking advantage of some imeplementation specific > memory management features, or operating system specific features of > the range of operating systems where the implementation runs). > Programs that employ USEable packages can then take advantage of > implementation-optimized libraries relatively easily, in principle. > > Anyhow, I'm curious what people's thoughts are about this. > > -- > RmK > > P.S. It might save time for me to concede up front that unUSEable > packages can have symbols with shorter symbol-names. However, this > only helps people who are writing code in such packages, and there are > a variety of means available for people who are really desparate for > short names in their own code: shadowing CL symbols and defining > symbol macros, using reader macros, etc.
From: Richard M Kreuter on 17 Dec 2006 18:25 Pascal Bourguignon <pjb(a)informatimago.com> writes: > Richard M Kreuter <kreuter(a)progn.net> writes: > >> [...] >> For my part, I think this is an unfortunate practice for library >> code, for the following reason: when a package is intentionally >> unUSEable or customarily unUSEd, the package name becomes de facto >> interface in the /source text/, where Lisp can't do much with it. >> [...] > > You're right. But we live in the hope for relative package names or > local package nicknames extensions... > > Have a look at: > http://www.franz.com/support/tech_corner/hierpackuser.lhtml I don't think this solves the problem I address. If the tokens in source text are package-qualified, then the package namespace has to be just right at read time. A hierarchical package system merely adds the wrinkle that "just right" is defiend to also depend on the read time value of *package*. As an aside, the Franz document makes mention of the hierarchical namespaces in Perl and Java, but the comparisons are misleading, because both of those languages use the code namespaces for naming classes and also for naming files in the deployment environment. What's more, in single-implementation languages, there's not much benefit to multiply-implemented libraries, since there's only one implementation to run on. In Common Lisp, both because of the history of diversity of implementations, and also, perhaps, because of the tendency to want to fold libraries into the language seamlessly, there's more of a call for multiply-implemented APIs than in other languages. -- RmK
From: Pascal Bourguignon on 17 Dec 2006 18:42
Richard M Kreuter <kreuter(a)progn.net> writes: > Pascal Bourguignon <pjb(a)informatimago.com> writes: >> Richard M Kreuter <kreuter(a)progn.net> writes: >> >>> [...] >>> For my part, I think this is an unfortunate practice for library >>> code, for the following reason: when a package is intentionally >>> unUSEable or customarily unUSEd, the package name becomes de facto >>> interface in the /source text/, where Lisp can't do much with it. >>> [...] >> >> You're right. But we live in the hope for relative package names or >> local package nicknames extensions... >> >> Have a look at: >> http://www.franz.com/support/tech_corner/hierpackuser.lhtml > > I don't think this solves the problem I address. > > If the tokens in source text are package-qualified, then the package > namespace has to be just right at read time. A hierarchical package > system merely adds the wrinkle that "just right" is defiend to also > depend on the read time value of *package*. Indeed, Franz's hierarchical packages are only part of the solution. But the same technique (or just rewritting the lisp reader) could be used to implement package relative nicknames. What is needed, is that package nicknames be in a name space relative to the current package, instead of a global name space. Then we could write for example: (defpackage "P1" (:use "COM.INFORMATIMAGO.COMMON-LISP.STRING" :as "STR") (:use #+feature-1 "COM.INFORMATIMAGO.COMMON-LISP.HTML" #+feature-2 "SOME.OTHER.HTML-PACKAGE" :as "HTML")) (in-package "P1") (html:p () "Some paragraph") (in-package "P2") (use-package "YET.ANOTHER.HTML" :as "HTML") (html:p (html:pcdata "Some other paragraph")) .... -- __Pascal Bourguignon__ http://www.informatimago.com/ Grace personified, I leap into the window. I meant to do that. |