[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: building other EQUIV?-like predicates

This page is part of the web mail archives of SRFI 85 from before July 7th, 2015. The new archives for SRFI 85 contain all messages, not just those from before July 7th, 2015.

Sebastian Egner raised an excellent point:

> In many cases I need an application-specific
> equivalence which is not among the predefined
> ones. For example, it should deal with cyclic
> structures the way EQUIV? does, but floats are
> compared only up to a certain tolerance (not
> that this results in an actual 'equivalence,'
> but it is often needed as a predicate anyhow).
> Another example is the presence of user-defined
> record types; equivalence predicates that are
> meaningful for the application can ignore some
> fields while recursing only on others.
> In these situations, I would still end up implementing a
> lot of code similar to the reference implementation you
> give but with little modifications in the recursion, or
> for the atomic types.

It would not be hard to provide parameterized
versions, say equivalent? and dag-equivalent?,
that take a predicate as their first argument
and use that predicate when comparing leaf nodes
(defined as anything that isn't a pair or vector).

Then (equiv? x y) would be like (equivalent? eqv? x y),
and (dag-equiv? x y) like (dag-equivalent? eqv? x y).
Your example might be something like

(define myequiv?
  (let* ((epsilon 1e-14)
         (leaf-equal? (lambda (x y)
                        (if (and (complex? x) (complex? y))
                            (< (magnitude (- x y))
                               (* epsilon
                                  (max 1.0
                                       (magnitude x)
                                       (magnitude y))))
                            (eqv? x y)))))
    (lambda (x y)
      (equivalent? leaf-equal? x y))))

It might be better to define make-equiv-predicate
and make-dag-equiv-predicate, which would take a
total predicate as their lone argument and return
a recursive binary predicate as their result.