The Revenge of Finalizers

George Russell ger at
Thu Oct 17 10:07:22 EDT 2002

Simon Marlow wrote:
> > > I don't know how to achieve the same goal with
> > > atomicModifyIORef.
> >
> > I do.  To modify ioRef1 and ioRef2 "simultaneously", write
> >
> > atomicModifyIORef ioRef1 (\ contents1 -> unsafePerformIO
> > ioRef2 (\ contents2 -> blah blah))
> >
> > The actual modification will take place when the result or
> > contents of ioRef1 or ioRef2 get evaluated.
> I don't understand how this works.  Unless I'm missing something, you'll
> see the contents of ioRef1 at the point at which the first
> atomicModifyIORef takes place, but the contents of ioRef2 from the time
> at which the unsafePerformIO is evaluated, which is some unspecified
> time later.

Perhaps we're talking about different sorts of atomicModifyIORef?  I am now
thinking of atomicModifyIORef as having the type

IORef a -> (a -> (a,b)) -> IO b

Thus when it is called the effect is to construct (1) a thunk of type (a,b) containing
the application of the function to the thunk previously in the IORef; (2) a thunk containing
fst $  the thunk from (1) of type (a,b), which is put in the IORef; (3) a thunk
containing snd $ the thunk from (1), to be returned.  Subsequent evaluation of the result of 
atomicModifyIORef will force the thunks in (1) and (3) to be evaluated, meaning the
unsafePerformIO gets evaluated.

More information about the FFI mailing list