3 ms·
The 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_Tozq2P53
by susam 2y ago
The 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.)
- akater 2y agoNote that the value returned by cons is guaranteed to have type cons, and it is guaranteed that a fresh cons is created. Neither is true for list*; note that its return type is t.
- zahlman 2y ago> 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. That's just how cons is defined. the first argument is a list and the second is an arbitrary object, and the result has the elements from the list plus the other object. It doesn't take a bunch of algebraic manipulation to understand this definition. It just takes a recognition that an "arbitrary object" could be a list, as well as a recognition that the other definition you imply ("make a new list with both arguments as elements") would have to either be variadic (which in turn would obviate `list`) or would only ever be able to make lists of exactly 2 elements. (The point is that `cons` can serve as a simpler primitive, and `list` can be implemented in terms of it.)
- kazinator 2y agoSomething you know because of what you learned cannot be called "intuitive". Intuitive means that, having studied nothing, you somehow make the right guesses about something. A device is intuitive if you can chuck the user manual aside as you unbox it, and proceed to use it without difficulty or puzzlement.