John Cowan <cowan_at_ccil.org> writes:
> The same applies to the != function, which Scheme does not have:
> it too must return #f.
No, it's the negation of ==, and for two NaNs it is #t.
< > <= >= for two NaNs are #f.
> However, we have more flexibility about the behavior of eqv? when both
> arguments are flonums. It could return #f if either argument is a NaN,
> as = does; or return #t iff the bit patterns being compared are the same;
> or return #t if both arguments are NaNs, whether the bit patterns are
> the same or different. (Chicken defers to =, and takes the first option.)
The first choice is silly. Since the language is fortunate to
distinguish equivalence and numeric equality, it's natural to make
eqv? the finest equivalence relation which doesn't take the physical
address of certain "value objects" into account. That is, 0.0 and -0.0
are not equivalent but equal, NaN is equivalent to itself but inequal
to itself, and 3 is not equivalent to 3.0 although numerically equal.
Both the second and the third choice is reasonable, because the
natural definition of eqv? is a bit self-referential. In order to
define eqv? in terms of distinguishable values, one needs to consider
operations which can be used to distinguish them. Including eqv?
among these operations makes the self-reference lead to an ambiguous
definition, including eq? even makes eqv? the same as eq?, OTOH a
language is not necessarily prepared for consideration of the language
with some important functions excluded.
On my x86 hardware one can easily construct at least two NaNs
which differ in the sign. Low-level C functions like signbit() and
copysign() clearly distinguish them, and unary negation transforms
one into the other.
Distinguishing them leads to a simpler implementation: eqv? can be
implemented by comparing bit representations, a binding to signbit()
(useful for distinguishing 0.0 from -0.0) doesn't have to treat NaNs
as a special case, and exposing the bit representation again doesn't
have to treat NaNs specially and pretend that there is only a single
NaN.
OTOH I see no practical utility in distinguishing these two kinds
of NaNs. I'm not even sure whether it is specified which operations
produce which NaNs.
I would vote for allowing NaNs which are not eqv? if they have
different bit representations, but each value, including a NaN,
must be eqv? to itself.
--
__("< Marcin Kowalczyk
\__/ qrczak_at_knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
Received on Wed Sep 20 2006 - 15:02:30 UTC