I refrained from proposing this in an earlier mail, but I've been thinking about it for a long time. I *really* *really* want to be able to insert small snippets of foreign code into the source of a Haskell module.
I *really* *really* don't want this. The current Hugs implementation of ffi could readily accomodate it because it generates a C file which you compile in the normal way but it would forever rule out an improved implementation (for use on especially well supported architectures) which doesn't need a compiler at all. One could argue that it'd be ok to support it as an optional extension on just some platforms and people would just have to be careful to use the portable subset when appropriate. Anyone who has tried to compile Linux code (intended for gcc) on some other compiler knows that people don't restrict themselves to the portable subset and, after a while, forget whether they're using extensions at all. In other words, I'd like to keep all ffi implementations identical: no non-portable extensions. [Note that the same portability argument applies to supporting unboxed pointers in the ffi:not portable and not necessary.]
Doing it in a separate tool will lose efficiency in some important cases. If the compiler is compiling via C, then it can insert inline C code directly in the generated code, and thus get inlining. But I think a separate tool would have to put the C code in a separate C file, which would prevent inlining.
My group at University of Utah will be releasing "Knit" in a week or two. Knit is mostly an adaptation/implementation of Matthew Flatt's component programming model for C (see his PLDI'98 paper). But Knit can also merge multiple C files into one file, flag functions for inlining (using a simple cost model to avoid exponential code size increase), and sort function definitions so that definitions come before uses (required by gcc's inliner). If you're really that obsessed with performance, you could use Knit :-) [Knit is, of course, written in Haskell.] Or, if you want a lower-tech solution, you could define all those little functions as inline functions in a .h file and use whatever flags or directives nhc/ffi provides to say "please #include this .h file". With the latter approach, we might want to tweak GreenCard and friends to optionally flag all the internal C functions it generates as "static inline" to enhance inlining when used this way. The "static" annotation would have to be optional (i.e., controlled by an ifdef) because we'd also want to be able to compile the file by itself. Alastair