On 27-Mar-2000, Sven Panne <[EMAIL PROTECTED]> wrote:
>    1) Mapping Haskell types to C types
>    2) Mapping C types to Haskell types

These two are a good idea.
For prior art, see the `Interfaces.C' package in normative Annex E of
the Ada 95 standard (available via www.ada.org).

>    3) Byte order

That one looks like a bad idea to me.

More detailed comments below...

> 1. Mapping Haskell types to C types
...
> Haskell type |    C type    | ... is probably |          Range
> -------------+--------------+-----------------+---------------------------
> Char         |  HsChar      | char (1)        | HsCharMin  .. HsCharMax   
> Int          |  HsInt       | int             | HsIntMin   .. HsIntMax    
> Int8         |  HsInt8      | signed char     | HsInt8Min  .. HsInt8Max   
> Int16        |  HsInt16     | short           | HsInt16Min .. HsInt16Max  
> Int32        |  HsInt32     | int             | HsInt32Min .. HsInt32Max  
> Int64        |  HsInt64     | long            | HsInt64Min .. HsInt64Max  
> Word8        |  HsWord8     | unsigned char   | 0          .. HsWord8Max  
> Word16       |  HsWord16    | unsigned short  | 0          .. HsWord16Max 
> Word32       |  HsWord32    | unsigned int    | 0          .. HsWord32Max 
> Word64       |  HsWord64    | unsigned long   | 0          .. HsWord64Max 
> Float        |  HsFloat     | float           | (2)
> Double       |  HsDouble    | double          |
> Addr         |  HsAddr      | void *          |
> StablePtr    |  HsStablePtr | void * (3)      |

This mapping assumes that you want the unboxed types in C.
What if you want to pass an unevaluated closure
(e.g. so that you can later pass it back to Haskell
and then evaluate it)?

What about Bool, lists, tuples, Array, Integer, Maybe, Either, ...?

Providing a C equivalent for Dynamic would help a bit; you could
use that as a catch-all.  But of course Dynamic itself is not yet
part of standard Haskell.

Are there any requirements on what kinds of types the Haskell types map to?
For example, is it OK for all these Haskell types to map to opaque struct
types in C?  If not, what exactly are the requirements?

What should happen with Int64 and Word64 if the C implementation does not
support any 64-bit integer type?   Or should conformance to the Haskell FFI
specification require that the C implementation support a 64-bit integer type?

> 2. Mapping C types to Haskell types
> ===========================================================================
> Another problem is finding the right Haskell type for a given C type,
> e.g. when using foreign import or foreign export dynamic. To accomplish
> this, the module FFI exports the following type synonyms:
> (type synonyms)
> 
> Haskell type |   C type
> -------------+---------------
> CChar        | char
> CSChar       | signed char
> CUChar       | unsigned char
> CShort       | short
> CInt         | int
> CLong        | long
> CUShort      | unsigned short
> CUInt        | unsigned int
> CULong       | unsigned long
> CFloat       | float
> CDouble      | double

What about `char *'?
What about pointer types in general?

> Remarks:
> ========
> 1) Manuel Chakravarty's C2HSConfig uses slightly different names, but the
>    ones above are more similar to the names used in some common C headers.
> 
> 2) ANSI C defines long double and some compilers have long longs, but these
>    special types are probably not worth the portability trouble.

ANSI/ISO C is pretty widespread these days; I think it would be worth including
`long double'.  The Ada 95 standard included `Interfaces.C.long_double',
and that was 5 years ago.  These days it's quite hard to find a pre-ANSI
C compiler.

> 3) Addr can be used for all kinds of C pointers.

That approach compromises strong typing.

It would be better to have a polymorphic Haskell type corresponding to C
pointers.

> 4) The following standard types are so ubiquitous that they should probably
>    be included, too:   (any further types wanted?)
> 
> Haskell type |   C type
> -------------+---------------
> CSize        | size_t
> CSSize       | ssize_t
> COff         | off_t
> CPtrdiff     | ptrdiff_t

Here's a full list of the types defined by ANSI/ISO C (89)
and POSIX.1:

ANSI   <setjmp.h>       typedef   jmp_buf
ANSI   <signal.h>       typedef   sig_atomic_t
ANSI   <stdarg.h>       typedef   va_list
ANSI   <stddef.h>       typedef   ptrdiff_t
ANSI   <stddef.h>       typedef   size_t
ANSI   <stddef.h>       typedef   wchar_t
ANSI   <stdio.h>        typedef   FILE
ANSI   <stdio.h>        typedef   fpos_t
ANSI   <stdio.h>        typedef   size_t
ANSI   <stdlib.h>       typedef   div_t
ANSI   <stdlib.h>       typedef   ldiv_t
ANSI   <stdlib.h>       typedef   size_t
ANSI   <stdlib.h>       typedef   wchar_t
ANSI   <string.h>       typedef   size_t
ANSI   <time.h>         typedef   clock_t
ANSI   <time.h>         typedef   size_t
ANSI   <time.h>         typedef   time_t
POSIX  <dirent.h>       typedef   DIR
POSIX  <setjmp.h>       typedef   sigjmp_buf
POSIX  <sys/times.h>    typedef   clock_t
POSIX  <sys/types.h>    typedef   dev_t
POSIX  <sys/types.h>    typedef   gid_t
POSIX  <sys/types.h>    typedef   ino_t
POSIX  <sys/types.h>    typedef   mode_t
POSIX  <sys/types.h>    typedef   nlink_t
POSIX  <sys/types.h>    typedef   off_t
POSIX  <sys/types.h>    typedef   pid_t
POSIX  <sys/types.h>    typedef   size_t
POSIX  <sys/types.h>    typedef   ssize_t
POSIX  <sys/types.h>    typedef   uid_t
POSIX  <termios.h>      typedef   cc_t
POSIX  <termios.h>      typedef   speed_t
POSIX  <termios.h>      typedef   tcflag_t
POSIX  <unistd.h>       typedef   size_t
POSIX  <unistd.h>       typedef   ssize_t

If you're going to provide any of these, then you should provide at least the
ANSI C types ptrdiff_t, size_t, wchar_t, FILE, fpos_t, clock_t, and time_t.
You should strongly consider providing the other ANSI C types
jmp_buf, sig_atomic_t, div_t, and ldiv_t, not because they
would be particularly useful, but simply because the additional
implementation effort required would be quite trivial.
va_list is probably the most problematic, since it is often dependent
on the particular C compiler.

Of the POSIX types, probably all of them except the ones in <termios.h>
are worth doing if any of them are.

> 3. Byte order
> ===========================================================================
> For the really dirty stuff one needs to know the byte order of the
> underlying architecture:
> 
>    data ByteOrder = SmallEndian | BigEndian -- are there more esoteric ones?
>    byteOrder :: ByteOrder

Yes, there are more esoteric ones.

Furthermore it's generally a bad idea to write code that relies on byte
ordering.  I don't see any reason for the Haskell FFI to encourage this.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]        |     -- the last words of T. S. Garp.

Reply via email to