GHC optimization changes evaluation strategy?

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... 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 *Behavior 1:* $ ghc Test.hs -o test $ ./test Start... ....................................................................................................True ....................................................................................................TrueStop... *Behavior 2:* $ rm test Test.o Test.hi $ ghc -O2 Test.hs -o test $ ./test Start... .True .TrueStop... -- Dusan Kolar tel: +420 54 114 1238 UIFS FIT VUT Brno fax: +420 54 114 1270 Bozetechova 2 e-mail: kolar@fit.vutbr.cz Brno 612 66 Czech Republic --

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.
participants (2)
-
Chris Kuklewicz
-
Dusan Kolar