
On Saturday 27 November 2004 17:10, you wrote:
On Sat, 27 Nov 2004, Benjamin Franksen wrote:
An execution context is a mutable finite map from types to (monomorphic) values. Each IO action implicitly carries exactly one such map and by default passes it on to the actions that follow.
Execution contexts sound a good description of them. Building on your recoding of this, if you have top-level declarations of newMVar / newIORef then how much of this can you do by just keeping a dictionary in a global variable?
This should certainly save some of the StateT plumbing; and such declarations are safe, becuase they are affine central (see http://groups.google.com/groups?selm=fa.doh68b9.96sgjd%40ifi.uio.no )
I like your definition of ACIO and I think it is sound (I have also suggested centrality, see http://www.haskell.org//pipermail/haskell/2004-November/014743.html). I would think that with ACIO we have a nice mathematical characterization for the IO actions that would be "safe" even at the top-level. ("Safe" meaning mainly that we do not open a can-of-worms with regard to execution order.) I don't know how easy or hard it is to prove of a certain IO action that is in fact in ACIO. However, monadic execution contexts don't need any safety proofs, because they are purely functional. With modest support from the compiler they could be implemented quite efficiently. And they would solve almost all problems for which global variables have been used or proposed as a solution. To be more precise, they would solve all those problems, provided you replace any reference to "the whole program" by "a certain execution context". I think this would be good enough for almost all applications.
A function is provided to (implicitly) create a new mapping and run a given IO action with the new mapping as its execution context, instead of the default one.
Update the global MVar, do the IO, then reset it?
This breaks down as soon as the IO action does a forkIO. This breakdown is one of the reasons I dislike global variables so much. Sure, you can find a way to code around this special probem.(*) But the fact that you have to (explicitly take concurrency into consideration) doesn't bode well for global variables. One of the nice features of (monadic) execution contexts is that they are automatically protected from such problems, without taking any special precaution.
I am almost sure that even the trick of indexing the dictionary via types (and thus the dependency on Data.Typeable and ghc extensions) can be avoided with a little more effort.
Another global MVar to issue a sequence of unique index keys?
Maybe this is possible. But I'd rather have a library that depends on Dynamics (plus some compiler support) than a highly controversial new language feature. Ben (*) You'd probably need a hack like using ThreadIds to identify the IO action being run under the new context, see George Russel's implementation.