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

Re: Exactness

This page is part of the web mail archives of SRFI 77 from before July 7th, 2015. The new archives for SRFI 77 contain all messages, not just those from before July 7th, 2015.

Marcin 'Qrczak' Kowalczyk <qrczak@xxxxxxxxxx> writes:

> It would lead to a way too complex interface. There are too many
> interacting features to specify.

Good grief, you seem to be approaching this as if we didn't have
computers handy to help out.

(with-ieee-floating-point ...) can just be syntactic sugar for a
specification of whatever options is the right set.

> But how can we agree on the way of specifying these details if we
> can't agree whether Scheme should be mandated to support any kind
> of floating point at all?

Oh, I think it's already agreed that Scheme should not be mandated to
support floating point arithmetic.  At least, I can see no advantage
to such a mandate.  Do you think that mandating it will somehow change
anyone's behavior materially?  Standards are not sticks with which to
beat implementors into doing what you want.

> The R5RS knobs are very limited. It's basically one button for all
> numbers: exact/inexact. Everything else is supposed to be automatic.

No, rather everything else is not standardized.

> The user must even be prepared that the implementation itself will
> sometimes switch the button to "inexact". This is too inflexible.
> How do you propose to specify more?

You must stop thinking of "inexact" as a synonym for "floating
point".  Please.

> Below are some other features which matter.
> a) Do you think they should be independently settable, and the
>    implementation would be required to produce a numeric format
>    which fulfills any self-consistent combination of them?

I think that they (or something like these) should all be understood
by all Scheme systems.  I do not object to that.  I do not think that
any particular combination should be mandated, much less mandating all
possible combinations.  Those which do not support them (or some
combination of them) should be required to document their behavior and
behave sensibly when the cannot implement something.

> b) Or the programmer should have no portable way to control them,
>    as everything (besides the exactness bit) should depend on the
>    implementation?

The programmer should be able to specify clearly what he wants (where
*implementation* is not "what he wants", but only *sets of features*).

> c) Or a few prepackaged sets of choices should be provided (ratnums,
>    flonums etc., less standard representations used explicitly -
>    not taking over the default reader formats)?

Certainly not.

The "features" you list aren't really features, they are questions.  

> 1. In case of functions which in general can't be computed exactly
>    (e.g. trigonometric), do we want an assurance about the interval
>    that the true result sits in (interval arithmetic), facing the
>    possibility that < can't be determined, or perhaps we will be happy
>    with a single approximate result?

Trig functions most certainly can be computed exactly if you have a
clever enough implementation.  You aren't thinking correctly here,
because you are wedded to implementation issues.  It is perfectly
possible to implement exacts reals, and make the trig functions
compute exact answers.  (Have you ever played with maxima?)  

So the starting point of that question is ill-phrased.  I can think of
several different rephrasings for it, however, which have different
answers.  So I can't guess at which is the correct rephrased question
to answer.

> 2. In case of functions like trigonometric, do we insist on specifying
>    the precision - perhaps quite large - or any reasonable hardware
>    default will do?

Perhaps we could insist on neither, and give programmers the option of
specifying the precision, and then implementations which can comply
will do so, and the others will either signal an error or (at user
preference) do the best they can.

> 3. How to format a number into text? Use a decimal point or vulgar
>    fraction? Do we want to get a decimal point in case of an inexact
>    number which looks like it's an integer? How many digits after the
>    point to display? Is the scientific (exponential) notation accepted?
>    Pad with leading and trailing zeros to some widths? Use "." or ","?
>    Do we accept "#" in place of trailing insignificant digits?

Once more, why do we need to answer such questions?  Just provide all
of those.  They all seem useful.

How to print a number is an entirely separate question from its
representation.  For example, on a system with exact reals, the system
might know that the value of some computation is 2π; what should
happen when it's printed?  Sometimes I might want to print 6.28,
sometimes 6.2831 (truncated), sometimes 6.2832 (rounded), sometimes
2π, and perhaps sometimes 6!

> 4. What should happen when the number being computed is getting too
>    large to be conveniently represented? Return "infinity"? Signal an
>    error? How an infinity is formatted into text?

As Alan Watson pointed out, this is simply a normal case of memory
exhaustion and does not need to be discussed separately.

But I would not object to optional features which signal errors if an
exact number is too big, or if the storage size of a number grows
beyond some bound.  Those are the same sorts of features I might want
if a hash table or an array grows "too big", and should be treated the
same way.

> 5. What should happen when the inherent inaccuracy of the operation
>    would make the implementation unable to sensibly compute the
>    result, e.g. (sin (exp 1000))? Return special not-a-number marker?
>    Signal an error?

If the user wants exact results, and the system is unable to compute
one, the result is normally said to be undefined.  I don't mind more
specific answers to those questions.  

If the user doesn't care about exactness, then I don't mind giving the
user options here.

> 6. What should happen if not-a-number is compared by eqv? = < > <= >=
>    with other numbers and itself? Return #t/#f? Signal an error?

Give the user options; in this case, by different functions or
optional arguments on the functions.

> 7. Should there be a distinguished -0.0 which determines the side
>    of a branch cut of a multivalued complex function?

Give the user options; in this case, by different functions or by
optional arguments.

> 8. Do we need exact complex numbers?

Who is "we"?

> 9. Should the implementation try to track inexactness of real and
>    imaginary part separately, or we don't care? If the imaginary part
>    comes very close to 0, should the result be indistinguishable from
>    a real number, or we care about being sure whether it's real or not?

This is an ongoing difficulty for some people.  The answer is
certainly "no", it should not be tracked differently, but that's
because I think of complex numbers as numbers, not as pairs of
numbers.  But I'm not inflexible on this point; I just don't see the
need to track it separately, and it seems to confuse the notion of
what "exact" means.

> 10. When we ask whether the number is even, and it happens to be
>    inexact, should the implementation try to answer hoping that
>    inexactness did not change the value, or we prefer an error to be
>    signalled?

Perhaps we need two functions!

>>> What do you mean by constant-width addition?
>> I mean "addition in which the space use of the output is no larger
>> than the input".  This is a feature which you said was needed for
>> reals (I agree) and it's a feature that is useful for integers too.
> This description is meaningful for inexact numbers (cut less
> significant digits which are over the limit, with proper rounding),
> but meaningless for exact ones: there are no digits to cut if the
> number should remain exact.

It's like you didn't read what I wrote.

As I said, if you do an operation which exceeds the limitation of such
a function using exact numbers, you need to be able to specify what
the resulting behavior is (for example, clamping, error, and modular
arithmetic are all sensible possibilities).

>> I don't know what you mean by "safe";
> That they don't cause undefined behavior.

Sure, I'm all for that.  I think we should let the programmer define
the behavior he wants.

> In general I'm asking to make the behavior of Scheme arithmetic
> defined in more details, to give less choice for implementations and
> more confidence for users about what to expect.

If you are right that all general-purpose implementations will want to
provide IEEE floating point arithmetic (and I certainly agree), then
what's wrong with the user saying (with ieee-floating-point-behavior
...) and having done with it?