To cut to the chase and save reading though all the unnecessary speculation, this is the relevant part of this article...
>"The 704 family (704, 709, 7090) had "Address" and "Decrement" fields that were 15 bits long in some of the looping instructions. There were also special load and store instructions that moved these 15-bit addresses between memory and the index regiseters ( 3 on the 704, 7 on the others )
We had devised a representation for list structure that took advantage of these instructions.
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."
Steve Russell wrote that. In case people don't know, he also co-wrote 'Spacewar!', one of the first video games. According to Wikipedia he also invented continuations and mentored Bill Gates and Paul Allen while they were teenagers: https://en.wikipedia.org/wiki/Steve_Russell_(computer_scient...
Yeah, certainly one of the first, I'd agree with that. First I'd ever heard about it was in the documentary Thumb Candy, at the beginning Steve Russell gives an introduction to Spacewar!, which is quite fun to see:
Digging around, I found even more early examples of computer-based games that appear to have been largely overlooked, I certainly don't remember hearing about them before, seems like the first video games may have emerged in the early 50s (between 1950 to 1951, depending on whether it needed to be on a general purpose computer):
Well, after all we've always used CAR and CDR! If it was good enough then, why shouldn't it be good enough now?
Also, the proposed new keywords were on average 50% longer. Just too much typing! With FST and RST they would have stood a chance. HD and TL would have been clear winners!
That's right, but I would go one step further and have F(irst) and R(est), with obvious composition as follows: (using kruhft's examples from another thread)
Instead of (f)irst/(r)est we could use (h)ead _or_ (f)irst and (r)est. Then the pronunciation is just exactly as it is spelled - https://www.youtube.com/watch?v=spefM2OjKp4
One interesting thing here is that the attempt to get people to stop using the 'bad' names car and cdr is only a few months younger than car and cdr themselves. This is analogous to the plan (which lasted a few years) to replace s-expressions with m-expressions. In both cases the 'bad' construct stuck around because it's easier to program with.
When I made my own Schemes back in the 90s, I included the ca/dr primitives, because yes, they were handy -- but coming back to this recently I didn't bother, because I built in pattern matching instead. I imagine that'll finally kill off the caaddars in most new Lisps.
Pattern matching would replace a call like cadar with a pattern like ((_ x @_) @_). Using cadar is sort of like point-free style in Haskell: they both invite you to mentally run a chain of operations to understand the meaning, in contrast to patterns and expressions with named variables, which are more like a picture of the input and output.
Of course pattern matching goes way back, but I used to think of it as less settled -- people might want to extend the kernel language with pattern matching in many different ways. Now I'd be more surprised by a new Lisp without some sensible default; plus if it is absent, you can add it in under a page of code, like http://okmij.org/ftp/Scheme/macros.html#match-case-simple
I don't know about respectable, but I prefer car/cdr even in a new Lisp. In addition to the composability of the notation, which others have cited, there's the clear lexical symmetry between the two; their compactness, which adds value when writing and reading concise programs; and how easy they are to say out loud. There's something also about their precision: when you say 'car' or 'cdr' in a Lisp context it's immediately clear that there's a linked list at hand and you're talking about it.
The main disadvantage is that they're words with no immediate connection to their meaning, but that's true of many words we're all familiar with. It really only costs anything in the learning stage—which admittedly is a critically important stage. But I think it's fair for a programming language to use specialized idioms for a small number of their most fundamental constructs.
CAR and CDR are also good names because they are part of the Lisp tradition. Also due to this tradition, they have a clear meaning in the context of Lisp. If the "new Lisp" keeps conses (and some may argue that if it doesn't, it shouldn't really fall under "a Lisp"...), perhaps it should also keep these names.
First and rest make more sense if you're only going one level down, true. Long-term Lisp fans will argue that the composability shorthand of caddar, cddddr, cadadar, etc. is just too useful to give up.
I think needing to use such operators is already indicative of inadequate tools to express structure.
And if I did need to use something as complex as `cadadar` frequently for some reason, I'd much rather give it a name (and a type) that expresses what I'm actually doing with it.
Well, the point is not that you use cadadar all the time as such, but that you also use cdddar, caadr, and so on, and that having these shorthand forms available means that you don't have to define a whole bunch of one-off functions.
I think saying you can use `cadadar` to operate on a data structure instead of defining an accessor is like saying you can use pointer arithmetic to work with data structures in C instead of using structs.
EDIT: And as other people have mentioned, most serious lisps already have proper tools for building data-structures, so I'm inclined to think that if you're using `cadadar` you're probably doing something wrong.
It's not pretty, but it has a consistency to it that includes a lot of compact information in a digestable manner. It takes no longer to decode what the instructions say, but it saves a lot of time parsing, for the human reader of the program.
You can make it even easier on human readers by defining accessors (even if they're just wrappers over car/cdr) and giving them meaningful names. Asking for the car of the car of the cdr of the car of an ad-hoc data structure is pretty hostile toward human readers regardless of whether or not you use caadar.
That's why you actually won't find many instances of such patterns in practice. Either you refactor to have structures/classes, or you define your own accessors. Besides, if you are using CL, FIRST, SECOND, THIRD, ... , TENTH, NTH and REST are defined by the spec (http://clhs.lisp.se/Body/f_firstc.htm).
Are you kidding? cdar would be the second element, cddar the third, and so on. And they're harder to misread on a scan through the code.
As a general rule, I assume that I read most lines of the code not when I'm writing it, nor fixing a bug, but while I'm trying to locate a bug of unknown location. The complexity or trickiness of a function that you are actively modifying can be pretty high and you'll still grasp it. But a function not even involved with a problem needs to be even more legible if you don't want to repeatedly waste time contemplating it to determine if you should move on.
There are first, etc... accessors (other Lisps might define them too, it is so easy to implement). People are encouraged to use them, especially for lists, and are even encouraged to not use them but prefer objects with named slots.
The general advice is to reserve C..R functions for trees, but this is actually rarely needed, especially when using pattern matching.
>"The 704 family (704, 709, 7090) had "Address" and "Decrement" fields that were 15 bits long in some of the looping instructions. There were also special load and store instructions that moved these 15-bit addresses between memory and the index regiseters ( 3 on the 704, 7 on the others )
We had devised a representation for list structure that took advantage of these instructions.
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."