malcolm-ffi@cs.york.ac.uk wrote,
In the current design of the FFI, it is assumed that most of the marshalling work is going to be done in Haskell. For example, to return more than one result from a C function, the results are packaged as a C struct, passed as an Addr (or Ptr) to Haskell, which then dereferences from the Addr to each individual component of the struct.
Now in GHC, the treatment of the IO monad may make this acceptably fast, but in other implementations (like nhc98 (of course)), this is just horribly inefficient, and can slow up FFI calls by an order of magnitude or more. (Comparing to previous implementations using either the builtin 'primitive' mechanism or GreenCard.) I agree that it is better in principle to have the marshalling code in Haskell because it has much better type-safety than C. But in practice, I have found other ways to do the marshalling, mainly because of the efficiency question.
Honestly, I don't think that there is an easy solution to this problem. And - while I understand that you may not be happy about this - I am tempted to put the burden on the compiler writers here. Marshalling-style IO monad operations just have do be optimised properly. The reason for my position is simply that marshalling in C is IMHO not an option for anything but small bindings. It certainly is out of question for something like GTK+Haskell. Except when the marshalling code is generated by a tool (like GreenCard), but I doubt that we will - in the long run - have tools which do C side marshalling. Simply because when writing a tool, it is also easier to generate Haskell marshalling code (as H/Direct demonstrated). In summary, I think, we should have an eye on that we exactly know what we expect a compiler to do to optimise Haskell marshalling code (and avoid code that we cannot reasonably expect a compiler to optimise), but I don't see how we can do without the co-operation of the compiler. Cheers, Manuel