Hi Jonathan, On Mon, 18 Oct 2010 18:02:58 -0700, Jonathan M Davis wrote:
> On Monday, October 18, 2010 17:54:50 Nick Sabalausky wrote: >> "Jonathan M Davis" <[email protected]> wrote in message >> news:[email protected]... >> >> > One word: monads. >> > >> > Now, to get monads to work, you're going to have to be fairly >> > organized about it, but that would be the classic solution to not >> > being able to have or alter global state and yet still be able to >> > effectively have global state. >> >> Oh yea, I've heard about them but don't have any real experience with >> them. Any FP experts know whether or not monads are known to be >> constructible from purely-FP building blocks? I always assumed "no", >> and that monads really just came from a deliberate compiler-provided >> hole in the whole purity thing, but maybe I'm wrong? (That would be >> quite interesting: constructing impurity from purity.) > > You can think of a monad as an extra parameter which is passed to each > function and holds the global state. It isn't a hole in purity at all. > For instance, it's how Haskell manages to have I/O and yet be > functionally pure. You don't need the compiler's help to do monads - > it's just easier if you have it. I don't see how monads will help here. Monads are useful for threading state through pure computations, and are an enabler for I/O in Haskell by threading the "real world" through a computation as a series of computational states. Something has to initiate the thread, and tie it up at the end: there's an implicit scope here, and I think here's where the hard questions start to crop up in the context of CTFE. Without permitting I/O, you could use a state-carrying monad to implement a kind of dynamically-scoped namespace during CTFE; the dynamically-scoped, mutable values would be global from the internal perspective of the CTFE computations, but they would not leak out of the monad into "truly global" state; and the overall effect would be pure. So, you can achieve an implicit, dynamic scope using monads. But if all CTFE expansions are done within a single such scope, it would be indistinguishable from running all CTFE expansions with access to globally shared state (though not I/O). So then, why not just use global state? Therefore, the monads could only practically be used as an isolation technique, to isolate dynamically scoped values during different CTFE expansions -- for example, at a compilation-unit level -- without sacrificing purity. But then, it seems you would lose the very thing you need to implement the challenge on the table: two modules would want access to the same counter during expansion, not two isolated copies of the counter. So again, you're back at global state, or mimicking it using a state-carrying monad, with no significant benefits accomplished by using a monad. Just my two cents, Graham
