[challenge] Limitation in D's metaprogramming

Jonathan M Davis jmdavisProg at gmx.com
Mon Oct 18 20:20:31 PDT 2010


On Monday 18 October 2010 18:49:41 bearophile wrote:
> Jonathan M Davis:
> > 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.
> 
> Yet, sooner or later the compiler has to help you giving you a hole to let
> the contents of those I/O monads pass though to/from the outside world,
> otherwise you will not see any program input/output unless you use
> something like a post-mortem debugger :-) So I think the Haskell compiler
> has to manage your I/O monads in a special way anyway. Purity can't be
> absolute.
> 
> Bye,
> bearophile

I've been dealing primarily with D in my free time these days instead of 
Haskell, so I don't remember all of the details, but the side effects are 
essentially removed by making the IO part of the output at the end. If there 
_is_ a hole of some kind in the functional purity of the language it's confined 
to one point and it does not affect your program overall at all. It would only be 
when the monad was finally consumed. And many other types of monads don't have 
anything do to with I/O and _definitely_ don't need any kind of hole in the 
functional purity of the system. Haskell wouldn't work if it weren't 
functionally pure (thanks to the fact that it's lazy). Monads were an ingenious 
solution to the problem of how to deal with stuff like I/O that needs side effects 
and/or global state without actually allowing either. Monads _do_ end up being a 
rather viral in that once you have one, pretty much everything in the call chain 
after that has to pass it along too, but it does allow for functional purity and 
still allow global state and side effects.

Regardless, you can implement basic monads in D just fine without any language 
support whatsoever. What you basically end up doing is passing around the global 
state to every function. It's returned as part of the result of the function. 
Think of passing the global state to every function and having those functions 
return a tuple of their actual return value and the global state. The caller 
takes out the actual return value to do whatever it does and passes on the 
global state variable to the next function that it calls and finally returning it 
in a tuple along with its own return value.

Tuple!(Retval, GlobalState) func(GlobalState gs, otherparams...)
{
	//....
	return tuple(retval, gs);
}

Monads can be a bit hard to wrap your mind around, but they're ingenious. 
Haskell couldn't really exist without them.

- Jonathan M Davis


More information about the Digitalmars-d mailing list