(cdr '(x a))
; does not return a, it returns (a)
(cdr '((x a) y))
; does not return y, it returns (y)
(cdr '((x a) (y b)))
; does not return (y b), it returns ((y b)) (cdr '(x a))
; does not return a, it returns (a)
(cdr '((x a) y))
; does not return y, it returns (y)
(cdr '((x a) (y b)))
; does not return (y b), it returns ((y b)) ((ab . c) . d . nil)
isn't a valid s-expression. Maybe it should be ((ab . c) d . nil)
Also, (eq '(a b) '(a b))
; (a b) is a list and cannot be evaluated by eq
eq works fine on lists. It returns T iff its arguments are the same object (i.e. are at the same memory location, or are small enough integers or floats). If they're copies (as is the case in the above), it returns NIL. If this isn't what you expect, you should probably be using equal.A couple more examples for the Common Lispers in the audience that highlight the difference between the reader and the evaluator:
(setf foo (list #1=(list 3 4 5) #1#))
(eq (car foo) (cadr foo)) ; --> ??
What should we expect the second form to return? T or NIL?Answer: It might return true in some implementations (very weird implementations), but in general one should not expect it to do so. Why?
(setf foo (list #1=(quote (3 4 5)) #1#))
(eq (car foo) (cadr foo)) ; --> ??
Now what should the second form return?Answer: It absolutely must return true. Why?
One of those is called SBCL.
'The main point' is that you can't depend on the value of (EQ '(a b) '(a b)) being NIL.
Reason: a compiler compiles a Lisp file. The compiler sees literal data like '(a b) ' and '(a b). The compiler determines that these are 'similar' objects and 'coalesces' them into one object. It might even do it for '(a b) and '(1 a b), seeing that one is a sublist of the other and coalesces the first list into the sublist of the other.
Common Lisp compilers are explicitly allowed by the language standard to do these things with literal data in a source file. It defines a concept of 'similarity', where this is allowed.
$ sbcl
This is SBCL 1.5.8.138-d53fb0eb3, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
* (eq '(a b) '(a b))
NIL
*
Which is exactly what I'd expect in any normal (non-weird) Common Lisp implementation. Is your SBCL returning T for this? /tmp % more test.lisp
(print (list :eq-or-not (eq '(a b) '(a b))))
/tmp % sbcl
This is SBCL 2.1.9, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (load (compile-file "test.lisp"))
; compiling file "/private/tmp/test.lisp" (written 03 JAN 2022 07:58:54 PM):
; processing (PRINT (LIST :EQ-OR-NOT ...))
; wrote /private/tmp/test.fasl
; compilation finished in 0:00:00.003
(:EQ-OR-NOT T)
TCCL and Lispworks return NIL for this test in both cases.
That is incorrect. It must always return false. LIST is called multiple times, and each time it is called it must produce a distinct cons. Note this is a different issue from literal coalescing (mentioned else-thread).
((ab . c) . d . nil)
isn't a valid s-expression. Maybe it should be
((ab . c) d . nil)
Can someone explain why ?