larcenists / larceny

Larceny Scheme implementation
Other
202 stars 32 forks source link

integer? returns false for all compnums #796

Closed jkoser closed 7 years ago

jkoser commented 7 years ago

For example,

> (integer? 0.0+0.0i)
#f

I think it should return true for a compnum x if (and (integer? (real-part x)) (zero? (imag-part x))).

WillClinger commented 7 years ago

This is not a bug.

R6RS section 11.7.4.1 says "If z is a complex number object, then (real? z) is true if and only if (zero? (imag-part z)) and (exact? (imag-part z)) are both true."

That means real? returns false for 0.0+0.0i. That means rational? and integer? also return false for 0.0+0.0i.

The (unofficial) R6RS Rationale explains, in section 11.6.6, that the real number objects are closed under certain operations, as are the integer objects. Those closure properties would not hold if 0.0+0.0i were considered a real or an integer. Section 11.6.6.2 elaborates:

R5RS creates a more insidious problem by defining (real? z) to be true if and only if (zero? (imag-part z)) is true. This means, for example, that -2.5+0.0i is real. If -2.5+0.0i is represented as a compnum, then the compiler cannot rely on x being a flonum in the consequent of (if (real? x) ). This problem could be fixed by writing all of the arithmetic operations so that any compnum with a zero imaginary part is converted to a flonum before it is returned, but that merely creates an analogous problem for compnum arithmetic, as explained below. R6RS adopted a proposal by Brad Lucier to fix the problem: (real? z) is now true if and only if (imag-part z) is an exact zero.

The compnum representation type is closed under virtually all operations, provided no operation that accepts two compnums as its argument ever returns a flonum. To work around the problem described in the paragraph above, several implementations automatically convert compnums with a zero imaginary part to the flonum representation. This practice virtually destroys the effectiveness of flow analysis for inferring the compnum representation, so it is not a good workaround. To improve the effectiveness of flow analysis, it is better to change the definition of Scheme’s real number objects as described in the paragraph above.

The R7RS retained an R6RS example saying (real? 2.5+0.0i) returns false. Some members of Working Group 1 believe that was an error. I suspect some members of that working group probably did fail to understand the importance of the R6RS change in specification. We are lucky the R7RS retained the R6RS example mandating the superior semantics of R6RS, but those who believe that was an error have succeeded in having this issue listed in the R6RS errata, which states "No resolution of the conflict has been reached as yet."

The R6RS specification is clear, and the R7RS specification is self-contradictory. Larceny will continue to implement the superior semantics.

jkoser commented 7 years ago

Got it. I was going on the statement that exactness is orthogonal to type, but I guess the issue is not as clear as it appeared to me. Thanks for setting me straight.