Common Lisp the Language, 2nd Edition


next up previous contents index
Next: Exporting and Importing Up: Packages Previous: Package Names

11.3. Translating Strings to Symbols

The value of the special variable *package* must always be a package object (not a name). Whatever package object is currently the value of *package* is referred to as the 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. If the name is found, the corresponding symbol is returned. If the name is not found (that is, there is no symbol of that name accessible in the current package), a new symbol is created for it and is placed in the current package as an internal symbol. Moreover, the current package becomes the owner (home package) of the symbol, and so the symbol becomes interned in the current package. If the name is later read again while this same package is current, the same symbol will then be found and returned.

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 qualified name, consisting of a package name, then a colon, then the 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, editor:buffer refers to the external symbol named buffer accessible in the package named editor, regardless of whether there is a symbol named buffer in the current package. If there is no package named editor, or if no symbol named buffer is accessible in editor, or if buffer is an internal symbol in editor, the Lisp reader will signal a correctable error to ask the user for instructions.

On rare occasions, a user may need to refer to an 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 a doubled colon :: is used as the separator in place of the usual single colon. If editor::buffer is seen, the effect is exactly the same as reading buffer with *package* temporarily rebound to the package whose name is editor. This special-purpose qualifier should be used with caution.

The package named 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 because these symbols are used only as labels 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 :foo) is added to (or looked up in) the keyword package as an external symbol. The keyword package is also treated specially in that whenever a symbol is added to the keyword package the symbol is always made external; the symbol is also automatically declared to be a constant (see defconstant) and 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; the user should never import or inherit keywords into any other package. It is an error to try to apply use-package to the keyword package.

Each symbol contains a package cell that is used to record the home package of the symbol, or nil if the symbol is uninterned. This cell may be accessed by using the function symbol-package. When an interned symbol is printed, if it is a symbol in the keyword package, then it is printed with a preceding colon; otherwise, if it is accessible (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 : as the separator if the symbol is external and :: if not.

A symbol whose package slot contains nil (that is, has no home package) is printed preceded by #:. It is possible, by the use of import and unintern, to create a symbol that has no recorded home package but that in fact is accessible in some package. The system does not check for this pathological case, and such symbols will always be printed preceded by #:.

In summary, the following four uses of symbol qualifier syntax are defined.

foo:bar
When read, looks up BAR among the external symbols of the package named FOO. Printed when symbol bar is external in its home package foo and is not accessible in the current package.

foo::bar
When read, interns BAR as if FOO were the current package. Printed when symbol bar is internal in its home package foo and is not accessible in the current package.

:bar
When read, interns BAR as an external symbol in the keyword package and makes it evaluate to itself. Printed when the home package of symbol bar is keyword.

#:bar
When read, creates a new uninterned symbol named BAR. Printed when the symbol bar is uninterned (has no home package), even in the pathological case that bar is uninterned but nevertheless somehow accessible in the current package.

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.



next up previous contents index
Next: Exporting and Importing Up: Packages Previous: Package Names


AI.Repository@cs.cmu.edu