
Hello all, It seems that I saw something like this in Cafe recevtly. But I am not sure... In GHC 6.12.1 (Platform 2010 on Windows Vista) I have Prelude> [1,1+2/3..10] [1.0,1.6666666666666665,2.333333333333333,2.9999999999999996,3.666666666666666,4.333333333333332,4.999999999999998,5.666666666666664,6.33333333333333,6.9999999999999964,7.6666666666666625,8.333333333333329,8.999999999999995,9.66666666666666,10.333333333333327] -- It is a bug! Prelude> [1,5/3..10] [1.0,1.6666666666666667,2.3333333333333335,3.0,3.6666666666666665,4.333333333333333,5.0,5.666666666666667,6.333333333333334,7.000000000000001,7.666666666666668,8.333333333333336,9.000000000000004,9.666666666666671] -- correct, but... Prelude> [1,5/3..4] [1.0,1.6666666666666667,2.3333333333333335,3.0,3.6666666666666665,4.333333333333333] -- ... wrong again Prelude> [1,1+2/3..10] :: [Float] [1.0,1.6666667,2.3333335,3.0000002,3.666667,4.333334,5.000001,5.666668,6.333335,7.000002,7.666669,8.333336,9.000003,9.66667] -- correct Prelude> [1,1+2/3..10] :: [Double] [1.0,1.6666666666666665,2.333333333333333,2.9999999999999996,3.666666666666666,4.333333333333332,4.999999999999998,5.666666666666664,6.33333333333333,6.9999999999999964,7.6666666666666625,8.333333333333329,8.999999999999995,9.66666666666666,10.333333333333327] -- wrong Any comments?

Dmitry Olshansky wrote:
It seems that I saw something like this in Cafe recevtly. But I am not sure... In GHC 6.12.1 (Platform 2010 on Windows Vista) I have
<snip>
Any comments?
The problem you point out is not a problem with Haskell, but a problem with the whole concept of floating point arithmetic as implemented on all modern CPUs. See: http://docs.sun.com/source/806-3568/ncg_goldberg.html You would have got similar problems with just about any language running on the same hardware. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

2010/5/19 Erik de Castro Lopo
Dmitry Olshansky wrote:
It seems that I saw something like this in Cafe recevtly. But I am not sure... In GHC 6.12.1 (Platform 2010 on Windows Vista) I have
<snip>
Any comments?
The problem you point out is not a problem with Haskell, but a problem with the whole concept of floating point arithmetic as implemented on all modern CPUs. See:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
You would have got similar problems with just about any language running on the same hardware.
This is what used for Double list generation (Haskell Platform 2010): -------------------------------------------------- numericEnumFromThenTo :: (Ord a, Fractional a) => a -> a -> a -> [a] numericEnumFromThenTo e1 e2 e3 = takeWhile predicate (numericEnumFromThen e1 e2) where mid = (e2 - e1) / 2 predicate | e2 >= e1 = (<= e3 + mid) | otherwise = (>= e3 + mid) -------------------------------------------------- So normal C loop like for {double i = 1; i <= 10; i += 1+2/3) { insert_list(i); } won't generate the same list, as Haskell does in [1,1+2/3..10]. PS Rationals: Prelude> [1,1+2/3..10] :: [Rational] [1 % 1,5 % 3,7 % 3,3 % 1,11 % 3,13 % 3,5 % 1,17 % 3,19 % 3,7 % 1,23 % 3,25 % 3,9 % 1,29 % 3,31 % 3] Same result.

Thanks, it's clear now.
2010/5/19 Serguey Zefirov
2010/5/19 Erik de Castro Lopo
: Dmitry Olshansky wrote:
It seems that I saw something like this in Cafe recevtly. But I am not sure... In GHC 6.12.1 (Platform 2010 on Windows Vista) I have
<snip>
Any comments?
The problem you point out is not a problem with Haskell, but a problem with the whole concept of floating point arithmetic as implemented on all modern CPUs. See:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
You would have got similar problems with just about any language running on the same hardware.
This is what used for Double list generation (Haskell Platform 2010): -------------------------------------------------- numericEnumFromThenTo :: (Ord a, Fractional a) => a -> a -> a -> [a] numericEnumFromThenTo e1 e2 e3 = takeWhile predicate (numericEnumFromThen e1 e2) where mid = (e2 - e1) / 2 predicate | e2 >= e1 = (<= e3 + mid) | otherwise = (>= e3 + mid) -------------------------------------------------- So normal C loop like for {double i = 1; i <= 10; i += 1+2/3) { insert_list(i); } won't generate the same list, as Haskell does in [1,1+2/3..10].
PS Rationals: Prelude> [1,1+2/3..10] :: [Rational] [1 % 1,5 % 3,7 % 3,3 % 1,11 % 3,13 % 3,5 % 1,17 % 3,19 % 3,7 % 1,23 % 3,25 % 3,9 % 1,29 % 3,31 % 3]
Same result. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Wed, May 19, 2010 at 10:57 AM, Serguey Zefirov
PS Rationals: Prelude> [1,1+2/3..10] :: [Rational] [1 % 1,5 % 3,7 % 3,3 % 1,11 % 3,13 % 3,5 % 1,17 % 3,19 % 3,7 % 1,23 % 3,25 % 3,9 % 1,29 % 3,31 % 3]
Same result.
This sounds like a bug to me. The section of the Haskell Report that deals with the Enum class mentions Float and Double, not Rational, and there's really no sensible reason why Rationals would exhibit this behaviour given that they don't have rounding error.

* Ben Millwood wrote:
Prelude> [1,1+2/3..10] :: [Rational] [1 % 1,5 % 3,7 % 3,3 % 1,11 % 3,13 % 3,5 % 1,17 % 3,19 % 3,7 % 1,23 % 3,25 % 3,9 % 1,29 % 3,31 % 3]
Same result.
This sounds like a bug to me. The section of the Haskell Report that deals with the Enum class mentions Float and Double, not Rational, and there's really no sensible reason why Rationals would exhibit this behaviour given that they don't have rounding error.
Double is not better: Prelude> [9,9+2/3..10] [9.0,9.666666666666666,10.333333333333332] Prelude> [7,9 .. 10] [7,9]

On 19/05/2010, at 23:44, Ben Millwood wrote:
On Wed, May 19, 2010 at 10:57 AM, Serguey Zefirov
wrote: PS Rationals: Prelude> [1,1+2/3..10] :: [Rational] [1 % 1,5 % 3,7 % 3,3 % 1,11 % 3,13 % 3,5 % 1,17 % 3,19 % 3,7 % 1,23 % 3,25 % 3,9 % 1,29 % 3,31 % 3]
Same result.
This sounds like a bug to me. The section of the Haskell Report that deals with the Enum class mentions Float and Double, not Rational, and there's really no sensible reason why Rationals would exhibit this behaviour given that they don't have rounding error.
From Section 12.1 of the Library Report: instance (Integral a) => Enum (Ratio a) where succ x = x+1 pred x = x-1 toEnum = fromIntegral fromEnum = fromInteger . truncate -- May overflow enumFrom = numericEnumFrom -- These numericEnumXXX functions enumFromThen = numericEnumFromThen -- are as defined in Prelude.hs enumFromTo = numericEnumFromTo -- but not exported from it! enumFromThenTo = numericEnumFromThenTo The numericEnum functions are defined in Section 8 of the Language Report and have semantics required for Float and Double. Roman

Dmitry Olshansky
Hello all,
It seems that I saw something like this in Cafe recevtly. But I am not sure... In GHC 6.12.1 (Platform 2010 on Windows Vista) I have
Prelude> [1,1+2/3..10] [1.0,1.6666666666666665,2.333333333333333,2.9999999999999996,3.666666666666666,4.333333333333332,4.999999999999998,5.666666666666664,6.33333333333333,6.9999999999999964,7.6666666666666625,8.333333333333329,8.999999999999995,9.66666666666666,10.333333333333327]
-- It is a bug!
No it isn't, because of the dodgy Ord instance for Float and Double values. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

Ivan Lazar Miljenovic
Dmitry Olshansky
writes: Hello all,
It seems that I saw something like this in Cafe recevtly. But I am not sure... In GHC 6.12.1 (Platform 2010 on Windows Vista) I have
Prelude> [1,1+2/3..10] [1.0,1.6666666666666665,2.333333333333333,2.9999999999999996,3.666666666666666,4.333333333333332,4.999999999999998,5.666666666666664,6.33333333333333,6.9999999999999964,7.6666666666666625,8.333333333333329,8.999999999999995,9.66666666666666,10.333333333333327]
-- It is a bug!
No it isn't, because of the dodgy Ord instance for Float and Double values.
And by "Ord", I of course mean "Enum"... -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 19/05/2010, at 19:24, Dmitry Olshansky wrote:
Prelude> [1,1+2/3..10] [1.0,1.6666666666666665,2.333333333333333,2.9999999999999996,3.666666666666666,4.333333333333332,4.999999999999998,5.666666666666664,6.33333333333333,6.9999999999999964,7.6666666666666625,8.333333333333329,8.999999999999995,9.66666666666666,10.333333333333327]
-- It is a bug!
Unfortunately, it isn't. Section 6.3.4 of the Haskell report says: 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. In this case, i = 2/3 so the last value in the list is 10+1/3. The same applies to the other examples. Personally, I consider the Enum class itself to be broken. Roman

Roman Leshchinskiy
Personally, I consider the Enum class itself to be broken.
Oh? In what sense? It seems to work fine for data types representing bounded enumerable values with a proper mapping to/from Int (it's not bijective since there's no proper mapping from Int -> Bool for example); the problem is the fact that Double, etc. are made instances of Enum when this is not the case for those data types. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 19/05/2010, at 20:36, Ivan Lazar Miljenovic wrote:
Roman Leshchinskiy
writes: Personally, I consider the Enum class itself to be broken.
Oh? In what sense?
Firstly, the enumFrom* family of functions shouldn't be methods and the class itself should provide enough facilities for implementing them generically. GHC, for instance, specialises them for all primitive numeric types just to get foldr/build fusion to work. That shouldn't be necessary and doesn't help with overloaded code anyway. For instance, this generates an intermediate list: foo :: Enum a => a -> a -> [Int] foo a b = [fromEnum x | x <- [a..b]] It's even worse when you want to implement similar functionality for other data structures. In vector, I basically had to duplicate all those specialisations to get decent performance. The generic case is horribly inefficient: enumFromTo x y = fromList [x .. y] There is no other sensible definition. Secondly, it should be possible to compute the length and the nth element of [a..b] in constant time. At the moment, it's impossible to distribute [a..b] efficiently across multiple threads - you have to generate the entire list first and then split it into chunks. It's completely unclear to me what [:a .. b:] should mean in DPH, for instance. So basically, Enum only provides enough functionality to desugar [a..b] and friends and even here, it doesn't interact well with fusion. Of course, these concerns weren't relevant back when the class was designed. But it is really broken now, IMO. Roman
participants (7)
-
Ben Millwood
-
Dmitry Olshansky
-
Erik de Castro Lopo
-
Ivan Lazar Miljenovic
-
Lutz Donnerhacke
-
Roman Leshchinskiy
-
Serguey Zefirov