Monads (Re: [challenge] Limitation in D's metaprogramming)

Graham Fawcett fawcett at uwindsor.ca
Tue Oct 19 12:13:19 PDT 2010


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" <jmdavisProg at gmx.com> wrote in message
>> news:mailman.715.1287449256.858.digitalmars-d at puremagic.com...
>> 
>> > 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


More information about the Digitalmars-d mailing list