[Haskell-cafe] weak references and sharing

Thomas Conway drtomc at gmail.com
Tue Mar 6 19:50:42 EST 2007


Hi All,

I have the situation where I have something like the following:

type Foo = TVar Int

data Clasp t = Clasp t

makeClasp x f
    = do
        let c = Clasp x
        mkWeakRef c (Just (f x))
        return c

finis p
    = do
        atomically $ do
            x <- readTVar p
            writeTVar p (x - 1)

.... makeClasp p finis ....

The Foo object has a greater lifetime than the Clasp.

The bit I want you to focus on is the three lines:
        let c = Clasp x
        mkWeakRef c (Just (f x))
        return c

We can only be sure that (f x) will be called after we let go of the
returned value if we can be sure that the language implementation
preserves the (explicit) sharing of 'c' between the call to mkWeakRef
and return. In particular, if the implementation rewrote the fragment
as:
        mkWeakRef (Clasp x) (Just (f x))
        return (Clasp x)
then the finalizer might be called sooner than we expect. The problem
is, that as I read it, making a distinction between the two fragments
would be a violation of referential transparency.

So here's the question: is there a way of writing this that is
guaranteed to work on all correct implementations of Haskell?

cheers,
T.

ps FWIW, the actual situation is that we have a TVar pointing to a
record representing a 'page' of an external data structure. For some
operations we need to make sure the the page is in-memory, but when
all the operations using a particular page are finished, we'd like to
flush it back to disk if it has been modified. Now it'd be really nice
to use the garbage collector to tell us when noone is using the
in-memory version of the page, so we can write it out. However, if we
can't be certain that we've got a genuine hard-reference to the
object, then we can't be sure it will not be prematurely flushed.
-- 
Dr Thomas Conway      You are beautiful; but learn to work,
drtomc at gmail.com         for you cannot eat your beauty.
                                              -- Congo proverb


More information about the Haskell-Cafe mailing list