A little more about the difference between FFI-via-C and RPC: the difference really boils down to three things:
- cross-address-space context-switching
- serializing explicitly via a buffer, as opposed to serializing implicitly via translation functions (that would translate OCaml heap graphs into Haskell heap graphs, etc).
- most of the memory-ownership/lifetime issues for the two approaches are similar.
- calls -back- (e.g. OCaml->Haskell->OCaml) are harder/perhaps-impossible with RPCs (well, sure, you can do it, but it requires much runtime hackery).
The biggest difference is that for small/simple cross-calls, you can avoid the performance overhead of a cross-address-space RPC. But for anything complex, you might find that it’s just too dangerous (requiring too much work to keep things memory-safe) to do it via FFI.