[scheme-reports-wg1] Re: Definition of expt (was #391 - a selection of error predicates)
Alex Shinn
(08 Aug 2012 11:55 UTC)
|
Re: [Scheme-reports] Definition of expt (was #391 - a selection of error predicates) Mark H Weaver (08 Aug 2012 18:08 UTC)
|
On 08/08/2012 07:55 AM, Alex Shinn wrote: > On Wed, Aug 8, 2012 at 8:44 PM, Mark H Weaver<mhw@netris.org> wrote: >> On 08/08/2012 02:49 AM, Alex Shinn wrote (on the WG1 list): >>> >>> These predicates seem random, reflecting only the >>> historical precedent of what was stated as "signals >>> an error" vs "is an error". I'm not even convinced that >>> distinction was made by design rather than the >>> stylistic convention of the editors at the time. >>> >>> For expt, in particular, we added this note ourselves, >>> and the actual text is: >>> >>> 0.0^z is 1.0 if z = 0.0, and 0.0 if (real-part z) is positive. >>> For other cases in which the first argument is zero, either >>> an error is signalled or an unspecified number is returned. >>> >>> Apart from the wording being a clumsy, saying >>> an "error is signalled _or_ an unspecified result >>> is returned" is the same as saying "the result is >>> an error." >> >> >> The text does not say "or an unspecified result is returned". It says "or >> an unspecified _number_ is returned". Therefore, it is not the same. > > Not quite the same, but close enough. > We should signal an error, or do something > unspecified, not one or the other. Given the tendency of the R6RS to specify so much more than other reports had, I suspect they had good reason to give implementations leeway here. Some of the cases are surely controversial, and yet some implementors may have strong opinions on how they should be handled. For example, I would argue that some of these cases (e.g. exact zero raised to any power that's not an exact non-negative integer) ought to raise an exception, others (e.g. +0.0 ^ -1.0) ought to return +inf.0, and others (e.g. +0.0 ^ -1.0+1.0i) should return a complex infinity (which some might represent as +nan.0+nan.0i, but I've recently learned that C99 and C11 represent as a complex number with one NaN part and one infinity of unspecified sign, with good reason). >>> I propose changing the text to: >>> >>> 0^z is 1 if z = 0, and 0 if (real-part z) is positive. >>> It is an error if (real-part z) is negative. >> >> >> You've made two questionable changes to the meaning of this definition, >> beyond the description of what happens in the error/unspecified case. >> >> 1. The current text uses "0.0" and "1.0" which suggests inexact numbers. >> You've changed these to exact numbers. I interpret the current text to >> apply only when the base is an _inexact_ zero, and to specify inexact >> results. I interpret your proposed text as mandating exact return values, >> and possibly also applying when the base is an exact zero. > > This was very much intentional. The current text > was a derivation from R5RS that was never voted > on - I simply fixed it. Actually, the current text is almost precisely taken from the R6RS, and while I disagree with many of the choices of the R6RS, they did a very competent job on numerics for the most part. > The general rule we've been taking is exact zero > causes errors, inexact zero returns whatever the > floating point processor returns. As far as I know, most (all?) floating-point processors don't do complex arithmetic directly, or at least not exponentials, so we can't rely on that rule here. As Kahan notes in section 10 of "Branch Cuts for Complex Elementary Functions (or: Much Ado About Nothing's Sign Bit)": The function z^w has two different definitions. One is recursive and applicable only when w is an integer: z^0 = 1 and z(w+1) = z^w * z whenever z^w exists. The second definition is analytic: z^w := limit as zeta->z of exp(w * ln(zeta)), provided that the limit exists using the principal value and domain of ln(zeta). The limit process is necessary to cope smoothly with z=0. More generally, limit processes are the method of choice in IEEE 754 style arithmetic to determine the behavior of functions in the presence of signed zeroes and infinities. However, I would strongly argue that limit processes are appropriate only for inexact arithmetic in Scheme. More specifically, a limit process must be used only for inexact inputs, and must produce inexact outputs. An exact result must always agree with the precise mathematically correct result of the function in question. In this case, if z is an exact zero, then we cannot use the analytic definition z^w = exp(w * ln(z)) because ln(z) is not defined at zero. Limit processes are not appropriate for an exact zero input. Therefore, here we can rely only on the recursive definition, which applies only when the exponent is a non-negative integer, and I'd go further and require that it be exact, but reasonable people might disagree here. Mark _______________________________________________ Scheme-reports mailing list Scheme-reports@scheme-reports.org http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports