Packaging of CDR APIs [was Re: [cdr-discuss] Three RFCs]

Richard M Kreuter kreuter at progn.net
Tue Mar 18 16:20:03 UTC 2008


"Pierre R. Mai" writes:
> 
> Which brings me to another question I've been meaning to bring up
> w.r.t. the latest CDRs:  Would it be sensible to have a defined
> package for these kinds of smallish extensions (like e.g. the index
> types, as well), maybe cdr-cl or ext-cl, or whatever?  Has this been
> discussed already?

I don't think this has been discussed, but I could be wrong.

Although it's undesirable to require a separate package for every tiny
API, I think that in general there are drawbacks to specifying package
names as part of interfaces (as opposed to implementations of
interfaces).  My main concern is that you can sometimes want two or more
libraries that implement the same interface loaded into one Lisp image.
You can do this pretty easily if interfaces don't specify the package
namespace, but less easily or not at all if package names are part of
interfaces: if all implementors of some interface are required to
associate their code with the same symbols in the Lisp image, there'll
be conflicts.  Possibly the conflicts won't matter much, but if the
different implementations have incompatible bugs or extensions, the
conflicts can be fairly frustrating; in order to debug, you'll need to
know which implementation you compiled against, which may be different
than the debug-time definitions, and so forth.  So my preference would
be to keep package names out of CDR document interfaces per se, and to
leave it to library authors and users to construct package namespaces as
they see fit.

There are a number of ways that users can get footholds on things, even
if CDR documents leave package names unspecified:

* A user who wants to depend on a particular library's implementation of
  some interface can just employ that library's package name(s), either
  by USE-PACKAGE, selective importing, package-qualified symbols in the
  client's source code, etc.  This is probably the easiest thing to do,
  and it's basically how people already use libraries.

* A user who wants a layer of package namespace indirection between
  different libraries' implementations of an interface can
  programmatically construct a package containing the symbols in the
  interface.  Something like this might suffice:

(defun make-api-package (new-package-name string-designator from-package)
  (let ((new-package (make-package new-package-name)))
    (dolist (string-designator string-designators new-package)
     (import (find-symbol string-designator from-package) new-package)
     (export (find-symbol string-designator new-package) new-package))))

* An author of library providing an interface might furnish an operator
  that "installs" the symbols in an interface into some package (this is
  analogous to what the SERIES system does).  For example, a library
  that provides a couple of CDR documents' interfaces might have an
  INSTALL function defined like this:

(in-package "WHIZ-BANG-LIBRARY")

(defvar *cdr-apis* '((:cdr-42 . (frob munge))
                     (:cdr-100 . (mangle hose))))

(defun install (api &optional (package *package*))
  (dolist (symbol (cdr (assoc api *cdr-apis*
                              :test 'string= #| or STRING-EQUAL? |#)))
    (shadowing-import symbol package)))

While I admit that having to do some amount of namespace bookkeeping can
be annoying, ISTM to be a tradeoff that buys the user flexibility in how
he can employ the package namespace in his Lisp image.

--
Richard



More information about the cdr-discuss mailing list