behave like MULTIPLE-VALUE-PROG1
, but neither is used often enough that it matters much. The OR
and COND
macros are also not always transparent to multiple values, returning only the primary value of certain subforms.
217
The reason loading a file with an IN-PACKAGE
form in it has no effect on the value of *PACKAGE*
after LOAD
returns is because LOAD
binds *PACKAGE*
to its current value before doing anything else. In other words, something equivalent to the following LET
is wrapped around the rest of the code in LOAD
:
(let ((*package* *package*)) ...)
Any assignment to *PACKAGE*
will be to the new binding, and the old binding will be restored when LOAD
returns. It also binds the variable *READTABLE*
, which I haven't discussed, in the same way.
218
In some implementations, you may be able to get away with evaluating DEFUN
s that use undefined macros in the function body as long as the macros are defined before the function is actually called. But that works, if at all, only when LOAD
ing the definitions from source, not when compiling with COMPILE-FILE
, so in general macro definitions must be evaluated before they're used.
219
By contrast, the subforms in a top-level LET
aren't compiled as top-level forms because they're not run directly when the FASL is loaded. They will run, but it's in the runtime context of the bindings established by the LET
. Theoretically, a LET
that binds no variables could be treated like a PROGN
, but it's not—the forms appearing in a LET
are never treated as top-level forms.
220
The one declaration that has an effect on the semantics of a program is the SPECIAL
declaration mentioned in Chapter 6.
221
The kind of programming that relies on a symbol data type is called, appropriately enough,
222
Every package has one official name and zero or more DEFPACKAGE
or IN-PACKAGE
form.
223
COMMON-LISP-USER
is also allowed to provide access to symbols exported by other implementation-defined packages. While this is intended as a convenience for the user—it makes implementation- specific functionality readily accessible—it can also cause confusion for new Lispers: Lisp will complain about an attempt to redefine some name that isn't listed in the language standard. To see what packages COMMON-LISP-USER
inherits symbols from in a particular implementation, evaluate this expression at the REPL:
(mapcar #'package-name (package-use-list :cl-user))
And to find out what package a symbol came from originally, evaluate this:
(package-name (symbol-package 'some-symbol))
with some-symbol
replaced by the symbol in question. For instance:
(package-name (symbol-package 'car)) ==> 'COMMON-LISP'
(package-name (symbol-package 'foo)) ==> 'COMMON-LISP-USER'
Symbols inherited from implementation-defined packages will return some other value.
224
This is different from the Java package system, which provides a namespace for classes but is also involved in Java's access control mechanism. The non-Lisp language with a package system most like Common Lisp's packages is Perl.
225
All the manipulations performed by DEFPACKAGE
can also be performed with functions that man- ipulate package objects. However, since a package generally needs to be fully defined before it can be used, those functions are rarely used. Also, DEFPACKAGE
takes care of performing all the package manipulations in the right order—for instance,