Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
963 views
in Technique[技术] by (71.8m points)

functional programming - What is the difference between eq?, eqv?, equal?, and = in Scheme?

I wonder what the difference is between those operations in Scheme. I have seen similar questions in Stack Overflow but they are about Lisp, and there is not a comparison between three of those operators.

I am writing the different types of commands in Scheme, and I get the following outputs:

(eq? 5 5) -->#t
(eq? 2.5 2.5) -->#f
(equal? 2.5 2.5) --> #t
(= 2.5 2.5) --> #t

Why is this the case?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'll answer this question incrementally. Let's start with the = equivalence predicate. The = predicate is used to check whether two numbers are equal. If you supply it anything else but a number then it will raise an error:

(= 2 3)     => #f
(= 2.5 2.5) => #t
(= '() '()) => error

The eq? predicate is used to check whether its two parameters respresent the same object in memory. For example:

(define x '(2 3))
(define y '(2 3))
(eq? x y)         => #f
(define y x)
(eq? x y)         => #t

Note however that there's only one empty list '() in memory (actually the empty list doesn't exist in memory, but a pointer to the memory location 0 is considered as the empty list). Hence when comparing empty lists eq? will always return #t (because they represent the same object in memory):

(define x '())
(define y '())
(eq? x y)      => #t

Now depending upon the implementation eq? may or may not return #t for primitive values such as numbers, strings, etc. For example:

(eq? 2 2)     => depends upon the implementation
(eq? "a" "a") => depends upon the implementation

This is where the eqv? predicate comes into picture. The eqv? is exactly the same as the eq? predicate, except that it will always return #t for same primitive values. For example:

(eqv? 2 2)     => #t
(eqv? "a" "a") => depends upon the implementation

Hence eqv? is a superset of eq? and for most cases you should use eqv? instead of eq?.

Finally we come to the equal? predicate. The equal? predicate is exactly the same as the eqv? predicate, except that it can also be used to test whether two lists, vectors, etc. have corresponding elements which satisfy the eqv? predicate. For example:

(define x '(2 3))
(define y '(2 3))
(equal? x y)      => #t
(eqv? x y)        => #f

In general:

  1. Use the = predicate when you wish to test whether two numbers are equivalent.
  2. Use the eqv? predicate when you wish to test whether two non-numeric values are equivalent.
  3. Use the equal? predicate when you wish to test whether two lists, vectors, etc. are equivalent.
  4. Don't use the eq? predicate unless you know exactly what you're doing.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...