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.