This page is meant to contain discussion about global state and "things with identity". It's a companion to Adrian's http://www.haskell.org/hawiki/GlobalMutableState, but that's in the old Wiki, so I thought it better to start a new page.
See also Ian Stark's ACIO message http://www.haskell.org/pipermail/haskell-cafe/2004-November/007664.html.
As Brian Hulley put it, at the moment, there is a strange unnatural discrepancy between the fixed set of built-in privileged operations such as Data.Unique.newUnique which are "allowed" to make use of global state, and user defined operations which have to rely on a shaky hack in order to preserve natural abstraction barriers between components such as a user-defined Unique, Atom, and anything involving memoisation or device management etc.
The kind of applications we have in mind are:
- A source of random numbers, or of unique numbers. This should be on a per-thread basis.
- The value of 'stdin' or 'stdout'. We don't want to mutate this, but we might want to set the value for sub-computations, including any spawned threads.
A straw man
Here's a straw-man proposal.
- New top-level declaration to allocate a new key
key rng :: Key StdGen
A key is globally unique in a program. It supports equality but not ordering.
- You can read and write global state and local state:
readLS, readGS :: Key a -> IO a writeLS, writeGS :: Key a -> a -> IO a
- We probably want to provide efficient finite maps on keys.
- Keys are useful independent of mutability. For example, GHC has lots of code going
thenIdKey = mkPreludeIdKey 3 returnIdName = mkPreludeIdKey 4
etc, where we hand out unique identifiers by hand. Easy to screw up.
- When you forkIO a thread, what (if anything) does the forked thread inherit?