Finally, a present symbol can be #:foo
syntax.
In the next section I'll show you how to define your own packages, including how to make one package use another and how to export, shadow, and import symbols. But first let's look at a few packages you've been using already. When you first start Lisp, the value of *PACKAGE*
is typically the COMMON-LISP-USER
package, also known as CL-USER
.[222] CL-USER
uses the package COMMON-LISP
, which exports all the names defined by the language standard. Thus, when you type an expression at the REPL, all the names of standard functions, macros, variables, and so on, will be translated to the symbols exported from COMMON-LISP
, and all other names will be interned in the COMMON-LISP-USER
package. For example, the name *PACKAGE*
is exported from COMMON-LISP
—if you want to see the value of *PACKAGE*
, you can type this:
CL-USER> *package*
#<The COMMON-LISP-USER package>
because COMMON-LISP-USER
uses COMMON-LISP
. Or you can use a package-qualified name.
CL-USER> common-lisp:*package*
#<The COMMON-LISP-USER package>
You can even use COMMON-LISP
's nickname, CL
.
CL-USER> cl:*package*
#<The COMMON-LISP-USER package>
But *X*
isn't a symbol in COMMON-LISP
, so you if type this:
CL-USER> (defvar *x* 10)
*X*
the reader reads DEFVAR
as the symbol from the COMMON- LISP
package and *X*
as a symbol in COMMON-LISP-USER
.
The REPL can't start in the COMMON-LISP
package because you're not allowed to intern new symbols in it; COMMON-LISP-USER
serves as a 'scratch' package where you can create your own names while still having easy access to all the symbols in COMMON-LISP
.[223] Typically, all packages you'll define will also use COMMON-LISP
, so you don't have to write things like this:
(cl:defun (x) (cl:+ x 2))
The third standard package is the KEYWORD
package, the package the Lisp reader uses to intern names starting with colon. Thus, you can also refer to any keyword symbol with an explicit package qualification of keyword
like this:
CL-USER> :a
:A
CL-USER> keyword:a
:A
CL-USER> (eql :a keyword:a)
T
Working in COMMON-LISP-USER
is fine for experiments at the REPL, but once you start writing actual programs you'll want to define new packages so different programs loaded into the same Lisp environment don't stomp on each other's names. And when you write libraries that you intend to use in different contexts, you'll want to define separate packages and then export the symbols that make up the libraries' public APIs.
However, before you start defining packages, it's important to understand one thing about what packages do
With that in mind, you can start looking at how to define packages and tie them together. You define new packages with the macro DEFPACKAGE
, which allows you to not only create the package but to specify what packages it uses, what symbols it exports, and what symbols it imports from other packages and to resolve conflicts by creating shadowing symbols.[225]
I'll describe the various options in terms of how you might use packages while writing a program that organizes e-mail messages into a searchable database. The program is purely hypothetical, as are the libraries I'll refer to—the point is to look at how the packages used in such a program might be structured.
The first package you'd need is one to provide a namespace for the application—you want to be able to name your functions, variables, and so on, without having to worry about name collisions with unrelated code. So you'd define a new package with DEFPACKAGE
.
If the application is simple enough to be written with no libraries beyond the facilities provided by the language itself, you could define a simple package like this:
(defpackage :com.gigamonkeys.email-db
(:use :common-lisp))
This defines a package, named COM.GIGAMONKEYS.EMAIL-DB
, that inherits all the symbols exported by the COMMON-LISP
package.[226]
You actually have several choices of how to represent the names of packages and, as you'll see, the names of symbols in a DEFPACKAGE
. Packages and symbols are named with strings. However, in a DEFPACKAGE
form, you can specify the names of packages and symbols with DEFPACKAGE
, is a common style that allows you to write the names in lowercase—the reader will convert the names to uppercase for you. You could also write the DEFPACKAGE
with strings, but then you have to write them in all uppercase, because the true names of most symbols and packages are in fact uppercase because of the case conversion performed by the reader.[227]
(defpackage 'COM.GIGAMONKEYS.EMAIL-DB'
(:use 'COMMON-LISP'))
You could also use nonkeyword symbols—the names in DEFPACKAGE
aren't evaluated—but then the very act of reading the DEFPACKAGE
form would cause those symbols to be interned in the current package, which at the very least will pollute that