-
Notifications
You must be signed in to change notification settings - Fork 566
/
Copy pathequality-distinctions.lisp
121 lines (111 loc) · 5.44 KB
/
equality-distinctions.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
;;; Copyright 2013 Google Inc.
;;;
;;; Licensed under the Apache License, Version 2.0 (the "License");
;;; you may not use this file except in compliance with the License.
;;; You may obtain a copy of the License at
;;;
;;; http://www.apache.org/licenses/LICENSE-2.0
;;;
;;; Unless required by applicable law or agreed to in writing, software
;;; distributed under the License is distributed on an "AS IS" BASIS,
;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;;; See the License for the specific language governing permissions and
;;; limitations under the License.
;;; The most common equality predicates in Common Lisp are, in order of
;;; strictness, EQ, EQL, EQUAL, and EQUALP.
(define-test eq
;; EQ checks the identity of the two objects; it checks whether the two
;; objects are, in fact, one and the same object.
;; It is the fastest of the four; however, not guaranteed to work on numbers
;; and characters because of that.
(true-or-false? ____ (eq 'a 'a))
(true-or-false? ____ (eq 3 3.0))
(true-or-false? ____ (eq '(1 2) '(1 2)))
(true-or-false? ____ (eq "Foo" "Foo"))
(true-or-false? ____ (eq "Foo" (copy-seq "Foo")))
(true-or-false? ____ (eq "FOO" "Foo")))
(define-test eql
;; EQL works like EQ, except it is specified to work for numbers and
;; characters.
;; Two numbers are EQL if they are of the same type and represent the same
;; number. Two characters are EQL if they represent the same character.
(true-or-false? ____ (eql 'a 'a))
(true-or-false? ____ (eql 3 3))
(true-or-false? ____ (eql 3 3.0))
(true-or-false? ____ (eql '(1 2) '(1 2)))
(true-or-false? ____ (eql '(:a . :b) '(:a . :b)))
(true-or-false? ____ (eql #\S #\S))
(true-or-false? ____ (eql "Foo" "Foo"))
(true-or-false? ____ (eql "Foo" (copy-seq "Foo")))
(true-or-false? ____ (eql "FOO" "Foo")))
(define-test equal
;; EQUAL works like EQL, except works differently for lists, strings, bit
;; vectors, and pathnames.
;; Two lists, strings, bit arrays, or pathnames are EQUAL if they have EQUAL
;; elements.
(true-or-false? ____ (equal 'a 'a))
(true-or-false? ____ (equal 3 3))
(true-or-false? ____ (equal 3 3.0))
(true-or-false? ____ (equal '(1 2) '(1 2)))
(true-or-false? ____ (equal '(:a . :b) '(:a . :b)))
(true-or-false? ____ (equal '(:a . :b) '(:a . :doesnt-match)))
(true-or-false? ____ (equal #\S #\S))
(true-or-false? ____ (equal "Foo" "Foo"))
(true-or-false? ____ (equal #*01010101 #*01010101))
(true-or-false? ____ (equal "Foo" (copy-seq "Foo")))
(true-or-false? ____ (equal "FOO" "Foo"))
(true-or-false? ____ (equal #p"foo/bar/baz" #p"foo/bar/baz")))
(defstruct thing slot-1 slot-2)
(define-test equalp
;; EQUALP works like EQUAL, except it works differently for characters,
;; numbers, arrays, structures, and hash tables.
;; Two characters are EQUALP if they represent the same character, ignoring
;; the differences in character case.
;; Two numbers are EQUALP if they represent the same number, even if they are
;; of different types.
;; Two arrays are EQUALP if they have the same dimensions and their characters
;; are pairwise EQUALP.
;; Two structures are EQUALP if they are of the same class and their slots are
;; pairwise EQUALP.
;; We will contemplate hash tables in the HASH-TABLES lesson.
(true-or-false? ____ (equalp 'a 'a))
(true-or-false? ____ (equalp 3 3))
(true-or-false? ____ (equalp 3 3.0))
(true-or-false? ____ (equalp '(1 2) '(1 2)))
(true-or-false? ____ (equalp '(:a . :b) '(:a . :b)))
(true-or-false? ____ (equalp '(:a . :b) '(:a . :doesnt-match)))
(true-or-false? ____ (equalp #\S #\S))
(true-or-false? ____ (equalp "Foo" "Foo"))
(true-or-false? ____ (equalp "Foo" (copy-seq "Foo")))
(true-or-false? ____ (equalp "FOO" "Foo"))
(true-or-false? ____ (equalp (make-array '(4 2) :initial-element 0)
(make-array '(4 2) :initial-element 0)))
(true-or-false? ____ (equalp (make-thing :slot-1 42 :slot-2 :forty-two)
(make-thing :slot-1 42 :slot-2 :forty-two))))
;;; In additional to the generic equality predicates, Lisp also provides
;;; type-specific predicates for numbers, strings, and characters.
(define-test =
;; The function = behaves just like EQUALP on numbers.
;; #C(... ...) is syntax sugar for creating a complex number.
(true-or-false? ____ (= 99.0 99 99.000 #C(99 0) #C(99.0 0.0)))
(true-or-false? ____ (= 0 1 -1))
(true-or-false? ____ (= (/ 2 3) (/ 6 9) (/ 86 129))))
(define-test string=
;; The function STRING= behaves just like EQUAL on strings.
;; The function STRING-EQUAL behaves just like EQUALP on strings.
(true-or-false? ____ (string= "Foo" "Foo"))
(true-or-false? ____ (string= "Foo" "FOO"))
(true-or-false? ____ (string-equal "Foo" "FOO"))
;; These functions accept additional keyword arguments that allow one to
;; only compare parts of the strings.
(true-or-false? ____ (string= "together" "frog" :start1 1 :end1 3
:start2 2))
(true-or-false? ____ (string-equal "together" "FROG" :start1 1 :end1 3
:start2 2)))
(define-test char=
;; The function CHAR= behaves just like EQL on characters.
;; The function CHAR-EQUAL behaves just like EQUALP on characters.
(true-or-false? ____ (char= #\A (char "ABCDEF" 0)))
(true-or-false? ____ (char= #\A #\a))
(true-or-false? ____ (char-equal #\A (char "ABCDEF" 0)))
(true-or-false? ____ (char-equal #\A #\a)))