symbol-namespaces
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 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".)
⚓
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:
Macro
symspace:define
defines a namespace and gives it a global name (symbol), or redefines an existing one;Function
symspace:locate
retrieves a namespace by name;Generic Function
symspace:find-symbol
retrieves the "implicitly managed" counterpart of a symbol in a namespace, if there is one, or else returns NIL.Generic Function
symspace:intern-symbol
attempts tosymspace:find-symbol
, and if the search is unsuccessful, creates and returns an appropriate implicitly managed counterpart for the symbol.
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.
⚓
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 tosymspace:ensure
. Otherwise, the default issymspace:standard-namespace
.symspace:standard-namespace
doesn't support any options other than:class
, but other subclasses ofsymspace:namespace
might. In that case, the value of the option in the plist will be a list of thecdr
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, thenreinitialize-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 bysymspace:name
. Also provides aprint-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
andsymspace: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
andsymspace:intern-package
operations. A related operation that might be supported issymspace:make-package-name
, potentially used bysymspace:intern-package
.See
symspace:packages-identity-mixin
andsymspace: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 whatsymspace: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 fromsymspace:name-mixin
,symspace:packages-identity-mixin
, andsymspace:namespace
.