
I wonder: why, in Haskell and also in other languages like ML, FFI is done with C type and code as references? Since, ultimately, compiled code goes to, say, ELF files or (in Windows) DLLs, shouldn't foreign interfaces be consistent with those?
Having an ELF file, a function name, and knowledge about the parameters for the function, is still not sufficient information to invoke it. I still need to know what calling convention is being used.
Is it possible to list the "set of sets" of suficient/consistent specifications one needs to list for each parameter for a function call? Types like those we have today (CInt, CSize, forall a. Ptr a etc.) are examples of such sets, but my naive guess is that we could have weaker ones. For instance, one doesn't need to know wheather a parameter is a pointer or an integer of the same size, as long as it's not actually used as a pointer, as opaque types sometimes do not identify themselves as pointers, and that doesn't prevent us from using them. Suppose we have C functions below. type_name give_me_opaque (void); void use_opaque (type_name); We could be able to say to Haskell (or other language) "foreign binder" that we have a type named MyOpaque and that: Properties of MyOpaque: may be copied. foreign import give_me_opaque :: IO MyOpaque foreign import use_opaque :: MyOpaque -> IO () MyOpaque would be assigned a type whose only property is to have a value (that you can copy and nothing else). The FFI tool would only have to verify (from a binary library header) that 'use_opaque' uses a parameter the same size of what 'give_me_opaque' returns. Other properties one could list for a type: be usable as an int32 (or int16, uint24 etc.), be usable as a pointer etc. A foreign function binding would have to list enough properties such that a set of suficient and consistent specifications could be obtained by crossing those properties with the information available in binary library headers. Does that make sense? Thanks for your toughts, Maurício