Reputation: 205
Switch statement with Strings in Lisp.
(defun switch(value)
(case value
(("XY") (print "XY"))
(("AB") (print "AB"))
)
)
I want to compare if value is "XY" then print "XY" or same for "AB". I have tried this code but it gives me nil. Can some please tell me what i am doing wrong?
Upvotes: 6
Views: 10906
Reputation: 2396
The Hyperspec on CASE
says:
These macros allow the conditional execution of a body of forms in a clause that is selected by matching the test-key on the basis of its identity.
And strings are not identical in CL, i.e. (EQ "AB" "AB") => NIL
.
That is why CASE
wouldn't work for strings. You either need to use symbols (they are interned once only, thus guaranteeing identity) or use COND
with EQUAL
or even EQUALP
if the letters case to be ignored.
Upvotes: 4
Reputation: 51531
You can use the library alexandria
, which has a configurable switch
macro:
(switch ("XY" :test 'equal)
("XY" "an X and a Y")
("AB" "an A and a B"))
Upvotes: 10
Reputation: 48765
print("XY")
looks more like Algol (and all of its descendants) rather than LISP. To apply print
one would surround the operator and arguments in parentheses like (print "XY")
case
happens to be a macro and you can test the result yourself with passing the quoted code to macroexpand
and in my implementation I get:
(let ((value value))
(cond ((eql value '"XY") (print "XY"))
((eql value '"AB") (print "AB"))))
You should know that eql
is only good for primiitive data types and numbers. Strings are sequences and thus (eql "XY" "XY") ;==> nil
Perhaps you should use something else than case
. eg. use cond
or if
with equal
.
Upvotes: 10