RE: Stricness of floor etc

Looking at
ghc --show-iface .../ghc/lib/ghc-5.05/imports/base/GHC/Float.hi
I see
floor1 :: forall b. (GHC.Real.Integral b) => Double -> b __S L
properFraction2 :: forall b. (GHC.Real.Integral b) => Double -> (b, Double) __S L
decodeFloat2 :: Double __S U(L)m
My understanding of this is that floor and properFraction of Doubles have a lazy argument while decodeFloat has a strict constructor of lazy values. It's not clear to me why the U(L) strictness isn't inherited by properFraction and then float, nor do I understand why decodeFloat is not strict in its argument when it seems to be working exclusively with unboxed values. Unfortunately decodeDouble# in PrimopWrappers.hi doesn't seem to have a strictness description so I can't see what's going on there.
So I guess what I'm asking is are these strictnesses the best that can be inferred or could GHC do better?
This floor is the dictionary selector, and for various (complicated looking) reasons it is lazy in its dictionary argument. It does some dictionary selections which might be shared, before returning a function.
Of course a strict floor (Double to Int and Integer) is what I'm really hoping for (without having to specify it explicitly with $! in my code).
There are specialised versions of floor for Double -> Int and Double -> Integer. You *ought* to get good code out if you call floor at one of these types. If not, please send us the example.
Incidentally, what are 'm's in the strictness descriptions?
It means the function returns a manifest constructor, which can be eliminated with CPR (constructed product result optimisation). Cheers, Simon

On Tue, Mar 18, 2003 at 10:22:52AM -0000, Simon Marlow wrote:
floor1 :: forall b. (GHC.Real.Integral b) => Double -> b __S L
This floor is the dictionary selector, and for various (complicated looking) reasons it is lazy in its dictionary argument.
Aha! Thanks.
Of course a strict floor (Double to Int and Integer) is what I'm really hoping for (without having to specify it explicitly with $! in my code).
There are specialised versions of floor for Double -> Int and Double -> Integer. You *ought* to get good code out if you call floor at one of these types. If not, please send us the example.
Well, with the following module, with the strictnesses in comments, it seems to me that floor is lazy even when explicitly given the type Double -> Int - am I confused again? It also looks to me like addition of unboxed Ints is also treated as being lazy. import GHC.Base foo :: Int# -> Int# -> Int# foo = (+#) -- __S LL bar :: Int -> Int -> Int bar = (+) -- __S U(L)U(L)m baz :: Integer -> Integer -> Integer baz = (+) -- __S SS quux :: Double -> Int quux x = floor x -- __S L -ddump-simpl gives the following for quux: Str.quux = \ x :: GHC.Float.Double -> case GHC.Float.properFraction2 @ GHC.Base.Int GHC.Real.$fIntegralInt x of wild { (n, r) -> case r of wild1 { GHC.Float.D# x1 -> case GHC.Prim.<## x1 0.0 of wild2 { GHC.Base.True -> case n of wild11 { GHC.Base.I# x11 -> GHC.Base.I# (GHC.Prim.-# x11 1) }; GHC.Base.False -> n } } } Thanks Ian
participants (2)
-
Ian Lynagh
-
Simon Marlow