
On Mon, Apr 08, 2002 at 11:58:22AM +0100, Simon Marlow wrote:
I'm afraid the answer is just "unsafePerformIO is called *unsafe*PerformIO for a reason"! You're using it in an inherently unsafe way here - the result of the program depends on whether the compiler duplicates the expression or not, something which it is normally free to do without affecting the meaning of the program.
However, it is possible to have global top-level references using unsafePerformIO if you're very careful about it. In GHC we do something like this:
{-# NOINLINE global_var #-} global_var :: IORef Int global_var = unsafePerformIO (newIORef 42)
the NOINLINE pragma is used to ensure that there is precisely *one* copy of the right hand side of global_var in the resulting program (NOTE: you also need to compile the program with -fno-cse to ensure that the compiler doesn't also common up the RHS of global_var with other similar top-level definitions).
this usage of unsafePerformIO is such a staple of real-world Haskell programming, it seems there should be some language (or experemental compiler *wink wink ghc nudge*) support for it. I am not sure what form it would take though. One idea I was toying with that would actually just require a new standard library function would be perhaps a 'safer' form of unsafePerformIO called memoIO :: IO a -> IO a which takes an arbitrary io action and returns an action which only calls the original action once and from then on returns the exact same value it returned the first time. it seems that this would allow much of what people want to do with unsafePerformIO, but in a nicer way as all io operations stay io operations, but the functional mapping of an io action to a memoed io action can be used anywhere. you can then do the above like getGlobalVar :: IO (IORef Int) getGlobalVar = memoIO (newIORef 42) note that this is not exactly the same since getting the global var is in the io monad, but that really makes sense if you think about it. and chances are you are already in IO if you need an IORef. John -- --------------------------------------------------------------------------- John Meacham - California Institute of Technology, Alum. - john@repetae.net ---------------------------------------------------------------------------