On 12-May-1998, S. Alexander Jacobson <[EMAIL PROTECTED]> wrote:
> Ideally there would be a system which takes a Haskell project and exports
> enumerated functions into a header file and set of C files. This would
> allow C code like:
>
> #include "myHaskellProg.h" //functions prototypes + Haskell fun data structures
>
> void main(int argc,char **argv) {
> printf(myHaskellFunction(argv[1]));
> }
>
> If the Haskell file contained its own main, then it would be a standalone
> executable.
>
> I could use this to write an adapter to the Apache module API.
> It would also allow the use of Haskell code in C and Java libraries.
> It would also run a lot faster than Hugs interpreted Haskell.
> If you are also required to execute some initialization function,
> that would not be soo bad either.
>
> (yes, this begs the question of translating C arguments to Haskell, but
> if export was restricted to basic types that would cover 80% of needs.
> it would be nice to write Haskell code to process C structs, but that is
> really just bonus.)
For what it is worth, all of this stuff ought to be quite feasible --
Mercury's C interface provides almost exactly the features you have
described. (Export is not restricted to basic types, but non-basic
types must be treated as ADTs in the other language.)
One issue that you may need to deal with is differences in data
representations. Note that the use of lazy data structures means that
the data types will almost certainly be different. But even if you
stick to unboxed data types, there may still be representation issues.
For example, I think the Haskell reports says that Haskell strings are
supposed to be able to contain Unicode characters, which may imply
a different representation than C strings. For another example, with
the current Mercury implementation Mercury strings are represented the
same way as C strings, but the Mercury compiler assumes that all
pointers are word-aligned, which is not necessarily true for `char *'
pointers in C. This means that when passing C strings to Mercury you
need to call a macro which makes sure the pointer is aligned (by making
a copy on the Mercury heap, if necessary).
Thus to deal with these differences in data representations,
for your example you may need to write something like
int main(int argc, char **argv) {
haskell_init();
printf(HSTR2CSTR(myHaskellFunction(CSTR2HSTR(argv[1])));
haskell_terminate();
return 0;
}
where `CSTR2HSTR' and `HSTR2CSTR' are functions or macros for
converting C strings to Haskell strings and vice versa.
There are also some issues with regard to memory management that might
make things a little more difficult for the current crop of Haskell
implementations. The current Mercury implementation uses conservative
garbage collection, which is great for the C interface, since it means
that memory management issues don't get in the way at all. I think
Gofer also does a conservative scan of the C stack, so the same would
apply there. However, for implementations such as ghc, you may not
be able to get away with this. Instead, you might have to explicitly
register and unregister any pointers to Haskell data structures from
the C data areas.
--
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.