Project author Jean-Philippe Paradis
Project type Library
Programming language Common Lisp
Status Ready-to-use
License Public Domain
Library type Data structure
Project complexity Simple
Latest release Version 1.0
Date 9 dec 2012
(Dec 2012 dist and later)
Status Available
Version Latest

symbol-namespaces defines a new kind of package that's named by a symbol rather than a string and that maps from existing symbols to their respective "implicitly managed" counterparts. The motivating use-case is to conceptually allow multiple definitions of the same kind on a single symbol, without conflicts.

symbol-namespaces » Packages

symbol-namespaces exports a single package called symbol-namespaces, also nicknamed symspaces and symspace. This package is designed for explicit qualification of symbols, such as symspace:namespace. Don't (:use)!

(In this documentation, "namespace" means "symbol-namespace".)

symbol-namespaces » API overview

The only strict guarantee obeyed by all namespace classes is that they inherit from symspace:namespace and implement symspace:find-symbol and symspace:intern-symbol.

Namespace classes may also inherit from symspace:packages, in which case they also support at least the symspace:find-package and symspace:intern-package operations.

The main operators of interest for "normal" users of the library are:

The rest of the API mostly has to do with making it easy to define custom kinds of namespaces with extended behavior.

For simple uses, it should be enough to subclass symspace:standard-namespace and refine behavior by adding new methods on appropriate generic functions.

For heavier customization, one can subclass symspace:namespace directly, and define appropriate methods to implement the contract of generic functions. It's easy to inherit standard pieces of state and behavior with the provided mixins. symspace:standard-namespace really just inherits from such mixins.

symbol-namespaces » API details

Macro symspace:define name &body options
=> new-or-redefined-namespace

Defines a namespace and gives it a global name (symbol), or redefines an existing one.

The expansion calls symspace:ensure with the name and the options, converted from an alist to a plist. If the :class option is specified, it must have only one argument, which is the class designator which will be forwarded to symspace:ensure. Otherwise, the default is symspace:standard-namespace. symspace:standard-namespace doesn't support any options other than :class, but other subclasses of symspace:namespace might. In that case, the value of the option in the plist will be a list of the cdr of the option. For instance, an option of (:option 1 2 3) would produce :option (1 2 3) in the plist. Neither the option keys nor values are evaluated.

Function symspace:ensure name
  &rest keys &key (class 'symspace:standard-namespace) &allow-other-keys
=> new-or-redefined-namespace

Creates a new namespace named name, or redefines it if it already exists.

If a new namespace is created, it will be of class class and the other keys are passed to make-instance.

If a namespace with that name is already registered, then if the class is different than the class of the existing instance, change-class is called with the class and other keys. If the class is the same, then reinitialize-instance is called with the instance and the other keys.

Accessor symspace:locate name &key (errorp t)
=> namespace-or-nil

Returns the namespace registered with name name. If there is no registered namespace with name name, then an error is signaled if errorp is true, else nil is returned.

Generic Function symspace:name namespace
=> name

Retrieves the name of a namespace. Typically implemented by symspace:name-mixin.

Mixin Class symspace:name-mixin

Provides a slot of type symbol, filled by initarg :name, whose value is retrieved by symspace:name. Also provides a print-object method that includes the name of the namespace in its output.

Marker Class symspace:namespace

All namespace kinds inherit from this class. At least symspace:find-symbol and symspace:intern-symbol are supported. symspace:standard-namespace provides a ready-to-use implementation.

Generic Function symspace:intern-symbol symbol symbol-namespace
=> symbol

Argument precedence order: symbol-namespace, symbol

Attempts to symspace:find-symbol, and if the search is unsuccessful, creates and returns an appropriate implicitly managed counterpart for the symbol.

Generic Function symspace:find-symbol symbol symbol-namespace
=> symbol-or-nil

Argument precedence order: symbol-namespace, symbol

Retrieves the "implicitly managed" counterpart of a symbol in a namespace, if there is one, or else returns nil.

Marker Class symspace:packages

Namespace classes inheriting from this class implicitly manage some packages internally, and support the symspace:find-package and symspace:intern-package operations. A related operation that might be supported is symspace:make-package-name, potentially used by symspace:intern-package.

See symspace:packages-identity-mixin and symspace:packages-name-mixin for built-in implementations. symspace:standard-namespace uses the former.

Generic Function symspace:intern-package package symbol-namespace
=> package

Argument precedence order: symbol-namespace, package

Attempts to symspace:find-package, and if the search is unsuccessful, creates and returns an appropriate implicitly managed counterpart for the package.

Generic Accessor symspace:find-package package symbol-namespace
=> package-or-nil

Argument precedence order: symbol-namespace, package

Retrieves the "implicitly managed" counterpart of a package in a namespace, if there is one, or else returns nil.

Generic Function symspace:make-package-name package symbol-namespace
=> name

Computes an appropriate package name for a new "implicitly managed" counterpart of package.

Mixin Class symspace:packages-identity-mixin

Implements symspace:packages. Packages are found and interned on the basis of their identity (eq comparison of packages). This is what symspace:standard-namespace uses.

Mixin Class symspace:packages-name-mixin

Implements symspace:packages. Packages are found and interned on the basis of equality of their package names.

Class symspace:standard-namespace

A ready-to-use implementation of symspace:namespace that simply inherits from symspace:name-mixin, symspace:packages-identity-mixin, and symspace:namespace.