caused a name conflict. Thus any application that is written in a package which uses the LISP
package is in peril of name clashes with implementation-specific symbols.
Many implementors are aware of this problem and have or will provide some mechanism
to get a "pure" COMMON LISP package (i.e., a package whose only external symbols are the
estimated 779 symbols mentioned in CLtL).7
However, there is as yet no de facto standard on
how a portable program can access that package; thus, each port could require some modification
of source code.8
One way to minimize code modification is to have all application packages
use the pure package, called COMMON-LISP, and then in a single place add that name as a nickname
for the implementation's pure COMMON LISP package. If the implementation does not
support a pure package, it is possible to portably create it, by creating a new package named
COMMON-LISP whose use-list is nil, and explicitly importing and then exporting each symbol
defined in CLtL. These potential difficulties with packages are largely due to the implementors
differing on "default" values to in-package, from which the following advice follows:
- Portability Tip 1:
- At the beginning of every {ile of a portable COMMON LISP program, put
an in-package with an explicit zuse argument that includes the "pure" package. When
referring to COMMON LISP symbols as constants in code, mark them with the explicit
lisp: prefix to avoid any possible confusion due to importing and shadowing.
4 The "Top-level Form" Distinction
When a code analysis program processes LISP forms in a file, it must execute some of the
forms. This may seem intuitively surprising, but it is due to the fact that LISP code can
contain directives to the reader and the compiler that affect the semantics of the code. For
example, XREF (like compile-file and load) processes forms one at a time, and uses read to
parse characters in a text file into LISP data structures. The COMMON LISP parser (read)
is parameterized by the current readtable and the state of the packages; the behavior of the
parser, and thus the interpretation of parsed code, can be modified by operations on readtables
and packages, such as set-macro-character and in-package. Calls to these functions must
be evaluated by the code analyzer at parse time. Similarly, forms contained in an (eval-when
(compile load eval) forms) should be executed by the code analysis program when it is
encountered, to produce side effects for processing later forms. C'LtL suggests that the package
functions be treated as though they were enclosed in an eval-when form; in actual practice,
other functions (e.g., require) may also be treated as "implicit eval-when" forms by the
compiler.
It has been suggested that the compile context in the (eval-when (compile . . .) body)
idiom is being used to refer to what might be called a read context [7]. For example, it is
typical in code that defines constants to be used later in a "#." reader macro to surround
the deiconstants with the eval-when idiom. This is purely a matter of "file processing",
*****************
7
This is or will soon be true of Digital Equipment, Lucid, Symbolics, and Texas Instruments implementations.
8
Actually there is some consensus (on the ARPAnet mailing list) that the package should have a standard
name, but whether it should be called LISP or COMMON-LISP is not completely worked out. Importantly, it
is agreed that vendor extension packages will include the vendor's name, to avoid clashes of names such as
EXTENSIONS or CDMMON-LISP-PLUS.[7] [8]
|