Formal comment #65 (defect)
eq?/eqv? misbehave around NaNs
Reported by: John Cowan
Component: Base library
Summary
The fact that (= +nan.0 +nan.0) is #f has unexpected knock-on effects
on eq? and eqv?. Description
In particular, (lambda (x) (eqv? x x) +nan.0) and its equivalent
(lambda (x) (eq? x x) +nan.0) are compelled to return #f by the
definitions of eqv? and eq?. This is extremely counterintuitive, and
makes the suggestion that eq? compare pointers unusable: the pointers
must be checked to see if they happen to point to flonums which happen
to be NaNs?.
I have two alternative proposals:
1) Allow eqv? and eq? to return either #t or #f if both arguments are
NaNs?. 2) Require eqv? to return #t if both arguments are NaNs?.
eq? would be permitted to return either #t or #f, as with all numbers.
RESPONSE:
That specification of `eqv?' says that `eqv?' returns #t "if" any of
several things are true, and returns #f "if" any of several other
things are true. There is no "only if" or "if and only if". The
behavior of eqv? on NaNs is not specified by section 9.6. A
clarifying example will be added to that effect.
The basic reason why the behavior of `eqv?' is not specified on NaNs
is that the IEEE-754 standard does not say much about how the bits of
a NaN are to be interpreted, and explicitly allows implementations of
that standard to use most of a NaN's bits to encode
implementation-dependent semantics. The implementors of a Scheme
system should therefore decide how `eqv?' should interpret those bits.