Manuel M. T. Chakravarty chak at cse.unsw.edu.au
Thu Nov 30 21:10:43 EST 2000

"Marcin 'Qrczak' Kowalczyk" <mk167280 at zodiac.mimuw.edu.pl> wrote,

> On Tue, 28 Nov 2000, Simon Peyton-Jones wrote:
> > Simon and I noticed this morning that ForeignObj should
> > really be parameterised.
> I was considering it too and IMHO it does not need to be parametrized.
> Values implemented as foreign objects are often exposed to the user of the
> module. For this reason they are usually wrapped in newtypes to make them
> truly abstract. So we don't worry for the external interface - it is safe
> anyway, the objects will not be mistaken for something from a different
> library.
> Values kept under foreign objects are usually C structs which don't have a
> Haskell equivalent. If the type was simple (e.g. struct RGB {double r, g,
> b;};), it would be represented as a Haskell record. Since the type needs a
> finalizer, it usually means that it's complex enough to be not exported
> concretely by a C library, so there is no appropriate Haskell type to make
> a Storable instance - it will be accessed only through functions imported
> from C. And since it's complex enough, it will not be marshalled as a
> whole - instead its fields will be extracted as needed. And since it's
> finalized, it usually means that its lifetime is important because it
> represents some external resource, so it will really not be ever
> marshalled!

That actually also matches my experience.  Foreign objects
are usually used as a kind of foreign "abstract data types".
Their values are only used as arguments to external routines
and nothing else.  This is very different to `Ptr a' values,
where we use our knowledge of `a' to peek and poke into the
concrete structure refereed to by the pointer.

However, I can also related to what Simon said,

> It's bizarre to have
>    withForeignObj :: ForeignObj -> (Ptr a -> IO b) -> IO b

So, how about the following?  Instead of the 

  newtype Window = Window ForeignObj

way of wrapping foreign ADTs that we used so far, should we

  newtype WindowTag = WindowTag ()
  type    Window    = ForeignObj WindowTag


This way, we would have the uniformity of having
parametrised ForeignObj and make good use of the parameter?


More information about the FFI mailing list