["Simon Marlow" <email@example.com>] RE: cvs commit:
Manuel M T Chakravarty
chak at cse.unsw.edu.au
Mon Jan 20 07:03:36 EST 2003
Alastair Reid <alastair at reid-consulting-uk.ltd.uk> wrote,
> > perhaps ForeignPtr should not be an instance of Eq so people can
> > provide their own?
> Note that if we did this, we'd want to consider adding an operation
> eqForeignPtr :: FP a -> FP a -> Bool
> FP b -- possible variant but not very useful
> which lets people test equality of the container and not the contents.
> In fact the more I think on it, the more convinced I am that the Eq
> instance should compare contaner equality and not contents equality.
> The reason is that I believe Eq instances should follow the following
> design rule:
> Eq instances should compute observational equivalence
> I believe this is satisfied by all Haskell98 types, all the usual
> extensions (IORefs and friends) and by derived instances of datatypes.
So far, I agree.
> Just to be clear what I mean by observational equivalence, consider
> comparing two IORefs x and y using this code:
> eq x y = do
> a <- readIORef x
> writeIORef (a+1)
> b <- readIORef x
> return (x==y)
> Obviously, this code is a bad way to test if two IORefs are the same
> IORef but the point is that we can observe the difference between
> them. Similarily, with ForeignPtrs, adding a finalizer to one and not
> the other and then watching for when the finalizer runs is a way that
> we might observe differences between two FPs.
There is no way in H98 + FFI to observe that a finalizer has
run. In fact, in the finalizer discussion your point was
that any means to observe this would lead to races.
> What I don't mean by observational (in)equivalence is this:
> One might be able to distinguish two data structures of type [Int]
> (say), by observing how much memory they consume.
> This is perfectly true but Haskell semantics doesn't let you observe
> this so we'll rule any such 'observations' as irrelevant or invalid.
In C, we can observe it, and only in C can we observe whether
a finalizer was executed.
Nevertheless, your point regarding observations is an
important one. We must not be able to observe a change in
the equality of two values. This is why we cannot define
equality of IORef's as the contents of the IORef's.
However, the "contents" (ie, vanilla pointer on which it is
based) of a ForeignPtr can never change. Hence, defining
the equality of ForeignPtrs via their contents is perfectly
Hence, I propose to leave the definition in the spec as it
was; ie, the equality of ForeignPtrs is defined via the
vanilla pointer that they encapsulate.
More information about the FFI