A string is stored as a vector of chars. eq?
is the identity procedure and thus it checks if two argument is the same object. Multiple variable pointed to the same Object, thus created at one instance of time for a single threaded implementation, are eq?
.
There is one exception. Literals in code can be cached such that objects that are created differently every time they are made can be made once for every occurrence in the code. Other languages does the same, eg. Java has a string literal pool where "yes" == "yes"
would be true
but of course ("y" + "es") == "yes"
would be false
since the left hand side is a new string with the same chars and not the same object as "yes"
from the literal pool.
This is true for all literals. '(some list)
or "some literal string"
compared with eq?
might give #t
where #f
would be the answer had one side been created at runtime and not by a literal. (eg. make-string
) or list
)
the rule of thumb
Use eqv?
or the special numeric comparison procedures (=
, <
, ...) for numbers. Numbers are the only data type where the implementaion are allowed to copy values to a different form at any time and thus the same number might be #f
with eq?
even if it seems like the same object. eqv?
are guaranteed to be #t
for every comparison that are eq?
.
Except for numbers you use eq?
if you want to know if two things are created at the same time. (the same object). Eg. finding a specific node form a tree in a assoc of seen elements are typical eq?
moment. Symbols are the only literals guaranteed to be #t
for the same symbol.
You should use equal?
if you want to know if two things look the same. equal?
is guaranteed to be #t
for every comparison that is eqv?
. If you are sure you have strings you can use string=?
for case sensitive comparison (like equal?
does) and string-ci=?
for case insensitive comparison.
Note that a string and a symbol don't look the same. One has the form "yes"
and the other yes
in the REPL.