
On Fri, Dec 03, 2004 at 10:05:08AM +0000, Graham Klyne wrote:
Looking at the wiki summary [1] (very good, BTW), I have a question (I've skipped much of the debate, so please just give a message pointer if I missed something).
Why does RandomIO need to use the unsafePerformIO hack if its already in the IO monad?
The random number state needs to be stored between calls to randomIO, it is global state which right now tends to be implemented via the unsafePerformIO hack. Any of the current global state hacks or the proposals on the Wiki would also suffice to implement it. All of the global state proposals would require access to the state via the IO monad. Which is why I like to think of it as 'extending the world' rather than global variables. IO can be thought of (and is how it is directly implemented in GHC) as functions similar to data World -- no constructors, World is an abstract type -- representing the 'state of the universe' type IO a = World -> (a,World) meaning an IO action that returns a Char is actually a pure function from the World to a new World and the Char. now, imagine we didn't have global variables, then we would have to pass the values of the global variables everywhere, collecting the new variables from the function results. note that this is exactly what the IO monad does! So, all the global variables semantics are completly defined by 'adding' the values of the global variables to World. if World were actually directly implemented, it might look something like: data World = World { keyPressedOnStandardInput :: Maybe Char, theFilesystem :: [(FileName,Contents)], presidentOfTheUnitedStates :: String, currentMoodOfUser :: Mood, -- every other property of the universe ... } (you can see why we like to keep World abstract :)) a global variable is just another entry in the World record. This is why global variables are safe to use in a lazy functional language (perhaps against intuition), their use is confined to the IO monad, which passes around the state of everything (including the global variables) in a purely functional way. The problem is there is just no mechanism in haskell to declare them and it is unclear what said mechanism should look like which is what the whole debate is about :)
BTW, if the goal is to have a random number generator as a pure (non-IO) function, I *do* think there's a reasonable semantic objection here.
Oh yes. no one is wanting that. John -- John Meacham - ⑆repetae.net⑆john⑈