8 ms·
Why does Lisp use cons cells? (1998)
- kagevf 2y agoThis doesn't come across as "caustic" as when I previously read it. And the "bile" isn't directed so much at Lee as it is at something he wrote; "All in all, the pairs notion is redundant." Naggum genuinely seems to be hoping that his long and thorough explanation will convince Lee of his point of view, and not as a put down. > I hope you understand and appreciate what I have written above so the following does not apply to you anymore. The "following" where he goes off on what Lee wrote, but not on Lee himself. It might be worth it for me to re-read Naggum's posts, now that I have a better understanding of where he was coming from.
- p_l 2y agoUnfortunately, from my experience, Xah Lee is someone who will ignore information from others if it requires to correct what he wrote/spoke, especially when he claims something authoritatively when in reality he has no in-depth, if any, information on the subject
- kagevf 2y agoHe does have a tendency to write off people as “fanatics”.
- Joker_vD 2y agoNot caustic? "Short-sighted users", "stupid language designers who believe too strongly in strong typing", "certainly can't be bothered to invent a useful concept for their short-sighted programmers", "dumb people who implement something the simple way, so it becomes complex and generally useless to everybody else", "unlike today's braindamaged CPU's", "just look at what C programmers do when they need lists! shudder". Sure, you may believe that LISP is the greatest invention since the sliced bread, and everything went downhill after that but even if you are correct — that's still just, like, your opinion, man.
- kagevf 2y agoI wrote "not *as* caustic" ... in particular, he wasn't being caustic toward Lee, but rather to the idea of cons pairs being redundant. It's enough of distinction to make me think I should re-examine what Naggum had to say - in this and in other posts - and not get caught up in any pre-conceived notions I might have had about him.
- abecedarius 2y agoIt was pretty mild for Naggum. Like the GP I was expecting a higher density of that sort of thing, but maybe my memory is too slanted by his worst flames.
- nescioquid 2y agoConsider that you may be eavesdropping on the sort of self-talk the author engages in. The clear reasoning mixed with vituperation makes me suspect he probably beats himself up. There is a lot of worry over being mistaken and stupid. I'm unfamiliar with the author, so I could be way off base.
- deleted 2y ago[deleted]
- mst 2y agoAnybody interested in efficient list (and other data structures, but mostly lists) implementation will probably find the VList approach interesting (relevant paper archived at https://trout.me.uk/lisp/vlist.pdf https://trout.me.uk/lisp/vlist.pdf)
- deepnet 2y ago[post] tl;dr A ( linked ) list is a collection of CONS ( Construct ) cells. A CONS cells can extract, via the commands: ‘car’ ( Contents of Address Register ) - the payload ( data item in list ); ‘cdr’ ( Contents of Decrement Register ) - the link ( to the next list item, e.g. CONS cell ) The names are for historical reasons ( using two halves of a single register ) lost in the beards of yore. The linked list appears simple, this belies the fact of its exquisite perfection and the great thought that went into inventing, perfecting and implementing it. “[The ‘list’ command]… creates a series of conses and sets the CAR pointers to point to each argument. which you have provided. (LIST (LIST 1 2) (LIST 3 4)) => ((1 2) (3 4))
- kerkeslager 2y agoErik Naggum's writings were pretty influential on me as a young programmer, and there's still some value in this piece, but nowadays I find a lot of this insufferable. Yes, it's not actually easy to implement lists, and there's semantic value to Common Lisp's implementation. But... 1. You can't tout the benefits of constant time appending to the beginning of a list while ignoring the benefits of constant time lookup and modification within the list. And before anyone starts talking about "but most programs don't need random access because you just traverse the list"--yes, and vectors do that better too because of cache locality. Cache-aware implementations of Lisps are still an order of magnitude slower than vectors for traversals because dereferencing the cdr pointer is obligatory. If you start talking about speed being a benefit of Lisp in comparison to C (a comparison which Naggum introduces later here), you've lost the plot. 2. Nostalgia for an architecture that no longer existed even in 1998 when this was written is poor reasoning for opaque names. "car" and "cdr" aren't good names. It kind of doesn't matter much: once you learn them it's fine, but it is a slight barrier to Lisp's success, as it does present yet another small challenge for beginning Lisp programmers. 3. In general, the ragging on Scheme is rather pointless--I found my way to Lisp via Scheme. And a large part of why I ended up back in Scheme land (well, Racket by that point) was that it became clear to me that the Scheme community benefits from ideas learned in Common Lisp, while Common Lisp often (not always) rejects NIH ideas.
- pfdietz 2y agoIt would be trivial to replace car and cdr in your code with any other symbol names you like. Even the Common Lisp standard supplies alternatives (first, rest). If this was not done, it was because people using lisp didn't see any great value in doing it.
- Majromax 2y agoYour point and the grandparent's point are not contradictory. 'car' and 'cdr' can be opaque pieces of jargon that make the language slightly but noticeably more difficult for new learners, and they also can be standard pieces of jargon that current users would find no value in changing. In that way, it's a bit like indentation in Python.
- pfdietz 2y agocomp.lang.lisp was one of the meatier parts of Usenet I read.
- e40 2y agoThe strange thing about Erik is that he was sweet, gentle and helpful in person. I spent a fair amount of time with him, and never once saw any of the behavior he was famous for on usenet. He was highly intelligent but he had an odd childhood and was somewhat isolated socially, in the real world. It’s what ultimately killed him. At least outside of tech. Near the end he was almost a cult-like figure, at conferences especially. He would accumulate a hoard of fans. I’m unsure if he liked that. He really loved coming to the Bay Area. I definitely miss him irl. Sorry for the ramblings. I’m on mobile and editing is hard.
- crystal_revenge 2y agoI never got the chance to interact with, much less meet, Erik, but I think the thing people misunderstand about even his more vitriolic messages (his XML rant warms my heart to this day), is that he wasn't being an asshole, he was pursuing values people had increasingly abandoned. He was an impassioned idealist. There was a time when technologists aggressively cared about the technically correct solution as a opposed to the "business correct" or "socially correct" answer. Erik's rants (which I'm more familiar with) didn't criticize the uninitiated, they attacked people who didn't care to know better. He's the fundamental opposite of today's Twitter/X "shitposter", those who promote rage for clicks and engagement above understanding and thinking. He inspired you (or at least young me) to be good enough, to understand well enough, that when you spoke you wouldn't insight the rage of people like him. He was a warning to neophytes not to get too cocky before you learned the ropes. He was an object lesson that ego was far less important than understanding. Something lost on the most recent Twitter/X generation. I'm certain anyone resembling Erik out there in the world would not have survived the tech industry the last 10 years and for me that is a tragedy. I hope Erik's name forever lives on in internet lore and at least some new people setting out secretly hope to understand their field enough not to invoke the rage of his lurking spirit.
- specialist 2y agoI was vocally apostate during the XML mania. Discovering Naggum validated me. He articulated what I merely intuited. Gratitude. I too am sorry Naggum's gone. XML did teach me one thing: This too shall pass. Eventually. So I should just chill and focus on my own thing. And sometimes I do.
- susam 2y agoThe original discussion is here: https://groups.google.com/g/comp.lang.lisp/c/T_Tozq2P53I/m/NB52fcDbGYMJ https://groups.google.com/g/comp.lang.lisp/c/T_Tozq2P53I/m/N... I found it intriguing that the original post there claims that (cons (list 1 2) (list 3 4)) intuitively seems to have the length 2 whereas the correct length is 3. I find 3 more intuitive though. It could be because right from my early days of learning various Lisps, I learnt about lists in terms of cons cells. There are many ways to explain this, such as by drawing diagrams of the cons cells from first principles, printing out each cons and list on a REPL and confirming the equivalences, etc. Here's one that happens to be my take on it. I'll be (ab)using the equals sign (=) to mean that the expression on the LHS and the one on the RHS are equivalent. First let us build a list of three items using cons cells: (cons 4 nil) = (list 4) (cons 3 (cons 4 nil)) = (list 3 4) [1] (cons 'x (cons 3 (cons 4 nil))) = (list 'x 3 4) [2] Now let us build a list of two items using cons cells: (cons 1 nil) = (list 1) (cons 1 (cons 2 nil)) = (list 1 2) [3] Now substituting LHS and RHS of [3] into 'x in LHS and RHS of [2], respectively, we get (cons (cons 1 (cons 2 nil)) (cons 3 (cons 4 nil))) = (list (list 1 2) 3 4) Simplifying the LHS above using [3] and [1], we get (cons (list 1 2) (list 3 4)) = (list (list 1 2) 3 4) Clearly, the length of RHS is 3. From the REPL: CL-USER> (cons (list 1 2) (list 3 4)) ((1 2) 3 4) CL-USER> (list (list 1 2) 3 4) ((1 2) 3 4) CL-USER> (length (cons (list 1 2) (list 3 4))) 3 CL-USER> (length (list (list 1 2) 3 4)) 3 CL-USER> Also, on Emacs: ELISP> (cons (list 1 2) (list 3 4)) ((1 2) 3 4) ELISP> (list (list 1 2) 3 4) ((1 2) 3 4) ELISP> (length (cons (list 1 2) (list 3 4))) 3 (#o3, #x3, ?\C-c) ELISP> (length (list (list 1 2) 3 4)) 3 (#o3, #x3, ?\C-c) ELISP> See also: https://gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing https://gigamonkeys.com/book/they-called-it-lisp-for-a-reaso...
- kagevf 2y agoTo me, the form is not intuitive, but the result is: ((1 2) 3 4) Someone else in that thread mentioned that CONS is basically adding (1 2) to the front of the (3 4) list, and that helped me understand it better.
- abecedarius 2y agoThat original post started with > (list 1 2 3) == (cons 1 (cons 2 (cons 3 nil))) and I'd have answered that cons could be a variable-arity function such that > (list 1 2 3) == (cons 1 2 3 nil) and maybe that'd help this newbie's intuition. (Common Lisp does have this variable-arity cons but by a different name list*, for some reason.)
- kragen 2y agoWell, shit. Educational, but filled with bile. This post is an example of how to go wrong and make yourself and everyone around you unhappy, while still being right.
- pavlov 2y agoBrings back unhappy memories of the conversation style in Usenet. I didn't dare to use newsgroups after I asked some wrong thing as a 15-year-old in some computing-related group and got dumped on by angry adult men. I get it that they were frustrated by Eternal September and whatever. But thinking back to those times makes me appreciate the moderation culture that dang has created here, as well as the non-linear structure that moves less popular comments out of the way of attention.
- dang 2y agoSimilar memories have been an influence on HN's moderation style. I've mentioned that a few times over the years: https://news.ycombinator.com/item?id=34328146 https://news.ycombinator.com/item?id=34328146 (Jan 2023) https://news.ycombinator.com/item?id=32725068 https://news.ycombinator.com/item?id=32725068 (Sept 2022) https://news.ycombinator.com/item?id=28832073 https://news.ycombinator.com/item?id=28832073 (Oct 2021) https://news.ycombinator.com/item?id=26855767 https://news.ycombinator.com/item?id=26855767 (April 2021) https://news.ycombinator.com/item?id=19773300 https://news.ycombinator.com/item?id=19773300 (April 2019) https://news.ycombinator.com/item?id=11839842 https://news.ycombinator.com/item?id=11839842 (June 2016) https://news.ycombinator.com/item?id=10979050 https://news.ycombinator.com/item?id=10979050 (Jan 2016) https://news.ycombinator.com/item?id=9813527 https://news.ycombinator.com/item?id=9813527 (July 2015) - and more generally https://hn.algolia.com/?dateRange=all&page=0&prefix=true&query=by%3Adang%20programming%20flamewar&sort=byDate&type=comment https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que... Occasionally I run into posts from the heyday of comp.lang.lisp and it's still astonishing how high-quality the discussion was, before it wasn't.
- kragen 2y agoI appreciate your work; I can see how difficult it must be.
- Jtsummers 2y agohttps://groups.google.com/g/comp.lang.lisp/c/T_Tozq2P53I/m/NB52fcDbGYMJ https://groups.google.com/g/comp.lang.lisp/c/T_Tozq2P53I/m/N... The full conversation.
- agency 2y agoThey're also the original and simplest persistent data structures https://en.wikipedia.org/wiki/Persistent_data_structure https://en.wikipedia.org/wiki/Persistent_data_structure
- guerrilla 2y agoWhat criteria do you use to judge those two properties?
- Nevermark 2y agoNot sure about original. But simplest: Address pairs are extremely simple, obviously. But they can implement anything. Lists, structures, arrays, trees, arbitrarily complex multidimensional and irregular data types. Using symbols as representational "links" they can even implement general (multi-, etc.) graphs. Which is everything. But remove one of those addresses, and all you have left are linked series of addresses, ending with one element, or an end-of-series marker. That isn't general or very useful. So address-pairs get the prize.
- guerrilla 2y agoThanks for the legit answer. What do you mean about reprensentational "links"?
- Nevermark 2y agoDirect links are done with addresses. When you use lists to define a data structure, you can linearize the whole structure. I.e. (... (...) ... ( ... ) ... ... ) What you can't do is have some leaf of the structure refer back to a higher point in the structure. Which is what you need to represent a graph. I.e. any point can refer to any other point. So instead, you linearize but use symbols to define a referencable point, and then to refer to it. I.e. ( ... (....) (define a ( ... )) ... ( ... ( ... a .... ) ... a ... ) ... ) In this case, "define a" indicates that the next list isn't just accessible at that location, but wherever "a" appears later. And then we reference it in more then one place later. This allows not only tree-like structures to be linearized, but graphs. Everything is still lists, and lists-of-lists, but just as symbol or number elements can appear at more than on place, now lists in the structure can be referenced in more than once place. All done with just pairs of addresses and symbols. Even numbers can be built out of pairs of addresses and symbols. I.e. a binary number: (one one zero one zero zero one zero) Of course, a friendly language is going to add lots of notation on top of address-pairs and symbols, for numbers, looping, functions, decimal number, etc. to make common code and data forms much easier to type and read than a jungle of parentheses. -- This is very much the reason we have defined and referenced symbols in all code (or complete data languages). So that linear text can describe a graph. And the same process occurs, first the text is parsed into a tree (parsing), then at some point, symbols defining references are replaced with addresses of symbol definitions (linking). The result is code can be a graph. We can have two functions that call each other, etc. Not just tree expressions.
- agambrahma 2y agoAh a Naggum re-discovery. See a yearly index here: https://www.xach.com/naggum/articles/ https://www.xach.com/naggum/articles/ I went through the whole thing a few years ago, there are some gems hidden in there.
- amy-petrik-214 2y agoThis is all quite good too: http://www.schnada.de/grapt/eriknaggum-xmlrant.html http://www.schnada.de/grapt/eriknaggum-xmlrant.html Great to see someone take down XML, what a nightmare. Of course for markup nowaday we use the pragmatically simple "README.md" not "README.xml", although I'm sure the latter is quite popular amongst Java circles.