Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

CAR and CDR can be used to do things other than take lists apart. That's why they have those names.


They have those names because they relate to the registers on the original implementation machine.

time to move on.


John MacCarthy knew that not every computer is an IBM 704, and that users want higher level languages developed on one system to be usable on another.

He stuck with those names because there is no problem with them. They are hard to improve upon in a ways that are only subjectively better while being objectively worse. For instance first and rest are subjectively better for some uses and for some people, while being objectively worse (wastefuly longer for something commonly needed, and falsely associating when the objects aren't used as linear lists). Thus at best we can adopt them as synonyms (and we have).

The were inspired by FLPL ("Fortran List Processing Language"): a Fortran library for list manipulation. FLPL, for mysterious reasons, used pretty horrible names like XCARF and XCDRF. MacCarthy must have been thinking about good naming, because he thankfully dropped the X...F.

I think if they were called something else, I'd still want them to be three-letter identifiers (not just one or two, to avoid clashes) which differ only in the middle letter, so a pattern similar to cadr, cddr ... is possible.

In quantum mechanics there is a <a|b> notation where a is the "bra" and b is the "ket". That doesn't have the right property for cadr, and would be the the target of bra and fig leaf jokes.

In TAOCP, I seem to recall, Knuth calls the fields of binary list cells alink and blink. Not sure if he wants us to pronounce that as blink (of an eye) or bee link. The names are a bit long, but aaabalink is possible. If shortened to alk and blk, that would work.

If both middle letters were vowels, that would be more conducive for the words being pronounceable. That restricts us to aiueo and y. The car using a high vowel is nice, so let's go with i.

How about: dit and dot? The dot is in the ... dot position!

One problem is that cdar becomes doit, which looks like "do it".


"FLPL, for mysterious reasons, used pretty horrible names like XCARF and XCDRF"

It's not mysterious at all, these were also named after the 704 register scheme.

Your argument that MacCarthy et al couldn't think of accurate names may be valid (naming is one of the hardest things, after all), but there are certainly 'better' names, so more likely these just stuck after the initial implementations.

"so a pattern similar to cadr, cddr ... is possible."

Honestly, these are abominations. Remember the point of high level languages etc is not just so you can write code as fast as possible, but that someone else (maybe your future self) can read and understand it easily.


> It's not mysterious at all

By that remark, I'm referring to the X...F dirt in XCARF, not to the CAR infix that we all understand. Why the authors of FLPL saddled the identifiers with that is puzzling. (Extract the content of the address part of the register function? Why?)

Regarding that "R" in car, though standing for "register", refers to a register in memory; Aontent of the Address part of the Register cell.

A piece of memory can be called a register today (e.g. virtual machines have registers that are actually in memory, and some processors have had memory mapped registers like zero page on the 6502). "Content" continues to apply. If someone doesn't like "register", they can pretend it stands for "record". CAR: content of the A part of the record; CDR: content of the D part of the record. The only weird thing are the choices of A and D; the "address" and "data" interpretations don't make sense. But they are just one letter out of three.

Why does it have to be English?

  A = antérieur
  D = derrière
In English we use Latin-derived prefixes where A and D form opposite pairs, like: Ascend/Descend; Approve/Disapprove; Adduce/Deduce .. Or cases where we have different roots: Arrive/Depart. Maybe some interpretation can be found.

In Japanese, car and cdr as the verbs "karu" and "kudaru" work. There are several verbs spelled "karu": 刈る (cut, mow, clip, ...), 借る (borrow) and some others like 狩る (hunt: animals, but also refers to picking and gathering berries and such). Kudaru is 下る, to descend. We can borrow/clip/pick the item at this cell (karu) or descend down (kudaru) to the next cell.

Not everyone who codes is a native speaker, yet most languages use English-derived words. Someone to whom "if" and "while" are foreign words may not care about some English speakers nitpicking over car and cdr.

> can read and understand it easily.

If you accept (car (cdr (cdr x))), then (caddr x) is a nice abbreviation for it, related by a transparent naming scheme. The source code is smaller, and if the compiler doesn't automatically reduce (car (cdr (cdr x))) to caddr, you get better code density.

The name doesn't work in a filter pipeline (-> x caddr ...) because the letters are now backwards w.r.t. pipe direction, since they indicate right to left application.

A good way for your future self to understand everything is not to keep changing names every year. The future self of some person coding in 1968 understands (if still alive) code I just wrote in a different Lisp dialect in 2023, because I used (cadr x). It may not be familiar to Lisp outsiders, but it's an utterly unmoving target for insiders.


You offer no actual arguments, just pronouncements and irrelevant history.


The argument is the names make no sense, they are purely historical.


They make perfect sense once you understand what they do.

They're not mnemonic for any specific usage because they have more than one possible specific usage in the language.

Besides, what kind of sense does '+' make for addition? It's also purely historical.


Imagine you were tasked with implementing a linked-list in, let's say 'C', but anything really.

So you choose 'cell' as your name for a node. OK, that's .. fine.

Now you choose 'car' and 'cdr' for each cell's 'data pointer' and 'next-cell-in-list pointer'. How many 'WTF?s'* do you think you'd get in code review? (except from lispers, I guess)

* obviously it's a rhetorical question, no-one writes or says WTF (out loud) in actual code reviews I hope.


> Now you choose 'car' and 'cdr' for each cell's 'data pointer' and 'next-cell-in-list pointer'. How many 'WTF?s'* do you think you'd get in code review?

Your names are too verbose.


Cons cells aren't a linked list.


struct node_t* node

node->data

node->next

Zero "WTF"s


Except those names are wrong in some contexts. That's the point.


You are tasked with writing a binary tree, and you pick car and cdr ... A key-value tuple-space... Complex numbers...

The point is they are 'wrong' in every context. For LISt Processing, they should probably default to something to do with lists.

And caaar et al are a fine example of why I completely skipped common lisp in favour of newer lisp-likes. Perhaps it happens to all languages eventually, people add a convenience here, an shortcut there, and a doodad here, and before long you have an impenetrable thicket.

And these things seem convenient, but they are a huge extra cognitive load, and impose a further learning cost even to practicing experts who have to keep up with the latest doodads.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: