Repair to floating point enumerations?

Mitchell, Neil neil.mitchell.2 at credit-suisse.com
Wed Oct 15 06:25:38 EDT 2008


Hi Malcolm,

The current behaviour does sound like a bug, and the revised behaviour
does sound like a fix - and one that has a sensible explanation if
people trip over it. In general having floating point be a member of
classes such as Eq has some obvious problems, but I realise is a
necessity for practical programming. Given that we have Eq Double, then
Enum Double seems no worse.

If we don't alter H98 then a valid program under H98 vs H' will give
different results without any warning - that seems really bad. In
addition, having two instances around for one typeclass/type pair in a
big library (base) which are switched with some flag seems like a
nightmare for compiler writers. So I think a good solution would be to
fix H98 as a typo, and include it in H'.

Thanks

Neil


> -----Original Message-----
> From: libraries-bounces at haskell.org 
> [mailto:libraries-bounces at haskell.org] On Behalf Of Malcolm Wallace
> Sent: 15 October 2008 10:41 am
> To: haskell-prime at haskell.org
> Cc: libraries at haskell.org
> Subject: Repair to floating point enumerations?
> 
> Dear Haskell-Primers (and libraries).
> 
> Recently, Phil Wadler has pointed out a weird anomaly in the 
> Haskell'98 Prelude, regarding numeric enumerations for Floats/Doubles:
> 
>     Prelude> [0, 0.3 .. 1.1]
>     [0.0,0.3,0.6,0.899999,1.2]
> 
> What is odd is that the last value of the list is much larger 
> than the specified termination value.  But this is exactly as 
> specified by the
> Haskell'98 Report.
> 
>     http://haskell.org/onlinereport/basic.html#sect6.3.4
> 
>     "For Float and Double, the semantics of the enumFrom 
> family is given
>     by the rules for Int above, except that the list 
> terminates when the
>     elements become greater than e3+i/2 for positive increment i, or
>     when they become less than e3+i/2 for negative i.
> 
> We have discussed this question (and related ones, such as 
> whether Float and Double belong in the Enum class at all) 
> several times before, and I do not wish to rehash all of 
> those points again e.g.:
> 
>     http://www.cse.unsw.edu.au/~dons/haskell-1990-2000/msg07289.html
>     http://www.haskell.org/pipermail/haskell/2001-October/008218.html
>     http://www.haskell.org/pipermail/haskell/2002-October/010607.html
> 
> Phil proposes that, although retaining the instances of Enum 
> for Float and Double, we simplify the definitions of the 
> numericEnumFrom family:
> 
>   numericEnumFromThenTo   :: (Fractional a, Ord a) => a -> a 
> -> a -> [a]
>   numericEnumFrom         =  iterate (+1)
>   numericEnumFromThen n m =  iterate (+(m-n)) n
>   numericEnumFromTo n m   =  takeWhile (<= m) (numericEnumFrom n)
>   numericEnumFromThenTo n m p = takeWhile (<= p) 
> (numericEnumFromThen n m)
> 
> The particular feature of note is that the odd fudge factor 
> of (1/2 * the increment) is removed.  The inexact nature of 
> floating point numbers would therefore cause a specification like
> 
>     [ 0.0, 0.1 .. 0.3 ]
> 
> to yield the sequence
> 
>     [ 0.0, 0.1, 0.2 ]
> 
> that is, to omit the upper bound, because (3 * 0.1) is 
> actually represented as 0.30000000000004, strictly greater than 0.3.
> 
> Phil argues that this behaviour is more desirable: "the 
> simple fix is that the user must add a suitable epsilon to 
> the upper bound.  The key word here is *suitable*.  The old 
> definitions included completely bizarre and often highly 
> unsuitable choices of epsilon."
> 
> This proposal seems to me to improve the consistency of the 
> enumeration syntax across both the integral and floating 
> types.  Some users may still be surprised, but the surprise 
> will be easier to explain.
> 
> I am bringing this question to the attention of all who are 
> interested in Haskell Prime, because it seems like a sensible 
> and well-reasoned change.  Discussion on whether to adopt 
> this proposal for H' is welcome.
> 
> But as maintainer and bug-fixer of the Haskell'98 Report, I 
> have also been asked whether we should make this change 
> retrospectively to the
> Haskell'98 language (as a "typo").  Since it involves not 
> merely an ordinary library function, but a Prelude function, 
> and moreover a function that is used in the desugaring of 
> syntax, it is less clear to me whether to alter Haskell'98.
> 
> Thoughts?
> 
> Regards,
>     Malcolm
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries
> 
> 

==============================================================================
Please access the attached hyperlink for an important electronic communications disclaimer: 

http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html
==============================================================================



More information about the Libraries mailing list