Further additions to the FFI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMHO, the FFI should really be self-contained and not rely on other non-standardised extensions/libraries. Therefore, I propose some additions.
This makes me slightly uneasy because the FFI specification will conflict with the new library specification that is currently evolving. For example, the names of all the modules are different (eg. CForeign -> Foreign.C). Now, the FFI spec is clearly much further along than the library spec, so I don't want to hold it up, but I think it would be useful if we could agree on what direction we want to go. My suggestion is that, since the new library spec will hopefully be adopted by NHC, Hugs and GHC, that the FFI and library proposals may co-exist and agree on the specification of the FFI modules. That means changing the FFI spec at a later date to accomodate the changes made as a result of the library reorganisation.
* I think, we should include the `Bits' module (or something similar). It is needed, eg, to handle bindings to C functions that expect bit vectors as arguments.
* To implement marshalling for foreign imported pure functions, `unsafePerformIO' is essential. We could add it to the module `Foreign' or `MarshalUtils'. This raises the question of whether `unsafeInterleaveIO' falls in the same category. I think, we should add `unsafePerformIO' and leave `unsafeInterleaveIO' our as it is less important for the FFI.
ok, but note that there will be some overlap with the library spec.
* I am also not really convinced about `MarshalUtils.withMany'. There may be situations, where such a function is handy, but should it really be in the standard libraries? Moreover, it isn't really marshalling specific - it is JAFL (Just Another Function on Lists).
We can move it to Data.List.withMany in the new library hierarchy.
Names ~~~~~ * I don't think `CTypesISO' is a good name. Maybe `CTypesLib' as it contains the types from the C library (as opposed to the normal builtin types)? Or put it all into `CTypes' after all - that doesn't mean GHC (or any other compiler) has to put it into a single module, just for the definition. I tend to having one module only.
One module is fine with me. I have a couple of other points: ForeignPtr ~~~~~~~~~~ Why do we still allow ForeignPtr as an argument to a foreign imported function, now that we have withForeignPtr? Is it just for convenience? If that's the case, it would be enlightening for the spec to say so (perhaps in a footnote). IOError ~~~~~~~ One thing that bugs me about writing FFI code at the moment is that there isn't a portable way to generate an IOError except through CError.throwErrno and friends. There's also no way to change the info (location, filename, handle) in an existing IOError. This is the single cause of non-portability in a lot of the FFI code I've written recently. Also, we currently can't provide a portable version of CError.hs. I'd like to see something like this: --------- data IOErrorType -- abstract mkIOError :: IOErrorType -> String -> Maybe FilePath -> Maybe Handle -> IOError alreadyExistsError :: IOErrorType alreadyInUseError :: IOErrorType ... addIOErrorLoc :: String -> IO a -> IO a addIOErrorLocAndPath :: String -> FilePath -> IO a -> IO a --------- This doesn't require any more functionality than is already required by Haskell 98 (although perhaps the range of IOErrorType could be expanded somewhat), and it should sit just as well on top of Nhc's implementation of IOErrors as GHC's. Furthermore it would let us provide a portable implementation of CError.hs. The addIOError functions are very useful. Quite often an error is generated by throwErrno in a function which is a long way from the one which the consumer of a library initially called; for example when I get an error from Directory.renameFile I want the error message to say "Directory.renameFile" and contain the filename that I passed to renameFile. So you'd implement renameFile as renameFile file1 file2 = addIOErrorLocAndPath "Directoy.renameFile" file1 $ do ... Cheers, Simon