Common Lisp the Language, 2nd Edition
![]()
Next: The Print Name
Up: Symbols
Previous: Symbols
Since its inception, Lisp has associated with each symbol a kind of tabular data structure called a property list (plist for short). A property list contains zero or more entries; each entry associates with a key (called the indicator), which is typically a symbol, an arbitrary Lisp object (called the value or, sometimes, the property). There are no duplications among the indicators; a property list may only have one property at a time with a given name. In this way, given a symbol and an indicator (another symbol), an associated value can be retrieved.
A property list is very similar in purpose to an association list.
The difference is that a property list is an object with a unique
identity; the operations for adding and removing property-list entries
are destructive operations that alter the property list rather than
making a new one. Association lists, on the other hand, are normally
augmented non-destructively (without side effects) by adding new entries
to the front (see acons and pairlis).
A property list is implemented as a memory cell containing a list
with an even number (possibly zero) of elements. (Usually this memory
cell is the property-list cell of a symbol, but any memory cell
acceptable to setf can be used if getf and
remf are used.) Each pair of elements in the list
constitutes an entry; the first item is the indicator, and the second is
the value. Because property-list functions are given the symbol and not
the list itself, modifications to the property list can be recorded by
storing back into the property-list cell of the symbol.
When a symbol is created, its property list is initially empty.
Properties are created by using get within a
setf form.
Common Lisp does not use a symbol’s property list as extensively as earlier Lisp implementations did. Less-used data, such as compiler, debugging, and documentation information, is kept on property lists in Common Lisp.
Compatibility note: In older Lisp implementations,
the print name, value, and function definition of a symbol were kept on
its property list. The value cell was introduced into MacLisp and
Interlisp to speed up access to variables; similarly for the print-name
cell and function cell (MacLisp does not use a function cell). Recent
Lisp implementations such as Spice Lisp, Lisp Machine Lisp, and NIL have
introduced all of these cells plus the package cell. None of the MacLisp
system property names (expr, fexpr,
macro, array, subr,
lsubr, fsubr, and in former times
value and pname) exist in Common Lisp.
In Common Lisp, the notion of ``disembodied property list’’
introduced in MacLisp is eliminated. It tended to be used for rather
kludgy things, and in Lisp Machine Lisp is often associated with the use
of locatives (to make it ``off by one’’ for searching alternating
keyword lists). In Common Lisp special setf-like
property-list functions are introduced: getf and
remf.
[Function]
getsymbolindicator&optionaldefault
get searches the property list of symbol for an
indicator eq to indicator. The first argument must
be a symbol. If one is found, then the corresponding value is returned;
otherwise default is returned.
If default is not specified, then nil is used
for default.
Note that there is no way to distinguish an absent property from one whose value is default.
(get x y) == (getf (symbol-plist x) y)
Suppose that the property list of foo is
(bar t baz 3 hunoz "Huh?"). Then, for example:
(get 'foo 'baz) => 3
(get 'foo 'hunoz) => "Huh?"
(get 'foo 'zoo) => nil
Compatibility note: In MacLisp, the first argument
to get could be a list, in which case the cdr of
the list was treated as a so-called ``disembodied property list.’’ The
first argument to get could also be any other object, in
which case get would always return nil. In
Common Lisp, it is an error to give anything but a symbol as the first
argument to get.
What Common Lisp calls get, Interlisp calls
getprop.
What MacLisp and Interlisp call putprop is accomplished
in Common Lisp by using get with setf.
setf may be used with get to create a new
property-value pair, possibly replacing an old pair with the same
property name. For example:
(get 'clyde 'species) => nil
(setf (get 'clyde 'species) 'elephant) => elephant
and now (get 'clyde 'species) => elephant
The default argument may be specified to get in
this context; it is ignored by setf but may be useful in
such macros as push that are related to
setf:
(push item (get sym 'token-stack '(initial-item)))
means approximately the same as
(setf (get sym 'token-stack '(initial-item))
(cons item (get sym 'token-stack '(initial-item))))
which in turn would be treated as simply
(setf (get sym 'token-stack)
(cons item (get sym 'token-stack '(initial-item))))

X3J13 voted in March 1989 (REMF-DESTRUCTION-UNSPECIFIED) to clarify
the permissible side effects of certain operations;
(setf (getsymbolindicator)newvalue)
is required to behave exactly the same as
(setf (getf (symbol-plistsymbol)indicator)newvalue).

[Function]
rempropsymbolindicator
This removes from symbol the property with an indicator
eq to indicator. The property indicator and the
corresponding value are removed by destructively splicing the property
list. It returns nil if no such property was found, or
non-nil if a property was found.
(remprop x y) == (remf (symbol-plist x) y)
For example, if the property list of foo is
initially
(color blue height 6.3 near-to bar)
then the call
(remprop 'foo 'height)
returns a non-nil value after altering
foo’s property list to be
(color blue near-to bar)

X3J13 voted in March 1989 (REMF-DESTRUCTION-UNSPECIFIED) to clarify
the permissible side effects of certain operations;
(rempropsymbolindicator)
is required to behave exactly the same as
(remf (symbol-plistsymbol)indicator).

[Function]
symbol-plistsymbol
This returns the list that contains the property pairs of symbol; the contents of the property-list cell are extracted and returned.
Note that using get on the result of
symbol-plist does not work. One must give the
symbol itself to get or else use the function
getf.
setf may be used with symbol-plist to
destructively replace the entire property list of a symbol. This is a
relatively dangerous operation, as it may destroy important information
that the implementation may happen to store in property lists. Also,
care must be taken that the new property list is in fact a list of even
length.
Compatibility note: In MacLisp, this function is
called plist; in Interlisp, it is called
getproplist.
[Function]
getfplaceindicator&optionaldefault
getf searches the property list stored in place
for an indicator eq to indicator. If one is found,
then the corresponding value is returned; otherwise default is
returned. If default is not specified, then nil is
used for default. Note that there is no way to distinguish an
absent property from one whose value is default. Often
place is computed from a generalized variable acceptable to
setf.
setf may be used with getf, in which case
the place must indeed be acceptable as a place to
setf. The effect is to add a new property-value pair, or
update an existing pair, in the property list kept in the
place. The default argument may be specified to
getf in this context; it is ignored by setf
but may be useful in such macros as push that are related
to setf. See the description of get for an
example of this.

X3J13 voted in March 1989 (REMF-DESTRUCTION-UNSPECIFIED) to clarify
the permissible side effects of certain operations; setf
used with getf is permitted to perform a setf
on the place or on any part, car or cdr, of
the top-level list structure held by that place.
X3J13 voted in March 1988 (PUSH-EVALUATION-ORDER) to clarify order
of evaluation (see section 7.2).

Compatibility note: The Interlisp function
listget is similar to getf. The Interlisp
function listput is similar to using getf with
setf.
[Macro]
remfplaceindicator
This removes from the property list stored in place the
property with an indicator eq to indicator. The
property indicator and the corresponding value are removed by
destructively splicing the property list. remf returns
nil if no such property was found, or some
non-nil value if a property was found. The form
place may be any generalized variable acceptable to
setf. See remprop.

X3J13 voted in March 1989 (REMF-DESTRUCTION-UNSPECIFIED) to clarify
the permissible side effects of certain operations; remf is
permitted to perform a setf on the place or on any
part, car or cdr, of the top-level list structure held
by that place.
X3J13 voted in March 1988 (PUSH-EVALUATION-ORDER) to clarify order
of evaluation (see section 7.2).

[Function]
get-propertiesplaceindicator-list
get-properties is like getf, except that
the second argument is a list of indicators. get-properties
searches the property list stored in place for any of the
indicators in indicator-list until it finds the first property
in the property list whose indicator is one of the elements of
indicator-list. Normally place is computed from a
generalized variable acceptable to setf.
get-properties returns three values. If any property was
found, then the first two values are the indicator and value for the
first property whose indicator was in indicator-list, and the
third is that tail of the property list whose car was the
indicator (and whose cadr is therefore the value). If no
property was found, all three values are nil. Thus the
third value serves as a flag indicating success or failure and also
allows the search to be restarted, if desired, after the property was
found.
![]()
Next: The Print Name
Up: Symbols
Previous: Symbols
AI.Repository@cs.cmu.edu