
The Origin of CAR and CDR in Lisp (2005) - tosh
http://www.iwriteiam.nl/HaCAR_CDR.html
======
montrose
I've programmed a lot in various dialects of Lisp, and I like car and cdr.
Using names like first and rest might make a language more attractive to new
users, but there is something to be said for designing at least some languages
for experienced users rather than new ones, and it doesn't take much
experience (a week?) for the words car and cdr to mean the left and right
halves of a cons cell to you. And once they do, they're better than first and
rest, because

1\. They're shorter.

2\. They're the same length, which means in practice that a _lot_ of code
lines up in a way that's easier to read.

3\. They look similar to one another, which telegraphs that they're part of
the same set of list access tools. Code that munges lists looks like it munges
lists.

4\. Their meaning is precise: car just takes the first element of a list.
Whereas something called first might reasonably be expected to also give you
the first element of a vector, or a string.

5\. When you're operating on lists as trees, the names first and rest are
actively misleading. The car and cdr are the left and right subtrees, not the
first and rest of something.

~~~
pcwalton
> Using names like first and rest might make a language more attractive to new
> users, but there is something to be said for designing at least some
> languages for experienced users rather than new ones, and it doesn't take
> much experience (a week?) for the words car and cdr to mean the left and
> right halves of a cons cell to you.

When designing Rust, we quickly learned that the idea of picking short names
to satisfy experienced users at the cost of new ones doesn't work in practice.
Too many users complain that the language is too hard to learn and ugly; it
took _years_ for "Rust is so ugly, it's the resurrection of Perl" to finally
stop being a meme. If we had stuck to our guns with short keywords, Rust might
have been dead by now.

Choosing unfamiliar syntax such as car and cdr worked for Lisp because, during
the '70s, Lisp as a whole was novel enough to gain a sizable following. It
doesn't work today. (And note that, even then, Lisp lost a lot of potential
users due to the S-expression based syntax.) I'm firmly in the "first" and
"rest" camp, because history has shown that readable languages much more
frequently go on to be successful than languages with idiosyncratic syntactic
choices.

~~~
brudgers
A sometimes overlooked feature of car and cdr is composibility, e.g. caadr,
cddr, etc. Though I don't think it is useful to go ten deep as the spec
requires if people are reading the code, deep composition may make some sense
for machine written code.

Car and cdr also reflect a sometimes misunderstood aspect of Lisp: lists are
an abstraction for sequential memory addresses in the Von Neumann
architecture. The sense in which Lisp was designed for functional programming
only goes about as far as one can _pragmatically_ throw the lambda calculus.
Practically and historically speaking Lisp programming was only slightly less
about mutation than any other language. Design for current state of the art
(in the 70's, 80's and 90's) is why Common Lisp has destructive versions of
everything useful. Heck, Lisp even mutates its source code.

At the end of the work week, the major language design choice is not so much
between car/cdr and first/rest it's between the language having a concept of
first/rest and not having one: e.g. Python, Javscript, Go[?], C, and so on.

Finally, car/cdr is not that much worse than first/rest for all those
programmers who are not fluent in English. Naming things is hard mostly
because names are arbitrary. Both car/cdr and first/rest require the harder
concept of fixed order data...and next makes more sense than first if one
applies the stream abstraction.

~~~
pcwalton
> A sometimes overlooked feature of car and cdr is composibility, e.g. caadr,
> cddr, etc. Though I don't think it is useful to go ten deep as the spec
> requires if people are reading the code, deep composition may make some
> sense for machine written code.

The 90% case here is "second", "third", etc. For more exotic cases, surely
there are other naming conventions that would be more readable. You could use
"h" and "t" for head and tail, or "l" and "r" for left and right...

> At the end of the work week, the major language design choice is not so much
> between car/cdr and first/rest it's between the language having a concept of
> first/rest and not having one: e.g. Python, Javscript, Go[?], C, and so on.

The "concept of first/rest" is just the concept of pairs, which are a special
case of tuples, which Python and JS certainly have.

~~~
brudgers
Erlang uses a {H|T} pattern matching convention in lieu of language keywords.
For what it is worth (limit x | x -> 0), I think Erlang is an exceptionally
elegant piece of engineering as engineering. But it's not the 90% use case.
Then again, neither is Lisp, ML, or Rust. The 90% use case these days is
Javascript. Which I would hesitate to associate with the phrase "elegant piece
of engineering" without an "in" prefix.

Python and Javascript may have pairs. They just live at the bottom of a Turing
Tarpit.

~~~
macintux
I rarely used Python before the last few months, but I've already stumbled
upon a great tragedy in the 3.x migration.

Although few know it, and fewer use it, Python 2.x allowed tuples to be
unpacked in function heads, like Erlang. Since my last job was 100% Erlang, I
stumbled into using it without knowing any better.

I decided a couple of months later that since it was a new project, I really
should convert to Python 3, whereupon I discovered that feature had been
removed due to parsing complexity and "because no one uses it."

Sigh.

~~~
ethagnawl
This feature is still good to know about for use on legacy projects. Thanks
for sharing!

~~~
macintux
With Python 2 due to be EOL'd in a couple of years, I'm not sure I should feel
good about encouraging more use of it!

------
kazinator
CAR and CDR can possibly work very well in Japanese, I have discovered:

[https://www.reddit.com/r/lisp_ja/comments/78i4ws/](https://www.reddit.com/r/lisp_ja/comments/78i4ws/)

CAR -> karu -> 借る (to borrow)

CDR -> kudaru -> 下る (to descend)

"Borrow" the first value/reference, or "descend" to the next cell.

The usual readings are カー/クダー (kaa/kudaa); these have to be altered to have a
final ル (ru) rather than "aa".

The world isn't all English; someone's Anglo-centric quibble about how "cdr"
doesn't mean anything means nothing to someone speaking another language.

By the way, descend starts with D:

C(Ante-, Ascend)R

C(Descend)R

I myself seem to be carrying the vestiges of a poorly articulated,
subconscious connection to _anno domini_ (A.D.).

~~~
Turing_Machine
"The world isn't all English"

But the history of computing largely _is_ (not totally of course, but
largely).

If we were discussing sushi, or katanas, or bushido, or netsuke, would you
complain about the language being "Japanese-centric"?

If we were discussing grand opera (or, for that matter, having a technical
discussion of almost any kind of music), would you complain about the language
being "Italian-centric"?

~~~
kazinator
> _would you complain_

I'm not complaining that programming languages use words based on English; my
point is about English speakers having bikeshedding quibbles about those words
that don't mean anything to non-English-speakers.

Suppose some Italian, due to some Italian reasons, doesn't like something
about the music term _dal segno_ or any other term. Why would I care, know
what I mean.

~~~
Turing_Machine
Hmm... if you didn't care, why would you be reading the Italian quibble on a
history site written in Italian?

I mean, this was quite clearly a page about the history of the terms, right?

~~~
macintux
You're turning a note about a happy coincidence into something very personal.
Why?

------
DonHopkins
My favorite pair of silly LISP function names derived from CAR and CDR is
RPLACA and RPLACD.

Then of course there's the whole family of derived function names CAAR, CADR,
CDAR, CADADR, CADDDDR, CAAAAR, etc.

I wonder if that's what inspired Oliver Steele's "The Aargh Page":

[http://osteele.com/words/aargh](http://osteele.com/words/aargh)

[http://blog.osteele.com/2005/12/aargh/](http://blog.osteele.com/2005/12/aargh/)

Even sillier is LOGO's alternative to CAR and CDR: FIRST and BUTFIRST. As in
"BUTFIRST recursion" (giggle).

[https://en.wikipedia.org/wiki/List_of_MicroWorlds_Logo_comma...](https://en.wikipedia.org/wiki/List_of_MicroWorlds_Logo_commands#butfirst)

~~~
bitwize
> Even sillier is LOGO's alternative to CAR and CDR: FIRST and BUTFIRST. As in
> "BUTFIRST recursion" (giggle).

Frosh-level CS classes may introduce linked lists as classes in some OO
programming language -- often with the accessor methods getHead() and
getTail(). Huh huh huh huh huh.

You'd think CAR and CDR, being abstruse acronyms steeped in technical
language, would be immune from this sort of unfortunate double entendre, but
no: my AI class professor had an Eastern European accent and pronounced CDR
like "cooter".

------
lispm
> Clojure both Keeps and Breaks Tradition ... When Rich Hickey invented
> Clojure, he kept the gems of the LISP tradition, but jettison much of the
> muck. This is why Clojure has first instead of car and rest instead of cdr

Rich Hickey did not invent 'first' and 'rest'. LISP has those since the end of
the 70s in language standards.

From Common Lisp the Language, published 1984, chapter on lists:

    
    
        [Function]
        first list 
        second list 
        third list 
        fourth list 
        fifth list 
        sixth list 
        seventh list 
        eighth list 
        ninth list 
        tenth list
    
        These functions are sometimes convenient for
        accessing particular elements of a list. first
        is the same as car, second is the same as cadr,
        third is the same as caddr, and so on.
        Note that the ordinal numbering used here is
        one-origin, as opposed to the zero-origin
        numbering used by nth:
    
        (fifth x) == (nth 4 x)
    
        setf may be used with each of these functions
        to store into the indicated position of a list.
    
    
        [Function]
        rest list
    
        rest means the same as cdr but mnemonically
        complements first. setf may be used with rest
        to replace the cdr of a list with a new value.
    

Lisp Machine Lisp had FIRST, SECOND, ... REST1, ..., REST4 at least in 1979.
They are documented in the 2nd edition Lisp Machine manual.

~~~
Goladus
> Rich Hickey did not invent 'first' and 'rest'.

No one claimed Hickey invented first and rest, or even implied it. The point
is not that first and rest didn't exist, but that car and cdr DID. Clojure
deliberately left them out, as a design choice. For good or ill, that's the
point.

~~~
kbp
> No one claimed Hickey invented first and rest, or even implied it.

I think that saying "This is why Clojure has first instead of car and rest
instead of cdr" is a very odd way of saying "this is why Clojure doesn't have
car and cdr" if you don't mean to imply that it added first and rest.

I also think the originally linked article was rather poorly written and
seemed to put all of the focus on "car and cdr sure are weird names" without
examining that they are operations on cons cells, which Clojure doesn't have.
Clojure leaving out the names car and cdr doesn't really have anything to do
with those names; it left out the data structure they operate on. A language
without numbers proably wouldn't have a sqrt function either, but that has
little to do with the clarity of the name sqrt.

Discussing the differences and tradeoffs between how Lisps and Schemes all
represent lists compared to how Clojure does (and the tradeoffs with how
Clojure makes up for the other things that conses are used for in Lisp) might
have made for a more interesting point, but it would have been a harder one to
make than just pointing at two not immediately obvious symbol names (without
even mentioning that it did keep the equally archaic and unhelpful name "cons"
but changed its behaviour).

------
lisper
I use FST and RST (for FIRST and REST). I like them because they are short,
mnemonic, and can be composed like CAR and CDR, e.g. CADADDR = FRFRRST (though
I also believe that if you find yourself doing this you're almost certainly
doing something wrong).

~~~
thatswrong0
I think I prefer this as well. I think the importance of the mnemonic aspect
can’t be overstated.. even though I did get _used_ to CAR and CDR, I feel like
I was never immediately able to comprehend code that used them.. I had to
always perform a mental translation as if I were somewhat bad at French or
something and didn’t intuitively know the words.

It’s the same thing when I see test code that uses foo, bar, and baz as
variables / strings instead of something more memorable like apple, banana,
and cherry (or preferably something even more relevant to the code being
tested). I feel like I have to work harder to understand what the tests are
actually testing when I don’t have a good mental association with the
variables under test. I get that it’s something programmers just do, but I’m
really not a fan.

Maybe I’m an odd one though.

~~~
lisper
Another possibility is LHS and RHS for Left Hand Side and Right Hand Side (if
you want to emphasize the use of a cons cell as a pair rather than a linked
list).

~~~
kbp

        Date: 5 March 1980 08:54-EST
        From: Mark L. Miller <MILLER at MIT-AI>
        To:   Dave.Touretzky at CMU-10A, RWK
        cc:   KMP, HIC, BUG-LISP
        Re:   CAR and CDR
        
        Of course, you could rename them to, e.g., "LHS" and "RHS" for "Left Hand
        Side" and "Right Hand Side".  This would address the composition argument
        in favor of CAR and CDR: CADR -> LRHS (left-hand-side of right-hand-side),
        CDADADR -> RLRLRHS, and so on.   It's easy to provide these as macros.
        
        Later, you can explain that the original names are CAR and CDR, and isn't
        that silly, etc.
             Regards, Mark

~~~
kazinator
Shows you how resilient _car_ and _cdr_ have been against decades of
complaining and bikeshedding. That just reaffirms them.

~~~
lisper
I would accept that if Lisp were a runaway success, but it's not. It is very
nearly a dead language [1]. It is entirely possible that the unwillingness of
the Lisp community to give up in this obscure terminology in favor of
something more user friendly contributed to its demise.

[1] Look at e.g.
[https://madnight.github.io/githut/](https://madnight.github.io/githut/). The
most popular Lisp is Clojure, with a whopping 0.33% market share. Scheme and
Common Lisp don't even make it to the top 50.

~~~
kbp
> It is entirely possible that the unwillingness of the Lisp community to give
> up in this obscure terminology in favor of something more user friendly
> contributed to its demise.

What more-user-friendly terminology do you suggest?

~~~
lisper
Did you not read the upstream comments? FST and RST, or LHS and RHS depending
on whether the intent is to access the cons as a linked list or a pair.

~~~
kazinator
The D in CDR already corresponds to "dexter-" (right); we just need "L" for
"levo-":

CLR: cell levo/left reference.

CDR: cell dexter reference.

Organic chemistry uses these letters and prefixes. E.g. "L-glutamine",
"D-glucose" (a.k.a "dextrose").

The H and S (hand side) don't really contribute anything. (Yes, left is side
and a hand).

~~~
lisper
The whole point of this exercise (if it has a point at all) is not to come up
with acronyms with justifiable expansions, but to come up with something that
is less newbie-bostile. I'm not sure CLR/CDR fits the bill any better than
CAR/CDR. Part of the problem with CAR/CDR is that CAR is an English word that
means automobile, and people get a little hung up on that when they first see
it. Likewise, CLR is usually a shortened form of the word "clear". So I'm not
sure that CLR/CDR is any better than CAR/CDR. One of the advantages of LHS/RHS
and FST/RST is that none of those trigrams have any semantic baggage
associated with them other than their intended meaning.

~~~
kazinator
Why trigrams: (cl x) (cr x). cell left, cell right.

I don't think _car_ and _cdr_ are newbie hostile; they are rather troll-
fertile.

------
CalChris
The LISP people should have changed those names way back when. Not 79, 59.
McCarthy himself said then that _this representation is independent of the IBM
704 computer, or of any other electronic computer_ [1]. So why stick with the
names of 704 registers? Was there a purpose to this?

[1]
[https://courses.engr.illinois.edu/cs421/sp2012/project/mccar...](https://courses.engr.illinois.edu/cs421/sp2012/project/mccarthy-
lisp.pdf)

~~~
kbp
> So why stick with the names of 704 registers? Was there a purpose to this?

Are there other, much better names for the two parts of a pair? First and
second aren't great because they're not clear that it's a pair and not a
larger sequence (and the difference is important in Lisp; since lists are
built on conses, it would be odd to get the tail of a list by calling
'second'). The only other names I can think of would be something like left
and right, but I don't think those would be substantially easier to understand
for beginners than car and cdr.

When working with lists, many people prefer to use the functions first and
rest, which behave identically to car and cdr but are more meaningfully named
for list applications. They would be terrible names for the general cons-
handling functions, though.

~~~
currymj
Left and Right are really commonly used in this situation in ML-descended
languages. It’s not the worst thing.

I don’t mind car and cdr though. I kind of wish they were in Clojure tbh. It
feels nice to pay tribute to a half-century of computing history.

~~~
kbp
> Left and Right are really commonly used in this situation in ML-descended
> languages. It’s not the worst thing.

Are you talking about Either types? OCaml and Haskell at least both call car
and cdr fst and snd respectively, but they're rarely used.

As for left and right as names, I don't think they're any worse than car and
cdr, I just don't think they're substantially better.

------
dang
Url changed from [http://www.howardism.org/Technical/Clojure/origin-of-car-
and...](http://www.howardism.org/Technical/Clojure/origin-of-car-and-
cdr.html), which points to this, which is far more informative.

The link in that previous article is a little weird, since the text says "lost
in the mists of time". That of course isn't true; if you read through to Steve
Russell's explanation the mists clear up quickly.

------
flavio81
> _When Rich Hickey invented Clojure, he kept the gems of the LISP tradition,
> but jettison much of the muck._

That's the myth that Hickey loves to pass around, but is a totally baseless
claim.

> _This is why Clojure has first instead of car and rest instead of cdr._

Just as Common Lisp also has "first" and "rest" if one feels like using them
instead of "car" and "cdr".

------
soegaard
These days `first` and `rest` is used in Racket to indicate the input is a
list. Since `cons` can build non-lists, the traditional `car` and `cdr` are
used when working on trees.

Well - actually most Racket programmers use pattern matching when working on
trees.

Note that `first` throws an error in modern Racket when used on a non-list.

~~~
TheHTMLCoder
Get best conversion services at one place. We convert your designed PSDs to
HTML, HTML5, WordPress, WooCommerce, Magento, BuddyPress Themes. All our code
is hand-written, W3C Validated, Google Page-Load Optimized, Cross-Browser,
Clean & Commented. Details Here:
[http://www.thehtmlcoder.com/](http://www.thehtmlcoder.com/)

------
kazinator
TXR is a new Lisp dialect (project started in 2009) with real conses, _car_
and _cdr_. Plus some little embellishments in that area:

    
    
      This is the TXR Lisp interactive listener of TXR 188.
      Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for cheatsheet.
      1> (defstruct kar nil
           kar kdr
           (:method car (me) me.kar)
           (:method cdr (me) me.kdr))
      #<struct-type kar>
      2> (new kar kar 1 kdr 2)
      #S(kar kar 1 kdr 2)
      3> (car *2)
      1
      4> (cdr *2)
      2
    

:)

TXR Lisp has the _cadr_ accessors down to depth five ( _caar_ to _cddddr_ ).

This stuff is not "muck" to be jettisoned; it is part of the essence without
which we don't have Lisp.

------
timonoko
For nonenglish speaker KAR and KUDER were of course as good as any other
foreign symbols. First derivatives were KA-AR, KADER and KUD-DER (for CAAR,
CADR and CDDR).

------
sulam
TIL that the guy who invented these names, Steve Russell, was the guy who 9
years later mentored Bill Gates and Paul Allen on the PDP-10. History's cool.

~~~
kbp
That is cool, but I was wondering if you had a citation for Steve Russell
coining the names? I don't believe that's true.

~~~
sulam
Scroll down on the parent. He talks about the 704 instructions and not having
a better idea at the time.

~~~
kbp
Oh, sorry, the linked story used to be different. I hadn't noticed it was
changed.

------
PyComfy
i don't like first/rest; car and cdr are about pairs, not about lists which is
an implicit type (like strings in C).

------
kruhft
Contents of Address Register and Contents of Decriment Register.

Two instructions on the original IBM that the first LISP imterpreter was
written on.

I heard.

~~~
aap_
Why don't you read the linked text to learn that you're wrong? There is no
address register and no decrement register on the IBM 704, and no instructions
CAR and CDR either. An instruction had an address _part_ and a decrement
_part_. The LISP functions CAR and CDR return the the address part and
decrement part of a given register and both were implemented with more than
one machine instruction.

~~~
kruhft
So why did I remember it the that way?

It must be part of history somehow, I didn't make it up.

