Hello, http://haskell.org/ghc/docs/latest/html/libraries/base/ System.IO.Unsafe.html#v%3AunsafePerformIO
talks about what optimizations you should disable if you apply unsafePerformIO to an action which contains side effects. These are: * inlining of functions which call unsafePerformIO * common subexpression elimination (on the module which contains the unsafePerformIO application, if I understand correctly) * let-floating Alas, the documentation is very terse, in my opinion, and I don't understand these things fully. First, what is the problem with inlining a function call? Say, I have a function f defined as follows: f :: Char -> () f c = unsafePerformIO (putChar c) If inlining is allowed, the expression f '*' becomes unsafePerformIO (putChar '*'). Is this a problem? Or is inlining dangerous in other situations? On the other hand, I can see that inlining non-functions could cause harm. Say I have something like this: u :: () u = unsafePerformIO (putChar '*') Now, inlining u would transform (u,u) to (unsafePerformIO (putChar '*),unsafePerformIO (putChar '*')) which could result in putChar '*' being executed multiple times. So why does the library documentation only talk about disabling inlining of functions? I understand that common subexpression elimination could cause harm. It could transform the expression (unsafePerformIO (putChar '*),unsafePerformIO (putChar '*')) to let u = unsafePerformIO (putChar '*') in (u,u), couldn't it? This would result in the I/O action be performed at most once which is not what was intended. But couldn't the same thing also happen if I use the expression (f '*',f '*'), probably in a different module? Does this mean that I have to use -fno-cse not only in the module which contains the unsafePerformIO application but also in every other module which uses unsafePerformIO indirectly via f or functions using f? Does let-floating only have to be disabled in the module which uses unsafePerformIO? Say, I have f defined as above and have the following definition in a module different from the one f is defined in: g :: Int -> () g n = f '*' Couldn't it be that the asterisk is output only once instead of every time, g is called? I would be thankful for any help. Best regards, Wolfgang _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users