► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

▼ | 4 | Datatypes

4.1 | Equality
4.2 | Booleans
4.3 | Numbers
4.4 | Strings
4.5 | Byte Strings
4.6 | Characters
4.7 | Symbols
4.8 | Regular Expressions
4.9 | Keywords
4.10 | Pairs and Lists
4.11 | Mutable Pairs and Lists
4.12 | Vectors
4.13 | Boxes
4.14 | Hash Tables
4.15 | Sequences and Streams
4.16 | Dictionaries
4.17 | Sets
4.18 | Procedures
4.19 | Void
4.20 | Undefined

► | 4.1 | Equality

4.1.1 | Object Identity and Comparisons
4.1.2 | Equality and Hashing
4.1.3 | Implementing Equality for Custom Types

On this page:

equal?
eqv?
eq?
equal?/ recur
4.1.1`` Object Identity and Comparisons
4.1.2`` Equality and Hashing
equal-hash-code
equal-secondary-hash-code
eq-hash-code
eqv-hash-code
4.1.3`` Implementing Equality for Custom Types
gen: equal+ hash
prop: equal+ hash

8.2
top ← prev up next →

#### 4.1`` Equality

Equality is the concept of whether two values are “the same.” Racket supports a few different kinds of equality by default, though equal? is preferred for most use cases.

> > procedure

> > (equal? v1 v2) → boolean?

> v1 : any/c
> v2 : any/c

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. See also gen:equal+hash and prop:impersonator-of.

Examples:

> > (equal? 'yes 'yes)
> #t
> > (equal? 'yes 'no)
> #f
> > (equal? (* 6 7) 42)
> #t
> > (equal? (expt 2 100) (expt 2 100))
> #t
> > (equal? 2 2.0)
> #f
> > (let ([v (mcons 1 2)]) (equal? v v))
> #t
> > (equal? (mcons 1 2) (mcons 1 2))
> #t
> > (equal? (integer->char 955) (integer->char 955))
> #t
> > (equal? (make-string 3 #\z) (make-string 3 #\z))
> #t
> > (equal? #t #t)
> #t

> > procedure

> > (eqv? v1 v2) → boolean?

> v1 : any/c
> v2 : any/c

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

The number and character datatypes are the only ones for which eqv? differs from eq?. Two numbers are eqv? when they have the same exactness, precision, and are both equal and non-zero, both +0.0, both +0.0f0, both -0.0, both -0.0f0, both +nan.0, or both +nan.f—considering real and imaginary components separately in the case of complex numbers. Two characters are eqv? when their char->integer results are equal.

Generally, eqv? is identical to equal? except that the former cannot recursively compare the contents of compound data types (such as lists and structs) and cannot be customized by user-defined data types. The use of eqv? is lightly discouraged in favor of equal?.

Examples:

> > (eqv? 'yes 'yes)
> #t
> > (eqv? 'yes 'no)
> #f
> > (eqv? (* 6 7) 42)
> #t
> > (eqv? (expt 2 100) (expt 2 100))
> #t
> > (eqv? 2 2.0)
> #f
> > (let ([v (mcons 1 2)]) (eqv? v v))
> #t
> > (eqv? (mcons 1 2) (mcons 1 2))
> #f
> > (eqv? (integer->char 955) (integer->char 955))
> #t
> > (eqv? (make-string 3 #\z) (make-string 3 #\z))
> #f
> > (eqv? #t #t)
> #t

> > procedure

> > (eq? v1 v2) → boolean?

> v1 : any/c
> v2 : any/c

Return #t if v1 and v2 refer to the same object, #f otherwise. As a special case among numbers, two fixnums that are = are also the same according to eq?. See also Object Identity and Comparisons.

Examples:

> > (eq? 'yes 'yes)
> #t
> > (eq? 'yes 'no)
> #f
> > (eq? (* 6 7) 42)
> #t
> > (eq? (expt 2 100) (expt 2 100))
> #f
> > (eq? 2 2.0)
> #f
> > (let ([v (mcons 1 2)]) (eq? v v))
> #t
> > (eq? (mcons 1 2) (mcons 1 2))
> #f
> > (eq? (integer->char 955) (integer->char 955))
> #t
> > (eq? (make-string 3 #\z) (make-string 3 #\z))
> #f
> > (eq? #t #t)
> #t

> > procedure

> > (equal?/recur v1 v2 recur-proc) → boolean?

> v1 : any/c
> v2 : any/c
> recur-proc : (any/c any/c -> any/c)

Like equal?, but using recur-proc for recursive comparisons (which means that reference cycles are not handled automatically). Non-#f results from recur-proc are converted to #t before being returned by equal?/recur.

Examples:

> > (equal?/recur 1 1 (lambda (a b) #f))
> #t
> > (equal?/recur '(1) '(1) (lambda (a b) #f))
> #f

> > (equal?/recur '#(1 1 1) '#(1 1.2 3/4)
> (lambda (a b) (<= (abs (- a b)) 0.25)))

> #t

##### 4.1.1`` Object Identity and Comparisons

The eq? operator compares two values, returning #t when the values refer to the same object. This form of equality is suitable for comparing objects that support imperative update (e.g., to determine that the effect of modifying an object through one reference is visible through another reference). Also, an eq? test evaluates quickly, and eq?-based hashing is more lightweight than equal?-based hashing in hash tables.

In some cases, however, eq? is unsuitable as a comparison operator, because the generation of objects is not clearly defined. In particular, two applications of + to the same two exact integers may or may not produce results that are eq?, although the results are always equal?. Similarly, evaluation of a lambda form typically generates a new procedure object, but it may re-use a procedure object previously generated by the same source lambda form.

The behavior of a datatype with respect to eq? is generally specified with the datatype and its associated procedures.

##### 4.1.2`` Equality and Hashing

All comparable values have at least one hash code — an arbitrary integer (more specifically a fixnum) computed by applying a hash function to the value. The defining property of these hash codes is that equal values have equal hash codes. Note that the reverse is not true: two unequal values can still have equal hash codes. Hash codes are useful for various indexing and comparison operations, especially in the implementation of hash tables. See Hash Tables for more information.

> > procedure

> > (equal-hash-code v) → fixnum?

> v : any/c

Returns a hash code consistent with equal?. For any two calls with equal? values, the returned number is the same. A hash code is computed even when v contains a cycle through pairs, vectors, boxes, and/or inspectable structure fields. Additionally, user-defined data types can customize how this hash code is computed by implementing gen:equal+hash.

For any v that could be produced by read, if v2 is produced by read for the same input characters, the (equal-hash-code v) is the same as (equal-hash-code v2) — even if v and v2 do not exist at the same time (and therefore could not be compared by calling equal?).

Changed in version 6.4.0.12 of package base: Strengthened guarantee for readable values.

> > procedure

> > (equal-secondary-hash-code v) → fixnum?

> v : any/c

Like equal-hash-code, but computes a secondary hash code suitable for use in double hashing.

> > procedure

> > (eq-hash-code v) → fixnum?

> v : any/c

Returns a hash code consistent with eq?. For any two calls with eq? values, the returned number is the same.

> > > Equal fixnums are always eq?.

> > procedure

> > (eqv-hash-code v) → fixnum?

> v : any/c

Returns a hash code consistent with eqv?. For any two calls with eqv? values, the returned number is the same.

##### 4.1.3`` Implementing Equality for Custom Types

> > value

> > gen:equal+hash : any/c

A generic interface (see Generic Interfaces) for types that can be compared for equality using equal?. The following methods must be implemented:

- equal-proc : (-> any/c any/c (-> any/c any/c boolean?) any/c) — tests whether the first two arguments are equal, where both values are instances of the structure type to which the generic interface is associated (or a subtype of the structure type).

  The third argument is an equal? predicate to use for recursive equality checks; use the given predicate instead of equal? to ensure that data cycles are handled properly and to work with equal?/recur (but beware that an arbitrary function can be provided to equal?/recur for recursive checks, which means that arguments provided to the predicate might be exposed to arbitrary code).

  The equal-proc is called for a pair of structures only when they are not eq?, and only when they both have a gen:equal+hash value inherited from the same structure type. With this strategy, the order in which equal? receives two structures does not matter. It also means that, by default, a structure sub-type inherits the equality predicate of its parent, if any.

- hash-proc : (-> any/c (-> any/c exact-integer?) exact-integer?) — computes a hash code for the given structure, like equal-hash-code. The first argument is an instance of the structure type (or one of its subtypes) to which the generic interface is associated.

  The second argument is an equal-hash-code-like procedure to use for recursive hash-code computation; use the given procedure instead of equal-hash-code to ensure that data cycles are handled properly.

  Although the result of hash-proc can be any exact integer, it will be truncated for most purposes to a fixnum (e.g., for the result of equal-hash-code). Roughly, truncation uses bitwise-and to take the lower bits of the number. Thus, variation in the hash-code computation should be reflected in the fixnum-compatible bits of hash-proc’s result. Consumers of a hash code are expected to use variation within the fixnum range appropriately, and producers are not responsible to reflect variation in hash codes across the full range of bits that fit within a fixnum.

- hash2-proc : (-> any/c (-> any/c exact-integer?) exact-integer?) — computes a secondary hash code for the given structure. This procedure is like hash-proc, but analogous to equal-secondary-hash-code.

Take care to ensure that hash-proc and hash2-proc are consistent with equal-proc. Specifically, hash-proc and hash2-proc should produce the same value for any two structures for which equal-proc produces a true value.

When a structure type has no gen:equal+hash implementation, then transparent structures (i.e., structures with an inspector that is controlled by the current inspector) are equal? when they are instances of the same structure type (not counting sub-types), and when they have equal? field values. For transparent structures, equal-hash-code and equal-secondary-hash-code derive hash code using the field values. For opaque structure types, equal? is the same as eq?, and equal-hash-code and equal-secondary-hash-code results are based only on eq-hash-code. If a structure has a prop:impersonator-of property, then the prop:impersonator-of property takes precedence over gen:equal+hash if the property value’s procedure returns a non-#f value when applied to the structure.

Examples:

> (define (farm=? farm1 farm2 recursive-equal?)
> (and (= (farm-apples farm1)
> (farm-apples farm2))
> (= (farm-oranges farm1)
> (farm-oranges farm2))
> (= (farm-sheep farm1)
> (farm-sheep farm2))))
> (define (farm-hash-code farm recursive-equal-hash)
> (+ (* 10000 (farm-apples farm))
> (* 100 (farm-oranges farm))
> (* 1 (farm-sheep farm))))
> (define (farm-secondary-hash-code farm recursive-equal-hash)
> (+ (* 10000 (farm-sheep farm))
> (* 100 (farm-apples farm))
> (* 1 (farm-oranges farm))))
> (struct farm (apples oranges sheep)
> #:methods gen:equal+hash
> [(define equal-proc farm=?)
> (define hash-proc farm-hash-code)
> (define hash2-proc farm-secondary-hash-code)])
> (define eastern-farm (farm 5 2 20))
> (define western-farm (farm 18 6 14))
> (define northern-farm (farm 5 20 20))
> (define southern-farm (farm 18 6 14))

> > (equal? eastern-farm western-farm)
> #f
> > (equal? eastern-farm northern-farm)
> #f
> > (equal? western-farm southern-farm)
> #t

> > value

> > prop:equal+hash : struct-type-property?

A structure type property (see Structure Type Properties) that supplies an equality predicate and hashing functions for a structure type. Using the prop:equal+hash property is discouraged; the gen:equal+hash generic interface should be used instead. A prop:equal+hash property value is a list of three procedures that correspond to the methods of gen:equal+hash:

- equal-proc : (-> any/c any/c (-> any/c any/c boolean?) any/c)

- hash-proc : (-> any/c (-> any/c exact-integer?) exact-integer?)

- hash2-proc : (-> any/c (-> any/c exact-integer?) exact-integer?)

top ← prev up next →