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-reaso...