-
Notifications
You must be signed in to change notification settings - Fork 566
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
371 additions
and
379 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,92 +1,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. | ||
;;; 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 are eq, eql, equal and equalp | ||
;; eq is similar to comparing c pointers | ||
(define-test test-eq | ||
"(eq x y) is true if and only if x and y are the same identical object | ||
eq is like comparing pointers in c. If the values are EQ, any non-nil | ||
value may be returned." | ||
(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"))) | ||
;;; The most common equality predicates in Common Lisp are, in order of | ||
;;; strictness, EQ, EQL, EQUAL, and EQUALP. | ||
|
||
(define-test test-eql | ||
"(eql x y) is true if (eq x y) | ||
also it is true if x and y are numeric of the same type | ||
and represent the same number. | ||
(eql x y) also if x and y are the same characters." | ||
(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 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 test-equal | ||
"(equal x y) is true if (eql x y), or | ||
x and y are lists with equal elements, or | ||
x and y character or bit arrays with 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 "Foo" (copy-seq "Foo"))) | ||
(true-or-false? ___ (equal "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 test-equalp | ||
"(equalp x y) if (equal x y) or | ||
if x and y are strings with the same characters (case independent). | ||
if x and y are arrays with the same dimensions and equal elements | ||
if x and y are numeric of different types but one may be upgraded to | ||
the other type without loss and still exhibit equality." | ||
(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"))) | ||
(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"))) | ||
|
||
(define-test test-numeric-equal | ||
"(= x y) is only for numerics | ||
and can take multiple arguments | ||
if x or y is not numeric there will be a compiler error." | ||
(true-or-false? ___ (= 99.0 99 99.000)) | ||
(true-or-false? ___ (= 0 1 -1)) | ||
(true-or-false? ___ (= (/ 2 3) (/ 6 9) (/ 86 129)))) | ||
(defstruct thing slot-1 slot-2) | ||
|
||
; EQ, EQL, EQUAL, and EQUALP are general equality predicates. | ||
; Additionally, Lisp also provides the type-specific predicates. | ||
; For example, STRING= and STRING-EQUAL are predicates for strings. | ||
(define-test test-string-equal | ||
"string-equal is just like string= except that differences in case are ignored." | ||
(true-or-false? ___ (string= "Foo" "Foo")) | ||
(true-or-false? ___ (string= "Foo" "FOO")) | ||
(true-or-false? ___ (string= "together" "frog" :start1 1 :end1 3 :start2 2)) | ||
(true-or-false? ___ (string-equal "Foo" "FOO")) | ||
(true-or-false? ___ (string-equal "together" "FROG" :start1 1 :end1 3 :start2 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))) |
Oops, something went wrong.