Sat, 29 Jul 2000 13:25:43 +0200, Sven Panne <[EMAIL PROTECTED]> 
pisze:

>    * Nuke lots of GHC-specific parts in hslibs in favour of the FFI,
>      e.g. remove all _casm_/_ccall_s. Hslibs should really be more
>      system independent.

This should be done after a higher-level marshalling library.

>    * Currently you can't match a given C signature exactly on the
>      Haskell side, e.g. const modifiers etc.  There have been some
>      experiments and proposals in this area, but AFAIK none of them
>      solved this problem in a smooth way.

Indeed. There are generally two approaches:
* try to express exact matching,
* try to avoid the need of exact matching.

>    * Marshaling pure sum types and pure product types, both are quite
>      common in APIs, is easy with GreenCard and H/Direct but a little
>      bit clumsy with the current FFI. Using a mechanism outside the
>      language (i.e. those preprocessors) for such common tasks is not
>      nice, so something has to be done here.

There is a big problem for common C APIs. APIs specify the interface
for calling functions sufficiently precisely that it's possible to
exactly express the binary calling convention of functions in Haskell
(except typedefs for argument and result types) and call them even from
the NCG. OTOH structs, enums, bit fields and macros are not specified
in a way that allows using them without the C headers (neither the
order nor the complete set of struct fields is usually specified).

It means that FFI has to either cooperate with the C compiler and
generate stubs for C when compiling to the native code, or process
C headers. It implies either additional low-level FFI features or
external tools. Information gained only from Haskell record and enum
definitions will not be enough.

I tried to make a mechanism for marshalling structs and unions of
a known layout (with the intent that a C wrapper would translate
between them and a truly foreign C struct or bit field), but I am not
happy with the result. It's not convenient. If tuples were changed
to be composed recursively, as proposed on the Haskell list, generic
marshalling of tuples would replace the rare case of marshalling a
struct with a known layout.

I think that the way to go will be to add some foreign language
dependent FFI features that will generate stubs and pass them through
the C compiler, after being told which C headers to include. Not
very nice in principle, but I don't have a better idea. This is how
Eiffel has done this (e.g. accessing and changing struct fields,
or invoking C++ constructors). Before that, hand-written C wrappers
can be used. Maybe an emerged style of these wrappers will suggest
FFI features.

>    * A higher-level marshaling library is urgently needed. There has
>      been some activity in this area recently, but the current state of
>      affairs is a little bit unclear to me: What kind of marshaling
>      problems are solved from a *user* perspective, not from an
>      implementor's perspective?

I can speak for my proposal.

It provides:
* Typed data pointer and function pointer types.
* Storing non-bottom values and arrays of them under pointers.
  Like Storable.Storable but done a bit differently: typed pointers,
  supports arrays with length stored elsewhere or an end-marker,
  allocation focused on ((Ptr a -> IO b) -> IO b)-style, special
  support for C strings.
* Making Haskell wrappers around C functions: automatic conversion
  of arguments and result in "obvious" ways derived from both C and
  Haskell types, handling common patterns for the result (throwing
  an exception when -1, repeating an operation failing with EINTR,
  ensuring single-threaded calls of a function). It will be a
  convenience mechanism wrapping things available elsewhere explicitly.

The version at <http://qrczak.ids.net.pl/qforeign.tar.gz> does not
include important recent changes yet.

An example involving an out parameter:

fgets:: Int -> Ptr CFile -> IO String
fgets n file = allocCString n $ \ptr -> do
    call fgetsC ptr (n+1) file :: IO (Ptr CChar)
    peekCString ptr
foreign import "fgets" unsafe
    fgetsC :: CString -> CInt -> Ptr CFile -> IO (ThrowNull (Ptr CChar))

One little problem: this way of throwing exceptions does not allow
adding custom data (e.g. function name) to the exception object.

>      Is it really necessary to use a plethora of non-H98 features?

In the interface I only use multi-parameter type classes.

Pattern type signatures are convenient in the implementation and
sometimes in usage (I've found one nasty example with qsort), but
they are not essential.

The implementation of course relies on FFI features, including
foreignable newtypes.

>      And even if it really is, does the user of the
>      lib has to know about them or are they implementation details?

MPTC are not explicitly visible unless one is going to add his own
types (e.g. newtypes) to the convenience mechanism of making wrappers.

Unfortunately using this convenience mechanism sometimes requires
adding explicit type signatures, the need of which may be not obvious.

-- 
 __("<  Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
 \__/            GCS/M d- s+:-- a23 C+++$ UL++>++++$ P+++ L++>++++$ E-
  ^^                W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK                5? X- R tv-- b+>++ DI D- G+ e>++++ h! r--%>++ y-


Reply via email to