[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

packages, yet again



One more try.  I guess if people always knew what they were getting
into, nobody would ever try to do anything interesting.

Major new features of this proposal:

1. The old "package augmenting" DECLARE-PACKAGE is gone.  Flexible, but
deemed to be too dangerous, since it allows users of a package to mess
with that package's external symbols.

2. INCLUDE-PACKAGE is gone.  If you want to do what INCLUDE-PACKAGE used
to do, you call USE-PACAKGE on the other package, then explictly EXPORT
all of the symbols that you want to pass along.  Deemed to make your
intentions clearer and to be less confusing overall.

3. If IMPORT or USE-PACAKGE creates a name conflict between one or more
of the imported symbols and some distinct symbol available in the
current package, a correctable error is signalled.  Each package keeps a
list of symbols that have been explicitly declared to be present and to
shadow other symbols (SHADOW and SHADOWING-INPUT add symbols to this
list) and these symbols always win any conflicts without signalling an
error.

4. A package must be created and all its externals must be set up before
any other package uses it.  If a package is being used by any other
package, an error is signalled if you try to change its set of external
symbols in any way.

5. The PROVIDE and REQUIRE functions from the Laser edition are
suggested as a way for the user to load complicated things without
having to worry about complicated order-of-load restrictions.  A few
changes are proposed in these functions.  They probably want to be moved
into this section, since there is a strong interaction with packages.
(Do we really want to keep these separate, or would a merger of modules
and packages make sense?)

The new version is relatively simple, fairly safe, and probably more
restrictive than it needs to be.  At this point it seems better to go
for something simple and restricitve that might conceivably survive the
onslaught of the critics.  We can always pass the user more rope later.

Here we go again:

***************************************************************************

@chapter [Packages]

@section [Overview]

One problem with earlier Lisp systems is the use of a single name space
for all symbols.  In large Lisp systems, with modules written by many
different programmers, accidental name collisions become a serious
problem.  Common Lisp addresses this problem through the @i[package
system], derived from an earlier package system developed for Lisp
Machine Lisp.  In addition to preventing name-space conflicts, the
package system makes the modular structure of large Lisp systems more
explicit.

A @i[package] is a data structure that establishes a mapping from print
names (strings) to symbols.  The package thus replaces the ``oblist'' or
``obarray'' machinery of earlier Lisp systems.  At any given time one
package is current, and this package is used by the reader in
translating strings into symbols.  The current package is always the
value of the global variable @b[*package*].  It is possible to refer to
symbols in packages other than the current one through the use of
@i[package qualifiers] in the symbol reference.  For example @b[foo:bar]
refers to the symbol whose name is @b[bar] in the package whose name is
@b[foo].

The string-to-symbol mappings available in a given package are divided
into two classes, @i[external] and @i[internal].  We refer to the
symbols accessible via these mappings as being @i[external] and
@i[internal] symbols of the package in question, though really it is the
mappings that are different and not the symbols themselves.  Within a
given package, a name refers to one symbol or to none; if it does refer
to a symbol, that symbol is either external or internal in that
package, but not both.

External symbols are part of the package's public interface to other
packages.  These are supposed to be chosen with some care and are
advertised to users of the package.  Internal symbols are for internal
use only, and these symbols are normally hidden from other packages.
Most symbols are created as internal symbols; they become external only
if they appear explicitly in some package's @b[export] command.

A symbol may appear in many packages.  It will always have the same
print name wherever it appears, but it may be external in one package
and internal in another.  A name may refer to different symbols in
different packages.

Packages may be built up in layers.  From the point of view of a
package's user, the package is a single collection of mappings from
strings into internal and external symbols.  However, some of these
mappings may be established within the package itself, while other
mappings are inherited from other packages via the @b[use-package]
construct.  (The mechansims responsible for this inheritance are
described below.)  In what follows, we will refer to a symbol as being
"accessible" in a package if it can be referred to in that package
without a qualifier, regardless of whether the mapping occurs within
that package or via inheirtance; we will refer to a symbol as being
"present" in a package if the mapping is in the package itself and is
not inherited from somewhere else.

@section [Consistency Rules]

Package-related bugs can be very subtle and confusing: things are not
what they appear to be.  The Common Lisp package system is designed with
a number of safety features to prevent most of the common bugs that
would otherwise occur in normal use.  This may seem over-protective, but
experience with earlier package systems has shown that such safety
features are needed.

In dealing with the package system, it is useful to keep in mind the
following consistency rules, which remain in force as long as the value
of @b[*package*] is not changed by the user or his code:

@begin [itemize]
@b[Read-Read consistency:] Reading the same print name always gets you
the same (EQ) symbol.

@b[Print-Read consistency:] An interned symbol always prints as a
sequence of characters which, when read back in, yields the same (EQ)
symbol.

@b[Print-Print consistency:] If two interned symbols are not EQ, then
their printed representations will not be the same sequence of
characters.
@end [itemize]

These consistency rules remain true in spite of any amount of implicit
interning caused by typing in Lisp forms, loading files, etc.  This has
the important implication that results are reproducible regardless of
the order of loading files or the exact history of what symbols were
typed in when.  The rules can only be violated by explicit action:
changing the value of @b[*package*], forcing some action by continuing
from an error, or calling one of the ``dangerous'' functions:
@b[unintern], @b[shadow], or @b[shadowing-import].

In general, an error is signalled if the user takes any action that
would replace one symbol available in a package with a different symbol of
the same name.  Such "implicit shadowing" is usually an error.  However,
the user can explictily ask for such shadowing to occur with the @b[shadow]
and @b[shadowing-import] functions.  These functions indicate that certain
symbols are to be directly present in a package and that they are to take
precedence over any symbol of the same name that would otherwise be
inherited by that package.  Each package keeps a list of such shadowing
symbols, so that subsequent calls to @b[use-package] or @b[import]
will not interfere with the user's declared intentions.

@section [Package Names]

Each package has a name (a string) and perhaps some nicknames.  These
are assigned when the package is created, though they can be changed
later.  A package's name should be something long and self-explanatory
like "editor"; there might be a nickname that is shorter and easier to
type, like "ed".  Package name strings retain whatever mixture of upper
and lower case characters the user supplies, but the translation from
names to packages is case-insensitive, so users can generally refer to
packages without worrying about case.

There is a single name space for packages.  The function
@b[find-package] translates a package-name or nickname into the
associated package.  The function @b[package-name] returns the name of a
package.  The function @b[package-nicknames] returns a list of all
nicknames for a package.  The function @b[rename-package] removes a
package's current name and nicknames and replaces them with new ones
specified by the user.  Package renaming is occasionally useful when, for
development purposes, it is desirable to load two versions of a package
into the same Lisp.  We can load one, rename it, and then load the
other, without getting a lot of name conflicts.

@section [Translating Strings to Symbols]

The value of the special variable @b[*package*] must always be a package
object (not a name).  This is referred to as the @i[current package].

When the Lisp reader has, by parsing, obtained a string of characters
thought to name a symbol, that name is looked up in the current package.
This lookup may involve looking in other packages whose external symbols
are inherited by the current package (see below).  If the name is found,
the corresponding symbol is returned.  If the name is not found, a new
symbol is created for it and is placed in the current package as an
internal symbol; if the name is seen again while this same package is
current, the same symbol will then be returned.

When a new symbol is created, a pointer to the package in which it is
initially placed is stored in the @i[package cell] of that symbol; the
package is said to be the symbol's @i[home package], and is said to
@i[own] the symbol.  (Some symbols are not owned by any package; they
are said to be @i[uninterned], and their package cell contains NIL.)

Often it is desirable to refer to an external symbol in some package
other than the current one.  This is done through the use of a
@i[qualified name], consisting of a package name, then a colon, then the
print name of the symbol.  This causes the symbol's name to be looked up
in the specified package, rather than in the current one.  For example,
``@b[editor:buffer]'' refers to the external symbol named ``@b[buffer]''
available in the package named ``@b[editor]'', regardless of whether
there is a symbol named ``@b[buffer]'' in the current package.  If there
is no package named ``@b[editor]'', or if no symbol named ``@b[buffer]''
is available in ``@b[editor]'' or if ``@b[buffer]'' is an internal
symbol in ``@b[editor]'', a correctable error is signalled to ask the
user what he really wants to do.

On rare occasions, a user may need to refer to an @b[internal] symbol of
some package other than the current one.  It is illegal to do this with
the colon qualifier, since accessing an internal symbol of some other
package is usually a mistake.  However, this operation is legal if you
use ``@b[#:]'' as the separator in place of the usual colon.  If
``@b[editor#:buffer]'' is seen, the effect is exactly the same as
reading ``@b[buffer]'' with @b[*package*] temporarily rebound to the
package whose name is ``@b[editor]''.  This special-purpose qualifier
should be used with caution.

The package named @b[keyword] contains all keyword symbols used by the
Lisp system itself and by user-written code.  Such symbols must be
easily accessible from any package, and name conflicts are not an issue
since these symbols are used only to label arguments and never to carry
package-specific values or properties.  Because keyword symbols are used
so frequently, Common Lisp provides a special reader syntax for them:
any symbol preceded by a colon but no package name (for example
``@b[:foo]'') is added to (or looked up in) the @b[keyword] package as
an @i[external] symbol.  The @b[keyword] package is also treated
specially in that whenever a symbol is added to the @b[keyword] package,
the symbol is automatically declared to be a constant and is made to
have itself as its value.  This is why every keyword evaluates to
itself.  As a matter of style, keywords should always be accessed using
the leading-colon convention; you never want to import or inherit
keywords into any other package.

Each symbol contains a package slot that is used to record the home
package of the symbol, or NIL if the symbol is uninterned.  When an
interned symbol is printed, if it is an external symbol in the keyword
package then it is printed with a preceding colon; otherwise, if it is
available (directly or by inheritance) in the current package, it is
printed without any qualification; otherwise, it is printed with the
name of the home package as the qualifier, using ``@b[:]'' as the
separator if the symbol is external and ``@b[#:]'' if not.

A symbol that is uninterned (has no home package) is printed preceded by
``@b[#:]''.  It is possible, by the clever use of import and unintern,
to create a symbol that has no recorded home package, but that in fact is
interned in some package.  The system does not check for this.

In summary, the following four cases are defined:

@Begin[describe]
@b[foo:bar] @\Look up "bar" among the external symbols available in the
package named "foo".

@b[foo#:bar] @\Look up "bar" among the external and internal symbols
available in the package named "foo".

@b[:bar] @\The symbol named "bar" is a self-evaluating keyword.

@b[#:bar] @\The symbol named "bar" is uninterned.
@End[describe]

All other uses of colons within names of symbols are not defined by
Common Lisp, but are reserved for implementation-dependent use; this
includes names that end in a colon, contain two or more colons, or
consist of just a colon.

@section [Exporting and Importing Symbols]

Symbols from one package may be made available in another package in
two ways.

First, any individual symbol may be added to a package by use
of the @b[import] function.  The form @b[(import 'editor:buffer)] takes
the external symbol named @b[buffer] in the @b[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 imported symbol is
not automatically exported from the current package, but if it is
already present and external, that is not changed.  After the call to
@i[import] it is possible to refer to @b[buffer] in the importing package
without any qualifier.  The status of @b[buffer] in the package named
@b[editor] is unchanged, and @b[editor] remains the home package for
this symbol.  Once imported, a symbol is @i[present] in the
importing package and can only be removed by calling @b[unintern].

If the symbol is already present in the importing package, @b[import]
has no effect.  If a distinct symbol with the name @b[buffer] is
available in the importing package (directly or by inheritance) a
correctable error is signalled.  The user will then be offered a choice
of whether or not the importation of this symbol is to proceed.

If the user really wants to do a shadowing import without getting an
error, he should use the @b[shadowing-import] function.  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.  The symbol is also added to the package's shadowing-symbols list.
@b[Shadowing-import] may create confusing situations which violate the
consistency rules, so it should be used with caution.

The second mechanism is provided by the @b[use-package] function.  This
causes a package to inherit all of the external symbols of some other
package.  These symbols become available as @i[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.

Often a user, working by default in the @b[user] package, will
load a number of packages into his Lisp to provide an augmented working
environment; then he will call @b[use-package] on each of these packages
so that he can easily access their external symbols.

When @b[use-package] is called, it checks the external symbols of the
package being used against the set of symbols already available in the
using package.  If there is a conflict -- that is, if one of the
imported symbols has the same name as a distinct symbol already present
in the package -- then a correctable error is signalled asking the user
whether the imported or the existing symbol is to be retained in the
package.  This error does not occur if the existing symbol is on the
package's shadowing-symbols list; in that case, the existing symbol wins
and continues to be available in that package, shadowing the symbol from
the package being used.  Thus, if the user wants to use a package, minus
a few of its external symbols (for which he has local versions), he can
avoid any error by explictly shadowing those symbols before calling
@b[use-package].

@b[Unuse-package] undoes the effects of a previous @b[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 @i[internal] symbols of another package;
to refer to an internal symbol, you must either make that symbol's home
package current, use a qualifier, or import that symbol into the current
package.

When @b[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 above 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 @b[export] function takes a symbol that is available in some package
and makes it an external symbol of that package.  If the symbol is
already available as an external symbol in the package, @b[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
available as an internal symbol via @b[use-package], the symbol is first
imported into the package, then exported.  (It is now present in this
package whether or not it continues to use the symbol's original
package.)  If the symbol is not available at all in the specified
package, a correctable error is signalled which, upon continuing, asks
the user whether the symbol should be imported.

The @b[unexport] function is provided mainly as a way to undo erroneous
calls to @b[export].  It works only on symbols that are directly present
in the current package, switching them back to internal status.  If
@b[unexport] is given a symbol that is already available as an internal
symbol in the current package, it does nothing; if it is given a symbol
that is not available in the packge at all, it signals an error.

@Section[Built-in Packages]

The following packages are built into the Common Lisp system:

@begin[description]
@b[lisp]@\The package named @b[lisp] contains the primitives of the
Common Lisp system.  Its external symbols include all of the
user-visible functions and global variables that are present in the
Common Lisp system, such as @b[car], @b[cdr], @b[*package*], etc.
Almost all other packages will want to use @b[lisp] so that these
symbols are available without qualification.

@b[user]@\The @b[user] package is, by default, the current package at the time
a Common Lisp system starts up.  This package uses the @b[lisp] package.

@b[keyword]@\This package contains all of the keywords used by built-in
or user-defined Lisp functions.  Symbols that start with a colon are
treated as external symbols in the this package.  All symbols in this
package are treated as constants that evaluate to themselves, so the
user can type @b[:foo] instead of @b[':foo].

@b[system]@\This package name is reserved to the implementation.
Normally this is used to contain names of implementation-dependent
system-interface functions.  This package uses @b[lisp] and has the
nickname @b[sys]. 
@end[description]

@Section[Package System Functions and Variables]

Some of the following have been described earlier, but are included here
for completeness.  Note that the following functions are meant to be
used at top-level in files, and should only be used at top-level if you
want to guarantee proper compilation across all Common Lisp
implemenations: @b[in-package], @b[import], @b[export], @b[unexport],
@b[shadow], @b[use-package], and @b[unuse-package].

For the functions described here, all optional arguments named
@i[package] default to the current value of @b[*package*].  Where a
function 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.

@Defvar[Var {*package*}]
The value of this variable must be a package; this package is said to be
the current package.  The initial value of @b[*package*] is the @b[user]
package.

The @b[load] function rebinds @b[*package*] to its current value.  If
some form in the file changes the value of @b[*package*] during loading,
the old value will be restored when the loading is completed.
@Enddefvar

@Defun[Fun {make-package}, Args {@i[package-name] @key @i[nicknames]
@i[use]}]
Creates and returns a new package with the specified package name.  The
@b[:nicknames] argument must be a list of strings to be used as
alternative names for the function.  These names must not conflict with
any existing package names; if they do, a correctable error is
signalled.

The @b[:use] argument is a list of packages or package names whose
external symbols are to be inherited by the new package.  These package
must already exist, and their external symbols must already have been
exported.  If not supplied, @i[:use] defaults to a list of one package,
the @b[lisp] package.
@Enddefun

@Defun[Fun {in-package}, Args {@i[package-name] @key @i[nicknames] @i[use]}]
The @b[in-package] function is intended to be placed at the start of a
file containing a subsystem that is to be loaded into some package other
than @b[user].  It is similar to @b[make-package], except that after the
new package is created, @b[*package*] is set to it.  This binding will
remain in force until changed by the user (perhaps with another
@b[in-package] call), or until the @b[*package*] variable reverts to its
old value at the completion of a @b[load] operation.
@enddefun

@Defun[Fun {find-package}, Args {@i[name]}]
The @i[name] must be a string that is the name or nickname for a
package.  Returns the corresponding package, or NIL if no such package
exists.  This match ignores case (as in @b[string-equal]).
@Enddefun

@Defun[Fun {package-name}, Args {@i[package]}]
The argument must be a package.  This function returns the string that
names that package.
@Enddefun

@Defun[Fun {package-nicknames}, Args {@i[package]}]
The argument must be a package.  This function returns the list of
nickname strings for that package, not including the primary name.
@Enddefun

@Defun[Fun {package-use-list}, Args {@i[package]}]
Returns the list of other packages used by the argument package.
@Enddefun

@Defun[Fun {package-used-by-list}, Args {@i[package]}]
Returns the list of other packages that use the argument package.
@Enddefun

@Defun[Fun {package-shadowing-symbols}, Args {@i[package]}]
Returns the list of symbols in that have been declared as shadowing
symbols in this package by @b[shadow] or @b[shadowing-import].  All
symbols on this list are present in the specified package.
@Enddefun

@Defun[Fun {list-all-packages}, Args {}]
This function returns a list of all packages that currently exist in the
Lisp system.
@Enddefun

@Defun[Fun {intern}, Args {@i[string] @optional @i[package]}]
@i[Package], which defaults to the current package, is
searched for a symbol with the name specified by the @b[string]
argument.  This search will include inherited symbols, as described
above.  If a symbol with the specified name is found, it is returned.
If no such symbol is found, one is created and is installed in the
current package as an internal symbol.  This symbol is returned.
@Incompatibility{Conceptually, @b[intern] translates a
string to a symbol.  In Maclisp and several other Lisps, @b[intern] can
take either a string or a symbol as its argument; in the latter case,
the symbol's print name is extracted and used as the string.  However,
this leads to some confusing issues about what to do if
@b[intern] finds a symbol that is not @b[eq] to the argument symbol.  To
avoid such confusion, we require the argument to be a string.}
@Enddefun

@Defun[Fun {find-symbol}, Args {@i[string] @optional @i[package]}]
This is identical to @b[intern], but it never creates a new symbol.  If
a symbol with the specified name is found in the current package,
directly or by inheritance, the symbol found is returned.  The second
return value is T, indicating that the symbol was found.  The third
value is T if the symbol is an external symbol in the specified package,
NIL if it is internal.  If the symbol is not found in the specified package,
@b[find-symbol] returns NIL for all three values.
@Enddefun

@Defun[Fun {find-external-symbol}, Args {@i[string] @optional @i[package]}]
This is identical to @b[find-symbol], but it does not look for internal
symbols even in @i[package] itself.  This is the type of search done by
the reader for symbols qualified with a package name and a colon.  The
return values are the same as for @b[find-symbol], with the third return
value always being T (external symbol) if a symbol is found.
@Enddefun

@Defun[Fun {unintern}, Args {@i[symbol] @optional @i[package]}]
If the specified symbol is present in the specified package, it is
removed from this package, and also from the package's shadowing-symbols
list if it is present there.  Moreover, if @i[package] is the home
package for the symbol, the symbol is made to have no home package.
@b[Unintern] returns T if it actually removed a symbol, and NIL otherwise.
Note that @i[unintern] should be used with caution, since it can produce
confusing situations that violate the consistency rules listed above.
@Incompatibility{The equivalent of this in @maclisp is @f[remob].}
@Enddefun

@Defun[Fun {export}, Args {@i[symbols] @optional @i[package]}]
The @i[symbols] argument should be a list of symbols, or possibly a single
symbol.  These symbols become available as external symbols in the
current package.  (See the previous section for details.)  If
@i[package] is currently used by another package, any use of @i[export]
signals a correctable error.  Returns T.

By convention, a call to @f[export] listing all exported symbols is
placed near the start of a file to advertise which of the symbols
mentioned the file are intended to be used by other programs.
@Enddefun

@Defun[Fun {unexport}, Args {@i[symbols] @optional @i[package]}]
The argument should be a list of symbols, or possibly a single symbol.
These symbols become internal symbols in @i[package].  (See the
previous section for details.)  If @i[package] is currently used by
another package, any use of @i[unexport] signals a correctable error.
Returns T.
@Enddefun

@Defun[Fun {import}, Args {@i[symbols] @optional @i[package]}]
The argument should be a list of symbols, or possibly a single symbol.
These symbols become internal symbols in @i[package], and can therefore
be referred to without a colon qualifier.  @b[Import] signals a
correctable error if any of the imported symbols has the same name as
some distinct symbol already available in the package.  (See the previous
section for details.)  Returns T.
@Enddefun

@Defun[Fun {shadowing-import}, Args {@i[symbols] @optional @i[package]}]
This is like import, but it does not signal an error even if the
importation of a symbol would shadow some symbol already available in
the package.  In addition to being imported, the symbol is placed on the
shadowing-symbols list of @i[package].  (See the previous section for
details.)  Note that @i[shadowing-import] should be used with caution,
since it can produce confusing situations that violate the consistency
rules listed above.  Returns T.
@Enddefun

@Defun[Fun {shadow}, Args {@i[symbols] @optional @i[package]}]
The argument should be a list of symbols, or possibly a single symbol.
The print-name of each symbol is extracted, and the current package is
searched for a symbol of that name.  If such a symbol is present in this
package (directly, not by inheritance) then nothing is done.  Otherwise,
a new symbol is created with this print name, and it is inserted in the
current package as an internal symbol.  The symbol is also placed on the
shadowing-symbols list of @i[package].  Note that @i[shadow] should be
used with caution, since it can produce confusing situations that
violate the consistency rules listed above.  Returns T.
@Enddefun

@Defun[Fun {use-package}, Args {@i[packages]}]
The argument should be a list of packages or package names, or possibly
a single package or package name.  These packages are added to the
the package's use-list if they are not there already.  All external
symbols in the argument packages become available in the current package
as internal symbols.  (See the previous section for details.)  Returns T.
@enddefun

@Defun[Fun {unuse-package}, Args {@i[packages]}]
The argument should be a list of packages or package names, or possibly
a single package or package name.  These packages are removed from the
current package's use-list.  Returns T.
@enddefun

@Defun[Fun {find-all-symbols}, Args {@i[string-or-symbol]}]
Searches every package in the Lisp system for symbols whose print-name is the
specified string, and returns a list of such symbols.  This search is
case-sensitive.  If the argument is a symbol, its print-name supplies
the string to be searched for.
@enddefun

@Defmac[Fun {do-symbols}, Args {(@i[var] @Mopt<@i[package]> @Mopt<@i[result-form]>) @Mstar<@i[declaration]> @mstar<@i[tag] @mor @i[statement]>}]
@b[Do-symbols] provides straightforward iteration over the symbols of a
package.  The body is performed once for each symbol available in the
@i[package], in no particular order, with the variable @i[var] bound to
the symbol.  Then @i[resultform] (a single form, @i[not] an implicit
@b[progn]) is evaluated, and the result is the value of the
@b[do-symbols] form.  (When the @i[resultform] is evaluated, the control
variable @i[var] is still bound, and has the value @nil.)  If
@i[resultform] is omitted, the result is NIL.  @b[Return] may be used to
terminate the iteration prematurely.  If execution of the body affects
which symbols are contained in the @i[package], other than possibly to
remove the symbol currently the value of @i[var] by using @b[unintern],
the effects are unpredictable.
@Enddefmac

@Defmac[Fun {do-external-symbols}, Args {(@i[var] @Mopt<@i[package]> @Mopt<@i[result-form]>) @Mstar<@i[declaration]> @mstar<@i[tag] @mor @i[statement]>}]
@b[Do-external-symbols] is just like @b[do-symbols], except that only
the external symbols of the specified package are scanned.
@Enddefmac

@Defmac[Fun {do-all-symbols}, Args {(@i[var] @Mopt<@i[result-form]>) @Mstar<@i[declaration]> @mstar<@i[tag] @mor @i[statement]>}]
This is similar to @b[do-symbols], but executes the body once for every
symbol contained in every package.  (This may not get all symbols
whatsoever, depending on the implementation.)  It is @i[not] in general
the case that each symbol is processed only once, since a symbol may
appear in many packages.
@Enddefmac

@Section[Modules]

A @i[module] is a Common Lisp subsystem that is loaded from one or more
files.  A module is normally loaded as a single unit, regardless of how
many files are involved.  A module may consist of one package or several
packages.  The file-loading process is necessarily
implementation-dependent, but Common Lisp provides some very simple
portable machinery for naming modules, keeping track of which modules
have been loaded, and for loading modules as a unit.

@Defvar[Var {*modules*}]
@Defun[Fun {provide}, Args {@i[module-name]}]
@Defun1[Fun {require}, Args {@i[module-name] @optional @i[pathname]}]

Each module has a unique name (a string).  If the module consists of a
single package, it is customary for the package and module names to be
the same.  The variable @b[*modules*] is a list of names of the modules
that have been loaded into the Lisp system so far.  The @b[provide]
function adds a new module name to this list, thereby indicating that
the module in question has been loaded.

The @b[require] function tests whether a module is already present
(using a case-insensitive comparison) and, if not, loads the appropriate
file or set of files.  The pathname argument, if present, is a single
pathname or a list of pathenames whose files are to be loaded in order,
left to right.  If the pathname argument is NIL or is not provided, the
system will attempt to determine which files to load in some
system-dependent manner.  This will typically involve some central
registry of module names and the associated file-lists.

@section [An Example]

Most users will want to load and use packages but will never need to
build one.  Often, a user will load a number of packages into the
@b[user] package whenever he uses Common Lisp.  Most implementations
will provide some sort of "init file" mechanism to make such setup
automatic when the Lisp starts up.  Init files are not normally
compiled.

@begin [Lisp]
;;; Lisp init file for I. Newton.

;;; Set up the USER package the way I like it.

;;; Calculus is used a lot.  Get easy access to all its symbols.
(require "calculus")
(use-package "calculus")

;;; Same for Newtonian mechanics.
(require "newtonian-mechanics")
(use-package "newtonian-mechanics")

;;; I just want a few thing from here, and other things conflict.
;;; Import just what I need into the USER package.
(require "relativity")
(import '(relativity:speed-of-light
	  relativity:ignore-small-errors))

;;; These are worth loading, but I will use qualifiers to get at any
;;; symbols I need.
(require "phlogiston.lsp")
(require "alchemy.lsp")
@end [Lisp]		

When each of two files uses some symbols from the other, we must be
careful to put the contents of the file in the file in the proper order.
Typically each file contains a single package that is a complete module.
The contents of such a file should include the following items, in
order:

@Begin[enumerate]
A @b[provide] call that announces the module name.

An @b[in-package] call that establishes the package.

A @b[shadow] call that establishes any local symbols that will shadow
symbols that would otherwise be inherited from packages that this
package will use.

An @b[export] call that establishes all of this package's external
symbols.

Any number of @b[require] calls to load other modules which the
contents of this file might want to use or refer to.  By placing these
@b[requires] calls here, we make it possible for the packages being
loaded to refer to external symbols in this package.

Any number of @b[use-package] and @b[import] calls, to make it the
symbols from other packages available in this package.

Finally, the definitions making up the contents of this package/module.
@End[enumerate]

<< Anybody got a good mnemonic for the sequence "PISERIUC"?  All I can
come up with is "Please insert seven extra rubles in user consultant."
Not too good. >>

Now, suppose that the @b[phlogiston] and @b[alchemy] packages are
single-file, single-package modules as described above.  Phlogiston
wants to use the alchemy package, and alchemy wants to use several
external symbols from phlogiston.  The following definitions allow the
user to supply @b[require] statement for either of these modules, or for
both of them in either order.

The file "alchemy.lisp":

@begin [lisp]
;;; Alchemy functions, written and maintained by Merlin, Inc.

;;; Both the module and the package are named "alchemy".
(provide "alchemy")
(in-package "alchemy")

;;; Nothing to shadow.

;;; Here is our external interface.
(export '(lead-to-gold gold-to-lead antimony-to-zinc elixir-of-life))

;;; This file uses some functions from the phlogiston package/module.
(require "phlogiston")

;;; We use this a lot, so import it.  It's external in phlogiston package.
(import '(phlogiston:make-fire-bottle))

;;; Now for the real contents of this file.

(defun lead-to-gold (x)
  "Takes a quantity of lead, returns gold."
  (when (> (phlogiston:heat-flow x) 3)	        ; Using a qualified symbol.
	(make-fire-bottle x))			; Using an imported symbol.
  (gild x))

;;; And so on ...
@end [lisp]

The file "phlogiston.lisp":

@begin [lisp]
;;; Phlogiston functions, written and maintained by Thermofluidics, Ltd.

;;; Both the module and the package are named "phlogiston".
(provide "phlogiston")
(in-package "phlogiston")

;;; Nothing to shadow.

;;; Here is our external interface.
(export '(heat-flow cold-flow mix-fluids separate-fluids
	  burn make-fire-bottle))

;;; This file uses some functions from the alchemy package/module.
(require "alchemy")

;;; We use alchemy functions a lot, so use the package.
(use-package "alchemy")

;;; The real contents of this package/module.

(defun heat-flow (amount x y)
  "Make some amount of heat flow from x to y."
  (when feeling-weak
	(quaff (elixir-of-life)))		; No qualifier needed.
  (push-heat amount x y))

;;; And so on ...
@end [lisp]

For very large packages whose contents are spread over several files
(the @b[lisp] package is an example), it is recommended that the author
create the package and declare all of the shadows and external symbols
in a separate file, so that this can be loaded before anything which
might use symbols from this package.