Common Lisp the Language, 2nd Edition
Next: Name Conflicts
Up: Packages
Previous: Translating Strings
to
Symbols from one package may be made accessible in another package in two ways.
First, any individual symbol may be added to a package by use of the
function import
. The form
(import 'editor:buffer)
takes the external symbol named
buffer
in the editor
package (this symbol was
located when the form was read by the Lisp reader) and adds it to the
current package as an internal symbol. The symbol is then present in the
current package. The imported symbol is not automatically exported from
the current package, but if it is already present and external, then the
fact that it is external is not changed. After the call to
import
it is possible to refer to buffer
in
the importing package without any qualifier. The status of
buffer
in the package named editor
is
unchanged, and editor
remains the home package for this
symbol. Once imported, a symbol is present in the importing
package and can be removed only by calling unintern
.
If the symbol is already present in the importing package,
import
has no effect. If a distinct symbol with the name
buffer
is accessible in the importing package (directly or
by inheritance), then a correctable error is signaled, as described in
section 11.5, because
import
avoids letting one symbol shadow another.
A symbol is said to be shadowed by another symbol in some
package if the first symbol would be accessible by inheritance if not
for the presence of the second symbol. To import a symbol without the
possibility of getting an error because of shadowing, use the function
shadowing-import
. This inserts the symbol into the
specified package as an internal symbol, regardless of whether another
symbol of the same name will be shadowed by this action. If a different
symbol of the same name is already present in the package, that symbol
will first be uninterned from the package (see unintern
).
The new symbol is added to the package’s shadowing-symbols list.
shadowing-import
should be used with caution. It changes
the state of the package system in such a way that the consistency rules
do not hold across the change.
The second mechanism is provided by the function
use-package
. This causes a package to inherit all of the
external symbols of some other package. These symbols become accessible
as internal symbols of the using package. That is, they can be
referred to without a qualifier while this package is current, but they
are not passed along to any other package that uses this package. Note
that use-package
, unlike import
, does not
cause any new symbols to be present in the current package but
only makes them accessible by inheritance.
use-package
checks carefully for name conflicts between the
newly imported symbols and those already accessible in the importing
package. This is described in detail in section 11.5.
Typically a user, working by default in the user
package, will load a number of packages into Lisp to provide an
augmented working environment, and then call use-package
on
each of these packages to allow easy access to their external symbols.
unuse-package
undoes the effects of a previous
use-package
. The external symbols of the used package are
no longer inherited. However, any symbols that have been imported into
the using package continue to be present in that package.
There is no way to inherit the internal symbols of another package; to refer to an internal symbol, the user must either make that symbol’s home package current, use a qualifier, or import that symbol into the current package.
The distinction between external and internal symbols is a primary means
of hiding names so that one program does not tread on the namespace of
another.
When intern
or some other function wants to look up a
symbol in a given package, it first looks for the symbol among the
external and internal symbols of the package itself; then it looks
through the external symbols of the used packages in some unspecified
order. The order does not matter; according to the rules for handling
name conflicts (see below), if conflicting symbols appear in two or more
packages inherited by package X, a symbol of this name must
also appear in X itself as a shadowing symbol. Of course,
implementations are free to choose other, more efficient ways of
implementing this search, as long as the user-visible behavior is
equivalent to what is described here.
The function export
takes a symbol that is accessible in
some specified package (directly or by inheritance) and makes it an
external symbol of that package. If the symbol is already accessible as
an external symbol in the package, export
has no effect. If
the symbol is directly present in the package as an internal symbol, it
is simply changed to external status. If it is accessible as an internal
symbol via use-package
, the symbol is first imported into
the package, then exported. (The symbol is then present in the specified
package whether or not the package continues to use the package through
which the symbol was originally inherited.) If the symbol is not
accessible at all in the specified package, a correctable error is
signaled that, upon continuing, asks the user whether the symbol should
be imported.
The function unexport
is provided mainly as a way to
undo erroneous calls to export
. It works only on symbols
directly present in the current package, switching them back to internal
status. If unexport
is given a symbol already accessible as
an internal symbol in the current package, it does nothing; if it is
given a symbol not accessible in the package at all, it signals an
error.
Next: Name Conflicts
Up: Packages
Previous: Translating Strings
to
AI.Repository@cs.cmu.edu