Dealing with configuration data

Nick Name nick.name@inwind.it
Thu, 26 Sep 2002 01:33:14 +0200


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

> I don't feel bad about doing
>  this because GHC does this itself for its own configuration :).

I am going to show you that using unsafePerformIO where there really are
side effects leads to unpredictable results, and is generally wrong in a
lazy language. Don't hate me for this :)

Consider this example (supposing that a Config is represented by an
Int):

storeConfig :: Int -> ()
readConfig :: Int

They both are obtained through the use of "unsafePerformIO".

Now, say I got this code:

 (storeConfig 0,storeConfig 1,readConfig,storeConfig 0,readConfig)

What is this 5-uple supposed to evaluate to?

First of all, this depends on order of evaluation. We can't say that all
the elements of the tuple will be evaluated, so we can't tell if the
fifth readConfig will evaluate to 0 or 1 (if the third storeConfig is
never evaluated, readConfig will evaluate to 0, else to 1) This is one
of the causes of the use of monads: ensuring correct order of
evaluation.

Second, suppose we were able to force order of evaluation (which
shouldn't be allowed, in a lazy language). We still can't say what the
last "readConfig" would evaluate to, since we don't know if the compiler
is substituting equals for equals (I am expecting a lazy functional
language to do this). 

If the compiler does, the last readConfig is equal to the first (in
fact, by the use of unsafePerformIO, you have told the compiler that
both the functions storeConfig and readConfig are pure, which is not
true) and will evaluate to 1, else it will evaluate to 0. And, besides,
the compiler should also substitute the second "storeConfig 0" with the
result of the first occurrence, so it would not evaluate the second
"storeConfig" at all.

This is another example of the need for monads: allowing program
transformations, first of all substituting equals for equals.

This is why (even if, by enough knoweledge of the implementation, we
could), by only relying on the semantics of a lazy language, we can not
have functions with side effects.

If it wasn't so, they would not have invented monads, believe me.

I apologize, as always, for my terrible english, and hope I have been
clear.

Vincenzo Ciancia