@riley@dougmerritt Yeah, (let ((alist '((:foo . bar) (:baz buz)))) (cdr (assoc :foo alist)) ; -> bar (cadr (assoc :baz alist))) ; -> buz There isn't a lot of cost (well, one cons to nil) of using cadr or second instead of cdr. And then you could store other stuff in later positions of the list as well. When I only knew the definitions of assoc and pairlis, I mostly used cdr, but then in lisp code I've read, like you said, the cadr one seems more common in lots of places.
@dougmerritt CDR coding was only really used on the Lisp Machine, which did not have kb of memory .. but rather megabytes. It also didn't save much, while lists are useful, for large sets of data there are better representations.
> There isn't a lot of cost (well, one cons to nil)
Back in the days when RAM was measured in kilobytes / kilowords, some implementations did in fact have space-optimized representations for short lists represented as small arrays.
That might still be in some implementations today, since its savings might be significant in large structures or in aiding cache locality.
The first paper may well have been L. Peter Deutsch: A LISP Machine with Very Compact Programs. IJCAI 1973, Pages 697 - 703
This is covered in 7.13 in the classic "Anatomy of Lisp", John Allen (1937-2022), 1978 (long out of print, and the author once replied to my query saying he didn't think it was worthwhile updating it for more modern times).
Has a lot on implemention, but tends to talk about abstractions in terms of M-Expressions, which is no longer in style.
@amszmidt Doug linked John Allen's book which spends about 50 pages asking people to please not use car and cdr as though they were intended as general list manipulation tools, even though they might be literally implemented as first and rest, since it's a failure of abstraction or something.
@screwtape FIRST/LAST .. make it confusing when working on improper lists. Which is why I disagree with Allen. CAR/CDR have very good names, and explain exactly what happens, similar with all the CnnnnR versions.
@amszmidt I might have garbled it, but he was talking about structured programming. So when the data structure being operated on is a cons cell, use car and cdr, and when the data structure being operated on is a list, use list functions like first and last (for example, but also consider something like subseq). I'm open to not necessarily agreeing with Allen's book (for undergraduates). @simon_brooke
Brain hurts from counting, and FLFLF .. doesn't sound as nice. Specially when you have a list structure where it is relatively common to access that specific element.
It was one of the first things I learned (and definitely not the easiest way to learn!). I don't use it very often, but when I need it, it is so much nicer to look at. It just confuses the hell out of people who don't understand, or ignore the List part of LISp.
Using CnnnnR accessors is awesome when coding something like a Sudoku solver, where you have to consider rows, blocks and columns.
@amszmidt@screwtape I still use cadr, cdar, cddar, etc. frequently when writing ad-hoc code to grovel through data; those would be cumbersome (to say the least) if they needed to be compositions of first and rest. I have also used cdr-coded lists, not only for space savings but to be able to refer to array data as a list (c.f. g-l-p) and to (in separate circumstances) interpolate less structured traditional cons list structure in the middle of compactly stored lists.
Both these practices fall in the category of "infrequently applicable but very useful when they do apply". I find that this category as a whole seems to be diminishing. When I try to explain this category to colleagues (usually in conjunction with explaining why I did something the way I'd chosen), they usually say that they'd never remember that it would apply.
@screwtape Etymology doesn't necessarily prove anything, but it *is* pretty weird that "CAR" was the mnemonic for "Contents of A Register" and "CDR" for "Contents of D Register" -- literal machine registers, not originally an abstraction at all.
BTW
> CDR coding was only really used on the Lisp Machine
@dougmerritt CDR was one of those things which the LispM hackers wanted to flush on the LispM cause it was just a pain in the ass .. slow, the benefits of it was nil.
@dougmerritt A for address, D for decrement. It wasn’t for A/D. Etymology is clear from the IBM 704. Now care to substantial the “100% false” wrt where CDR coding was used? @screwtape@ksaj @riley@toot.cat
On the Symbolics system, the type tags were all encoded in the microcode source and recognized in the hardware (ok, really the microcode). The type tag names were constants whose names all began with "DTP-" (for "data type", probably).
There was a type calld DTP-NULL (see below, page 7, though I think that's for the Ivory chip).