["Simon Marlow" <firstname.lastname@example.org>] RE: cvs commit:
Manuel M T Chakravarty
chak at cse.unsw.edu.au
Wed Nov 6 20:41:07 EST 2002
Alastair Reid <alastair at reid-consulting-uk.ltd.uk> wrote,
> [Thread moved from the library cvs mailing list]
> Simon Marlow:
> > - Fix the Eq instance for ForeignPtr to match the behaviour
> > specified by the spec. Two ForeignPtrs are equal iff their
> > underlying Ptrs are equal (previously they were equal iff they were
> > the same ForeignPtr).
> Alastair Reid:
> > Hmmm, the Hugs implementation goes for 'same foreignptr' and, to me,
> > that seems to make more sense.
> > I wonder why the spec changed the semantics from that in the
> > Hugs-GHC spec?
> Simon Marlow:
> > I don't have any strong opinions on the matter, I just changed it to
> > match the spec because someone complained.
> > Do you have an example where the previous behaviour is more useful?
> > Perhaps it should be brought up on the FFI list.
> I don't have a really compelling example just a nagging feeling and
> worry that a design is being changed without (as far as I can recall)
> any discussion of the matter.
> Here's some questions that might help understand the difference:
> 1) Is there any practical difference between the old semantics and the new?
> There used to be a big difference because ForeignObjects supported
> an operation to replace the underlying Ptr. Equality on mutable
> objects is clearly different from equality on the contents of the
> mutable objects.
> But, ForeignPtrs with the same Ptr but different finalizers are different
> and the finalizer list _is_ mutable so there is a useful difference.
> The difference between two ForeignPtrs which contain the same Ptr is
> especially clear if we think about what happens if the first one dies
> before the second or the second is the first to die.
> 2) Can either semantics be implemented in terms of something we already have?
> We can implement the new semantics using castForeignPtrToPtr.
> There's no way to implement the old semantics using other existing
> operations. Even if there was a way to extract the list of
> finalizers (and assuming we're happy using pointer equality on the
> finalizer functions), we still couldn't implement it because
> ForeignPtrs are, effectively, mutable objects.
> In short, I can see that switching to the new semantics (ForeignPtr
> equality == equality of contents) removes something we had before and
> doesn't add anything new but I don't have any examples of where it is
> actually useful. (I also have no examples of where the new semantics
> is useful.)
The issue came up in a binding to a BDD library currently
being implemented by Peter Gammie <peteg at cse.unsw.edu.au>.
With BDDs, it is important that when you construct a BDD for
the same expression two times that you get the same BDD (ie,
the resulting BDD values should be (==)). The C API of the
BDD library represents BDD values as pointers that in
Haskell land become ForeignPtrs as they need finalisers.
This application obviously requires equality on ForeignPtrs
to be the same as the equality of the underlying C pointers.
On the other hand, I don't know any application where the
semantics currently implemented by GHC-Hugs (ie, to
ForeignPtrs are equal only when they were generated by the
same newForeignPtr) would be essential.
As for the reasons why the FFI spec adopted the "new"
* The documentation of the existing libraries didn't say
anything about the implemented semantics.
* So, I choose the one which I regarded to be the "natural"
one when trying to fill in the gaps in the existing
I still think that the "new" semantics documented in the FFI
spec is what a user would intuitively expect. When you
compare two foreign pointers, you want to know something
about the equality of the things being referenced. You are
not interested whether the two objects share the same
finalizer. In other words, I think the old GHC-Hugs
semantics is misleading.
More information about the FFI