Keyword Symbols
:foo is a keyword symbol.
- interned in and exported from the
KEYWORD package
- constantly bound to itself
Usage
Keyword symbols are used when one needs the combination of the following properties:
- a symbol is the right data structure
- symbols with the same name should be unique (by interning them in a package) -> package
KEYWORD
- different packages are not needed or wanted -> package
KEYWORD
- writing the symbol should be easy by not needing to quote them ->
:foo better than ':foo
- the ability to act as a variable with different values is not needed ->
:foo evaluates to :foo itself and only to :foo
In Common Lisp generally symbols can be in a package (kind of a namespace).
An unexported symbol bar in a package foo is written as foo::bar. The double colon is between the package name and the symbol name.
An exported symbol then is written as foo:bar. A single colon is used.
If the symbol is available in the current package then is written as bar without the package.
The package KEYWORD
There is a special package called KEYWORD. A symbol bar in that package is simply and always written as :bar.
Examples
These keyword symbols have also these interesting properties: the symbols are automatically exported from the package KEYWORD (so keyword::bar, keyword:bar, ::bar and :bar are all the same symbol) and they evaluate to themselves:
CL-USER 5 > :bar
:BAR
CL-USER 6 > (describe :bar)
:BAR is a SYMBOL
NAME "BAR"
VALUE :BAR
FUNCTION #<unbound function>
PLIST NIL
PACKAGE #<The KEYWORD package, 0/4 internal, 5830/8192 external>
CL-USER 7 > (eq 'keyword::bar ':bar)
T
CL-USER 8 > (eq :bar ':bar) ; quoted or unquoted, each subform evaluates to :bar
T
Usage
Keyword symbols are used for example as names in named arguments:
(defun foo (&key bar) (+ bar 10))
(foo :bar 7)
Typically they are also used in arguments to instance and structure construction.
(defstruct node state parent action)
DEFSTRUCT is a Common Lisp macro and it generates several functions. One of them is a function MAKE-NODE, which can be used as:
(make-node :state 'open
:parent some-parent
:action an-action)
Note: sometimes the data might also be a keyword. For example in above form, the state might be :open and not open:
(make-node :state :open
:parent some-parent
:action an-action)