In book 'land of lisp' I read
Because the case command uses eq for comparisons, it is usually used only for branching on symbol values. It cannot be used to branch on string values, among other things.
Please explain why?
In book 'land of lisp' I read
Because the case command uses eq for comparisons, it is usually used only for branching on symbol values. It cannot be used to branch on string values, among other things.
Please explain why?
The other two excellent answers do answer the question asked. I will try to answer the natural next question - why does case
use eql
?
The reason is actually the same as in C
(where the corresponding switch
statement uses numeric comparison): the case
forms in Lisp are usually compiled to something like goto
, so (case x (1 ...) (2 ...) (3 ...))
is much more efficient than the corresponding cond
. This is often accomplished by compiling case
to a hash table lookup which maps the value being compared to the clause directly.
That said, the next question would be - why not have a case
variant with equal
hash table clause lookup instead of eql
? Well, this is not in the ANSI standard, but implementations can provide such extensions, e.g., ext:fcase
in CLISP.
See also why eql
is the default comparison.
Two strings with the same content "foo" and "foo" are not EQL. CASE
uses EQL
as a comparison (not EQ
as in your question). Usually one might want different tests: string comparison case and case insensitive, for example. But for CASE
on cannot use another test. EQL
is built-in. EQL
compares for pointer equality, numbers and characters. But not string contents. You can test if two strings are the identical data objects, though.
So, two strings "FOO"
and "FOO"
are usually two different objects.
But two symbols FOO
and FOO
are usually really the same object. That's a basic feature of Lisp. Thus they are EQL
and CASE
can be used to compare them.
Because (eq "foo" "foo")
is not necessarily true. Each time you type a string literal, it may create a fresh, unique string. So when CASE
is comparing the value with the literals in the cases with EQ
, they won't match.
(eq "foo" "foo")
could be true. You're right, of course, that there's no guarantee that (eq "foo" "foo")
is true. "(eq "Foo" "Foo")
=> true OR=> false" is even one of the examples in the hyperspec entry on eq
. –
Faxun © 2022 - 2024 — McMap. All rights reserved.
case
-like constructs in the libraryalexandria
, including such that can compare strings. – Varanasi