Do you have a mnemonic for remembering the meaning of car and cdr?
Asked Answered
W

12

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.

Walden answered 20/8, 2009 at 2:40 Comment(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.Striking
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.Jeremyjerez
E
16

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

Expression answered 25/8, 2009 at 12:30 Comment(0)
F
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.

Furring answered 20/8, 2009 at 3:35 Comment(1)
At least you suggested something. That's more of what I was looking for.Walden
K
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 ...))))
Krispin answered 20/8, 2009 at 2:44 Comment(9)
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 …))))Laky
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 …))))Laky
Thanks. Alphabetical is what I've considered too.Walden
If somebody said "cadaddr" to me over the telephone, I'd worry that they were choking on something.Condensate
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.Registration
@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.Krispin
@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.Eupatorium
@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...Krispin
@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.Eupatorium
W
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

Weingarten answered 20/8, 2009 at 2:53 Comment(2)
This isn't really a mnemonic because there's nothing mnemonic about address=first and decrement=last.Bipod
"Contents of Address Register" is at least a bit mnemonic,Fettle
B
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.

Becerra answered 20/8, 2009 at 2:51 Comment(0)
L
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.

Lafayette answered 20/8, 2009 at 2:52 Comment(1)
In Elisp first and rest are only aliases for car and cdr defined in cl package.Shelleyshellfire
I
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.

Inellineloquent answered 22/8, 2009 at 15:43 Comment(0)
G
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

Galloglass answered 30/11, 2013 at 3:20 Comment(1)
Better yet Copy Alpha Return, Copy Dendrite ReturnGalloglass
G
1

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

Gratulant answered 30/11, 2013 at 4:52 Comment(0)
G
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.

Gonsalve answered 17/7, 2014 at 8:48 Comment(0)
R
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.

Registration answered 20/8, 2009 at 4:9 Comment(2)
Clojure doesn't even have car and cdr anymore.Laky
Interesting. Good info. car and cdr do appear more prevalent in the Elisp community though. Probably due to all the old packages.Walden
M
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.

Malign answered 22/11, 2019 at 23:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.