# Equal?/recur examples

**URL:** <https://racket.discourse.group/t/equal-recur-examples/4143>\
**Category:** Questions & Answers\
**Created:** [March 12, 2026, 6:14pm UTC](https://racket.discourse.group/t/equal-recur-examples/4143 "2026-03-12T18:14:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![matteo-daddio](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/matteo-daddio/32/1245_2.png) [@matteo-daddio](https://racket.discourse.group/u/matteo-daddio)\
**Post date:** [March 12, 2026, 6:14pm UTC](https://racket.discourse.group/t/equal-recur-examples/4143/1 "2026-03-12T18:14:54Z")

</div>

Hello,

reading the racket guide I found the `equal?/recur` function. I find difficult to understand how it works. Does somebody have some interesting examples?

Thank you

Matteo

---

<div class="post-metadata">

**Author:** ![AlexKnauth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/alexknauth/32/242_2.png) [@AlexKnauth](https://racket.discourse.group/u/AlexKnauth)\
**Post date:** [March 12, 2026, 7:07pm UTC](https://racket.discourse.group/t/equal-recur-examples/4143/2 "2026-03-12T19:07:44Z")

</div>

Here's an example of one way I've used `equal?/recur` to compare syntax objects in test cases:

```scheme
(require rackunit)

;; Works on fully wrapped, non-wrapped, and partially
;; wrapped values, and it checks that the inputs are
;; wrapped in all the same places. It checks scopes,
;; but it does not check source location.
(define-binary-check (check-stx=? stx=? actual expected))

;; Stx Stx -> Bool
(define (stx=? a b)
  (cond
    [(and (identifier? a) (identifier? b))
     (bound-identifier=? a b)]
    [(and (syntax? a) (syntax? b))
     (and (bound-identifier=? (datum->syntax a '||) (datum->syntax b '||))
          (stx=? (syntax-e a) (syntax-e b)))]
    [else
     (equal?/recur a b stx=?)]))

```

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [March 13, 2026, 3:19pm UTC](https://racket.discourse.group/t/equal-recur-examples/4143/3 "2026-03-13T15:19:27Z")

</div>

One way to think about `equal?/recur` is that it knows how to recur on built-in compound data, and it knows how to determine equality of built-in atomic data.

By supplying a `recur-proc`, we can customize how atomic data are compared, without having to explicitly handle the recurrence on compound data.

For example, say I want to compare reals approximately. If they are within 0.5, they should be considered equal. But I also want to make the comparison work with vectors, lists, structures containing reals.

Here’s one possible implementation.

```scheme
#lang racket

(define (approx-= a b)
  (cond
    [(and (real? a) (real? b))
     (<= (abs (- a b)) 0.5)]
    [else (equal?/recur a b approx-=)]))

(approx-= 1 2) ;=> #f
(approx-= 1 1) ;=> #t
(approx-= 0.7 1) ;=> #t
(approx-= (list 0.7 2 "hello") (list 1 2.1 "hello")) ;=> #t
(approx-= (vector 0.7 2 "hello") (vector 1 10 "hello")) ;=> #f
(approx-= (list (vector 0.7)) (list (vector 1))) ;=> #t

```

---

<div class="post-metadata">

**Author:** ![matteo-daddio](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/matteo-daddio/32/1245_2.png) [@matteo-daddio](https://racket.discourse.group/u/matteo-daddio)\
**Post date:** [March 14, 2026, 9:50am UTC](https://racket.discourse.group/t/equal-recur-examples/4143/4 "2026-03-14T09:50:14Z")

</div>

Thank you Sorawee!
