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.
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.
Suppose that the property list of foo is (bar t baz 3 hunoz "Huh?"). Then, for example:
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:
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:
means approximately the same as
which in turn would be treated as simply
X3J13 voted in March 1989 to clarify the permissible side effects of certain operations; (setf (get symbol indicator) newvalue) is required to behave exactly the same as (setf (getf (symbol-plist symbol) indicator) newvalue).
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.
For example, if the property list of foo is initially
then the call
returns a non-nil value after altering foo’s property list to be
X3J13 voted in March 1989 to clarify the permissible side effects of certain operations; (remprop symbol indicator) is required to behave exactly the same as (remf (symbol-plist symbol) indicator).
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.
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 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 to clarify order of evaluation (see section 7.2).
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 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 to clarify order of evaluation (see section 7.2).
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.