16

Most of my Lisp experience comes from Elisp. As such, I find myself writing Lisp only on occasion. By the time I come back to it, I often forget the difference between car and cdr and need to reference the docs to jog my memory.

What kinds of clever mnemonics do you use to remember the difference between Lisp functions that have naming roots stemming from 1954 era computer architectures (car, cdr, cadr, caar, cddr, etc)?

In addition, why haven't the well-named aliases of first and rest gained more traction as idiomatic alternatives for car and cdr?

Update: I know the actual definitions of car and cdr and how they should be pronounced. Mnemonics only please.

Full Disclosure: This question isn't entirely for me. It's to help other Lisp newcomers get past some of the initial hurdles.

Ryan McGeary
  • 235,892
  • 13
  • 95
  • 104
  • 2
    Just in case -- if you're reading them as c.a.r and c.d.r they'll be confusing. They're usually pronounced differently, as "car" and "kooder", roughly. – Eli Barzilay Aug 20 '09 at 03:12
  • A Lisp style guide I read a while back recommended `first` and friends, `rest`, and `nth` for list manipulation and `c[ad]+r` for trees. – Jordan Wade Jun 29 '11 at 01:13

12 Answers12

15

Of the two words car and cdr, car is the one I've heard first.

Eisen
  • 450
  • 4
  • 11
12

This is really lame, but since no one else has suggested anything...

car to me is the thing that drives, so it's first. cdr is the caboose; it comes after.

See, I told you it was lame.

kajaco
  • 2,547
  • 3
  • 24
  • 33
11

I have no mnemonics for remembering car/cdr, though they are alphabetical (a comes before d, thus car is first).

As far as why did they stick (over things like first and rest)? A big part is probably just momentum, but the other is what you already wrote. You can easily write composition functions for them:

(caadar ...) -> (car (car (cdr (car ...))))
Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
  • 2
    I think in the SICP videos, they also mention another non-obvious advantage: you can say "`cadaddr`" over the phone, and it is immediately understandable, unambiguous and very efficient. If you were instead saying "`car` of `cdr` of `car` of `cdr` of `cdr`" or even "`first` of `rest` of `first` of `rest` of `rest`", that would be much slower, much harder to understand correctly, and would probably require the other person writing it down synchronously while you are saying it. OTOH, there is nothing stopping you from *saying* `caadar` and the other person *writing* `(car (car (cdr (car …))))` – Jörg W Mittag Aug 20 '09 at 09:20
  • *aargh* I screwed up. I meant: there is nothing stopping you from *saying* `caadar` and the other person *writing* `(head (head (tail (head …))))` or `(first (first (rest (first …))))` – Jörg W Mittag Aug 20 '09 at 09:22
  • Thanks. Alphabetical is what I've considered too. – Ryan McGeary Aug 20 '09 at 10:34
  • 6
    If somebody said "cadaddr" to me over the telephone, I'd worry that they were choking on something. – Pillsy Aug 20 '09 at 15:54
  • I don't think that names like caddadar are a really good thing. I think that they are only used when lists are used to emulate other data structures - which is wrong. – dmitry_vk Aug 23 '09 at 13:39
  • @dmitry-vk Lisp is all about lists, it's pretty natural to use them as data structures. Using structs, in C/C++ (for example), seems pretty awkward to me (though I've been using them for 15 years). To each his own. – Trey Jackson Aug 23 '09 at 23:55
  • @TreyJackson Sure, the underlying structure can be a list, but in Common Lisp, if you want that, you'd do `(defstruct (person (:type list)) name age)` so that `(make-person :name "John Doe" :age 32) => ("John Doe" 32)` and `(person-age '("John Doe" 32)) => 32`. There's no need to use cadr instead of person-age. Meaningful abstraction is very important. – Joshua Taylor Apr 28 '15 at 20:36
  • @JoshuaTaylor Yes, abstraction is meaningful. You can make a person a raw list, and hide that implementation via hand-crafted access functions (like `person-age`). Or make a struct as you did, or craft an object system out of lambdas. The question isn't really about abstraction... – Trey Jackson Apr 29 '15 at 22:14
  • 1
    @TreyJackson My point was that **(defstruct (person (:type list)) ...)** *doesn't* use a structure type, but uses a list, and creates those **person-age**, etc., functions automatically. The question's not about abstraction, but your earlier comment said *"Lisp is all about lists, it's pretty natural to use them as data structures."* That's true, but when using lists as the *implementation* for a data structure, it's still good practice to define the abstraction properly, even if the methods are just thin wrappers for **car**, **cadr**, etc., and CL provides lots of tools for doing that. – Joshua Taylor Apr 29 '15 at 22:19
5

They stand for "Contents of the Address Register" and "Contents of the Decrement Register", terms derived from the IBM 704 machine architecture. Not that that helps you much!

See http://www.iwriteiam.nl/HaCAR_CDR.html

Jim Ferrans
  • 30,582
  • 12
  • 56
  • 83
2

I don't have mnemonics for car and cdr. I mean, there are only the two of them, and if you use Lisp at all, it seems to me you would Just Know. (Hell, I don't even use Lisp and I can remember.)

Besides the convenient composition, car and cdr have the following advantages over first and rest: (1) shorter, (2) same length as each other, (3) they appeared earlier.

John Y
  • 14,123
  • 2
  • 48
  • 72
1

"car" and "cdr", for me at least, are things you just learn, like the sounds for the words "left" and "right".

"first" and "rest" are only mnemonic if the object being deconstructed is a list. If it is an actual cons (i.e., a dotted pair), they don't help.

They stuck because there WASN'T anything else, almost fifty years ago, when LISP was first developed. All the articles, all the books, all the code used CAR and CDR, and everyone got used to them.

John R. Strohm
  • 7,547
  • 2
  • 28
  • 33
1

If you don't care about being idiomatic, use first and rest. car and cdr do have the advantage of being able to be composed into combinations like caddr cddr and so on, if you find that useful.

Otherwise, car is first and it's alphabetically first of the two.

justinhj
  • 11,147
  • 11
  • 58
  • 104
1

The Mnemonics that I use are:

CAR - Copy Alpha position and Return

CDR - Copy Dendrite (tree part - without the root) and Return

I am newly getting back to trying Lisp, but hopefully this fits.

I tend to think of the starting of a list as the alpha or the root position.

If the first position is the root, and I am used to seeing binary trees (which can be represented as a list), then a word related to trees would seem to be in order. Dendrite has the right beginning letter and seems to fit. It represents the last of the tree without the root.

Another take is from Robert Smith:

CAR - "Cell’s Anterior Region"

CDR - "Cell’s Dorsal Region"

"We can get the second part of the cell. Let’s call this part the dorsal region (why not posterior? The meaning of dorsal makes more sense with lists, in that the dorsal region of a list [1,2,3] is the part “near the end”, [2,3], whereas the posterior would just be 3)."

from Lisp has too many parentheses… (…or so they say!) By Robert Smith, on November 7th, 2010

Symbo1ics

I know this bears no relation to what the acronyms originally were, but even Steve Russell said:

"Because of an unfortunate temporary lapse of inspiration, we couldn't think of any other names for the 2 pointers in a list node than "address" and "decrement", so we called the functions CAR for "Contents of Address of Register" and CDR for "Contents of Decrement of Register".

After several months and giving a few classes in LISP, we realized that "first" and "rest" were better names, and we (John McCarthy, I and some of the rest of the AI Project) tried to get people to use them instead.

Alas, it was too late! We couldn't make it stick at all. So we have CAR and CDR."

The origin of CAR and CDR in LISP

1

You could avoid the problem by using first and rest instead.

PuercoPop
  • 6,707
  • 4
  • 30
  • 40
1

The book "A gentle Introduction to Lisp" does a great job of explaining really big ones like

CADDDAADDR

Start from the right side going left(ADDDAADD), so the above is(where -> is "then"): CDR->CDR->CAR->CAR->CDR->CDR->CDR->CAR.

The reason why CAR & CDR are preffered over firt and rest is(I think) because they can be chained to form functions such as the above.

automaton
  • 1,091
  • 1
  • 9
  • 23
0

I actually seldom see car and cdr, much more often I see first and rest in the code. So I can't agree that those named haven't gained traction.

dmitry_vk
  • 4,399
  • 18
  • 21
0

The full reference to the book above is ‘Common Lisp A Gentle Introduction to Symbolic Computation’ By David S. Touretzky. It’s available (Nov 2019) from: https://www.cs.cmu.edu/~dst/LispBook/book.pdf

My (very late) suggestion to mnemonics for CAR & CDR is:

Think of the first element of a list obtained by CAR as represented by A but in one of the fonts which looks like a mirror image of D. This character points to (ie the curved surface of the character points to) the ‘C’omentmence of the list. Then think of the rest of the list obtained by CDR as represented by D. The D points to the ‘R’est or remainder at the back of the list.

Because of restrictions on fonts here I will use ‘<|’ to denote the A in the font which is a reflection of ‘D’ about the vertical axis. For symmetry I will denote the D character by ‘|>’.

Regard R = C^-1. Then CARCDR=CAC^-1CDR=CADR etc are represented by C<|RC|>R = C<||>R etc.