namespace and may also cause problems later if you try to use the package. [228]
To read code in this package, you need to make it the current package with the IN- PACKAGE
macro:
(in-package :com.gigamonkeys.email-db)
If you type this expression at the REPL, it will change the value of *PACKAGE*
, affecting how the REPL reads subsequent expressions, until you change it with another call to IN-PACKAGE
. Similarly, if you include an IN-PACKAGE
in a file that's loaded with LOAD
or compiled with COMPILE-FILE
, it will change the package, affecting the way subsequent expressions in the file are read.[229]
With the current package set to the COM.GIGAMONKEYS.EMAIL-DB
package, other than names inherited from the COMMON-LISP
package, you can use any name you want for whatever purpose you want. Thus, you could define a new hello-world
function that could coexist with the hello-world
function previously defined in COMMON-LISP-USER
. Here's the behavior of the existing function:
CL-USER> (hello-world)
hello, world
NIL
Now you can switch to the new package using IN-PACKAGE
.[230] Notice how the prompt changes—the exact form is determined by the development environment, but in SLIME the default prompt consists of an abbreviated version of the package name.
CL-USER> (in-package :com.gigamonkeys.email-db)
#<The COM.GIGAMONKEYS.EMAIL-DB package>
EMAIL-DB>
You can define a new hello-world
in this package:
EMAIL-DB> (defun hello-world () (format t 'hello from EMAIL-DB package~%'))
HELLO-WORLD
And test it, like this:
EMAIL-DB> (hello-world)
hello from EMAIL-DB package
NIL
Now switch back to CL-USER
.
EMAIL-DB> (in-package :cl-user)
#<The COMMON-LISP-USER package>
CL-USER>
And the old function is undisturbed.
CL-USER> (hello-world)
hello, world
NIL
While working on the e-mail database, you might write several functions related to storing and retrieving text that don't have anything in particular to do with e-mail. You might realize that those functions could be useful in other programs and decide to repackage them as a library. You should define a new package, but this time you'll export certain names to make them available to other packages.
(defpackage :com.gigamonkeys.text-db
(:use :common-lisp)
(:export :open-db
:save
:store))
Again, you use the COMMON-LISP
package, because you'll need access to standard functions within COM.GIGAMONKEYS.TEXT-DB
. The :export
clause specifies names that will be external in COM.GIGAMONKEYS.TEXT-DB
and thus accessible in packages that :use
it. Therefore, after you've defined this package, you can change the definition of the main application package to the following:
(defpackage :com.gigamonkeys.email-db
(:use :common-lisp :com.gigamonkeys.text-db))
Now code written in COM.GIGAMONKEYS.EMAIL-DB
can use unqualified names to refer to the exported symbols from both COMMON-LISP
and COM.GIGAMONKEYS.TEXT-DB
. All other names will continue to be interned directly in the COM.GIGAMONKEYS.EMAIL-DB
package.
Now suppose you find a third-party library of functions for manipulating e-mail messages. The names used in the library's API are exported from the package COM.ACME.EMAIL
, so you could :use
that package to get easy access to those names. But suppose you need to use only one function from this library, and other exported symbols conflict with names you already use (or plan to use) in our own code.[231] In this case, you can import the one symbol you need with an :import-from
clause in the DEFPACKAGE
. For instance, if the name of the function you want to use is parse-email-address
, you can change the DEFPACKAGE
to this:
(defpackage :com.gigamonkeys.email-db
(:use :common-lisp :com.gigamonkeys.text-db)
(:import-from :com.acme.email :parse-email-address))
Now anywhere the name parse-email-address
appears in code read in the COM.GIGAMONKEYS.EMAIL-DB
package, it will be read as the symbol from COM.ACME.EMAIL
. If you need to import more than one symbol from a single package, you can include multiple names after the package name in a single :import-from
clause. A DEFPACKAGE
can also include multiple :import-from
clauses in order to import symbols from different packages.
Occasionally you'll run into the opposite situation—a package may export a bunch of names you want to use and a few you don't. Rather than listing all the symbols you :import-from
clause, you can instead :use
the package and then list the names you :shadow
clause. For instance, suppose the COM.ACME.TEXT
package exports a bunch of names of functions and classes used in text processing. Further suppose that most of these functions and classes are ones you'll want to use in your code, but one of the names, build-index
, conflicts with a name you've already used. You can make the build-index
from COM.ACME.TEXT
inaccessible by shadowing it.
(defpackage :com.gigamonkeys.email-db
(:use