Common Lisp’s package system provides a simple way to avoid name clashes by means of separate namespace. No more, no less. Albeit having their shadowy corners, as illustrated in this excellent tutorial by E. Gat, packages are very easy to use and, most of the time, get the work done. Basically, think of a package as a map from strings to symbols, with associated lookup functions, and bindings resolved at read time.
But, simple as they are, packages in CL are second-class citizens: you cannot modify them at runtime, add new symbols, create new packages and pass them around as first-class values. For instance, Python modules are dictionary objects (and, as such directly manipulable as, say message receivers or function arguments). Languages in the ML family provide powerful module manipulation facilities, including functors, that is, parametric modules that take modules as arguments and generate new ones (see, for instance, a sample in Alice ML). This kind of trick is not limited to ML: PLT’s units offer the same functionality for Scheme (although i find them cumbersome).
Back to CL, i recently discovered Tim Bradshaw’s Conduits, a nice library adding very interesting functionality to the vanilla package system. For instance, you can define variants of pre-existing modules, or extend a given package including only a subset of the symbols defined by its parent. You can also clone existing packages. Tim’s hacks also include a hierarchical package system for CMUCL that mimics Allegro CL’s one.
Tim’s pages on Lisp and its obscurities are also worth a visit.
Tags: common lisp, lisp
February 23, 2006 at 3:41 am
But, simple as they are, packages in CL are second-class citizens: you cannot modify them at runtime, add new symbols, create new packages and pass them around as first-class values.
Um… yes, you can. MAKE-PACKAGE creates packages. FIND-PACKAGE returns the package object with a specified name (or nickname). INTERN creates a new symbol in a package. And so on. See section 11 of the Common Lisp standard for all the package-manipulating functions and macros.
What you can’t do with a package is export just one aspect of a symbol (for example, just its function binding) or make symbols be accessible elsewhere with different symbol names.
February 23, 2006 at 9:27 am
Thanks for the correction, Paul. My apologies to CLers for my uninformed FUD.