"Fossies" - the Fresh Open Source Software Archive

Member "emacs-26.1/doc/lispref/lists.texi" (23 Apr 2018, 58981 Bytes) of package /linux/misc/emacs-26.1.tar.xz:


Caution: As a special service "Fossies" has tried to format the requested Texinfo source page into HTML format but that may be not always succeeeded perfectly. Alternatively you can here view or download the uninterpreted Texinfo source code. A member file download can also be achieved by clicking within a package contents listing on the according byte size field. See also the latest Fossies "Diffs" side-by-side code changes report for "lists.texi": 25.3_vs_26.1.

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1 Lists

A list represents a sequence of zero or more elements (which may be any Lisp objects). The important difference between lists and vectors is that two or more lists can share part of their structure; in addition, you can insert or delete elements in a list without copying the whole list.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1 Lists and Cons Cells

Lists in Lisp are not a primitive data type; they are built up from cons cells (@pxref{Cons Cell Type}). A cons cell is a data object that represents an ordered pair. That is, it has two slots, and each slot holds, or refers to, some Lisp object. One slot is known as the CAR, and the other is known as the CDR. (These names are traditional; see @ref{Cons Cell Type}.) CDR is pronounced “could-er”.

We say that “the CAR of this cons cell is” whatever object its CAR slot currently holds, and likewise for the CDR.

A list is a series of cons cells chained together, so that each cell refers to the next one. There is one cons cell for each element of the list. By convention, the CARs of the cons cells hold the elements of the list, and the CDRs are used to chain the list (this asymmetry between CAR and CDR is entirely a matter of convention; at the level of cons cells, the CAR and CDR slots have similar properties). Hence, the CDR slot of each cons cell in a list refers to the following cons cell.

Also by convention, the CDR of the last cons cell in a list is nil. We call such a nil-terminated structure a true list. In Emacs Lisp, the symbol nil is both a symbol and a list with no elements. For convenience, the symbol nil is considered to have nil as its CDR (and also as its CAR).

Hence, the CDR of a true list is always a true list. The CDR of a nonempty true list is a true list containing all the elements except the first.

If the CDR of a list’s last cons cell is some value other than nil, we call the structure a dotted list, since its printed representation would use dotted pair notation (@pxref{Dotted Pair Notation}). There is one other possibility: some cons cell’s CDR could point to one of the previous cons cells in the list. We call that structure a circular list.

For some purposes, it does not matter whether a list is true, circular or dotted. If a program doesn’t look far enough down the list to see the CDR of the final cons cell, it won’t care. However, some functions that operate on lists demand true lists and signal errors if given a dotted list. Most functions that try to find the end of a list enter infinite loops if given a circular list.

Because most cons cells are used as part of lists, we refer to any structure made out of cons cells as a list structure.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2 Predicates on Lists

The following predicates test whether a Lisp object is an atom, whether it is a cons cell or is a list, or whether it is the distinguished object nil. (Many of these predicates can be defined in terms of the others, but they are used so often that it is worth having them.)

Function: consp object

This function returns t if object is a cons cell, nil otherwise. nil is not a cons cell, although it is a list.

Function: atom object

This function returns t if object is an atom, nil otherwise. All objects except cons cells are atoms. The symbol nil is an atom and is also a list; it is the only Lisp object that is both.

(atom object) ≡ (not (consp object))
Function: listp object

This function returns t if object is a cons cell or nil. Otherwise, it returns nil.

(listp '(1))
     ⇒ t
(listp '())
     ⇒ t
Function: nlistp object

This function is the opposite of listp: it returns t if object is not a list. Otherwise, it returns nil.

(listp object) ≡ (not (nlistp object))
Function: null object

This function returns t if object is nil, and returns nil otherwise. This function is identical to not, but as a matter of clarity we use null when object is considered a list and not when it is considered a truth value (see not in @ref{Combining Conditions}).

(null '(1))
     ⇒ nil
(null '())
     ⇒ t

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3 Accessing Elements of Lists

Function: car cons-cell

This function returns the value referred to by the first slot of the cons cell cons-cell. In other words, it returns the CAR of cons-cell.

As a special case, if cons-cell is nil, this function returns nil. Therefore, any list is a valid argument. An error is signaled if the argument is not a cons cell or nil.

(car '(a b c))
     ⇒ a
(car '())
     ⇒ nil
Function: cdr cons-cell

This function returns the value referred to by the second slot of the cons cell cons-cell. In other words, it returns the CDR of cons-cell.

As a special case, if cons-cell is nil, this function returns nil; therefore, any list is a valid argument. An error is signaled if the argument is not a cons cell or nil.

(cdr '(a b c))
     ⇒ (b c)
(cdr '())
     ⇒ nil
Function: car-safe object

This function lets you take the CAR of a cons cell while avoiding errors for other data types. It returns the CAR of object if object is a cons cell, nil otherwise. This is in contrast to car, which signals an error if object is not a list.

(car-safe object)
≡
(let ((x object))
  (if (consp x)
      (car x)
    nil))
Function: cdr-safe object

This function lets you take the CDR of a cons cell while avoiding errors for other data types. It returns the CDR of object if object is a cons cell, nil otherwise. This is in contrast to cdr, which signals an error if object is not a list.

(cdr-safe object)
≡
(let ((x object))
  (if (consp x)
      (cdr x)
    nil))
Macro: pop listname

This macro provides a convenient way to examine the CAR of a list, and take it off the list, all at once. It operates on the list stored in listname. It removes the first element from the list, saves the CDR into listname, then returns the removed element.

In the simplest case, listname is an unquoted symbol naming a list; in that case, this macro is equivalent to (prog1 (car listname) (setq listname (cdr listname))).

x
     ⇒ (a b c)
(pop x)
     ⇒ a
x
     ⇒ (b c)

More generally, listname can be a generalized variable. In that case, this macro saves into listname using setf. @xref{Generalized Variables}.

For the push macro, which adds an element to a list, See section Modifying List Variables.

Function: nth n list

This function returns the nth element of list. Elements are numbered starting with zero, so the CAR of list is element number zero. If the length of list is n or less, the value is nil.

(nth 2 '(1 2 3 4))
     ⇒ 3
(nth 10 '(1 2 3 4))
     ⇒ nil

(nth n x) ≡ (car (nthcdr n x))

The function elt is similar, but applies to any kind of sequence. For historical reasons, it takes its arguments in the opposite order. @xref{Sequence Functions}.

Function: nthcdr n list

This function returns the nth CDR of list. In other words, it skips past the first n links of list and returns what follows.

If n is zero, nthcdr returns all of list. If the length of list is n or less, nthcdr returns nil.

(nthcdr 1 '(1 2 3 4))
     ⇒ (2 3 4)
(nthcdr 10 '(1 2 3 4))
     ⇒ nil
(nthcdr 0 '(1 2 3 4))
     ⇒ (1 2 3 4)
Function: last list &optional n

This function returns the last link of list. The car of this link is the list’s last element. If list is null, nil is returned. If n is non-nil, the nth-to-last link is returned instead, or the whole of list if n is bigger than list’s length.

Function: safe-length list

This function returns the length of list, with no risk of either an error or an infinite loop. It generally returns the number of distinct cons cells in the list. However, for circular lists, the value is just an upper bound; it is often too large.

If list is not nil or a cons cell, safe-length returns 0.

The most common way to compute the length of a list, when you are not worried that it may be circular, is with length. @xref{Sequence Functions}.

Function: caar cons-cell

This is the same as (car (car cons-cell)).

Function: cadr cons-cell

This is the same as (car (cdr cons-cell)) or (nth 1 cons-cell).

Function: cdar cons-cell

This is the same as (cdr (car cons-cell)).

Function: cddr cons-cell

This is the same as (cdr (cdr cons-cell)) or (nthcdr 2 cons-cell).

In addition to the above, 24 additional compositions of car and cdr are defined as cxxxr and cxxxxr, where each x is either a or d. cadr, caddr, and cadddr pick out the second, third or fourth elements of a list, respectively. ‘cl-lib’ provides the same under the names cl-second, cl-third, and cl-fourth. See List Functions in Common Lisp Extensions.

Function: butlast x &optional n

This function returns the list x with the last element, or the last n elements, removed. If n is greater than zero it makes a copy of the list so as not to damage the original list. In general, (append (butlast x n) (last x n)) will return a list equal to x.

Function: nbutlast x &optional n

This is a version of butlast that works by destructively modifying the cdr of the appropriate element, rather than making a copy of the list.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4 Building Cons Cells and Lists

Many functions build lists, as lists reside at the very heart of Lisp. cons is the fundamental list-building function; however, it is interesting to note that list is used more times in the source code for Emacs than cons.

Function: cons object1 object2

This function is the most basic function for building new list structure. It creates a new cons cell, making object1 the CAR, and object2 the CDR. It then returns the new cons cell. The arguments object1 and object2 may be any Lisp objects, but most often object2 is a list.

(cons 1 '(2))
     ⇒ (1 2)
(cons 1 '())
     ⇒ (1)
(cons 1 2)
     ⇒ (1 . 2)

cons is often used to add a single element to the front of a list. This is called consing the element onto the list. (1) For example:

(setq list (cons newelt list))

Note that there is no conflict between the variable named list used in this example and the function named list described below; any symbol can serve both purposes.

Function: list &rest objects

This function creates a list with objects as its elements. The resulting list is always nil-terminated. If no objects are given, the empty list is returned.

(list 1 2 3 4 5)
     ⇒ (1 2 3 4 5)
(list 1 2 '(3 4 5) 'foo)
     ⇒ (1 2 (3 4 5) foo)
(list)
     ⇒ nil
Function: make-list length object

This function creates a list of length elements, in which each element is object. Compare make-list with make-string (@pxref{Creating Strings}).

(make-list 3 'pigs)
     ⇒ (pigs pigs pigs)
(make-list 0 'pigs)
     ⇒ nil
(setq l (make-list 3 '(a b)))
     ⇒ ((a b) (a b) (a b))
(eq (car l) (cadr l))
     ⇒ t
Function: append &rest sequences

This function returns a list containing all the elements of sequences. The sequences may be lists, vectors, bool-vectors, or strings, but the last one should usually be a list. All arguments except the last one are copied, so none of the arguments is altered. (See nconc in Functions that Rearrange Lists, for a way to join lists with no copying.)

More generally, the final argument to append may be any Lisp object. The final argument is not copied or converted; it becomes the CDR of the last cons cell in the new list. If the final argument is itself a list, then its elements become in effect elements of the result list. If the final element is not a list, the result is a dotted list since its final CDR is not nil as required in a true list.

Here is an example of using append:

(setq trees '(pine oak))
     ⇒ (pine oak)
(setq more-trees (append '(maple birch) trees))
     ⇒ (maple birch pine oak)
trees
     ⇒ (pine oak)
more-trees
     ⇒ (maple birch pine oak)
(eq trees (cdr (cdr more-trees)))
     ⇒ t

You can see how append works by looking at a box diagram. The variable trees is set to the list (pine oak) and then the variable more-trees is set to the list (maple birch pine oak). However, the variable trees continues to refer to the original list:

more-trees                trees
|                           |
|     --- ---      --- ---   -> --- ---      --- ---
 --> |   |   |--> |   |   |--> |   |   |--> |   |   |--> nil
      --- ---      --- ---      --- ---      --- ---
       |            |            |            |
       |            |            |            |
        --> maple    -->birch     --> pine     --> oak

An empty sequence contributes nothing to the value returned by append. As a consequence of this, a final nil argument forces a copy of the previous argument:

trees
     ⇒ (pine oak)
(setq wood (append trees nil))
     ⇒ (pine oak)
wood
     ⇒ (pine oak)
(eq wood trees)
     ⇒ nil

This once was the usual way to copy a list, before the function copy-sequence was invented. @xref{Sequences Arrays Vectors}.

Here we show the use of vectors and strings as arguments to append:

(append [a b] "cd" nil)
     ⇒ (a b 99 100)

With the help of apply (@pxref{Calling Functions}), we can append all the lists in a list of lists:

(apply 'append '((a b c) nil (x y z) nil))
     ⇒ (a b c x y z)

If no sequences are given, nil is returned:

(append)
     ⇒ nil

Here are some examples where the final argument is not a list:

(append '(x y) 'z)
     ⇒ (x y . z)
(append '(x y) [z])
     ⇒ (x y . [z])

The second example shows that when the final argument is a sequence but not a list, the sequence’s elements do not become elements of the resulting list. Instead, the sequence becomes the final CDR, like any other non-list final argument.

Function: copy-tree tree &optional vecp

This function returns a copy of the tree tree. If tree is a cons cell, this makes a new cons cell with the same CAR and CDR, then recursively copies the CAR and CDR in the same way.

Normally, when tree is anything other than a cons cell, copy-tree simply returns tree. However, if vecp is non-nil, it copies vectors too (and operates recursively on their elements).

Function: number-sequence from &optional to separation

This returns a list of numbers starting with from and incrementing by separation, and ending at or just before to. separation can be positive or negative and defaults to 1. If to is nil or numerically equal to from, the value is the one-element list (from). If to is less than from with a positive separation, or greater than from with a negative separation, the value is nil because those arguments specify an empty sequence.

If separation is 0 and to is neither nil nor numerically equal to from, number-sequence signals an error, since those arguments specify an infinite sequence.

All arguments are numbers. Floating-point arguments can be tricky, because floating-point arithmetic is inexact. For instance, depending on the machine, it may quite well happen that (number-sequence 0.4 0.6 0.2) returns the one element list (0.4), whereas (number-sequence 0.4 0.8 0.2) returns a list with three elements. The nth element of the list is computed by the exact formula (+ from (* n separation)). Thus, if one wants to make sure that to is included in the list, one can pass an expression of this exact type for to. Alternatively, one can replace to with a slightly larger value (or a slightly more negative value if separation is negative).

Some examples:

(number-sequence 4 9)
     ⇒ (4 5 6 7 8 9)
(number-sequence 9 4 -1)
     ⇒ (9 8 7 6 5 4)
(number-sequence 9 4 -2)
     ⇒ (9 7 5)
(number-sequence 8)
     ⇒ (8)
(number-sequence 8 5)
     ⇒ nil
(number-sequence 5 8 -1)
     ⇒ nil
(number-sequence 1.5 6 2)
     ⇒ (1.5 3.5 5.5)

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.5 Modifying List Variables

These functions, and one macro, provide convenient ways to modify a list which is stored in a variable.

Macro: push element listname

This macro creates a new list whose CAR is element and whose CDR is the list specified by listname, and saves that list in listname. In the simplest case, listname is an unquoted symbol naming a list, and this macro is equivalent to (setq listname (cons element listname)).

(setq l '(a b))
     ⇒ (a b)
(push 'c l)
     ⇒ (c a b)
l
     ⇒ (c a b)

More generally, listname can be a generalized variable. In that case, this macro does the equivalent of (setf listname (cons element listname)). @xref{Generalized Variables}.

For the pop macro, which removes the first element from a list, See section Accessing Elements of Lists.

Two functions modify lists that are the values of variables.

Function: add-to-list symbol element &optional append compare-fn

This function sets the variable symbol by consing element onto the old value, if element is not already a member of that value. It returns the resulting list, whether updated or not. The value of symbol had better be a list already before the call. add-to-list uses compare-fn to compare element against existing list members; if compare-fn is nil, it uses equal.

Normally, if element is added, it is added to the front of symbol, but if the optional argument append is non-nil, it is added at the end.

The argument symbol is not implicitly quoted; add-to-list is an ordinary function, like set and unlike setq. Quote the argument yourself if that is what you want.

Here’s a scenario showing how to use add-to-list:

(setq foo '(a b))
     ⇒ (a b)

(add-to-list 'foo 'c)     ;; Add c.
     ⇒ (c a b)

(add-to-list 'foo 'b)     ;; No effect.
     ⇒ (c a b)

foo                       ;; foo was changed.
     ⇒ (c a b)

An equivalent expression for (add-to-list 'var value) is this:

(or (member value var)
    (setq var (cons value var)))
Function: add-to-ordered-list symbol element &optional order

This function sets the variable symbol by inserting element into the old value, which must be a list, at the position specified by order. If element is already a member of the list, its position in the list is adjusted according to order. Membership is tested using eq. This function returns the resulting list, whether updated or not.

The order is typically a number (integer or float), and the elements of the list are sorted in non-decreasing numerical order.

order may also be omitted or nil. Then the numeric order of element stays unchanged if it already has one; otherwise, element has no numeric order. Elements without a numeric list order are placed at the end of the list, in no particular order.

Any other value for order removes the numeric order of element if it already has one; otherwise, it is equivalent to nil.

The argument symbol is not implicitly quoted; add-to-ordered-list is an ordinary function, like set and unlike setq. Quote the argument yourself if necessary.

The ordering information is stored in a hash table on symbol’s list-order property.

Here’s a scenario showing how to use add-to-ordered-list:

(setq foo '())
     ⇒ nil

(add-to-ordered-list 'foo 'a 1)     ;; Add a.
     ⇒ (a)

(add-to-ordered-list 'foo 'c 3)     ;; Add c.
     ⇒ (a c)

(add-to-ordered-list 'foo 'b 2)     ;; Add b.
     ⇒ (a b c)

(add-to-ordered-list 'foo 'b 4)     ;; Move b.
     ⇒ (a c b)

(add-to-ordered-list 'foo 'd)       ;; Append d.
     ⇒ (a c b d)

(add-to-ordered-list 'foo 'e)       ;; Add e.
     ⇒ (a c b e d)

foo                       ;; foo was changed.
     ⇒ (a c b e d)

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.6 Modifying Existing List Structure

You can modify the CAR and CDR contents of a cons cell with the primitives setcar and setcdr. These are destructive operations because they change existing list structure.

Common Lisp note: Common Lisp uses functions rplaca and rplacd to alter list structure; they change structure the same way as setcar and setcdr, but the Common Lisp functions return the cons cell while setcar and setcdr return the new CAR or CDR.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.6.1 Altering List Elements with setcar

Changing the CAR of a cons cell is done with setcar. When used on a list, setcar replaces one element of a list with a different element.

Function: setcar cons object

This function stores object as the new CAR of cons, replacing its previous CAR. In other words, it changes the CAR slot of cons to refer to object. It returns the value object. For example:

(setq x '(1 2))
     ⇒ (1 2)
(setcar x 4)
     ⇒ 4
x
     ⇒ (4 2)

When a cons cell is part of the shared structure of several lists, storing a new CAR into the cons changes one element of each of these lists. Here is an example:

;; Create two lists that are partly shared.
(setq x1 '(a b c))
     ⇒ (a b c)
(setq x2 (cons 'z (cdr x1)))
     ⇒ (z b c)
;; Replace the CAR of a shared link.
(setcar (cdr x1) 'foo)
     ⇒ foo
x1                           ; Both lists are changed.
     ⇒ (a foo c)
x2
     ⇒ (z foo c)
;; Replace the CAR of a link that is not shared.
(setcar x1 'baz)
     ⇒ baz
x1                           ; Only one list is changed.
     ⇒ (baz foo c)
x2
     ⇒ (z foo c)

Here is a graphical depiction of the shared structure of the two lists in the variables x1 and x2, showing why replacing b changes them both:

        --- ---        --- ---      --- ---
x1---> |   |   |----> |   |   |--> |   |   |--> nil
        --- ---        --- ---      --- ---
         |        -->   |            |
         |       |      |            |
          --> a  |       --> b        --> c
                 |
       --- ---   |
x2--> |   |   |--
       --- ---
        |
        |
         --> z

Here is an alternative form of box diagram, showing the same relationship:

x1:
 --------------       --------------       --------------
| car   | cdr  |     | car   | cdr  |     | car   | cdr  |
|   a   |   o------->|   b   |   o------->|   c   |  nil |
|       |      |  -->|       |      |     |       |      |
 --------------  |    --------------       --------------
                 |
x2:              |
 --------------  |
| car   | cdr  | |
|   z   |   o----
|       |      |
 --------------

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.6.2 Altering the CDR of a List

The lowest-level primitive for modifying a CDR is setcdr:

Function: setcdr cons object

This function stores object as the new CDR of cons, replacing its previous CDR. In other words, it changes the CDR slot of cons to refer to object. It returns the value object.

Here is an example of replacing the CDR of a list with a different list. All but the first element of the list are removed in favor of a different sequence of elements. The first element is unchanged, because it resides in the CAR of the list, and is not reached via the CDR.

(setq x '(1 2 3))
     ⇒ (1 2 3)
(setcdr x '(4))
     ⇒ (4)
x
     ⇒ (1 4)

You can delete elements from the middle of a list by altering the CDRs of the cons cells in the list. For example, here we delete the second element, b, from the list (a b c), by changing the CDR of the first cons cell:

(setq x1 '(a b c))
     ⇒ (a b c)
(setcdr x1 (cdr (cdr x1)))
     ⇒ (c)
x1
     ⇒ (a c)

Here is the result in box notation:

                   --------------------
                  |                    |
 --------------   |   --------------   |    --------------
| car   | cdr  |  |  | car   | cdr  |   -->| car   | cdr  |
|   a   |   o-----   |   b   |   o-------->|   c   |  nil |
|       |      |     |       |      |      |       |      |
 --------------       --------------        --------------

The second cons cell, which previously held the element b, still exists and its CAR is still b, but it no longer forms part of this list.

It is equally easy to insert a new element by changing CDRs:

(setq x1 '(a b c))
     ⇒ (a b c)
(setcdr x1 (cons 'd (cdr x1)))
     ⇒ (d b c)
x1
     ⇒ (a d b c)

Here is this result in box notation:

 --------------        -------------       -------------
| car  | cdr   |      | car  | cdr  |     | car  | cdr  |
|   a  |   o   |   -->|   b  |   o------->|   c  |  nil |
|      |   |   |  |   |      |      |     |      |      |
 --------- | --   |    -------------       -------------
           |      |
     -----         --------
    |                      |
    |    ---------------   |
    |   | car   | cdr   |  |
     -->|   d   |   o------
        |       |       |
         ---------------

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.6.3 Functions that Rearrange Lists

Here are some functions that rearrange lists destructively by modifying the CDRs of their component cons cells. These functions are destructive because they chew up the original lists passed to them as arguments, relinking their cons cells to form a new list that is the returned value.

See delq, in Using Lists as Sets, for another function that modifies cons cells.

Function: nconc &rest lists

This function returns a list containing all the elements of lists. Unlike append (see section Building Cons Cells and Lists), the lists are not copied. Instead, the last CDR of each of the lists is changed to refer to the following list. The last of the lists is not altered. For example:

(setq x '(1 2 3))
     ⇒ (1 2 3)
(nconc x '(4 5))
     ⇒ (1 2 3 4 5)
x
     ⇒ (1 2 3 4 5)

Since the last argument of nconc is not itself modified, it is reasonable to use a constant list, such as '(4 5), as in the above example. For the same reason, the last argument need not be a list:

(setq x '(1 2 3))
     ⇒ (1 2 3)
(nconc x 'z)
     ⇒ (1 2 3 . z)
x
     ⇒ (1 2 3 . z)

However, the other arguments (all but the last) must be lists.

A common pitfall is to use a quoted constant list as a non-last argument to nconc. If you do this, your program will change each time you run it! Here is what happens:

(defun add-foo (x)            ; We want this function to add
  (nconc '(foo) x))           ;   foo to the front of its arg.
(symbol-function 'add-foo)
     ⇒ (lambda (x) (nconc (quote (foo)) x))
(setq xx (add-foo '(1 2)))    ; It seems to work.
     ⇒ (foo 1 2)
(setq xy (add-foo '(3 4)))    ; What happened?
     ⇒ (foo 1 2 3 4)
(eq xx xy)
     ⇒ t
(symbol-function 'add-foo)
     ⇒ (lambda (x) (nconc (quote (foo 1 2 3 4) x)))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.7 Using Lists as Sets

A list can represent an unordered mathematical set—simply consider a value an element of a set if it appears in the list, and ignore the order of the list. To form the union of two sets, use append (as long as you don’t mind having duplicate elements). You can remove equal duplicates using delete-dups. Other useful functions for sets include memq and delq, and their equal versions, member and delete.

Common Lisp note: Common Lisp has functions union (which avoids duplicate elements) and intersection for set operations. Although standard GNU Emacs Lisp does not have them, the ‘cl-lib’ library provides versions. See Lists as Sets in Common Lisp Extensions.

Function: memq object list

This function tests to see whether object is a member of list. If it is, memq returns a list starting with the first occurrence of object. Otherwise, it returns nil. The letter ‘q’ in memq says that it uses eq to compare object against the elements of the list. For example:

(memq 'b '(a b c b a))
     ⇒ (b c b a)
(memq '(2) '((1) (2)))    ; (2) and (2) are not eq.
     ⇒ nil
Function: delq object list

This function destructively removes all elements eq to object from list, and returns the resulting list. The letter ‘q’ in delq says that it uses eq to compare object against the elements of the list, like memq and remq.

Typically, when you invoke delq, you should use the return value by assigning it to the variable which held the original list. The reason for this is explained below.

The delq function deletes elements from the front of the list by simply advancing down the list, and returning a sublist that starts after those elements. For example:

(delq 'a '(a b c)) ≡ (cdr '(a b c))

When an element to be deleted appears in the middle of the list, removing it involves changing the CDRs (see section Altering the CDR of a List).

(setq sample-list '(a b c (4)))
     ⇒ (a b c (4))
(delq 'a sample-list)
     ⇒ (b c (4))
sample-list
     ⇒ (a b c (4))
(delq 'c sample-list)
     ⇒ (a b (4))
sample-list
     ⇒ (a b (4))

Note that (delq 'c sample-list) modifies sample-list to splice out the third element, but (delq 'a sample-list) does not splice anything—it just returns a shorter list. Don’t assume that a variable which formerly held the argument list now has fewer elements, or that it still holds the original list! Instead, save the result of delq and use that. Most often we store the result back into the variable that held the original list:

(setq flowers (delq 'rose flowers))

In the following example, the (4) that delq attempts to match and the (4) in the sample-list are not eq:

(delq '(4) sample-list)
     ⇒ (a c (4))

If you want to delete elements that are equal to a given value, use delete (see below).

Function: remq object list

This function returns a copy of list, with all elements removed which are eq to object. The letter ‘q’ in remq says that it uses eq to compare object against the elements of list.

(setq sample-list '(a b c a b c))
     ⇒ (a b c a b c)
(remq 'a sample-list)
     ⇒ (b c b c)
sample-list
     ⇒ (a b c a b c)
Function: memql object list

The function memql tests to see whether object is a member of list, comparing members with object using eql, so floating-point elements are compared by value. If object is a member, memql returns a list starting with its first occurrence in list. Otherwise, it returns nil.

Compare this with memq:

(memql 1.2 '(1.1 1.2 1.3))  ; 1.2 and 1.2 are eql.
     ⇒ (1.2 1.3)
(memq 1.2 '(1.1 1.2 1.3))  ; 1.2 and 1.2 are not eq.
     ⇒ nil

The following three functions are like memq, delq and remq, but use equal rather than eq to compare elements. @xref{Equality Predicates}.

Function: member object list

The function member tests to see whether object is a member of list, comparing members with object using equal. If object is a member, member returns a list starting with its first occurrence in list. Otherwise, it returns nil.

Compare this with memq:

(member '(2) '((1) (2)))  ; (2) and (2) are equal.
     ⇒ ((2))
(memq '(2) '((1) (2)))    ; (2) and (2) are not eq.
     ⇒ nil
;; Two strings with the same contents are equal.
(member "foo" '("foo" "bar"))
     ⇒ ("foo" "bar")
Function: delete object sequence

This function removes all elements equal to object from sequence, and returns the resulting sequence.

If sequence is a list, delete is to delq as member is to memq: it uses equal to compare elements with object, like member; when it finds an element that matches, it cuts the element out just as delq would. As with delq, you should typically use the return value by assigning it to the variable which held the original list.

If sequence is a vector or string, delete returns a copy of sequence with all elements equal to object removed.

For example:

(setq l '((2) (1) (2)))
(delete '(2) l)
     ⇒ ((1))
l
     ⇒ ((2) (1))
;; If you want to change l reliably,
;; write (setq l (delete '(2) l)).
(setq l '((2) (1) (2)))
(delete '(1) l)
     ⇒ ((2) (2))
l
     ⇒ ((2) (2))
;; In this case, it makes no difference whether you set l,
;; but you should do so for the sake of the other case.
(delete '(2) [(2) (1) (2)])
     ⇒ [(1)]
Function: remove object sequence

This function is the non-destructive counterpart of delete. It returns a copy of sequence, a list, vector, or string, with elements equal to object removed. For example:

(remove '(2) '((2) (1) (2)))
     ⇒ ((1))
(remove '(2) [(2) (1) (2)])
     ⇒ [(1)]

Common Lisp note: The functions member, delete and remove in GNU Emacs Lisp are derived from Maclisp, not Common Lisp. The Common Lisp versions do not use equal to compare elements.

Function: member-ignore-case object list

This function is like member, except that object should be a string and that it ignores differences in letter-case and text representation: upper-case and lower-case letters are treated as equal, and unibyte strings are converted to multibyte prior to comparison.

Function: delete-dups list

This function destructively removes all equal duplicates from list, stores the result in list and returns it. Of several equal occurrences of an element in list, delete-dups keeps the first one.

See also the function add-to-list, in Modifying List Variables, for a way to add an element to a list stored in a variable and used as a set.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.8 Association Lists

An association list, or alist for short, records a mapping from keys to values. It is a list of cons cells called associations: the CAR of each cons cell is the key, and the CDR is the associated value.(2)

Here is an example of an alist. The key pine is associated with the value cones; the key oak is associated with acorns; and the key maple is associated with seeds.

((pine . cones)
 (oak . acorns)
 (maple . seeds))

Both the values and the keys in an alist may be any Lisp objects. For example, in the following alist, the symbol a is associated with the number 1, and the string "b" is associated with the list (2 3), which is the CDR of the alist element:

((a . 1) ("b" 2 3))

Sometimes it is better to design an alist to store the associated value in the CAR of the CDR of the element. Here is an example of such an alist:

((rose red) (lily white) (buttercup yellow))

Here we regard red as the value associated with rose. One advantage of this kind of alist is that you can store other related information—even a list of other items—in the CDR of the CDR. One disadvantage is that you cannot use rassq (see below) to find the element containing a given value. When neither of these considerations is important, the choice is a matter of taste, as long as you are consistent about it for any given alist.

The same alist shown above could be regarded as having the associated value in the CDR of the element; the value associated with rose would be the list (red).

Association lists are often used to record information that you might otherwise keep on a stack, since new associations may be added easily to the front of the list. When searching an association list for an association with a given key, the first one found is returned, if there is more than one.

In Emacs Lisp, it is not an error if an element of an association list is not a cons cell. The alist search functions simply ignore such elements. Many other versions of Lisp signal errors in such cases.

Note that property lists are similar to association lists in several respects. A property list behaves like an association list in which each key can occur only once. See section Property Lists, for a comparison of property lists and association lists.

Function: assoc key alist &optional testfn

This function returns the first association for key in alist, comparing key against the alist elements using testfn if it is non-nil and equal otherwise (@pxref{Equality Predicates}). It returns nil if no association in alist has a CAR equal to key. For example:

(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
     ⇒ ((pine . cones) (oak . acorns) (maple . seeds))
(assoc 'oak trees)
     ⇒ (oak . acorns)
(cdr (assoc 'oak trees))
     ⇒ acorns
(assoc 'birch trees)
     ⇒ nil

Here is another example, in which the keys and values are not symbols:

(setq needles-per-cluster
      '((2 "Austrian Pine" "Red Pine")
        (3 "Pitch Pine")
        (5 "White Pine")))

(cdr (assoc 3 needles-per-cluster))
     ⇒ ("Pitch Pine")
(cdr (assoc 2 needles-per-cluster))
     ⇒ ("Austrian Pine" "Red Pine")

The function assoc-string is much like assoc except that it ignores certain differences between strings. @xref{Text Comparison}.

Function: rassoc value alist

This function returns the first association with value value in alist. It returns nil if no association in alist has a CDR equal to value.

rassoc is like assoc except that it compares the CDR of each alist association instead of the CAR. You can think of this as reverse assoc, finding the key for a given value.

Function: assq key alist

This function is like assoc in that it returns the first association for key in alist, but it makes the comparison using eq. assq returns nil if no association in alist has a CAR eq to key. This function is used more often than assoc, since eq is faster than equal and most alists use symbols as keys. @xref{Equality Predicates}.

(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
     ⇒ ((pine . cones) (oak . acorns) (maple . seeds))
(assq 'pine trees)
     ⇒ (pine . cones)

On the other hand, assq is not usually useful in alists where the keys may not be symbols:

(setq leaves
      '(("simple leaves" . oak)
        ("compound leaves" . horsechestnut)))

(assq "simple leaves" leaves)
     ⇒ nil
(assoc "simple leaves" leaves)
     ⇒ ("simple leaves" . oak)
Function: alist-get key alist &optional default remove testfn

This function is similar to assq. It finds the first association (key . value) by comparing key with alist elements, and, if found, returns the value of that association. If no association is found, the function returns default. Comparison of key against alist elements uses the function specified by testfn, defaulting to eq.

This is a generalized variable (@pxref{Generalized Variables}) that can be used to change a value with setf. When using it to set a value, optional argument remove non-nil means to remove key’s association from alist if the new value is eql to default.

Function: rassq value alist

This function returns the first association with value value in alist. It returns nil if no association in alist has a CDR eq to value.

rassq is like assq except that it compares the CDR of each alist association instead of the CAR. You can think of this as reverse assq, finding the key for a given value.

For example:

(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))

(rassq 'acorns trees)
     ⇒ (oak . acorns)
(rassq 'spores trees)
     ⇒ nil

rassq cannot search for a value stored in the CAR of the CDR of an element:

(setq colors '((rose red) (lily white) (buttercup yellow)))

(rassq 'white colors)
     ⇒ nil

In this case, the CDR of the association (lily white) is not the symbol white, but rather the list (white). This becomes clearer if the association is written in dotted pair notation:

(lily white) ≡ (lily . (white))
Function: assoc-default key alist &optional test default

This function searches alist for a match for key. For each element of alist, it compares the element (if it is an atom) or the element’s CAR (if it is a cons) against key, by calling test with two arguments: the element or its CAR, and key. The arguments are passed in that order so that you can get useful results using string-match with an alist that contains regular expressions (@pxref{Regexp Search}). If test is omitted or nil, equal is used for comparison.

If an alist element matches key by this criterion, then assoc-default returns a value based on this element. If the element is a cons, then the value is the element’s CDR. Otherwise, the return value is default.

If no alist element matches key, assoc-default returns nil.

Function: copy-alist alist

This function returns a two-level deep copy of alist: it creates a new copy of each association, so that you can alter the associations of the new alist without changing the old one.

(setq needles-per-cluster
      '((2 . ("Austrian Pine" "Red Pine"))
        (3 . ("Pitch Pine"))
        (5 . ("White Pine"))))
⇒
((2 "Austrian Pine" "Red Pine")
 (3 "Pitch Pine")
 (5 "White Pine"))

(setq copy (copy-alist needles-per-cluster))
⇒
((2 "Austrian Pine" "Red Pine")
 (3 "Pitch Pine")
 (5 "White Pine"))

(eq needles-per-cluster copy)
     ⇒ nil
(equal needles-per-cluster copy)
     ⇒ t
(eq (car needles-per-cluster) (car copy))
     ⇒ nil
(cdr (car (cdr needles-per-cluster)))
     ⇒ ("Pitch Pine")
(eq (cdr (car (cdr needles-per-cluster)))
    (cdr (car (cdr copy))))
     ⇒ t

This example shows how copy-alist makes it possible to change the associations of one copy without affecting the other:

(setcdr (assq 3 copy) '("Martian Vacuum Pine"))
(cdr (assq 3 needles-per-cluster))
     ⇒ ("Pitch Pine")
Function: assq-delete-all key alist

This function deletes from alist all the elements whose CAR is eq to key, much as if you used delq to delete each such element one by one. It returns the shortened alist, and often modifies the original list structure of alist. For correct results, use the return value of assq-delete-all rather than looking at the saved value of alist.

(setq alist '((foo 1) (bar 2) (foo 3) (lose 4)))
     ⇒ ((foo 1) (bar 2) (foo 3) (lose 4))
(assq-delete-all 'foo alist)
     ⇒ ((bar 2) (lose 4))
alist
     ⇒ ((foo 1) (bar 2) (lose 4))
Function: rassq-delete-all value alist

This function deletes from alist all the elements whose CDR is eq to value. It returns the shortened alist, and often modifies the original list structure of alist. rassq-delete-all is like assq-delete-all except that it compares the CDR of each alist association instead of the CAR.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.9 Property Lists

A property list (plist for short) is a list of paired elements. Each of the pairs associates a property name (usually a symbol) with a property or value. Here is an example of a property list:

(pine cones numbers (1 2 3) color "blue")

This property list associates pine with cones, numbers with (1 2 3), and color with "blue". The property names and values can be any Lisp objects, but the names are usually symbols (as they are in this example).

Property lists are used in several contexts. For instance, the function put-text-property takes an argument which is a property list, specifying text properties and associated values which are to be applied to text in a string or buffer. @xref{Text Properties}.

Another prominent use of property lists is for storing symbol properties. Every symbol possesses a list of properties, used to record miscellaneous information about the symbol; these properties are stored in the form of a property list. @xref{Symbol Properties}.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.9.1 Property Lists and Association Lists

Association lists (see section Association Lists) are very similar to property lists. In contrast to association lists, the order of the pairs in the property list is not significant, since the property names must be distinct.

Property lists are better than association lists for attaching information to various Lisp function names or variables. If your program keeps all such information in one association list, it will typically need to search that entire list each time it checks for an association for a particular Lisp function name or variable, which could be slow. By contrast, if you keep the same information in the property lists of the function names or variables themselves, each search will scan only the length of one property list, which is usually short. This is why the documentation for a variable is recorded in a property named variable-documentation. The byte compiler likewise uses properties to record those functions needing special treatment.

However, association lists have their own advantages. Depending on your application, it may be faster to add an association to the front of an association list than to update a property. All properties for a symbol are stored in the same property list, so there is a possibility of a conflict between different uses of a property name. (For this reason, it is a good idea to choose property names that are probably unique, such as by beginning the property name with the program’s usual name-prefix for variables and functions.) An association list may be used like a stack where associations are pushed on the front of the list and later discarded; this is not possible with a property list.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.9.2 Property Lists Outside Symbols

The following functions can be used to manipulate property lists. They all compare property names using eq.

Function: plist-get plist property

This returns the value of the property property stored in the property list plist. It accepts a malformed plist argument. If property is not found in the plist, it returns nil. For example,

(plist-get '(foo 4) 'foo)
     ⇒ 4
(plist-get '(foo 4 bad) 'foo)
     ⇒ 4
(plist-get '(foo 4 bad) 'bad)
     ⇒ nil
(plist-get '(foo 4 bad) 'bar)
     ⇒ nil
Function: plist-put plist property value

This stores value as the value of the property property in the property list plist. It may modify plist destructively, or it may construct a new list structure without altering the old. The function returns the modified property list, so you can store that back in the place where you got plist. For example,

(setq my-plist '(bar t foo 4))
     ⇒ (bar t foo 4)
(setq my-plist (plist-put my-plist 'foo 69))
     ⇒ (bar t foo 69)
(setq my-plist (plist-put my-plist 'quux '(a)))
     ⇒ (bar t foo 69 quux (a))
Function: lax-plist-get plist property

Like plist-get except that it compares properties using equal instead of eq.

Function: lax-plist-put plist property value

Like plist-put except that it compares properties using equal instead of eq.

Function: plist-member plist property

This returns non-nil if plist contains the given property. Unlike plist-get, this allows you to distinguish between a missing property and a property with the value nil. The value is actually the tail of plist whose car is property.


[Top] [Contents] [Index] [ ? ]

Footnotes

(1)

There is no strictly equivalent way to add an element to the end of a list. You can use (append listname (list newelt)), which creates a whole new list by copying listname and adding newelt to its end. Or you can use (nconc listname (list newelt)), which modifies listname by following all the CDRs and then replacing the terminating nil. Compare this to adding an element to the beginning of a list with cons, which neither copies nor modifies the list.

(2)

This usage of “key” is not related to the term “key sequence”; it means a value used to look up an item in a table. In this case, the table is the alist, and the alist associations are the items.


[Top] [Contents] [Index] [ ? ]

About This Document

This document was generated on May 30, 2018 using texi2html.

The buttons in the navigation panels have the following meaning:

Button Name Go to From 1.2.3 go to
[ << ] FastBack Beginning of this chapter or previous chapter 1
[ < ] Back Previous section in reading order 1.2.2
[ Up ] Up Up section 1.2
[ > ] Forward Next section in reading order 1.2.4
[ >> ] FastForward Next chapter 2
[Top] Top Cover (top) of document  
[Contents] Contents Table of contents  
[Index] Index Index  
[ ? ] About About (help)  

where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:


This document was generated on May 30, 2018 using texi2html.