[Haskell] Re: Global Variables and IO initializers
Keean Schupke
k.schupke at imperial.ac.uk
Fri Nov 5 16:07:27 EST 2004
Okay, now for the purposes of my understanding, let me explore this:
myRef :: IORef Int
myRef = unsafePerformIO $ newIORef 0
This should always return the same reference, whereas:
myIORef :: IO (IORef Int)
myIORef = newIORef 0
Will return a new reference every time. I agree it would seem that the first
form does not need to be in the IO monad as it is effectively a
constant. The problem
I guess is there is no way in the language itself to indicate that the
function should
not be inlined (which will make each use of myRef refer to a different
IORef). So what
we need is a way in the type system to tell the compiler the function
must have
a single unique definition... Something like:
myRef :: Unique (IORef Int)
myRef = uniquePerformIO $ newIORef 0
and then have:
runUnique :: Unique x -> x
Then modify the compilers to never inline fundtions in the Unique monad.
Is this
what the CIO Monad proposes?
Keean
Jules Bean wrote:
>
> 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