A package establishes a mapping from names to symbols.
At any given time, one package is current.
The current package is the one that is the value of *package*
.
When using the Lisp reader,
it is possible to refer to symbols in packages
other than the current one through the use of package prefixes in the
printed representation of the symbol.
The next figure lists some defined names that are applicable
to packages.
Where an operator
takes an argument that is either a symbol or a list
of symbols,
an argument of nil
is treated as an empty list of symbols.
Any package argument may be either a string, a symbol, or
a package. If a symbol is supplied, its name will be used
as the package name.
|
Figure 11.1: Some Defined Names related to Packages
Each package has a name (a string) and perhaps some nicknames (also strings). These are assigned when the package is created and can be changed later.
There is a single namespace for packages.
The function find-package
translates a package
name or nickname into the associated package.
The function package-name
returns the name of a package.
The function package-nicknames
returns
a list of all nicknames for a package.
rename-package
removes a package's
current name and nicknames and replaces them with new ones
specified by the caller.
The mappings in a package are divided into two classes, external and internal. The symbols targeted by these different mappings are called external symbols and internal symbols of the package. Within a package, a name refers to one symbol or to none; if it does refer to a symbol, then it is either external or internal in that package, but not both. External symbols are part of the package's public interface to other packages. Symbols become external symbols of a given package if they have been exported from that package.
A symbol has the same name no matter what package it is present in, but it might be an external symbol of some packages and an internal symbol of others.
Packages can be built up in layers. From one point of view,
a package is a single collection
of mappings from strings into internal symbols and
external symbols.
However, some of these mappings might be established within the package
itself, while other mappings are inherited from other packages
via use-package
.
A symbol is said to be present in a package
if the mapping is in the package itself and is
not inherited from somewhere else.
There is no way to inherit the internal symbols of another package; to refer to an internal symbol using the Lisp reader, a package containing the symbol must be made to be the current package, a package prefix must be used, or the symbol must be imported into the current package.
A symbol becomes accessible in a package
if that is its home package when it is created,
or if it is imported into that package,
or by inheritance via use-package
.
If a symbol is accessible in a package, it can be referred to when using the Lisp reader without a package prefix when that package is the current package, regardless of whether it is present or inherited.
Symbols from one package can be made accessible in another package in two ways.
import
. After the call to import
the
symbol is present in the importing package.
The status of the symbol in the package
it came from (if any) is unchanged, and the home package for
this symbol is unchanged.
Once imported, a symbol is present in the
importing package
and can be removed only by calling unintern
.
A symbol is shadowed3 by another symbol
in some package if the first symbol would be accessible
by inheritance if not for the presence of the second symbol.
See shadowing-import
.
use-package
.
All of the external symbols of the used package are inherited
by the using package.
The function unuse-package
undoes the effects of a previous use-package
.
When a symbol is to be located in a given package the following occurs:
Within one package, any particular name can refer to at most one symbol. A name conflict is said to occur when there would be more than one candidate symbol. Any time a name conflict is about to occur, a correctable error is signaled.
The following rules apply to name conflicts:
string=
).
import
).
See shadow
and shadowing-import
.
use-package
, import
, and
export
check for name conflicts.
shadow
and shadowing-import
never signal a name-conflict error.
unuse-package
and unexport
do not need to do any name-conflict checking.
unintern
does name-conflict checking only when a symbol
being uninterned is a shadowing symbol
.
unintern
can uncover a name conflict that had
previously been resolved by the shadowing.
package-error
before making any
change to the package structure. When multiple changes are to be made,
it is
permissible for the implementation to process each change separately.
For example, when export
is given a
list of
symbols,
aborting from a name
conflict caused by the second symbol
in the list might still export the
first symbol in the list.
However, a name-conflict error caused by export
of a single symbol will be signaled before
that symbol's accessibility in any package is changed.
shadowing-import
,
unintern
,
or unexport
.
use-package
between a symbol
present in the using package and an external symbol of the used
package is resolved in favor of the first symbol by making it a
shadowing symbol, or in favor of the second symbol by uninterning
the first symbol from the using package.
export
or unintern
due to a package's inheriting two distinct symbols
with the same name (under string=
)
from two other packages can be resolved in
favor of either symbol by importing it into the using
package and making it a shadowing symbol
,
just as with use-package
.