[Haskell-cafe] GHC optimization changes evaluation strategy?
Chris Kuklewicz
haskell at list.mightyreason.com
Tue Mar 13 07:40:48 EDT 2007
Dusan Kolar wrote:
> Hello all,
>
> the following program changes behavior if translated using different
> options for ghc compiler. Is this correct or not? I used The Glorious
> Glasgow Haskell Compilation System, version 6.6. And I would expect in
> both cases behavior 1.
>
> But I may be wrong...
You do not get to expect that unsafe* function are unaffected by optimizations.
>
> Thanks for any resolution.
>
> Dusan
>
>
> *Program:*
>
> $ cat Test.hs
> import System.IO.Unsafe
> import System.IO
>
> main = do
> putStr "Start...\n"
> putStr $ show $ falling' falling10000
> putStr "\n"
> putStr $ show $ sorted' rising10000
> putStr "Stop...\n"
>
> sorted' [] = True
> sorted' [_] = True
> sorted' l = sx l 1
> where
> sx [] _ = True
> sx [_] _ = True
> sx (x:l@(y:ys)) n =
> if n==1000 then unsafePerformIO (putChar '.' >> hFlush stdout)
> `seq` x<=y && sx l 1
> else x<=y && (sx l $! n+1)
>
> falling' [] = True
> falling' [_] = True
> falling' l = sx l 1
> where
> sx [] _ = True
> sx [_] _ = True
> sx (x:l@(y:ys)) n =
> if n==1000 then unsafePerformIO (putChar '.' >> hFlush stdout)
> `seq` x>=y && sx l 1
> else x>=y && (sx l $! n+1)
>
> rising10000 = [0..100000]
>
> falling10000 = [100000,99999..0]
>
> -- EOF
>
the expression
> unsafePerformIO (putChar '.' >> hFlush stdout)
has type "()" and does not depend on anything in scope. The `seq` command
demands that this be evaluated to see it is bottom or the value "()", but then
it never needs to be re-evaluated, as Haskell may assume it is will be immutably
the value "()".
>
>
> *Behavior 1:*
>
> $ ghc Test.hs -o test
> $ ./test
> Start...
> ....................................................................................................True
>
> ....................................................................................................TrueStop...
There it is re-evaluated.
>
>
>
> *Behavior 2:*
>
> $ rm test Test.o Test.hi
> $ ghc -O2 Test.hs -o test
> $ ./test
> Start...
> .True
> .TrueStop...
>
There it is evaluated once and cached.
More information about the Haskell-Cafe
mailing list