7.3 Packages
1. Define, or create, a package all in one place. Avoid having incremental pieces of the package definition distributed throughout several files.
2. A package definition should consist of some subset of calls to the following functions, in the order indicated, with no intervening computations that could affect the outcome:
in-package
(or an equivalent use ofmake-package
)require
shadow
(and possiblyshadowing-import
)use-package
import
(and possibly shadowing-import
)export
As a mnemonic device, you might try "I remember six user interface expressions."
Note that this list is slightly different from the suggestion found on page 280 of CLtL2. Theuse-package
statement should precede theexport
andimport
statements, since it might affect the way in which arguments to these later statements are read in. Theexport
statement should come last so that it can refer to inherited, imported, or shadowing symbols specified by statements preceding it. In some circumstances it might be necessary forshadowing-import
to precedeuse-package
to prevent name conflicts from multiple inheritance.
Therequire
statement should precedeimport
anduse-package
so that it can refer to a file that creates the used packages. Theprovide
statement should be placed elsewhere; see item 7 below.
If you create packages with the Common Lisp macrodefpackage
, the order of package operations is handled correctly and automatically.
car
from theuser
package, you could typelisp:car
orlisp::car
, but you should use the unqualified form:car
.4. Avoid the use of double-colon qualification in files under almost all circumstances; certainly do not use it where any other qualification specifies the same symbol.
For example, assume that theace
package uses thedud
package, thatring
is an external symbol ofdud
, and thatsong
is present as an internal symbol ofdud
:
ace
package and need to refer toring
, you should not use any colon qualifiers becausering
is available by inheritance.ace
or todud
, you could access the symbolring
asace::ring
, since it is available in theace
package by inheritance; usedud:ring
instead.(import 'dud::song)
, you can use(import (intern "SONG" "DUD"))
.ace:spades
, ace::spades
, or merelyspades
. Thus, Lisp reading is inherently an information-losing operation. 6. Whenever possible, use strings as names rather than symbols. Thus, say(in-package "RABBIT")
rather than(in-package 'rabbit)
. The functionsexport
,import
, andshadowing-import
require an explicit symbol rather than a name, so you cannot use strings for them.
Note: Liquid Common Lisp permitsshadow
to take a string as an argument.
7. Define a file to be all in one package; avoid multiplein-package
statements. Put aprovide
statement at the very end of the last file defining a module, rather than at the beginning of a file as suggested by CLtL2. The facilities of a module are not truly "provided" until after the file or files defining it have been fully and successfully loaded.
These rules are described in detail in the following sections.
Generated with Harlequin WebMaker