Regarding the "hunks" he mentioned, here's what Guy Steele had to say about them when I interviewed him for Coders at Work: "I implemented a new data type called a 'hunk,' which was probably the biggest disaster in language design we ever put in. It was essentially a cons cell with more than two pointers. It was a desperation move because we were running out of address space on the PDP-10. Recall that the -10 only had an 18-bit address space. In a list, 50 percent of the pointers were dedicated to just maintaining the structure of the list, whereas with a threaded set of hunks, maybe only one-eighth of the pointers were dedicated to the threading of the chunks so you’d get better memory usage that way."
Of course since Clojure is built upon abstractions, and because it's simple to introduce your own protocols and extend them to existing types w/o conflicts - it's straightforward to reintroduce the concept of a "pair" where the right-hand side is not a sequence. I recently encountered this challenge working on a Clojure port of miniKanren (the relational programming system described in the The Reasoned Schemer).
In miniKanren the concept of a "pair" is useful because the right hand side of a sequence in miniKanren might be a logic variable and not a sequence.
What's lovely is how simple this is. I can define a custom iteration protocol (LogicSeq) which define two functions - lfirst, lnext. Then I create a custom sequence type that returns a legitimate Sequence or logic variable for lnext.
To bring all the other collections into this protocols is 4 lines of code:
Why are people so offended by syntax? So many people complain about parentheses or names like car and cdr. Is it the programming equivalent of being shallow or judging by appearance?
When I first started learning scheme I was much more challenged by the rest of the cognitive assault - tail recursion is "free", call/cc or continuations, the shift to thinking in "higher order" mode, macros, being able to effectively define your own syntax.
It's disingenuous to split people into those who whine about syntax and those who enjoy deeper challenges. It's possible to be in both camps.
Syntax isn't any more important than the other things you mention, but it's certainly as important. Syntax is not mere window dressing. Like punctuation in written language, there's good and bad, confusing and obvious, opaque and transparent, and it will be judged and analyzed like anything else.
Indeed, so was I: the cºr indirections strike me as a very good reason to not switch to `first` and `rest` (or `head` and `tail`) in Lisp: they provide an unambiguous and readable way to quickly traverse multiple levels of datastructures (as long as they're not abused too much) which is not as easy to generally replicate using more meaningful names.
Maybe it's just my mental model, or being new to the language. But while going through SICP - 'cdadadr', 'cddaadr', etc. never really "clicked" in my mind. Really anything past 3 levels (cadar, cddar, etc.) always slowed down reading code, like hitting a speed bump.
I would have to stop and really try to grok what list item it was referring to. Not saying that that is a bad thing, just an observation.
Is there a common way of thinking that makes it easier to comprehend, or is it just something that comes with experience?
> Maybe it's just my mental model, or being new to the language. But while going through SICP - 'cdadadr', 'cddaadr', etc. never really "clicked" in my mind. Really anything past 3 levels (cadar, cddar, etc.) always slowed down reading code, like hitting a speed bump
I've used Lisp for a while, and where I tend to wind up on these composite forms is that I use a few of the simpler composites, but tend to switch to either destructuring-bind or some other data type if it gets too complex. (Practically speaking, that means anything much beyond 'car', 'cdr', and 'cadr' gets refactored.)
I worked with Scheme (a type of Lisp) professionally for over a year and even after heavy usage there were still lots of syntax "speed bumps" like this that slowed me down. I really enjoyed a lot of the concepts of Scheme but the syntax was a bummer and I'm so glad I'm not programming with it anymore. :)
car and cdr must have something going for them that first and rest don't, or else people would have abandoned them decades ago. The author mentions one point in their favor: generality. I'd add another two: brevity, and symmetry.
It's also worth noting that the primary disadvantage of car and cdr, their arbitrariness, fades as one becomes familiar with the language.