A list is basically a list of things:
(1 2 3 4)
We call the head of the list the car and the tail of the list (which is everything except the head) is called the cdr (pronounced “coulder”).
Let’s try a few examples with the list (a b c d). Find the car and the cdr, and then find the cdr of the cdr. (That will be (cdr (cdr (a b c d))), because cdr is just the same as any other prefix operator and follows the same rules, that is, we execute the most deeply nested on first.
Now try to get the cdr of the list (+ 1 2).
Hm, that seemed to go horribly wrong, didn’t it? Let’s go through it step by step:
(cdr (+ 1 2))
Because we execute the most deeply nested thing first, we evaluate (+ 1 2) which gives us this:
But 3 doesn’t have a tail, so the cdr is the empty list. Some implementations of Lisp will cause an error here because cdr is really only defined to operate on lists and we’re giving it what’s called an atom, which is basically the smallest unit in Lisp and something that doesn’t have a tail.
Similarly, what would happen if we had an operator called a for the earlier examples? Wouldn’t that cause the same sort of problem? It turns out that this is a common issue with Lisp, so it is possible to precede a list with a single quote (‘) to tell Lisp not to evaluate the list, even though it may be the most deeply nested thing in brackets.
Try evaluating this:
(cdr '(+ 1 2))
So we now have very subtle distinction between an expression (+ 1 2) and a list ‘(+ 1 2). Play around with them for a while and when you’re satisfied with how to manipulate them, let’s look at how we can use them to evaluate arbitrarily long expressions like we saw in the last section which introduced Functional Programming..