I am writing a bunch of tests using check-equal? with objects that contain syntax objects that are not eq?. For the purposes of these tests, I am okay with saying that two syntax objects are equal if they're equal when given to syntax->datum. (Yes, I know that looses a lot of binding information, but for now, ensuring their datums are equal is good enough. I will test that the binding information is good later.)
If the two objects are not syntax objects, however, I want them to be equal if they are equal? to each other.
However, if those objects contain syntax objects in them at some recursive point, I want to test their equality on their datums, so I can't just do:
(define (my-equal? a b)
(if (and (syntax? a) (syntax? b)
(equal? (syntax->datum a) (syntax->datum b))
(equal? a b)))
(define-binary-check (check-my-equal? my-equal? actual expected))
Because this will not do the recursive check.
I could handle the recursion myself, and only use equal? on primitives, but that would be paramount to implementing my own equality testing.
You can use
equal?/recurto get this behavior. This function behaves likeequal?, but takes a different function in the case of a recursive call. So you could potentially implementmy-equal?like this:However, note that because you are providing the recursive function,
equal?/recurdoes not do any cycle detection for you. As such, you need to do it yourself. One easy way to do this is with parameters:And then, of course, as you noticed in your question, you can use
define-binary-checkto turn this procedure into something RackUnit can you.