[Haskell] Re: Global Variables and IO initializers

Jules Bean jules at jellybean.co.uk
Fri Nov 5 15:12:49 EST 2004


On 5 Nov 2004, at 19:03, MR K P SCHUPKE wrote:

>> You don't want stdin/stdout/stderr?
>
> Also these are only available in the IO monad...
>
>> without breaking referential transparency
>> by use of unsafePerformIO hack.
>
> I don't understand this still... how can it not break referntial 
> transparancy.
> For example consider if stdin were available outside the IO monad.
>
> Could someone give an example of what these things are that need to be 
> initialised
> and that are safe.
>

The typical example is an IORef.

As in:

myRef :: IORef Int
myRef = unsafePerformIO $ newIORef 0

Now it's perfectly safe for myRef to exist outside the IO monad: all it 
is, is some kind of pointer to the actual value. Of course, we can't do 
anything to it outside the IO monad, but it can exist.

Therefore, if it is at the toplevel, it can be referenced by all the 
other functions in the same module. The functions therefore share a 
common 'pointer' to a value: however none of them can actually access 
the value or change it without using the IO monad, as is right and 
proper.

This is typical of the kind of commutative operations that Koen 
proposes: what it is really about is 'fresh names'.  newIORef returns a 
'fresh name' for a 'box' which stores things.  (I notice that name 
supply is one of the key issues for John Petersen too).

There appears to be no problem in principle with having such objects 
around at the top level, but haskell provides no syntax to create them 
(safely). The syntax above is obviously 'wrong' in that it is rather 
assuming that two different calls to unsafePerformIO $ newIORef 0 will 
return different values, which violates ref. integrity.

The compiler has something like an internal fresh name monad: every 
time you define a new top-level value, it is given some fresh 
(internal) name. Most language compilers can be thought of as operating 
like this, but haskell makes it hard to get at the bit of this monad we 
want.

Jules



More information about the Haskell mailing list