2

Currently I am reading "Land of Lisp". In one of the recent code samples the author gave:

> (eq 'fooo 'FoOo)
T

to prove that the symbols are case-insensitive. A few pages later data mode is formally introduced.

However I fail to really understand the following. eq is a function, so its name is case-insensitive as well. Therefore I should be able to do this:

> (eq 'Eq 'EQ)
T

Great. That worked as expected. But what if I put this into a list in data mode? Keep in mind, I am just experimenting with something that's new for me.

> (eq '(Eq) '(EQ))
NIL
> (eq '('Eq) '('EQ))
NIL

Uhm. Okay? Why is that? I would have expected that if I put the same symbol into two lists, that the lists would be considered equal.

Now the question: does that mean that not the contents of the lists are compared, but the list "objects" themselves? What am I missing?

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
0xC0000022L
  • 20,597
  • 9
  • 86
  • 152

4 Answers4

4

Symbols are Case-Sensitive

> (eq (print (intern "foo")) (print (intern "FOO")))
|foo|   ; printed 
FOO     ; printed
==> NIL ; returned

The default reader is Case-Converting

(eq (read-from-string "foo") (read-from-string "FOO"))
==> T

However, you can make the reader case-preserving:

(let ((*readtable* (copy-readtable)))
  (setf (readtable-case *readtable*) :preserve)
  (eq (read-from-string "foo") (read-from-string "FOO")))
==> NIL

Please take a look at

EQ compares for pointer identity

Common Lisp provides 4 equality predicates, you should use the right one for your needs:

(equal '(Eq) '(EQ))
==> T
(equal '('Eq) '('EQ))
==> T
Community
  • 1
  • 1
sds
  • 58,617
  • 29
  • 161
  • 278
2

eq compares for things to be exactly the same, think pointer equality. This is like == in Java, even logically equivalent data will be falsy.

The solution here is to use equal which just does the "intelligent" thing and compares the lists' elements

> (equal '(A) '(a))
T

Additionally symbols are case sensitive. But by default the reader (the thing that turns code into an AST) defaults to being case insensitive. You can notice this distinction with a function like intern.

daniel gratzer
  • 52,833
  • 11
  • 94
  • 134
1

Lisp symbols are case sensitive. And even the lisp reader is case sensitive. The only point is that when the reader reads a symbol it usually make it in uppercase. The easiest way to tell the reader that the case in important is to put it between the vertical lines.

> '|asd|def|ghj|
|asdDEFght|
> '|asd|
|asd|
> '|ASD|
ASD
> 'ASD
ASD
> (eq 'asd '|ASD|)
t
> (eq 'asd '|aSd|)
nil

The eq predicate check that the arguments are the same objects (similar to compare the pointers to variables in C)

> (defparameter *x* 1)
> (defparameter *y* 1)
> (eq *x* *y*)
nil

So when you write '(asd) in REPL the list with one element is created. And when you write it the second time another list is created and these lists are actually different objects.

> (defparameter *list1* '('qwe))
> (defparameter *list2* '('qwe))
> (eq *list1* list2*) ;this are 2 different objects
nil
> (setf (first *list1* 'def))
> *list1* ;this list has changed
(DEF)
> *list2* ;and this did not
(QWE)

> (setf *list1* *list2*) ;now they are just different names for one object
> *list1*
(QWE)
> (eq *list1* *list2*)
t

There are another ways how to compare objects (eq eql equal equalp =). It's better to read documentation and play with REPL to see the difference.

JustAnotherCurious
  • 2,208
  • 15
  • 32
1

To complicate things a bit.

Let's say we have the following in a file. Then we compile and load that file.

(defparameter *a* '(1))
(defparameter *b* '(1))

Now we calculate:

(eq *a* *b*)

It is undefined if this is NIL or T. The Common Lisp compiler may detect that the lists are equal and set both variables to the same list - that is EQ then also would be true. Actually there are Common Lisp compilers which are doing this. Executing the two DEFPARAMETER forms in a *REPLone would usually expect that the Lisp system does not detect that and that(eq a *b*)isNIL`.

EQUAL compares structure and (eq *a* *b*) for our example is always T.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346