Dealing with configuration data

Nick Name
Thu, 26 Sep 2002 15:36:35 +0200

I just wrote a long and clear answer, but my e-mail client has crashed.
I am going to change it (or to rewrite one in Haskell, grrr) but the
answer will be shorter, I apologize.

On Wed, 25 Sep 2002 16:34:02 -0700 (PDT)
Hal Daume III <hdaume@ISI.EDU> wrote:

> I don't mean to troll, but this isn't what I meant.

You aren't. I misunderstood you, of course.

> now, we have doStuff :: IO a.  doStuff is allowed (even in its pure
> methods) to use getConfig.  I claim that this is safe.  I could be
> wrong; this is only a hand-waiving argument.  Why?
> The first reference in the program to globalConfig is through a
> writeIORef.  This means that at this point globalConfig gets evaluated
> and thus a ref is created.  Immediately we put a value in it.
> Now, when doStuff runs, since it is an action run *after* the call to
> writeIORef, provided that it doesn't also write to 'globalConfig'
> (which I mentioned in my original message), any call to getConfig is
> deterministic.

Even this appears correct, and I feel that it's a technique widely used
in the haskell community, nothing prevents a global optimizer to
evaluate all pure functions wich do not depend on a value obtained by IO
*before the "main" function*.

This is also stated in the GHC documentation, about "unsafePerformIO":

"If the I/O computation wrapped in unsafePerformIO performs side
effects, then the relative order in which those side effects take place
(relative to the main I/O trunk, or other calls to unsafePerformIO) is

If getConfig is evaluated before the main function (nothing prevents it)
and if all equal pure expressions are evaluated only once, readConfig
will always lead to "undefined" (yes, it will always be evaluated after

The first idea from Koen Claessen (getConfig operates directly on the
file with unsafePerformIO) appears to work, but this time we are
*relying* on the fact that the function will be evaluated once, since
the file could change and multiple evaluations of readConfig wouldn't
lead to the same result. This is not good anyway.