I want to create following list in Lisp.
((lambda(x) (cons x x)) (cons'A 'B))
creates this list, but
((lambda(x y) (cons x y)) (cons'A 'B) (cons 'A 'B))
and
(cons (cons 'A 'B) (cons 'A 'B))
do not create the list.
My challenge is why!? How does the first command create this list and the others do not? Any detail?
You want to create a cons
of A and B:
(cons 'A 'B)
Then you want to refer to it twice from another cons. So if x
is a reference to this existing cons
, you want
(cons x x)
Wrapping up, we get
(let ((x (cons 'A 'B)) (cons x x))
or equivalently
((lambda (x) (cons x x)) (cons 'A 'B))
If you do (cons 'A 'B)
twice you create two cells:
A B
A B
and the cons
of those will contain one link to the first, and another to the second.
(Using a lambda
to refer to them is a pointless obfuscation; the point of the example with the lambda
form is that you use x
twice. The form
((lambda (x y) (cons x y)) (cons 'A 'B) (cons 'A 'B))
is just a very tedious way to write
(cons (cons 'A 'B) (cons 'A 'B))
whereas in the original example there is -- pointedly -- only one instance of (cons 'A 'B)
which you want to be able to refer to twice.)
The purpose of this exercise is to illustrate the difference between "surface" equivalence and identity. Two lists which contain the same values are still two different lists, whereas two references to the same list are identical. As @sde hints, this makes a difference for understanding comparisons; the prototypical example is that equal
is true for distinct lists containing the same values (as well as identical lists, of course), whereas eql
is only true if its arguments are in fact identical (ie they refer to the same object).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.