The Origin of CAR and CDR in Lisp (2005)
iwriteiam.nl
iwriteiam.nl
>"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."
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!
caar -> ffst
cddar -> rrfst (ff x) == (caar x) == (car (car x))
(rrf x) == (cddar x) == (cdr (cdr (car x)))
I would argue that it's worth sacrificing the 'f' and 'r' symbols for such a common construct.If not, a common prefix (lacking in HD and TL) could be used:
(.ff x) == (caar x) == (car (car x))
(.rrf x) == (cddar x) == (cdr (cdr (car x)))
Yes, I realize I'm 55 years late to the party.However, whilst I respect it's open for interpretation, I would say the first video game was Tennis for Two.
https://en.m.wikipedia.org/wiki/Tennis_for_Two
There's also OXO, which predates both Spacewar! and Tennis for Two:
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):
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.
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.
That's nice. I'm inclined to think that you haven't written very much Lisp code.
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.
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
(caar x) == (car (car x))
(cddar x) == (cdr (cdr (car (x)))
Something which you can't do with first and rest. This has (AFAIK) always been one of the arguments for car and cdr.http://www.nongnu.org/txr/txr-manpage.html#N-03E5CED9
The code for them is generated textually: http://www.kylheku.com/cgit/txr/tree/gencadr.txr
Compare:
(caadar x) => (car (car (car (cdr (car x)))))
Saves parens too.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.