#### LISP : consp or listp ?

##### December 19, 2014

I recently began my long-awaited journey(or a pilgrimage to be honest!) towards the wonderful ‘land’ of LISP. And along the path, I started understanding the so-called predicates.1

I also began to learn about the predicates that are built-in, such as oddp, evenp, atomp, etc.

Then, I stumbled across what seemed like 2 different predicates that are ‘equivalent’, but which I realized are not exactly so.

So, I want to discuss briefly about the subtle difference between these 2 predicates viz., consp & listp in LISP.

Beginning LISPers are bound to be a bit confused by the existence of the predicates consp & listp. One seems to check if its argument is a cons-cell (Please see the Notes section at the bottom for more info or intro to cons-cell ) while the other tells if the argument represents a list. After all, isn’t every list a cons-cell? Or so, the thought process goes…leading one to believe (erroneously!) that these predicates are interchangeable.

### Isn’t every list a cons-cell?

Seems so, but it is not the case.

### So, are consp & listp not the same?

Short answer : They are not the same. There’s a subtle difference due to one chief exception.

Note that NIL is a list, also denoted by (). But it is not a cons-cell.

There! I’m done!

I hope you ‘got’ the subtle difference between consp & listp predicates in LISP.

It should now be clear what the following code snippets produce:


(consp NIL)



Output: NIL

where as,


(listp NIL)



Output: T

## Q & A

What is a cons-cell?

A cons-cell, in Java-parlance, is like the node struct/class of a linked-list. Like so,

class Node<T> {
T data;
Node next;
}


Note that the data field above is also a pointer/reference to some location in memory, just like next points to the ‘next’ node of the list. Thus a cons-cell is essentially a pair of pointers used to represent lists in LISP. In a singly-linked-list the last node has next set to null.

LISP uses this cons-cell concept to represent lists. For more information on cons-cells, you can refer to this introductory article. Enjoy!

If a predicate always returns Yes/No or True/False why does the output here show T & NIL ?

Good observation! You will understand this when you learn the basics of LISP.

• LISP denotes the boolean value of “true” by the symbol T, and uses NIL for “false”. To make it clear, No, LISP does not use F for “false”, as one might expect!
• Note that NIL is also used to represent an empty list i.e., (). Thus, the expression (equalp NIL ()) evaluates to T (= true)

Update: Thanks to Jean-Philippe Paradis of HexstreamSoft for pointing out another observation worth sharing–that NIL sometimes exhibits cons-like behaviour too, in that both (car NIL) and (cdr NIL) return NIL just like it would if you had used (car ()) and (cdr ()). Try it out!

### Footnotes

1. Predicates (in LISP) are nothing but functions that answer Yes/No type of questions. By convention LISP predicate-names end in the letter p (stands for ‘predicate’!) ↩︎