0

I'm learning Scheme and I want to compare two variables, but I don't know which type will have each of them.

On this SO answer, tells when to use =, eqv?, equal? and eq?, but I haven't found what I'm looking for.

My problem is that, the variables could be:

  1. List: '(1 2) or '((10) 2).
  2. String: 'sunny.
  3. Number: 2.

So I could be comparing a number with a list, or a list with a string.

I have this code:

(define contains?
  (lambda (lst element)
    (cond
      [(null? lst) #f]
      [(equal? (car lst) element) #t]
      (else [(contains? (cdr lst) elements)]))))

Which operator could I use to compare two of these variables?

VansFannel
  • 45,055
  • 107
  • 359
  • 626

2 Answers2

3

If you want to test them for equality, then equal? is your best bet, it's the most general equality predicate and as such it works on multiple data types, and does recursive comparisons for the cases of lists, vectors, etc.:

Two values are equal? if and only if they are eqv?, unless otherwise specified for a particular datatype.

Datatypes with further specification of equal? include strings, byte strings, pairs, mutable pairs, vectors, boxes, hash tables, and inspectable structures. In the last six cases, equality is recursively defined; if both v1 and v2 contain reference cycles, they are equal when the infinite unfoldings of the values would be equal.

Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
0

Just to add to Oscars answer. There are type specific procedures like string=?, char=?, and = for numbers, but to compare on general there are 3:

  • eq? tests if two arguments are the same value, as in created at the same instant or pointer equal.
  • eqv? tests if two primitive/scalar/atomic values look the same when displayed
  • equal? tests if two values look the same

Also, what is #t for eq? is guaranteed to be #t for eqv? abd what is #t for eqv? is guaranteed to be #t for equal?.

I have read books that completely skip eqv? and just keep eq? and equal? as general comparison. A fair amount of procedures that compare stuff have 3 versions of the 3 methods of comparison across the board. Eg. member (equal?), memv (eqv?), memq (eq?).

About eq?: We are guaranteed that '(), #t, #f and the symbols, like 'test would evaluate to the same value each and every time so they are always pointer equal. Other values might be, like number between a billion, but you have no guarantee all implementations will do it. (eq? 10 10) ; ==> #f is correct according to the standard as well as (eq? '(a) '(a)) ; ==> #t. In fact the two examnples can have any result and it's OK for the report. Notice how I say you are guaranteed to be #t withe eqv? if eq? yuilds #t but not vice versa. If something is eqv? you still have no idea what eq? would be.

Sylwester
  • 47,942
  • 4
  • 47
  • 79