
Hi, the following "toy" program has a strange behaviour, when compiling with ghc5.04.3 an no optimisation (-O0) module Main(main) where import System.IO.Unsafe main = case unsafePerformIO (print "test") of () -> main ok, probably I use unsafePerformIO in an "unsafe" way and so on, but executing the program prints infinitely often "test" on the screen, but I think it would be correct to do so one time? I think it has something to do with exporting main, because the following program module Main(main) where import System.IO.Unsafe main = seq f (return ()) f = case unsafePerformIO (print "test") of () -> f behaves ok. Does someone, what's the reason for this? Thanks, David

On 2003-08-11 at 11:44+0200 "David Sabel" wrote:
module Main(main) where
import System.IO.Unsafe
main = case unsafePerformIO (print "test") of () -> main
ok, probably I use unsafePerformIO in an "unsafe" way and so on, but executing the program prints infinitely often "test" on the screen, but I think it would be correct to do so one time?
It's correct behaviour to print "test" any number of
times. Haskell is non-strict, which only means that things
aren't evaluated unless needed. It's not (defined to be)
lazy, which would mean that named expressions would be
evaluated at most once (though ghc meets this). It's also
not defined to be "fully lazy" meaning that unnamed
expressions would be evaluated at most once in any given
closure. So GHC is entirely within its rights to evaluate
<

On 2003-08-11 at 11:44+0200 "David Sabel" wrote:
module Main(main) where
import System.IO.Unsafe
main = case unsafePerformIO (print "test") of () -> main
ok, probably I use unsafePerformIO in an "unsafe" way and so on, but executing the program prints infinitely often "test" on the screen, but I think it would be correct to do so one time?
It's correct behaviour to print "test" any number of times. Haskell is non-strict, which only means that things aren't evaluated unless needed. It's not (defined to be) lazy, which would mean that named expressions would be evaluated at most once (though ghc meets this). It's also not defined to be "fully lazy" meaning that unnamed expressions would be evaluated at most once in any given closure. So GHC is entirely within its rights to evaluate <
> any number of times, or possible even none, since it knows that that expression always returns the same value ().
Thanks for your comments. Ok, Haskell is not lazy, an "referential transparency" allows you to evalute (unsafePerformIO print "test") as often you want. But GHC provides to to do sharing in some sense and the compilation should be "Work-safe". My point here is to know, what's the reason for the different behaviour, rather than discussing the correctness of using unsafePerformIO.
So you /have/ used it in an unsafe way, and the above discussion illustrates why unsafePerformIO really is completely unsafe.
Jón
-- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
participants (2)
-
David Sabel
-
Jon Fairbairn