;; equivalence predicates : eq?, eqv? and equal? ;; ;; eq? is the most picky, it returns true when given two ;; symbols that look the same, two numbers with the ;; same value, two references to the same string or ;; two references to the same list. ;; Note that in some situations the behavior of eq? is ;; not well defined (could be different in different ;; implementations of scheme). It always returns true or false, ;; but which it returns can depend on the internal representation of things. ;; ;; For example, in some scheme implementations a string literal like "foo" ;; is created and stored in memory only once, no matter how many times that ;; string literal appears in a program. In this case (eq? "foo" "foo") would ;; return true. If an implementation has multiple copies of the string ;; literal foo, it would return false. ;; (define a "hi") (define b a) (define d (list 1 2 3)) (define e d) (eq? 3 3) ; #t (eq? 3 9/3) ; #t (eq? 'g 'g) ; #t (eq? "hi" "hi") ; MIT scheme #f, others could return #t (eq? "hi" a) ; #f (eq? a b) ; #t (eq? '(1 2) '(1 2)) ; #f (eq? '(1 2 3) d) ; #f (eq? e d) ; #t ;; eqv? is less picky than eq? with the difference being that ;; is able to realize that two numbers have the same value in ;; some situations that eq? would miss. ;; In general you should always use eqv? instead of eq? ;; to compare numbers unless you have a specific reason not to. (eq? 3 3) ; #t (eq? 3 9/3) ; #t (eq? 'g 'g) ; #t (eq? "hi" "hi") ; MIT scheme #f, others could return #t (eq? "hi" a) ; #f (eq? a b) ; #t (eq? '(1 2) '(1 2)) ; #f (eq? '(1 2 3) d) ; #f (eq? e d) ; #t ;; equal? will recursively compare lists, pairs, strings, etc. ;; this means equal? will generally return #t whenever two thing ;; would look the same when printed. The obvious need for this is ;; to compare two strings (eq? and eqv? say strings are the same only ;; if they are the same memory location) or lists. (equal? (list 1 2 3) (cons 1 '( 2 3)) ; #t (equal? "hello" "hello") ; #t (equal? a "hi") ; #t (equal? '( 1 (2 3) 4) (list 1 (list 2 3) 4)) ; #t ;; list membership predicates memq, memv and member ;; search a list for a specific value. If the value is found, ;; the sublist starting at the found list item is returned. ;; if the value if not found, the empty list is returned. ;; These procedures can be used as predicates in most situations ;; (unless you are looking for the empty list in a list). ;; memq uses eq? ;; memv uses eqv? ;; member uses equal? (member 3 '(1 2 3 4 5)) ; (3 4 5) (member '(1 2) '( 3 (1 2) 4 (4 4))) ;