Symbols
A symbol is an object with a name (a string), a home package (or none), a value, a function and a property list. The same symbol can name a variable, a function, a macro, a class and a type at once, because these live in different namespaces: list is a function ((list 1 2)), a type ((typep x 'list)) and may be a variable ((let ((list …)))). Common Lisp is a Lisp-2 in this sense; Scheme is a Lisp-1.
The reader looks up the name it has read in the current package and creates the symbol if it is not there. That is interning. Two tokens that read to the same name in the same package are the same object, so symbols compare with eq.
| Written | Meaning |
|---|---|
foo | the symbol FOO in the current package (*package*), found among the symbols the package owns or has inherited from packages it uses, or created there |
pkg:foo | the external symbol FOO of package PKG; an error if foo is not exported |
pkg::foo | the symbol FOO of PKG, exported or not (a style warning in good code, since it reaches into internals) |
:foo | the symbol FOO in the KEYWORD package; always exported, and it has itself as its value, so it needs no quote |
#:foo | a new symbol with name FOO that has no home package (uninterned); each occurrence is distinct unless linked by #1= and #1# |
|Foo|, Foo\ Bar | symbols whose names keep their case and any character; pkg:|Foo| works too |
nil, t | symbols in COMMON-LISP, constants that evaluate to themselves. nil is also the empty list and the false value; () reads as nil. |
Names of symbols follow naming conventions and no rules: words are separated by hyphens (make-hash-table); special variables are written *like-this* (earmuffs); constants as +like-this+ in good code (the standard’s own constants such as pi and most-positive-fixnum do not follow it); predicates end in p (listp, or -p after a hyphenated name: hash-table-p); setters are (setf name), which names a function but is not a symbol; and conversions use -> or -to-. The standard reserves the names of the COMMON-LISP package: a program may not define them, bind them as functions, or alter them, apart from using them as lexical variable names.
Packages
A package maps names to symbols. A package owns the symbols interned in it, can use other packages (inherits their external symbols), can export some of its symbols for others to use, and can have nicknames. A symbol is present in a package when the package owns it or has imported it; it is accessible when it is present or inherited.
Three packages exist in every standard image: COMMON-LISP (nickname CL), holding the 978 standard symbols, COMMON-LISP-USER (CL-USER), where the program is evaluated at start and which uses COMMON-LISP plus whatever the implementation adds, and KEYWORD. Implementations add their own: SBCL has SB-EXT, SB-ALIEN, SB-THREAD, SB-SYS, SB-IMPL and others; CCL has CCL; CLISP has EXT and SYS; ECL has EXT, SI and FFI; ABCL has JAVA and EXTENSIONS; Allegro has EXCL and SYS; LispWorks has HCL and LW.
defpackage
(defpackage name option*) defines or redefines a package. The name is a string designator: :foo, #:foo and "FOO" all mean the package FOO; writing it as #:foo avoids interning a symbol in the package that is current when the form is read. The options, which may each appear any number of times except where noted, are:
| Option | Meaning |
|---|---|
(:nicknames name*) | other names for the package |
(:documentation string) | a documentation string (at most once) |
(:use package*) | inherit the external symbols of these packages (default: implementation-defined, usually COMMON-LISP; write (:use #:cl) to be certain) |
(:shadow symbol-name*) | create symbols in this package with these names, hiding inherited ones |
(:shadowing-import-from package symbol-name*) | import these symbols and let them replace conflicting inherited ones |
(:import-from package symbol-name*) | import these symbols of another package (a conflict is an error) |
(:export symbol-name*) | export these (creating them if needed) |
(:intern symbol-name*) | intern these without exporting |
(:size n) | an estimate of the number of symbols; ignored by most implementations |
The standard also allows implementation-defined options. SBCL has (:local-nicknames (local global)*) (also in CCL, ECL, ABCL and others), (:lock t) and (:implement …); uiop:define-package and defpackage-plus add :mix, :reexport, :recycle and :use-reexport.
(defpackage #:my-app
(:use #:cl)
(:nicknames #:app)
(:shadow #:search)
(:import-from #:alexandria #:when-let #:curry)
(:export #:main
#:*config*)
(:documentation "A small application."))
(in-package #:my-app)
(defun search (needle haystack)
(cl:search needle haystack))
cl:search with its own function, and still reaches the standard one with a package prefix.in-package and the functions
(in-package name) is (setq *package* (find-package name)) at read, compile and load time. The reader needs it to have run before it reads the symbols that follow, which is why it is a macro with an eval-when around it. The functions that work on packages are: find-package, make-package, delete-package, rename-package, list-all-packages, package-name, package-nicknames, package-use-list, package-used-by-list, package-shadowing-symbols, use-package, unuse-package, export, unexport, import, shadow, shadowing-import, intern, unintern, find-symbol, find-all-symbols, symbol-package, symbol-name, make-symbol, gensym, gentemp, copy-symbol, keywordp, packagep, package-error-package and the macros do-symbols, do-external-symbols, do-all-symbols and with-package-iterator. The variable is *package*, and *gensym-counter* numbers generated symbols.
Name conflicts (two different symbols with one name accessible in a package) signal a package-error with restarts to choose which to keep. An implementation may lock the packages it defines: SBCL’s package locks make defining a function or binding a name in COMMON-LISP or SB-EXT an error or warning, and ANSI itself calls it undefined behaviour.
The names the viewer knows
The viewer separates a package prefix (coloured as a type) from the name behind it, and gives the name its normal colour when the prefix is cl: or common-lisp:; for any other prefix the name is a function (or a macro, when it is written like a definer such as def… or with-…) at the head of a list, a variable when it has earmuffs and a constant when it is written +like-this+. A #:name or :name is a literal. All 978 symbols of the COMMON-LISP package were checked against the symbol index of the HyperSpec.