Common Lisp the Language, 2nd Edition
Next: Modules
Up: Packages
Previous: Built-in
Packages
Some of the functions and variables in this section are described in previous sections but are included here for completeness.
It is up to each implementation’s compiler to ensure that when a
compiled file is loaded, all of the symbols in the file end up in the
same packages that they would occupy if the Lisp source file were
loaded. In most compilers, this will be accomplished by treating certain
package operations as though they are surrounded by
(eval-when (compile load eval) ...)
; see
eval-when
. These operations are make-package
,
in-package
, shadow
,
shadowing-import
, export
,
unexport
, use-package
,
unuse-package
, and import
. To guarantee proper
compilation in all Common Lisp implementations, these functions should
appear only at top level within a file. As a matter of style, it is
suggested that each file contain only one package, and that all of the
package setup forms appear near the start of the file. This is discussed
in more detail, with examples, in section 11.9.
X3J13 voted in March 1989 (IN-PACKAGE-FUNCTIONALITY) to cancel the
specifications of the preceding paragraph in order to support a model of
file compilation in which the compiler need never take special note of
ordinary function calls; only special forms and macros are recognized as
affecting the state of the compilation process. As part of this change
in-package
was changed to be a macro rather than a function
and its functionality was restricted. The actions of
shadow
, shadowing-import
,
use-package
, import
, intern
, and
export
for compilation purposes may be accomplished with
the new macro defpackage
.
Implementation note: In the past, some Lisp compilers have read the entire file into Lisp before processing any of the forms. Other compilers have arranged for the loader to do all of its intern operations before evaluating any of the top-level forms. Neither of these techniques will work in a straightforward way in Common Lisp because of the presence of multiple packages.
For the functions described here, all optional arguments named
package default to the current value of *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. Any argument described as a package name may be either a string
or a symbol. If a symbol is supplied, its print name will be used as the
package name; if a string is supplied, the user must take care to
specify the same capitalization used in the package name, normally all
uppercase.
[Variable]
*package*
The value of this variable must be a package; this package is said to
be the current package. The initial value of *package*
is
the user
package.
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the
forthcoming ANSI Common Lisp will use the package name
common-lisp-user
instead of user
.
The function load
rebinds *package*
to its
current value. If some form in the file changes the value of
*package*
during loading, the old value will be restored
when the loading is completed.
X3J13 voted in October 1988 (COMPILE-FILE-PACKAGE) to require
compile-file
to rebind *package*
to its
current value.
[Function]
make-package
package-name
&key :nicknames :use
This creates and returns a new package with the specified package
name. As described above, this argument may be either a string or a
symbol. The :nicknames
argument must be a list of strings
to be used as alternative names for the package. Once again, the user
may supply symbols in place of the strings, in which case the print
names of the symbols are used. These names and nicknames must not
conflict with any existing package names; if they do, a correctable
error is signaled.
The :use
argument is a list of packages or the names
(strings or symbols) of packages whose external symbols are to be
inherited by the new package. These packages must already exist. If not
supplied, :use
defaults to a list of one package, the
lisp
package.
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the
forthcoming ANSI Common Lisp will use the package name
common-lisp
instead of lisp
.
X3J13 voted in January 1989 (MAKE-PACKAGE-USE-DEFAULT) to change
the specification of make-package
so that the default value
for the :use
argument is unspecified. Portable code should
specify :use '("COMMON-LISP")
explicitly.
Rationale: Many existing implementations of Common
Lisp happen to have violated the first edition specification, providing
as the default not only the lisp
package but also (or
instead) a package containing implementation-dependent language
extensions. This is for good reason: usually it is much more convenient
to the user for the default :use
list to be the entire,
implementation-dependent, extended language rather than only the
facilities specified in this book. The X3J13 vote simply legitimizes
existing practice.
[Function]
in-package
package-name
&key :nicknames :use
The 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 user
.
If there is not already a package named package-name, this
function is similar to make-package
, except that after the
new package is created, *package*
is set to it. This
binding will remain in force until changed by the user (perhaps with
another in-package
call) or until the
*package*
variable reverts to its old value at the
completion of a load
operation.
If there is an existing package whose name is package-name,
the assumption is that the user is re-loading a file after making some
changes. The existing package is augmented to reflect any new nicknames
or new packages in the :use
list (with the usual error
checking), and *package*
is then set to this package.
X3J13 voted in January 1989 (RETURN-VALUES-UNSPECIFIED) to specify
that in-package
returns the new package, that is, the value
of *package*
after the operation has been executed.
X3J13 voted in March 1989 (LISP-PACKAGE-NAME) to specify that the
forthcoming ANSI Common Lisp will use the package name
common-lisp-user
instead of user
.
X3J13 voted in March 1989 (IN-PACKAGE-FUNCTIONALITY) to restrict
the functionality of in-package
and to make it a macro.
This is an incompatible change.
Making in-package
a macro rather than a function means
that there is no need to require compile-file
to handle it
specially. Since defpackage
is also defined to have side
effects on the compilation environment, there is no need to require any
of the package functions to be treated specially by the compiler.
[Macro]
in-package
name
This macro causes *package*
to be set to the package
named name, which must be a symbol or string. The name
is not evaluated. An error is signaled if the package does not already
exist. Everything this macro does is also performed at compile time if
the call appears at top level.
[Function]
find-package
name
The name must be a string that is the name or nickname for a
package. This argument may also be a symbol, in which case the symbol’s
print name is used. The package with that name or nickname is returned;
if no such package exists, find-package
returns
nil
. The matching of names observes case (as in
string=
).
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to allow
find-package
to accept a package object, in which case the
package is simply returned (see section 11.2).
[Function]
package-name
package
The argument must be a package. This function returns the string that names that package.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to allow
package-name
to accept a package name or nickname, in which
case the primary name of the package so specified is returned (see
section 11.2).
X3J13 voted in January 1989 (PACKAGE-DELETION) to add a function to
delete packages. One consequence of this vote is that
package-name
will return nil
instead of a
package name if applied to a deleted package object. See
delete-package
.
[Function]
package-nicknames
package
The argument must be a package. This function returns the list of nickname strings for that package, not including the primary name.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to allow
package-nicknames
to accept a package name or nickname, in
which case the nicknames of the package so specified are returned (see
section 11.2).
[Function]
rename-package
package
new-name
&optional
new-nicknames
The old name and all of the old nicknames of package are
eliminated and are replaced by new-name and
new-nicknames. The new-name argument is a string or
symbol; the new-nicknames argument, which defaults to
nil
, is a list of strings or symbols.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
X3J13 voted in January 1989 (RETURN-VALUES-UNSPECIFIED) to specify
that rename-package
returns package.
[Function]
package-use-list
package
A list of other packages used by the argument package is returned.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
package-used-by-list
package
A list of other packages that use the argument package is returned.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
package-shadowing-symbols
package
A list is returned of symbols that have been declared as shadowing
symbols in this package by shadow
or
shadowing-import
. All symbols on this list are present in
the specified package.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
list-all-packages
This function returns a list of all packages that currently exist in the Lisp system.
[Function]
delete-package
package
X3J13 voted in January 1989 (PACKAGE-DELETION) to add the
delete-package
function, which deletes the specified
package from all package system data structures. The
package argument may be either a package or the name of a
package.
If package is a name but there is currently no package of
that name, a correctable error is signaled. Continuing from the error
makes no deletion attempt but merely returns nil
from the
call to delete-package
.
If package is a package object that has already been
deleted, no error is signaled and no deletion is attempted; instead,
delete-package
immediately returns nil
.
If the package specified for deletion is currently used by other
packages, a correctable error is signaled. Continuing from this error,
the effect of the function unuse-package
is performed on
all such other packages so as to remove their dependency on the
specified package, after which delete-package
proceeds to
delete the specified package as if no other package had been using
it.
If any symbol had the specified package as its home package before
the call to delete-package
, then its home package is
unspecified (that is, the contents of its package cell are unspecified)
after the delete-package
operation has been completed.
Symbols in the deleted package are not modified in any other way.
The name and nicknames of the package cease to be recognized
package names. The package object is still a package, but anonymous;
packagep
will be true of it, but package-name
applied to it will return nil
.
The effect of any other package operation on a deleted package object
is undefined. In particular, an attempt to locate a symbol within a
deleted package (using intern
or find-symbol
,
for example) will have unspecified results.
delete-package
returns t
if the deletion
succeeds, and nil
otherwise.
[Function]
intern
string
&optional
package
The package, which defaults to the current package, is
searched for a symbol with the name specified by the string
argument. This search will include inherited symbols, as described in
section 11.4. 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 specified package as an
internal symbol (as an external symbol if the package is the
keyword
package); the specified package becomes the home
package of the created symbol.
X3J13 voted in March 1989 (CHARACTER-PROPOSAL) to specify that
intern
may in effect perform the search using a copy of the
argument string in which some or all of the implementation-defined
attributes have been removed from the characters of the string. It is
implementation-dependent which attributes are removed.
Two values are returned. The first is the symbol that was found or
created. The second value is nil
if no pre-existing symbol
was found, and takes on one of three values if a symbol was found:
:internal
The symbol was directly present in the package as an internal
symbol.
:external
The symbol was directly present as an external symbol.
:inherited
The symbol was inherited via use-package
(which implies
that the symbol is internal).
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that the package argument may be either a package object or a package name (see section 11.2).
Compatibility note: Conceptually,
intern
translates a string to a symbol. In MacLisp and
several other dialects of Lisp, 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 intern
finds a
symbol that is not eq
to the argument symbol. To avoid such
confusion, Common Lisp requires the argument to be a string.
[Function]
find-symbol
string
&optional
package
This is identical to intern
, but it never creates a new
symbol. If a symbol with the specified name is found in the specified
package, directly or by inheritance, the symbol found is returned as the
first value and the second value is as specified for
intern
. If the symbol is not accessible in the specified
package, both values are nil
.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
unintern
symbol
&optional
package
If the specified symbol is present in the specified package,
it is removed from that package and also from the package’s
shadowing-symbols list if it is present there. Moreover, if the
package is the home package for the symbol, the symbol is made
to have no home package. Note that in some circumstances the symbol may
continue to be accessible in the specified package by inheritance.
unintern
returns t
if it actually removed a
symbol, and nil
otherwise.
unintern
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.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
Compatibility note: The equivalent of this in
MacLisp is remob
.
[Function]
export
symbols
&optional
package
The symbols argument should be a list of symbols, or
possibly a single symbol. These symbols become accessible as external
symbols in package (see section 11.4). export
returns t
.
By convention, a call to export
listing all exported
symbols is placed near the start of a file to advertise which of the
symbols mentioned in the file are intended to be used by other
programs.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
unexport
symbols
&optional
package
The argument should be a list of symbols, or possibly a single
symbol. These symbols become internal symbols in package. It is
an error to unexport a symbol from the keyword
package (see
section 11.4).
unexport
returns t
.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
import
symbols
&optional
package
The argument should be a list of symbols, or possibly a single
symbol. These symbols become internal symbols in package and
can therefore be referred to without having to use qualified-name
(colon) syntax. import
signals a correctable error if any
of the imported symbols has the same name as some distinct symbol
already accessible in the package (see section 11.4). import
returns t
.
X3J13 voted in June 1987 (IMPORT-SETF-SYMBOL-PACKAGE) to clarify that
if any symbol to be imported has no home package then
import
sets the home package of the symbol to the
package to which the symbol is being imported.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to
clarify that the package argument may be either a package
object or a package name (see section 11.2).
[Function]
shadowing-import
symbols
&optional
package
This is like import
, but it does not signal an error
even if the importation of a symbol would shadow some symbol already
accessible in the package. In addition to being imported, the symbol is
placed on the shadowing-symbols list of package (see section 11.5).
shadowing-import
returns t
.
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.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
shadow
symbols
&optional
package
The argument should be a list of symbols, or possibly a single
symbol. The print name of each symbol is extracted, and the specified
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 package as an internal symbol. The symbol is
also placed on the shadowing-symbols list of the package (see
section 11.5).
shadow
returns t
.
X3J13 voted in March 1988 (SHADOW-ALREADY-PRESENT) to change
shadow
to accept strings as well as well as symbols (a
string in the symbols list being treated as a print name), and
to clarify that if a symbol of specified name is already in the
package but is not yet on the shadowing-symbols list for that
package, then shadow
does add it to the
shadowing-symbols list rather than simply doing nothing.
shadow
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.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
use-package
packages-to-use
&optional
package
The packages-to-use argument should be a list of packages or
package names, or possibly a single package or package name. These
packages are added to the use-list of package if they are not
there already. All external symbols in the packages to use become
accessible in package as internal symbols (see section 11.4). It is an error to try
to use the keyword
package. use-package
returns t
.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
[Function]
unuse-package
packages-to-unuse
&optional
package
The packages-to-unuse argument should be a list of packages
or package names, or possibly a single package or package name. These
packages are removed from the use-list of package.
unuse-package
returns t
.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
X3J13 voted in January 1989 (DEFPACKAGE) to add a macro
defpackage
to the language to make it easier to create new
packages, alleviating the burden on the programmer to perform the
various setup operations in exactly the correct sequence.
[Macro]
defpackage
defined-package-name
{
option
}*
This creates a new package, or modifies an existing one, whose name
is defined-package-name. The defined-package-name may
be a string or a symbol; if it is a symbol, only its print name matters,
and not what package, if any, the symbol happens to be in. The newly
created or modified package is returned as the value of the
defpackage
form.
Each standard option is a list of a keyword (the name of the
option) and associated arguments. No part of a defpackage
form is evaluated. Except for the :size
option, more than
one option of the same kind may occur within the same
defpackage
form.
The standard options for defpackage
are as follows. In
every case, any option argument called package-name or
symbol-name may be a string or a symbol; if it is a symbol,
only its print name matters, and not what package, if any, the symbol
happens to be in.
(:size
integer
)
This specifies approximately the number of symbols expected to be in the
package. This is purely an efficiency hint to the storage allocator, so
that implementations using hash tables as part of the package data
structure (the usual technique) will not have to incrementally expand
the package as new symbols are added to it (for example, as a large file
is read while ``in’’ that package).
(:nicknames {
package-name
}*)
The specified names become nicknames of the package being defined. If
any of the specified nicknames already refers to an existing package, a
continuable error is signaled exactly as for the function
make-package
.
(:shadow {
symbol-name
}*)
Symbols with the specified names are created as shadows in the package
being defined, just as with the function shadow
.
(:shadowing-import-from
package-name
{
symbol-name
}*)
Symbols with the specified names are located in the specified package.
These symbols are imported into the package being defined, shadowing
other symbols if necessary, just as with the function
shadowing-import
. In no case will symbols be created in a
package other than the one being defined; a continuable error is
signaled if for any symbol-name there is no symbol of that name
accessible in the package named package-name.
(:use {
package-name
}*)
The package being defined is made to ``use’’ (inherit from) the packages
specified by this option, just as with the function
use-package
. If no :use
option is supplied,
then a default list is assumed as for make-package
.
X3J13 voted in January 1989 (MAKE-PACKAGE-USE-DEFAULT) to change
the specification of make-package
so that the default value
for the :use
argument is unspecified. This change affects
defpackage
as well. Portable code should specify
(:use '("COMMON-LISP"))
explicitly.
(:import-from
package-name
{
symbol-name
}*)
Symbols with the specified names are located in the specified package.
These symbols are imported into the package being defined, just as with
the function import
. In no case will symbols be created in
a package other than the one being defined; a continuable error is
signaled if for any symbol-name there is no symbol of that name
accessible in the package named package-name.
(:intern {
symbol-name
}*)
Symbols with the specified names are located or created in the package
being defined, just as with the function intern
. Note that
the action of this option may be affected by a :use
option,
because an inherited symbol will be used in preference to creating a new
one.
(:export {
symbol-name
}*)
Symbols with the specified names are located or created in the package
being defined and then exported, just as with the function
export
. Note that the action of this option may be affected
by a :use
, :import-from
, or
:shadowing-import-from
option, because an inherited or
imported symbol will be used in preference to creating a new one.
The order in which options appear in a defpackage
form
does not matter; part of the convenience of defpackage
is
that it sorts out the options into the correct order for processing.
Options are processed in the following order:
:shadow
and :shadowing-import-from
:use
:import-from
and :intern
:export
Shadows are established first in order to avoid spurious name conflicts when use links are established. Use links must occur before importing and interning so that those operations may refer to normally inherited symbols rather than creating new ones. Exports are performed last so that symbols created by any of the other options, in particular, shadows and imported symbols, may be exported. Note that exporting an inherited symbol implicitly imports it first (see section 11.4).
If no package named defined-package-name already exists,
defpackage
creates it. If such a package does already
exist, then no new package is created. The existing package is modified,
if possible, to reflect the new definition. The results are undefined if
the new definition is not consistent with the current state of the
package.
An error is signaled if more than one :size
option
appears.
An error is signaled if the same symbol-name
argument
(in the sense of comparing names with string=
) appears more
than once among the arguments to all the :shadow
,
:shadowing-import-from
, :import-from
, and
:intern
options.
An error is signaled if the same symbol-name
argument
(in the sense of comparing names with string=
) appears more
than once among the arguments to all the :intern
and
:export
options.
Other kinds of name conflicts are handled in the same manner that the
underlying operations use-package
, import
, and
export
would handle them.
Implementations may support other defpackage
options.
Every implementation should signal an error on encountering a
defpackage
option it does not support.
The function compile-file
should treat top-level
defpackage
forms in the same way it would treat top-level
calls to package-affecting functions (as described at the beginning of
section 11.7).
Here is an example of a call to defpackage
that ``plays
it safe’’ by using only strings as names.
(cl:defpackage "MY-VERY-OWN-PACKAGE"
(:size 496)
(:nicknames "MY-PKG" "MYPKG" "MVOP")
(:use "COMMON-LISP")
(:shadow "CAR" "CDR")
(:shadowing-import-from "BRAND-X-LISP" "CONS")
(:import-from "BRAND-X-LISP" "GC" "BLINK-FRONT-PANEL-LIGHTS")
(:export "EQ" "CONS" "MY-VERY-OWN-FUNCTION"))
The preceding defpackage
example is designed to operate
correctly even if the package current when the form is read happens not
to ``use’’ the common-lisp
package. (Note the use in this
example of the nickname cl
for the common-lisp
package.) Moreover, neither reading in nor evaluating this
defpackage
form will ever create any symbols in the current
package. Note too the use of uppercase letters in the strings.
Here, for the sake of contrast, is a rather similar use of
defpackage
that ``plays the whale’’ by using all sorts of
permissible syntax.
(defpackage my-very-own-package
(:export :EQ common-lisp:cons my-very-own-function)
(:nicknames "MY-PKG" #:MyPkg)
(:use "COMMON-LISP")
(:shadow "CAR")
(:size 496)
(:nicknames mvop)
(:import-from "BRAND-X-LISP" "GC" Blink-Front-Panel-Lights)
(:shadow common-lisp::cdr)
(:shadowing-import-from "BRAND-X-LISP" CONS))
This example has exactly the same effect on the newly created package
but may create useless symbols in other packages. The use of explicit
package tags is particularly confusing; for example, this
defpackage
form will cause the symbol cdr
to
be shadowed in the new package; it will not be shadowed in the
package common-lisp
. The fact that the name
``CDR
’’ was specified by a package-qualified reference to a
symbol in the common-lisp
package is a red herring. The
moral is that the syntactic flexibility of defpackage
, as
in other parts of Common Lisp, yields considerable convenience when used
with commonsense competence, but unutterable confusion when used with
Malthusian profusion.
Implementation note: An implementation of
defpackage
might choose to transform all the
package-name and symbol-name arguments into strings at
macro expansion time, rather than at the time the resulting expansion is
executed, so that even if source code is expressed in terms of strange
symbols in the defpackage
form, the binary file resulting
from compiling the source code would contain only strings. The purpose
of this is simply to minimize the creation of useless symbols in
production code. This technique is permitted as an implementation
strategy but is not a behavior required by the specification of
defpackage
.
Note that defpackage
is not capable by itself of
defining mutually recursive packages, for example two packages each of
which uses the other. However, nothing prevents one from using
defpackage
to perform much of the initial setup and then
using functions such as use-package
, import
,
and export
to complete the links.
The purpose of defpackage
is to encourage the user to
put the entire definition of a package and its relationships to other
packages in a single place. It may also encourage the designer of a
large system to place the definitions of all relevant packages into a
single file (say) that can be loaded before loading or compiling any
code that depends on those packages. Such a file, if carefully
constructed, can simply be loaded into the common-lisp-user
package.
Implementations and programming environments may also be better able
to support the programming process (if only by providing better error
checking) through global knowledge of the intended package setup.
[Function]
find-all-symbols
string-or-symbol
find-all-symbols
searches every package in the Lisp
system to find every symbol whose print name is the specified string. A
list of all such symbols found is returned. This search is
case-sensitive. If the argument is a symbol, its print name supplies the
string to be searched for.
[Macro]
do-symbols (var [package [result-form]])
{declaration}* {tag | statement}*
do-symbols
provides straightforward iteration over the
symbols of a package. The body is performed once for each symbol
accessible in the package, in no particular order, with the
variable var bound to the symbol. Then result-form (a
single form, not an implicit progn
) is evaluated,
and the result is the value of the do-symbols
form. (When
the result-form is evaluated, the control variable var
is still bound and has the value nil
.) If the
result-form is omitted, the result is nil
.
return
may be used to terminate the iteration prematurely.
If execution of the body affects which symbols are contained in the
package, other than possibly to remove the symbol currently the
value of var by using unintern
, the effects are
unpredictable.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
X3J13 voted in March 1988 (DO-SYMBOLS-DUPLICATES) to specify that
the body of a do-symbols
form may be executed more than
once for the same accessible symbol, and users should take care to allow
for this possibility.
The point is that the same symbol might be accessible via more than one chain of inheritance, and it is implementationally costly to eliminate such duplicates. Here is an example:
(setq *a* (make-package 'a)) ;Implicitly uses package common-lisp
(setq *b* (make-package 'b)) ;Implicitly uses package common-lisp
(setq *c* (make-package 'c :use '(a b)))
(do-symbols (x *c*) (print x)) ;Symbols in package common-lisp
; might be printed once or twice here
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict user side effects; see section 7.9.
Note that the loop
construct provides a kind of
for
clause that can iterate over the symbols of a package
(see chapter 26).
[Macro]
do-external-symbols (var [package [result]])
{declaration}* {tag | statement}*
do-external-symbols
is just like
do-symbols
, except that only the external symbols of the
specified package are scanned. The clarification voted by X3J13 in March
1988 for do-symbols
(DO-SYMBOLS-DUPLICATES) , regarding
redundant executions of the body for the same symbol, applies also to
do-external-symbols
.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify
that the package argument may be either a package object or a
package name (see section 11.2).
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to
restrict user side effects; see section 7.9.
[Macro]
do-all-symbols (var [result-form])
{declaration}* {tag | statement}*
This is similar to do-symbols
but executes the body once
for every symbol contained in every package. (This will not process
every symbol whatsoever, because a symbol not accessible in any package
will not be processed. Normally, uninterned symbols are not accessible
in any package.) It is not in general the case that each symbol
is processed only once, because a symbol may appear in many
packages.
The clarification voted by X3J13 in March 1988 for
do-symbols
(DO-SYMBOLS-DUPLICATES) , regarding redundant
executions of the body for the same symbol, applies also to
do-all-symbols
.
X3J13 voted in January 1989 (PACKAGE-FUNCTION-CONSISTENCY) to clarify that the package argument may be either a package object or a package name (see section 11.2).
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict user side effects; see section 7.9.
X3J13 voted in January 1989 (HASH-TABLE-PACKAGE-GENERATORS) to add
a new macro with-package-iterator
to the language.
[Macro]
with-package-iterator (mname package-list {symbol-type}+)
{form}*
The name mname is bound and defined as if by
macrolet
, with the body forms as its lexical
scope, to be a ``generator macro’’ such that each invocation of
(
mname
)
will return a
symbol and that successive invocations will eventually deliver, one by
one, all the symbols from the packages that are elements of the list
that is the value of the expression package-list (which is
evaluated exactly once).
Each element of the package-list value may be either a
package or the name of a package. As a further convenience, if the
package-list value is itself a package or the name of a
package, it is treated as if a singleton list containing that value had
been provided. If the package-list value is nil
,
it is considered to be an empty list of packages.
At each invocation of the generator macro, there are two
possibilities. If there is yet another unprocessed symbol, then four
values are returned: t
, the symbol, a keyword indicating
the accessibility of the symbol within the package (see below), and the
package from which the symbol was accessed. If there are no more
unprocessed symbols in the list of packages, then one value is returned:
nil
.
When the generator macro returns a symbol as its second value, the
fourth value is always one of the packages present or named in the
package-list value, and the third value is a keyword indicating
accessibility: :internal
means present in the package and
not exported; :external
means present and exported; and
:inherited
means not present (thus not shadowed) but
inherited from some package used by the package that is the fourth
value.
Each symbol-type in an invocation of
with-package-iterator
is not evaluated. More than one may
be present; their order does not matter. They indicate the accessibility
types of interest. A symbol is not returned by the generator macro
unless its actual accessibility matches one of the symbol-type
indicators. The standard symbol-type indicators are
:internal
, :external
, and
:inherited
, but implementations are permitted to extend the
syntax of with-package-iterator
by recognizing additional
symbol accessibility types. An error is signaled if no
symbol-type is supplied, or if any supplied
symbol-type is not recognized by the implementation.
The order in which symbols are produced by successive invocations of the generator macro is not necessarily correlated in any way with the order of the packages in the package-list. When more than one package is in the package-list, symbols accessible from more than one package may be produced once or more than once. Even when only one package is specified, symbols inherited in multiple ways via used packages may be produced once or more than once.
The implicit interior state of the iteration over the list of
packages and the symbols within them has dynamic extent. It is an error
to invoke the generator macro once the
with-package-iterator
form has been exited.
Any number of invocations of with-package-iterator
and
related macros may be nested, and the generator macro of an outer
invocation may be called from within an inner invocation (provided, of
course, that its name is visible or otherwise made available).
X3J13 voted in January 1989 (MAPPING-DESTRUCTIVE-INTERACTION) to restrict user side effects; see section 7.9.
Rationale: This facility is a bit more flexible in
some ways than do-symbols
and friends. In particular, it
makes it possible to implement loop
clauses for iterating
over packages in a way that is both portable and efficient (see chapter
26).
Next: Modules
Up: Packages
Previous: Built-in
Packages
AI.Repository@cs.cmu.edu