11.6 Built-in Packages

X3J13 voted in January 1989 to modify the requirements on the built-in packages so as to limit what may appear in the common-lisp package and to lift the requirement that every implementation have a package named system. The details are as follows.

Not only must the common-lisp package in any given implementation contain all the external symbols prescribed by the standard; the common-lisp package moreover may not contain any external symbol that is not prescribed by the standard. However, the common-lisp package may contain additional internal symbols, depending on the implementation.

An external symbol of the common-lisp package may not have a function, macro, or special operator definition, or a top-level value, or a special proclamation, or a type definition, unless specifically permitted by the standard. Programmers may validly rely on this fact; for example, fboundp is guaranteed to be false for all external symbols of the common-lisp package except those explicitly specified in the standard to name functions, macros, and special operators. Similarly, boundp will be false of all such external symbols except those documented to be variables or constants.

Portable programs may use external symbols in the common-lisp package that are not documented to be constants or variables as names of local lexical variables with the presumption that the implementation has not proclaimed such variables to be special; this legitimizes the common practice of using such names as list and string as names for local variables.

A valid implementation may initially have properties on any symbol, or dynamically put new properties on symbols (even user-created symbols), as long as no property indicator used for this purpose is an external symbol of any package defined by the standard or a symbol that is accessible from the common-lisp-user package or any package defined by the user.

This vote eliminates the requirement that every implementation have a predefined package named system. An implementation may provide any number of predefined packages; these should be described in the documentation for that implementation.

The common-lisp-user package may contain symbols not described by the standard and may use other implementation-specific packages.

X3J13 voted in March 1989 to restrict user programs from performing certain actions that might interfere with built-in facilities or interact badly with them. Except where explicitly allowed, the consequences are undefined if any of the following actions are performed on a symbol in the common-lisp package.

X3J13 also voted in June 1989 to add to this list the item

If such a symbol is not globally defined as a variable or a constant, a user program is allowed to lexically bind it and declare the type of that binding.

If such a symbol is not defined as a function, macro, or special operator, a user program is allowed to (lexically) bind it as a function and to declare the ftype of that binding and to trace that binding.

If such a symbol is not defined as a function, macro, or special operator, a user program is allowed to (lexically) bind it as a macro.

As an example, the behavior of the code fragment

(flet ((open (filename &key direction)
         (format t "~%OPEN was called.")
         (open filename :direction direction)))
  (with-open-file (x "frob" :direction ’:output)
    (format t "~%Was OPEN called?")))

is undefined. Even in a “reasonable” implementation, for example, the macro expansion of with-open-file might refer to the open function and might not. However, the preceding rules eliminate the burden of deciding whether an implementation is reasonable. The code fragment violates the rules; officially its behavior is therefore completely undefined, and that’s that.

Note that “altering the property list” is not in the list of proscribed actions, so a user program is permitted to add properties to or remove properties from symbols in the common-lisp package.