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

Re: Exactness



Thomas Bushnell BSG <tb@xxxxxxxxxx> writes:

>> Querying is too late: when program needs a particular characteristic,
>> it doesn't help it that it could detect that the implementation
>> doesn't meet its expectations.
>
> Oh, so you want to demand that all Scheme systems must implement
> whatever feature you need for that program?  How does that go?

It's not an exotic feature but quite a common need, and they already
mostly provide it. Except some embedded implementations, and except
that it's not done consistently wrt. +inf.0, -inf.0, +nan.0, -0.0,
exactness of complex numbers, acceptability of inexact integers by
procedures which require integers, the set of additional procedures
provided as extensions, and perhaps other minor issues.

>> I disagree. There are programs which require flonums or something
>> which behave similarly. All Scheme implementations I know and all
>> other general-purpose languages I know provide flonums.
>
> No, Scheme does not provide "flonums".  Some Scheme systems provide an
> implementation of inexact reals which is similar to the Lisp notion of
> a flonum.  But that's not the same thing.

Which differences do you have in mind? For me it's close enough.

>> Consider the example at the end of R5RS run on a typical Scheme
>> implementation with floats and ratios, augmented with displaying all
>> elements of the lazy list it produces. It runs fine. But when we
>> replace the two inexact numbers in the initial state with exact ones
>> of the same values, fractions become bigger and bigger, even though
>> the growing precision it accumulates is useless: the algorithm is
>> inexact to begin with!
>
> But this is not a feature of exactness; it's a feature of the
> particular strategy chosen to implement exactness.

Which everybody chooses. So we have the choice:

A. The programmer could use exact numbers here, hoping that some day
   someone will invent a Scheme implementation which would compile
   this program into efficient code. The decision was also supported
   by the fear that some weird Scheme implementation could choose the
   default format of inexact real numbers such that the version with
   inexact numbers would accumulate increasing precision eating more
   and more memory.

B. The programmer knows that ratnums are inappropriate here, and
   at the same time knows that flonums are appropriate. He chooses
   flonums by writing a number with a decimal point, and all existing
   Scheme implementations run this code fine.

I'm choosing B. Everybody would do that in practice. The Scheme
standard doesn't guarantee that it will work well however, and it
doesn't provide any better way either. The common practice suggests
that it's fine, so it's the only sane choice.

Here is another story. A programmer wants to make a portable program
which calculates taxes and Bank interests, and he needs to choose the
representation of monetary amounts and interest percentages. He knows
that flonums are inappropriate. Choices:

C. He uses ratnums, and (hypothetical for now) functions which format
   ratnums into decimal fractions with the given number of trailing
   zeros, parsers which convert "12.99" into an exact number, and
   procedures for rounding at the given decimal place.

D. He is afraid that for some Scheme implementations 1/100 is a
   flonum, so he uses scaled integers, reimplementing arithmetic
   operations, formatting and parsing, being careful to not confuse
   scaled and unscaled numbers, and deciding whether the scale can
   be a global constant or must be different for different numbers.
   On some Scheme implementations the program only handles intermediate
   results up to $10M, above which they silently become negative.

This time I would prefer C. Now we have D.

Speciyfing too little is as bad as specifying too much.

>> I want portable flonums.
>
> Do you care whether they are called "portable flonums"?
> Can we call them something else and you will be happy?

I care that they are fast, that they are used by default for numbers
entered with a decimal point, that I don't have to check whether
exp(x) will overflow before applying exp, that a number which has
overflowed can be printed and read by other implementations, that
arctangent of a number which has overflowed is close to pi/2, and that
if I need to interface to C in order to compute erf(x), then the only
portability issues will be with linking with C - not with passing the
numeric value.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@xxxxxxxxxx
    ^^     http://qrnik.knm.org.pl/~qrczak/