Working with Strings
Issue: EQL is often the default, but it won't compare strings, lists and compound objects.
(find "hello" (list "foo" "hello"))
Will return nil. VS
(find "hello" (list "foo" "hello") :test #'string=)
Will return the string.
Why? EQL is true for
- Same identical objects (pointers)
- or numbers of the same type (int and int, not int and float)
(eql "hello" "hello") ;; NIL
(eql 2 2.0) ;; NIL
(eql 2 2) ;; T
EQ is the lowest level one.
- Only true for identical objects: same pointers.
Only reliable for:
- keywords
- symbols
(eq :a :b)
(eq 'a 'b)
For numbers, characters... Unspecified (so it might be true for you, false for me)
EQ < EQL < EQUAL (in terms of utility)
EQUALP is not as strict on the types.
(equalp 2 2.0) ;; T
(= 2 nil) ;; ERROR, so to be defensive use EQUAL or EQUALP
Strings: STRING=, EQUAL |
- and EQUALP for case insensivity
- and string-equal to specify :start and :end indexes.
(string= "hello" "hello") ;; T
(string= "hello" "HELLO") ;; NIL
(equal "hello" "HELLO") ;; NIL
(equalp "hello" "HELLO") ;;; T
;; compare in substrings:
(string-equal "hello" "hello world" :end2 5) ;; T
- see the Common Lisp cookbook and Vindarel CL str library for more information. Also check out the generic cl library.