A package @IGindex{package} establishes a mapping from names to symbols. At any given time, one package is current. The current package @IGindex{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.
Figure 11--1 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.
*modules* import provide *package* in-package rename-package defpackage intern require do-all-symbols list-all-packages shadow do-external-symbols make-package shadowing-import do-symbols package-name unexport export package-nicknames unintern find-all-symbols package-shadowing-symbols unuse-package find-package package-use-list use-package find-symbol package-used-by-list
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 @IGindex{internal symbol} 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 @IGindex{external symbol}
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 @IGindex{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 @IGindex{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.
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:
This section describes the packages that are available in every conforming implementation. A summary of the names and nicknames of those standardized packages is given in Figure 11--2.
Name Nicknames COMMON-LISP CL COMMON-LISP-USER CL-USER KEYWORD none
Figure 11--2: Standardized Package Names
@IPindex{common-lisp}
@IPindex{cl}
The COMMON-LISP package contains the primitives of the Common Lisp system as defined by this specification. Its external symbols include all of the defined names (except for defined names in the KEYWORD package) that are present in the Common Lisp system, such as car, cdr, *package*, etc. The COMMON-LISP package has the nickname CL.
The COMMON-LISP package has as external symbols those symbols enumerated in the figures in section Symbols in the COMMON-LISP Package, and no others. These external symbols are present in the COMMON-LISP package but their home package need not be the COMMON-LISP package.
For example, the symbol HELP cannot be an external symbol of the COMMON-LISP package because it is not mentioned in section Symbols in the COMMON-LISP Package. In contrast, the symbol variable must be an external symbol of the COMMON-LISP package even though it has no definition because it is listed in that section (to support its use as a valid second argument to the function documentation).
The COMMON-LISP package can have additional internal symbols.
In a conforming implementation, an external symbol of the COMMON-LISP package can have a function, macro, or special operator definition, a global variable definition (or other status as a dynamic variable due to a special proclamation), or a type definition only if explicitly permitted in this standard. For example, fboundp yields false for any external symbol of the COMMON-LISP package that is not the name of a standardized function, macro or special operator, and boundp returns false for any external symbol of the COMMON-LISP package that is not the name of a standardized global variable. It also follows that conforming programs can use external symbols of the COMMON-LISP package as the names of local lexical variables with confidence that those names have not been proclaimed special by the implementation unless those symbols are names of standardized global variables.
A conforming implementation must not place any property on an external symbol of the COMMON-LISP package using a property indicator that is either an external symbol of any standardized package or a symbol that is otherwise accessible in the COMMON-LISP-USER package.
@ITindex{redefinition}
Except where explicitly allowed, the consequences are undefined if any of the following actions are performed on an external symbol of the COMMON-LISP package:
If an external symbol of the COMMON-LISP package is not globally defined as a standardized dynamic variable or constant variable, it is allowed to lexically bind it and to declare the type of that binding, and it is allowed to locally establish it as a symbol macro (e.g., with symbol-macrolet).
Unless explicitly specified otherwise, if an external symbol of the COMMON-LISP package is globally defined as a standardized dynamic variable, it is permitted to bind or assign that dynamic variable provided that the "Value Type" constraints on the dynamic variable are maintained, and that the new value of the variable is consistent with the stated purpose of the variable.
If an external symbol of the COMMON-LISP package is not defined as a standardized function, macro, or special operator, it is allowed to lexically bind it as a function (e.g., with flet), to declare the ftype of that binding, and (in implementations which provide the ability to do so) to trace that binding.
If an external symbol of the COMMON-LISP package is not defined as a standardized function, macro, or special operator, it is allowed to lexically bind it as a macro (e.g., with macrolet).
If an external symbol of the COMMON-LISP package is not defined as a standardized function, macro, or special operator, it is allowed to lexically bind its setf function name as a function, and to declare the ftype of that binding.
@IPindex{common-lisp-user}
@IPindex{cl-user}
The COMMON-LISP-USER package is the current package when a Common Lisp system starts up. This package uses the COMMON-LISP package. The COMMON-LISP-USER package has the nickname CL-USER.
The COMMON-LISP-USER package can have additional symbols interned within it; it can use other implementation-defined packages.
@IPindex{keyword}
The KEYWORD package contains symbols, called keywords_1, that are typically used as special markers in programs and their associated data expressions_1.
Symbol tokens that start with a package marker are parsed by the Lisp reader as symbols in the KEYWORD package; see section Symbols as Tokens. This makes it notationally convenient to use keywords when communicating between programs in different packages. For example, the mechanism for passing keyword parameters in a call uses keywords_1 to name the corresponding arguments; see section Ordinary Lambda Lists.
Symbols in the KEYWORD package are, by definition, of type keyword.
The KEYWORD package is treated differently than other packages in that special actions are taken when a symbol is interned in it. In particular, when a symbol is interned in the KEYWORD package, it is automatically made to be an external symbol and is automatically made to be a constant variable with itself as a value.
It is generally best to confine the use of keywords to situations in which there are a finitely enumerable set of names to be selected between. For example, if there were two states of a light switch, they might be called :on and :off.
In situations where the set of names is not finitely enumerable (i.e., where name conflicts might arise) it is frequently best to use symbols in some package other than KEYWORD so that conflicts will be naturally avoided. For example, it is generally not wise for a program to use a keyword_1 as a property indicator, since if there were ever another program that did the same thing, each would clobber the other's data.
Other, implementation-defined packages might be present in the initial Common Lisp environment.
It is recommended, but not required, that the documentation for a conforming implementation contain a full list of all package names initially present in that implementation but not specified in this specification. (See also the function list-all-packages.)
package, t
A package is a namespace that maps symbol names to symbols; see section Package Concepts.
section Package Concepts, section Printing Other Objects, section Symbols as Tokens
export
symbols {&optional package} => t
symbols---a designator for a list of symbols.
package---a package designator.
The default is the current package.
export makes one or more symbols that are accessible in package (whether directly or by inheritance) be external symbols of that package.
If any of the symbols is already accessible as an external symbol of package, export has no effect on that symbol. If the symbol is present in package as an internal symbol, it is simply changed to external status. If it is accessible as an internal symbol via use-package, it is first imported into package, then exported. (The symbol is then present in the package whether or not package continues to use the package through which the symbol was originally inherited.)
export makes each symbol accessible to all the packages that use package. All of these packages are checked for name conflicts: (export s p) does (find-symbol (symbol-name s) q) for each package q in (package-used-by-list p). Note that in the usual case of an export during the initial definition of a package, the result of package-used-by-list is nil and the name-conflict checking takes negligible time. When multiple changes are to be made, for example when export is given a list of symbols, it is permissible for the implementation to process each change separately, so that aborting from a name conflict caused by any but the first symbol in the list does not unexport the first symbol in the list. However, aborting from a name-conflict error caused by export of one of symbols does not leave that symbol accessible to some packages and inaccessible to others; with respect to each of symbols processed, export behaves as if it were as an atomic operation.
A name conflict in export between one of symbols being exported and a symbol already present in a package that would inherit the newly-exported symbol may be resolved in favor of the exported symbol by uninterning the other one, or in favor of the already-present symbol by making it a shadowing symbol.
(make-package 'temp :use nil) => #<PACKAGE "TEMP"> (use-package 'temp) => T (intern "TEMP-SYM" 'temp) => TEMP::TEMP-SYM, NIL (find-symbol "TEMP-SYM") => NIL, NIL (export (find-symbol "TEMP-SYM" 'temp) 'temp) => T (find-symbol "TEMP-SYM") => TEMP-SYM, :INHERITED
The package system is modified.
Accessible symbols.
If any of the symbols is not accessible at all in package, an error of type package-error is signaled that is correctable by permitting the user to interactively specify whether that symbol should be imported.
section import [Function] , section unexport [Function] , section Package Concepts
find-symbol
string {&optional package} => symbol, status
string---a string.
package---a package designator.
The default is the current package.
symbol---a symbol accessible in the package, or nil.
status---one of :inherited, :external, :internal, or nil.
find-symbol locates a symbol whose name is string in a package. If a symbol named string is found in package, directly or by inheritance, the symbol found is returned as the first value; the second value is as follows:
If no such symbol is accessible in package, both values are nil.
(find-symbol "NEVER-BEFORE-USED") => NIL, NIL (find-symbol "NEVER-BEFORE-USED") => NIL, NIL (intern "NEVER-BEFORE-USED") => NEVER-BEFORE-USED, NIL (intern "NEVER-BEFORE-USED") => NEVER-BEFORE-USED, :INTERNAL (find-symbol "NEVER-BEFORE-USED") => NEVER-BEFORE-USED, :INTERNAL (find-symbol "never-before-used") => NIL, NIL (find-symbol "CAR" 'common-lisp-user) => CAR, :INHERITED (find-symbol "CAR" 'common-lisp) => CAR, :EXTERNAL (find-symbol "NIL" 'common-lisp-user) => NIL, :INHERITED (find-symbol "NIL" 'common-lisp) => NIL, :EXTERNAL (find-symbol "NIL" (prog1 (make-package "JUST-TESTING" :use '()) (intern "NIL" "JUST-TESTING"))) => JUST-TESTING::NIL, :INTERNAL (export 'just-testing::nil 'just-testing) (find-symbol "NIL" 'just-testing) => JUST-TESTING:NIL, :EXTERNAL (find-symbol "NIL" "KEYWORD") => NIL, NIL OR=> :NIL, :EXTERNAL (find-symbol (symbol-name :nil) "KEYWORD") => :NIL, :EXTERNAL
intern, import, export, use-package, unintern, unexport, unuse-package
section intern [Function] , section find-all-symbols [Function]
find-symbol is operationally equivalent to intern, except that it never creates a new symbol.
find-package
name => package
name---a string designator or a package object.
package---a package object or nil.
If name is a string designator, find-package locates and returns the package whose name or nickname is name. This search is case sensitive. If there is no such package, find-package returns nil.
If name is a package object, that package object is returned.
(find-package 'common-lisp) => #<PACKAGE "COMMON-LISP"> (find-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> (find-package 'not-there) => NIL
The set of packages created by the implementation.
defpackage, delete-package, make-package, rename-package
section make-package [Function]
find-all-symbols
string => symbols
string---a string designator.
symbols---a list of symbols.
find-all-symbols searches every registered package for symbols that have a name that is the same (under string=) as string. A list of all such symbols is returned. Whether or how the list is ordered is implementation-dependent.
(find-all-symbols 'car) => (CAR) OR=> (CAR VEHICLES:CAR) OR=> (VEHICLES:CAR CAR) (intern "CAR" (make-package 'temp :use nil)) => TEMP::CAR, NIL (find-all-symbols 'car) => (TEMP::CAR CAR) OR=> (CAR TEMP::CAR) OR=> (TEMP::CAR CAR VEHICLES:CAR) OR=> (CAR TEMP::CAR VEHICLES:CAR)
section find-symbol [Function]
import
symbols {&optional package} => t
symbols---a designator for a list of symbols.
package---a package designator.
The default is the current package.
import adds symbol or symbols to the internals of package, checking for name conflicts with existing symbols either present in package or accessible to it. Once the symbols have been imported, they may be referenced in the importing package without the use of a package prefix when using the Lisp reader.
A name conflict in import between the symbol being imported and a symbol inherited from some other package can be resolved in favor of the symbol being imported by making it a shadowing symbol, or in favor of the symbol already accessible by not doing the import. A name conflict in import with a symbol already present in the package may be resolved by uninterning that symbol, or by not doing the import.
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.
If any symbol to be imported has no home package (i.e., (symbol-package symbol) => nil), import sets the home package of the symbol to package.
If the symbol is already present in the importing package, import has no effect.
(import 'common-lisp::car (make-package 'temp :use nil)) => T (find-symbol "CAR" 'temp) => CAR, :INTERNAL (find-symbol "CDR" 'temp) => NIL, NIL
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 buffer is then present in the current package.
The package system is modified.
Current state of the package system.
import signals a correctable error of type package-error if any of the symbols to be imported has the same name (under string=) as some distinct symbol (under eql) already accessible in the package, even if the conflict is with a shadowing symbol of the package.
section shadow [Function] , section export [Function]
list-all-packages
<no arguments> => packages
packages---a list of package objects.
list-all-packages returns a
fresh
list of
all registered packages.
(let ((before (list-all-packages))) (make-package 'temp) (set-difference (list-all-packages) before)) => (#<PACKAGE "TEMP">)
defpackage, delete-package, make-package
rename-package
package new-name {&optional new-nicknames} => package-object
package---a package designator.
new-name---a package designator.
new-nicknames---a list of string designators. The default is the empty list.
package-object---the renamed package object.
Replaces the name and nicknames of package. The old name and all of the old nicknames of package are eliminated and are replaced by new-name and new-nicknames.
The consequences are undefined if new-name or any new-nickname conflicts with any existing package names.
(make-package 'temporary :nicknames '("TEMP")) => #<PACKAGE "TEMPORARY"> (rename-package 'temp 'ephemeral) => #<PACKAGE "EPHEMERAL"> (package-nicknames (find-package 'ephemeral)) => () (find-package 'temporary) => NIL (rename-package 'ephemeral 'temporary '(temp fleeting)) => #<PACKAGE "TEMPORARY"> (package-nicknames (find-package 'temp)) => ("TEMP" "FLEETING")
section make-package [Function]
shadow
symbol-names {&optional package} => t
symbol-names---a designator for a list of string designators.
package---a package designator.
The default is the current package.
shadow assures that symbols with names given by symbol-names are present in the package.
Specifically, package is searched for symbols with the names supplied by symbol-names.
For each such name, if a corresponding symbol is not present in package (directly, not by inheritance), then a corresponding symbol is created with that name, and inserted into package as an internal symbol. The corresponding symbol, whether pre-existing or newly created, is then added, if not already present, to the shadowing symbols list of package.
(package-shadowing-symbols (make-package 'temp)) => NIL (find-symbol 'car 'temp) => CAR, :INHERITED (shadow 'car 'temp) => T (find-symbol 'car 'temp) => TEMP::CAR, :INTERNAL (package-shadowing-symbols 'temp) => (TEMP::CAR)
(make-package 'test-1) => #<PACKAGE "TEST-1"> (intern "TEST" (find-package 'test-1)) => TEST-1::TEST, NIL (shadow 'test-1::test (find-package 'test-1)) => T (shadow 'TEST (find-package 'test-1)) => T (assert (not (null (member 'test-1::test (package-shadowing-symbols (find-package 'test-1)))))) (make-package 'test-2) => #<PACKAGE "TEST-2"> (intern "TEST" (find-package 'test-2)) => TEST-2::TEST, NIL (export 'test-2::test (find-package 'test-2)) => T (use-package 'test-2 (find-package 'test-1)) ;should not error
shadow changes the state of the package system in such a way that the package consistency rules do not hold across the change.
Current state of the package system.
section package-shadowing-symbols [Function] , section Package Concepts
If a symbol with a name in symbol-names already exists in package, but by inheritance, the inherited symbol becomes shadowed_3 by a newly created internal symbol.
shadowing-import
symbols {&optional package} => t
symbols---a designator for a list of symbols.
package --a package designator.
The default is the current package.
shadowing-import is like import, but it does not signal an error even if the importation of a symbol would shadow some symbol already accessible in package.
shadowing-import inserts each of symbols into package as an internal symbol, regardless of whether another symbol of the same name is shadowed by this action. If a different symbol of the same name is already present in package, that symbol is first uninterned from package. The new symbol is added to package's shadowing-symbols list.
shadowing-import does name-conflict checking to the extent that it checks whether a distinct existing symbol with the same name is accessible; if so, it is shadowed by the new symbol, which implies that it must be uninterned if it was present in package.
(in-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> (setq sym (intern "CONFLICT")) => CONFLICT (intern "CONFLICT" (make-package 'temp)) => TEMP::CONFLICT, NIL (package-shadowing-symbols 'temp) => NIL (shadowing-import sym 'temp) => T (package-shadowing-symbols 'temp) => (CONFLICT)
shadowing-import changes the state of the package system in such a way that the consistency rules do not hold across the change.
package's shadowing-symbols list is modified.
Current state of the package system.
section import [Function] , section unintern [Function] , section package-shadowing-symbols [Function]
delete-package
package => generalized-boolean
package---a package designator.
generalized-boolean---a generalized boolean.
delete-package deletes package from all package system data structures. If the operation is successful, delete-package returns true, otherwise nil. The effect of delete-package is that the name and nicknames of package cease to be recognized package names. The package object is still a package (i.e., packagep is true of it) but package-name returns nil. The consequences of deleting the COMMON-LISP package or the KEYWORD package are undefined. The consequences of invoking any other package operation on package once it has been deleted are unspecified. In particular, the consequences of invoking find-symbol, intern and other functions that look for a symbol name in a package are unspecified if they are called with *package* bound to the deleted package or with the deleted package as an argument.
If package is a package object that has already been deleted, delete-package immediately returns nil.
After this operation completes, the home package of any symbol whose home package had previously been package is implementation-dependent. Except for this, symbols accessible in package are not modified in any other way; symbols whose home package is not package remain unchanged.
(setq *foo-package* (make-package "FOO" :use nil)) (setq *foo-symbol* (intern "FOO" *foo-package*)) (export *foo-symbol* *foo-package*) (setq *bar-package* (make-package "BAR" :use '("FOO"))) (setq *bar-symbol* (intern "BAR" *bar-package*)) (export *foo-symbol* *bar-package*) (export *bar-symbol* *bar-package*) (setq *baz-package* (make-package "BAZ" :use '("BAR"))) (symbol-package *foo-symbol*) => #<PACKAGE "FOO"> (symbol-package *bar-symbol*) => #<PACKAGE "BAR"> (prin1-to-string *foo-symbol*) => "FOO:FOO" (prin1-to-string *bar-symbol*) => "BAR:BAR" (find-symbol "FOO" *bar-package*) => FOO:FOO, :EXTERNAL (find-symbol "FOO" *baz-package*) => FOO:FOO, :INHERITED (find-symbol "BAR" *baz-package*) => BAR:BAR, :INHERITED (packagep *foo-package*) => true (packagep *bar-package*) => true (packagep *baz-package*) => true (package-name *foo-package*) => "FOO" (package-name *bar-package*) => "BAR" (package-name *baz-package*) => "BAZ" (package-use-list *foo-package*) => () (package-use-list *bar-package*) => (#<PACKAGE "FOO">) (package-use-list *baz-package*) => (#<PACKAGE "BAR">) (package-used-by-list *foo-package*) => (#<PACKAGE "BAR">) (package-used-by-list *bar-package*) => (#<PACKAGE "BAZ">) (package-used-by-list *baz-package*) => () (delete-package *bar-package*) |> Error: Package BAZ uses package BAR. |> If continued, BAZ will be made to unuse-package BAR, |> and then BAR will be deleted. |> Type :CONTINUE to continue. |> Debug> |>>:CONTINUE<<| => T (symbol-package *foo-symbol*) => #<PACKAGE "FOO"> (symbol-package *bar-symbol*) is unspecified (prin1-to-string *foo-symbol*) => "FOO:FOO" (prin1-to-string *bar-symbol*) is unspecified (find-symbol "FOO" *bar-package*) is unspecified (find-symbol "FOO" *baz-package*) => NIL, NIL (find-symbol "BAR" *baz-package*) => NIL, NIL (packagep *foo-package*) => T (packagep *bar-package*) => T (packagep *baz-package*) => T (package-name *foo-package*) => "FOO" (package-name *bar-package*) => NIL (package-name *baz-package*) => "BAZ" (package-use-list *foo-package*) => () (package-use-list *bar-package*) is unspecified (package-use-list *baz-package*) => () (package-used-by-list *foo-package*) => () (package-used-by-list *bar-package*) is unspecified (package-used-by-list *baz-package*) => ()
If the package designator is a name that does not currently name a package, a correctable error of type package-error is signaled. If correction is attempted, no deletion action is attempted; instead, delete-package immediately returns nil.
If package is used by other packages, a correctable error of type package-error is signaled. If correction is attempted, unuse-package is effectively called to remove any dependencies, causing package's external symbols to cease being accessible to those packages that use package. delete-package then deletes package just as it would have had there been no packages that used it.
section unuse-package [Function]
make-package
package-name {&key nicknames use} => package
package-name---a string designator.
nicknames---a list of string designators. The default is the empty list.
use--- a list of package designators.
The default is implementation-defined.
package---a package.
Creates a new package with the name package-name.
Nicknames are additional names which may be used to refer to the new package.
use specifies zero or more packages the external symbols of which are to be inherited by the new package. See the function use-package.
(make-package 'temporary :nicknames '("TEMP" "temp")) => #<PACKAGE "TEMPORARY"> (make-package "OWNER" :use '("temp")) => #<PACKAGE "OWNER"> (package-used-by-list 'temp) => (#<PACKAGE "OWNER">) (package-use-list 'owner) => (#<PACKAGE "TEMPORARY">)
The existence of other packages in the system.
The consequences are unspecified if packages denoted by use do not exist.
A correctable error is signaled if the package-name or any of the nicknames is already the name or nickname of an existing package.
section defpackage [Macro] , section use-package [Function]
In situations where the packages to be used contain symbols which would conflict, it is necessary to first create the package with :use '(), then to use shadow or shadowing-import to address the conflicts, and then after that to use use-package once the conflicts have been addressed.
When packages are being created as part of the static definition of a program rather than dynamically by the program, it is generally considered more stylistically appropriate to use defpackage rather than make-package.
with-package-iterator
(name package-list-form {&rest {symbol-types})
{declaration}{*} {form}{*}}
=> {result}{*}
name---a symbol.
package-list-form---a form; evaluated once to produce a package-list.
package-list---a designator for a list of package designators.
symbol-type---one of the symbols :internal, :external, or :inherited.
declaration---a declare expression; not evaluated.
forms---an implicit progn.
results---the values of the forms.
Within the lexical scope of the body forms, the name is defined via macrolet such that successive invocations of (name) will return the symbols, one by one, from the packages in package-list.
It is unspecified whether symbols inherited from multiple packages are returned more than once. The order of symbols returned does not necessarily reflect the order of packages in package-list. When package-list has more than one element, it is unspecified whether duplicate symbols are returned once or more than once.
Symbol-types controls which symbols that are accessible in a package are returned as follows:
When more than one argument is supplied for symbol-types, a symbol is returned if its accessibility matches any one of the symbol-types supplied. Implementations may extend this syntax by recognizing additional symbol accessibility types.
An invocation of (name) returns four values as follows:
After all symbols have been returned by successive invocations of (name), then only one value is returned, namely nil.
The meaning of the second, third, and fourth values is that the returned symbol is accessible in the returned package in the way indicated by the second return value as follows:
It is unspecified what happens if any of the implicit interior state of an iteration is returned outside the dynamic extent of the with-package-iterator form such as by returning some closure over the invocation form.
Any number of invocations of with-package-iterator can be nested, and the body of the innermost one can invoke all of the locally established macros, provided all those macros have distinct names.
The following function should return t on any package, and signal an error if the usage of with-package-iterator does not agree with the corresponding usage of do-symbols.
(defun test-package-iterator (package) (unless (packagep package) (setq package (find-package package))) (let ((all-entries '()) (generated-entries '())) (do-symbols (x package) (multiple-value-bind (symbol accessibility) (find-symbol (symbol-name x) package) (push (list symbol accessibility) all-entries))) (with-package-iterator (generator-fn package :internal :external :inherited) (loop (multiple-value-bind (more? symbol accessibility pkg) (generator-fn) (unless more? (return)) (let ((l (multiple-value-list (find-symbol (symbol-name symbol) package)))) (unless (equal l (list symbol accessibility)) (error "Symbol ~S not found as ~S in package ~A [~S]" symbol accessibility (package-name package) l)) (push l generated-entries))))) (unless (and (subsetp all-entries generated-entries :test #'equal) (subsetp generated-entries all-entries :test #'equal)) (error "Generated entries and Do-Symbols entries don't correspond")) t))
The following function prints out every present symbol (possibly more than once):
(defun print-all-symbols () (with-package-iterator (next-symbol (list-all-packages) :internal :external) (loop (multiple-value-bind (more? symbol) (next-symbol) (if more? (print symbol) (return))))))
with-package-iterator signals an error of type program-error if no symbol-types are supplied or if a symbol-type is not recognized by the implementation is supplied.
The consequences are undefined if the local function named name established by with-package-iterator is called after it has returned false as its primary value.
section Traversal Rules and Side Effects
unexport
symbols {&optional package} => t
symbols---a designator for a list of symbols.
package---a package designator.
The default is the current package.
unexport reverts external symbols in package to internal status; it undoes the effect of export.
unexport works only on symbols present in package, switching them back to internal status. If unexport is given a symbol that is already accessible as an internal symbol in package, it does nothing.
(in-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> (export (intern "CONTRABAND" (make-package 'temp)) 'temp) => T (find-symbol "CONTRABAND") => NIL, NIL (use-package 'temp) => T (find-symbol "CONTRABAND") => CONTRABAND, :INHERITED (unexport 'contraband 'temp) => T (find-symbol "CONTRABAND") => NIL, NIL
Package system is modified.
Current state of the package system.
If unexport is given a symbol not accessible in package at all, an error of type package-error is signaled.
The consequences are undefined if package is the KEYWORD package or the COMMON-LISP package.
section export [Function] , section Package Concepts
unintern
symbol {&optional package} => generalized-boolean
symbol---a symbol.
package---a package designator.
The default is the current package.
generalized-boolean---a generalized boolean.
unintern removes symbol from package. If symbol is present in package, it is removed from package and also from package's shadowing symbols list if it is present there. If package is the home package for symbol, symbol is made to have no home package. Symbol may continue to be accessible in package by inheritance.
Use of unintern can result in a symbol that has no recorded home package, but that in fact is accessible in some package. Common Lisp does not check for this pathological case, and such symbols are always printed preceded by #:.
unintern returns true if it removes symbol, and nil otherwise.
(in-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> (setq temps-unpack (intern "UNPACK" (make-package 'temp))) => TEMP::UNPACK (unintern temps-unpack 'temp) => T (find-symbol "UNPACK" 'temp) => NIL, NIL temps-unpack => #:UNPACK
unintern changes the state of the package system in such a way that the consistency rules do not hold across the change.
Current state of the package system.
Giving a shadowing symbol to unintern can uncover a name conflict that had previously been resolved by the shadowing. If package A uses packages B and C, A contains a shadowing symbol x, and B and C each contain external symbols named x, then removing the shadowing symbol x from A will reveal a name conflict between b:x and c:x if those two symbols are distinct. In this case unintern will signal an error.
section Package Concepts
in-package
name => package
name---a string designator; not evaluated.
package---the package named by name.
Causes the the package named by name to become the current package---that is, the value of *package*. If no such package already exists, an error of type package-error is signaled.
Everything in-package does is also performed at compile time if the call appears as a top level form.
The variable *package* is assigned. If the in-package form is a top level form, this assignment also occurs at compile time.
An error of type package-error is signaled if the specified package does not exist.
section package [System Class]
unuse-package
packages-to-unuse {&optional package} => t
packages-to-unuse---a designator for a list of package designators.
package---a package designator. The default is the current package.
unuse-package causes package to cease inheriting all the external symbols of packages-to-unuse; unuse-package undoes the effects of use-package. The packages-to-unuse are removed from the use list of package.
Any symbols that have been imported into package continue to be present in package.
(in-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> (export (intern "SHOES" (make-package 'temp)) 'temp) => T (find-symbol "SHOES") => NIL, NIL (use-package 'temp) => T (find-symbol "SHOES") => SHOES, :INHERITED (find (find-package 'temp) (package-use-list 'common-lisp-user)) => #<PACKAGE "TEMP"> (unuse-package 'temp) => T (find-symbol "SHOES") => NIL, NIL
The use list of package is modified.
Current state of the package system.
section use-package [Function] , section package-use-list [Function]
use-package
packages-to-use {&optional package} => t
packages-to-use---a designator for a list of package designators. The KEYWORD package may not be supplied.
package---a package designator. The KEYWORD package cannot be supplied. The default is the current package.
use-package causes package to inherit all the external symbols of packages-to-use. The inherited symbols become accessible as internal symbols of package.
Packages-to-use are added to the use list of package if they are not there already. All external symbols in packages-to-use become accessible in package as internal symbols. use-package does not cause any new symbols to be present in package but only makes them accessible by inheritance.
use-package checks for name conflicts between the newly imported symbols and those already accessible in package. A name conflict in use-package between two external symbols inherited by package from packages-to-use may be resolved in favor of either symbol by importing one of them into package and making it a shadowing symbol.
(export (intern "LAND-FILL" (make-package 'trash)) 'trash) => T (find-symbol "LAND-FILL" (make-package 'temp)) => NIL, NIL (package-use-list 'temp) => (#<PACKAGE "TEMP">) (use-package 'trash 'temp) => T (package-use-list 'temp) => (#<PACKAGE "TEMP"> #<PACKAGE "TRASH">) (find-symbol "LAND-FILL" 'temp) => TRASH:LAND-FILL, :INHERITED
The use list of package may be modified.
section unuse-package [Function] , section package-use-list [Function] , section Package Concepts
It is permissible for a package P_1 to use a package P_2 even if P_2 already uses P_1. The using of packages is not transitive, so no problem results from the apparent circularity.
defpackage
defined-package-name [[!option]] => package
option ::={{(:nicknames {nickname}{*})}{*} | } (:documentation string) | {{(:use {package-name}{*})}{*} | } {{(:shadow {!symbol-name}{*})}{*} | } {{(:shadowing-import-from package-name {!symbol-name}{*})}{*} | } {{(:import-from package-name {!symbol-name}{*})}{*} | } {{(:export {!symbol-name}{*})}{*} | } {{(:intern {!symbol-name}{*})}{*} | } (:size integer)
symbol-name ::=(symbol | string)
defined-package-name---a string designator.
package-name---a package designator.
nickname---a string designator.
symbol-name---a string designator.
package---the package named package-name.
defpackage creates a package as specified and returns the package.
If defined-package-name already refers to an existing package, the name-to-package mapping for that name is not changed. If the new definition is at variance with the current state of that package, the consequences are undefined; an implementation might choose to modify the existing package to reflect the new definition. If defined-package-name is a symbol, its name is used.
The standard options are described below.
The order in which the options appear in a defpackage form is irrelevant. The order in which they are executed is as follows:
Shadows are established first, since they might be necessary to block spurious name conflicts when the :use option is processed. The :use option is executed next so that :intern and :export options can refer to normally inherited symbols. The :export option is executed last so that it can refer to symbols created by any of the other options; in particular, shadowing symbols and imported symbols can be made external.
If a {defpackage} form appears as a top level form, all of the actions normally performed by this macro at load time must also be performed at compile time.
(defpackage "MY-PACKAGE" (:nicknames "MYPKG" "MY-PKG") (:use "COMMON-LISP") (:shadow "CAR" "CDR") (:shadowing-import-from "VENDOR-COMMON-LISP" "CONS") (:import-from "VENDOR-COMMON-LISP" "GC") (:export "EQ" "CONS" "FROBOLA") ) (defpackage my-package (:nicknames mypkg :MY-PKG) ; remember Common Lisp conventions for case (:use common-lisp) ; conversion on symbols (:shadow CAR :cdr #:cons) (:export "CONS") ; this is the shadowed one. )
Existing packages.
If one of the supplied :nicknames already refers to an existing package, an error of type package-error is signaled.
An error of type program-error should be signaled if :size or :documentation appears more than once.
Since implementations might allow extended options an error of type program-error should be signaled if an option is present that is not actually supported in the host implementation.
The collection of symbol-name arguments given to the options :shadow, :intern, :import-from, and :shadowing-import-from must all be disjoint; additionally, the symbol-name arguments given to :export and :intern must be disjoint. Disjoint in this context is defined as no two of the symbol-names being string= with each other. If either condition is violated, an error of type program-error should be signaled.
For the :shadowing-import-from and :import-from options, a correctable error of type package-error is signaled if no symbol is accessible in the package named by package-name for one of the argument symbol-names.
Name conflict errors are handled by the underlying calls to make-package, use-package, import, and export. See section Package Concepts.
@xref{documentation; (setf documentation)} , section Package Concepts, section Compilation
The :intern option is useful if an :import-from or a :shadowing-import-from option in a subsequent call to defpackage (for some other package) expects to find these symbols accessible but not necessarily external.
It is recommended that the entire package definition is put in a single place, and that all the package definitions of a program are in a single file. This file can be loaded before loading or compiling anything else that depends on those packages. Such a file can be read in the COMMON-LISP-USER package, avoiding any initial state issues.
defpackage cannot be used to create two "mutually recursive" packages, such as:
(defpackage my-package (:use common-lisp your-package) ;requires your-package to exist first (:export "MY-FUN")) (defpackage your-package (:use common-lisp) (:import-from my-package "MY-FUN") ;requires my-package to exist first (:export "MY-FUN"))
However, nothing prevents the user from using the package-affecting functions such as use-package, import, and export to establish such links after a more standard use of defpackage.
The macroexpansion of defpackage could usefully canonicalize the names into strings, so that even if a source file has random symbols in the defpackage form, the compiled file would only contain strings.
Frequently additional implementation-dependent options take the form of a keyword standing by itself as an abbreviation for a list (keyword T); this syntax should be properly reported as an unrecognized option in implementations that do not support it.
do-symbols
(var [package [result-form]])
{declaration}{*
{tag | statement}{*}}
=> {result}{*}
do-external-symbols
(var [package [result-form]])
{declaration}{*
{tag | statement}{*}}
=> {result}{*}
do-all-symbols
(var [result-form])
{declaration}{*
{tag | statement}{*}}
=> {result}{*}
var---a variable name; not evaluated.
package---a package designator; evaluated.
The default in do-symbols and do-external-symbols is the current package.
result-form---a form; evaluated as described below. The default is nil.
declaration---a declare expression; not evaluated.
tag---a go tag; not evaluated.
statement---a compound form; evaluated as described below.
results---the values returned by the result-form if a normal return occurs, or else, if an explicit return occurs, the values that were transferred.
do-symbols, do-external-symbols, and do-all-symbols iterate over the symbols of packages. For each symbol in the set of packages chosen, the var is bound to the symbol, and the statements in the body are executed. When all the symbols have been processed, result-form is evaluated and returned as the value of the macro.
do-symbols iterates over the symbols accessible in package.
Statements may execute more than once for symbols that are inherited from multiple packages.
do-all-symbols iterates on every registered package. do-all-symbols will not process every symbol whatsoever, because a symbol not accessible in any registered package will not be processed. do-all-symbols may cause a symbol that is present in several packages to be processed more than once.
do-external-symbols iterates on the external symbols of package.
When result-form is evaluated, var is bound and has the value nil.
An implicit block named nil surrounds the entire do-symbols, do-external-symbols, or do-all-symbols form.
return or return-from may be used to terminate the iteration prematurely.
If execution of the body affects which symbols are contained in the set of packages over which iteration is occurring, other than to remove the symbol currently the value of var by using unintern, the consequences are undefined.
For each of these macros, the scope of the name binding does not include any initial value form, but the optional result forms are included.
Any tag in the body is treated as with tagbody.
(make-package 'temp :use nil) => #<PACKAGE "TEMP"> (intern "SHY" 'temp) => TEMP::SHY, NIL ;SHY will be an internal symbol ;in the package TEMP (export (intern "BOLD" 'temp) 'temp) => T ;BOLD will be external (let ((lst ())) (do-symbols (s (find-package 'temp)) (push s lst)) lst) => (TEMP::SHY TEMP:BOLD) OR=> (TEMP:BOLD TEMP::SHY) (let ((lst ())) (do-external-symbols (s (find-package 'temp) lst) (push s lst)) lst) => (TEMP:BOLD) (let ((lst ())) (do-all-symbols (s lst) (when (eq (find-package 'temp) (symbol-package s)) (push s lst))) lst) => (TEMP::SHY TEMP:BOLD) OR=> (TEMP:BOLD TEMP::SHY)
section intern [Function] , section export [Function] ,
section Traversal Rules and Side Effects
intern
string {&optional package} => symbol, status
string---a string.
package---a package designator.
The default is the current package.
symbol---a symbol.
status---one of :inherited, :external, :internal, or nil.
intern enters a symbol named string into package. If a symbol whose name is the same as string is already accessible in package, it is returned. If no such symbol is accessible in package, a new symbol with the given name is created and entered into package as an internal symbol, or as an external symbol if the package is the KEYWORD package; package becomes the home package of the created symbol.
The first value returned by intern, symbol, is the symbol that was found or created. The meaning of the secondary value, status, is as follows:
(in-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> (intern "Never-Before") => |Never-Before|, NIL (intern "Never-Before") => |Never-Before|, :INTERNAL (intern "NEVER-BEFORE" "KEYWORD") => :NEVER-BEFORE, NIL (intern "NEVER-BEFORE" "KEYWORD") => :NEVER-BEFORE, :EXTERNAL
section find-symbol [Function] , @xref{read; read-preserving-whitespace} , symbol, section unintern [Function] , section Symbols as Tokens
intern does not need to do any name conflict checking because it never creates a new symbol if there is already an accessible symbol with the name given.
package-name
package => name
package---a package designator.
name---a string
or nil.
package-name returns the string that names package,
or nil if the package designator is a package object that has no name (see the function delete-package).
(in-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> (package-name *package*) => "COMMON-LISP-USER" (package-name (symbol-package :test)) => "KEYWORD" (package-name (find-package 'common-lisp)) => "COMMON-LISP"
(defvar *foo-package* (make-package "FOO")) (rename-package "FOO" "FOO0") (package-name *foo-package*) => "FOO0"
Should signal an error of type type-error if package is not a package designator.
package-nicknames
package => nicknames
package---a package designator.
nicknames---a list of strings.
Returns the list of nickname strings for package, not including the name of package.
(package-nicknames (make-package 'temporary :nicknames '("TEMP" "temp"))) => ("temp" "TEMP")
Should signal an error of type type-error if package is not a package designator.
package-shadowing-symbols
package => symbols
package---a package designator.
symbols---a list of symbols.
Returns a list of symbols that have been declared as shadowing symbols in package by shadow or shadowing-import (or the equivalent defpackage options). All symbols on this list are present in package.
(package-shadowing-symbols (make-package 'temp)) => () (shadow 'cdr 'temp) => T (package-shadowing-symbols 'temp) => (TEMP::CDR) (intern "PILL" 'temp) => TEMP::PILL, NIL (shadowing-import 'pill 'temp) => T (package-shadowing-symbols 'temp) => (PILL TEMP::CDR)
Should signal an error of type type-error if package is not a package designator.
section shadow [Function] , section shadowing-import [Function]
Whether the list of symbols is fresh is implementation-dependent.
package-use-list
package => use-list
package---a package designator.
use-list---a list of package objects.
Returns a list of other packages used by package.
(package-use-list (make-package 'temp)) => (#<PACKAGE "COMMON-LISP">) (use-package 'common-lisp-user 'temp) => T (package-use-list 'temp) => (#<PACKAGE "COMMON-LISP"> #<PACKAGE "COMMON-LISP-USER">)
Should signal an error of type type-error if package is not a package designator.
section use-package [Function] , section unuse-package [Function]
package-used-by-list
package => used-by-list
package---a package designator.
used-by-list---a list of package objects.
package-used-by-list returns a list of other packages that use package.
(package-used-by-list (make-package 'temp)) => () (make-package 'trash :use '(temp)) => #<PACKAGE "TRASH"> (package-used-by-list 'temp) => (#<PACKAGE "TRASH">)
Should signal an error of type type-error if package is not a package.
section use-package [Function] , section unuse-package [Function]
packagep
object => generalized-boolean
object---an object.
generalized-boolean---a generalized boolean.
Returns true if object is of type package; otherwise, returns false.
(packagep *package*) => true (packagep 'common-lisp) => false (packagep (find-package 'common-lisp)) => true
(packagep object) == (typep object 'package)
a package object.
the COMMON-LISP-USER package.
Whatever package object is currently the value of *package* is referred to as the current package.
(in-package "COMMON-LISP-USER") => #<PACKAGE "COMMON-LISP-USER"> *package* => #<PACKAGE "COMMON-LISP-USER"> (make-package "SAMPLE-PACKAGE" :use '("COMMON-LISP")) => #<PACKAGE "SAMPLE-PACKAGE"> (list (symbol-package (let ((*package* (find-package 'sample-package))) (setq *some-symbol* (read-from-string "just-testing")))) *package*) => (#<PACKAGE "SAMPLE-PACKAGE"> #<PACKAGE "COMMON-LISP-USER">) (list (symbol-package (read-from-string "just-testing")) *package*) => (#<PACKAGE "COMMON-LISP-USER"> #<PACKAGE "COMMON-LISP-USER">) (eq 'foo (intern "FOO")) => true (eq 'foo (let ((*package* (find-package 'sample-package))) (intern "FOO"))) => false
load, compile-file, in-package
section compile-file [Function] , section in-package [Macro] , section load [Function] , section package [System Class]
package-error, error, serious-condition, condition, t
The type package-error consists of error conditions related to operations on packages. The offending package (or package name) is initialized by the :package initialization argument to make-condition, and is accessed by the function package-error-package.
section package-error-package [Function] , section Conditions
package-error-package
condition => package
condition---a condition of type package-error.
package---a package designator.
Returns a designator for the offending package in the situation represented by the condition.
(package-error-package (make-condition 'package-error :package (find-package "COMMON-LISP"))) => #<Package "COMMON-LISP">
package-error
Go to the first, previous, next, last section, table of contents.