[R6RS] NaNs and infinities

William D Clinger will at ccs.neu.edu
Wed Mar 8 11:21:45 EST 2006

```Kent wrote:
> > > > (integer? -inf.0)  ==>  #f
> > >
> > > If (integer? 0.0) => #t, I'd prefer that (integer? -inf.0) be #t.
> >
> > If (integer? -inf.0) is #t, then -inf.0 would be an integer
> > that isn't rational, which seems strange.  We just went to
> > some trouble to eliminate a similar strangeness in SRFI 77,
> > and I'm not eager to create that problem again.
>
> I would have (rational? -inf.0) be #t as well.
>
> Beyond a certain number of digits, all IEEE floats are integers.  +inf.0
> and -inf.0, which represent the limits that the sequence of representable
> floats apprach in either direction, should also be integers.

As you explained, +inf.0 actually stands for all of the real
numbers that are above a certain size.  Most of the numbers
for which +inf.0 stands are not integers.  That argument is
not at all convincing, however, because the same is true of
*all* inexact integers.

At some point, you have to look at the operational meaning
of integer? and other predicates.  One of the main uses of
integer? in SRFI 77 is to define the domain on which things
like flodd?, fleven?, flquotient, flremainder, inexact-odd?,
and inexact-even? are defined.  If we don't want to have to
describe how these things behave on +inf.0 or -inf.0, then
we can exclude them from the domain by defining them as
non-integers.  That is the approach taken in SRFI 77.

This would be a bad thing to do if there were plausible
examples of problems it would cause.  If you can think
of such problems, we'd like to hear about them.

> I'm not even sure why you treat +nan.0 as irrational.  This is definitely
> a departure from R5RS, which not only allows rational? to be the same as
> real? but states that this is how it will be in most implementations.

No, the R5RS says rational? and real? will be the same
in *many* implementations.  A quick check shows that
they aren't the same in Chez Scheme, Larceny, Gambit,
Bigloo, scheme48, or MzScheme.  (Hint: eq?)

> I don't understand why you have departed from that.

In mathematics, a rational number has a finite integral
numerator and denominator.  Both the standards document
and working programmers need some way to distinguish
the finite inexact reals from the infinities and NaNs.
That seems like a natural use for the rational? predicate,
which has not heretofore had much in the way of a portable
semantics on inexact numbers anyway.

Gambit and perhaps a few other implementations have
already been using the SRFI 77 semantics for rational?.
It's a reasonable thing to do.

> > The behaviors exhibited by Larceny, Gambit, Bigloo, Java,
> > and Common Lisp preserve the closure properties that were
> > part of the rationale for SRFI 77.  The behaviors exhibited
> > by MzScheme, Chez Scheme, and MIT Scheme do not have those
> > closure properties, but they are very much in tune with the
> > model for arithmetic that was adopted in the RRRS that came
> > out of the Brandeis meeting.
>
> Can you elaborate?

I was talking about the general idea of closure properties
being desirable, as discussed in the rationale for SRFI 77.
There exist desirable closure properties that SRFI 77 does
not require or even address explicitly.

One of those is connected to the idea of function types,
where a function type A x B -> C means that functions
of that type, when given an argument of type A and one
of type B, will return a result of type C if they return
at all.  With this notion of function type, the type of
+ is the intersection type formed by intersecting all of
the following function types:

complex x complex -> complex
real x real -> real
rational x rational -> rational
integer x integer -> integer
exact x exact -> exact
inexact x inexact -> inexact

In Larceny, and in several other systems that use flow
analysis to infer types, + also has the function types

inexact x exact -> inexact
exact x inexact -> inexact

I regard these last two types are closure properties,
just as the second function type shown below is a closure
property of the type of cons:

object x object -> pair
object x list -> list

If the R6RS were to *require* the * procedure to return
an exact result in cases where the R5RS allows an inexact,
then * would no longer be allowed to have the
inexact x exact -> inexact and exact x inexact -> inexact
types on which Larceny/Gambit/Bigloo/Stalin rely for flow
analysis.  That is the connection with the rationale for
SRFI 77.

> > Some of the participants in the SRFI 77 discussion would
> > argue as I would.  IIRC, the participants who argued for
> > allowing (* 0 3.5) to evaluate to an exact 0 were mainly
> > concerned that this behavior be allowed; I don't remember
> > anyone arguing that it should be required (although there
> > were some pretty strange things said in that discussion).
>
> I would prefer that it be required, but I'll settle for allowed.
> Similarly, I prefer that (/ x 0) be an error, but I'll settle for allowed.

> I'm interested in your response to this comment in my earlier note:
>
> > > (flonum->fixnum -inf.0)  ==>  -8388608      ; correct under supposition
>
> > Even under the supposition that the fixnum range is [-8388608,8388607], I
> > really dislike this.  I think this should raise an exception (in safe
> > mode, of course), as should any input outside of the fixnum range.

IMO, the flonum->fixnum procedure is unnecessary.  I think
Mike added it to SRFI 77 to satisfy his sense of orthogonality,
but it doesn't make much sense if the fixnum and flonum
operations are in separate libraries.  Programmers can use

> One more thing:  I'd prefer that we not allow nan.0 and inf.0, partly
> because these were previously valid R5RS symbols, and partly to avoid the
> extra overhead in the reader.  I think +nan.0, -nan.0, +inf.0, and -inf.0
> are sufficient.