# Is '(a . b) really a list?

I'm really confused with the `.` notation. Is `'(a . b)` a list?

`(listp '(a . b))` returns `t` but when I want to know its length `(length '(a . b))` gives an error `Wrong type argument: listp, b`. The same is for other functions as `nth,mapcar` etc. they all give the same error

Is there any function which can I distinguish between `'(a b)` and `'(a . b)`?

Context: I encountered this problem when I wanted to implement recursive version of `mapcar`. Here is my implementation

``````(defun true-listp (object)
"Return non-`nil' if OBJECT is a true list."
(and (listp object)  (null (cdr (last object)))))

(defun recursive-mapcar (func list)
"Evaluates func on elements of the list, then on elements of elements  of the list and so forth."
(let ((output nil))
(flet ((comp (a b) nil)
(call-fun-and-save (x) (add-to-list 'output (funcall func x) t 'comp))
(recursion (l)
(mapcar
(lambda (x)
(call-fun-and-save x)
(if (and (true-listp x))  ;; HERE I use true-listp, testing for list or cons is not sufficient
(recursion x)))
l)))
(recursion list))
output))
``````

I use this to extract all specific tags from parsed html. Example of `html` to parse

``````;; buffer 'html'
<html>
<body>
<table style="width:100%">
<tr>  <td>Jill</td>  <td>Smith</td>  <td>50</td> </tr>
<tr>  <td>Eve</td>   <td>Jackson</td>   <td>94</td> </tr>
</table>
</body>
</html>
``````

Then I extract all `<td>` as

``````(with-current-buffer (get-buffer "html")
(let ((data (libxml-parse-html-region (point-max) (point-min))))

;; gat only <td> tags
(-non-nil
(recursive-mapcar
(lambda(x) (and (consp x) (equal 'td (car x)) x))
data))
data
)
)
``````
• There is no `true-list-p` in Elisp simply because it hasn't been found to be useful enough to provide it. Indeed, I can't remember the last time I wanted to test if a list was proper, so maybe if you give us a bit more info about your use-case we can help you solve your problem in another way. – Stefan Jun 1 '16 at 13:59
• @Stefan In short, I want to implement recursive mapcar, I evaluates given function on elements of a given list, then on elements of elements of the list, then on elements of elements of elements of the list and so forth. So I need to know if an element is a true list or not. – tom Jun 1 '16 at 17:34
• It is usefull for example when I parse html with `libxml-parse-html-region` and I want to extract all `<td>` tags. – tom Jun 1 '16 at 17:36
• Can you show us a concrete example where you might get either a proper list, or an improper list, or something else, and where you need to handle the 3 cases differently? In most cases I've had to deal with, the "proper" and "improper" cases can be shared until we get to the actual improper tail, so you again don't need to test if it's proper or not: just test if it's `consp` instead. – Stefan Jun 2 '16 at 1:05
• libxml doesn't just return lists-of-lists. Each list representing an XML element has the form (symbol attributes . contents). So your code shouldn't apply mapcar recursively over all elements of the lists, only over the `cddr` of the list (to skip the element name and the attributes). Once you do that, you should find that all lists are proper and your problem will disappear. It will also fix a bug in your code where you may confuse a `td` attribute for a `td` element. – Stefan Jun 2 '16 at 18:18

It satisfies `listp`, so in that sense it is a list. `listp` just tests whether something is a cons or `nil` (aka `()`), on the one hand, or something else, on the other hand.

A proper list or true list (or a list that is not a dotted list or a circular list) is something that is `listp` and also has `nil` as its last cdr. That is, a list `XS` is proper if `(cdr (last XS))` is `nil` (and that is how you distinguish it).

Another way to put this is that a proper list has a proper list as its cdr. This is the way the data type (proper) List is defined in typed languages. It is a generic and recursive type definition: The generic part says that the first argument to the non-empty list constructor (often called `cons`, BTW) can be of any type. The recursive part says that its second argument is an instance of type (proper) List.

Yes, you check whether a given `listp` is a proper list using `(cdr (last XS))` is `nil`. In order to check whether the cdr of the critter is itself a proper list, you must continue checking its cdr, down to the end - the last cons, to see whether it is `nil`. You could define a predicate for this as follows, if you wanted to:

``````(defun true-listp (object)
"Return non-`nil' if OBJECT is a true list."
(and (listp object)  (null (cdr (last object)))))
``````

Although a circular list has no end, Emacs (starting with Emacs 24) is smart enough to check `last` correctly, so this code works even for a circular list (but only for Emacs 24.1 and later; for earlier versions you get an "infinite" recursion until stack overflow).

You can use functions such as `length` only on proper lists and other sequences. See also function `safe-length`.

See the Elisp manual, node Cons Cells.

As for notation, `(a b)` is just syntactic sugar for `(a . (b . nil))` -- see the Elisp manual, node Dotted Pair Notation

• What is the best practice to check for proper list? Checking if `(cdr (last XS))` is `nil` is crumblesome. Isn't there a function like `proper-list-p` ? – tom May 30 '16 at 10:54
• @tom: That, or something equivalent, is necessary - you must check the last cons cell. I've added more about this in the answer now. – Drew May 30 '16 at 13:43
• @Drew I would change the body of the function to `(unless (atom x) (not (cdr (last x))))` So you can even call `(true-list-p "text")` and get `nil` not an error. – tom May 30 '16 at 14:12
• @tom: Right; thx. Actually, it should be tested first to ensure it is a cons or `nil` (i.e., `listp`). (Also, FWIW, I don't use `unless` or `when` for their return value. I use `and`, `or`, and `if` for that.) – Drew May 30 '16 at 15:18