FFI – foreign function interface – is a common way for new languages to integrate with existing systems. But FFI is problematic in many ways. FFI represents ambient authority (the ability to ‘import’ authority to ad-hoc resources without a specific grant) which makes it difficult to integrate untrusted code. FFI requires more information about the platform (i.e. that it provides the foreign language), which hinders portability and cross-compilation. FFIs integrate awkwardly with GC, runtime plugins, concurrency, debuggers, rich types, etc..
Instead of FFI, we should define programs against well-defined interfaces, which may vary based on the kind of the application.
The integration code is shifted outside the language. The program has well-defined authorities and contextual requirements, making it secure-able and portable.
On a per app-type basis, the integration burden is lower because we’re dealing with a specific API and context rather than a generic one-size-fits-all FFI. We don’t need to deal with generic type adapters, generic GC integration, etc.. There is some opportunity for specialized optimizations. The overall integration cost (across many kinds) will be higher, but not too much: while there are many ‘kinds’ of applications (end-user apps, web servers, pubsub apps (ROS, DDS), console apps, dock apps, etc.), there are a great many apps of each kind, and the overhead of supporting a new kind is readily amortized. And the backend itself might be extensible or pluggable, at least for common capabilities like network and storage.
One reason I’m thinking about this regards use of import expressions – avoidance of them.
Gilad Bracha argues against imports in his article Ban on Imports. His argument is based on abstraction and extension issues: imports tie modules to concrete implementations of potentially abstract dependencies. While those are valid issues, I’m more concerned about entanglement: imports create a web of names, and it is difficult to extract a module for reuse in another project without dragging along enormous sections of that web; and name or version conflicts easily result in DLL hell.
FFI without import seems not very practical. Also, FFI can be understood as a form of import. To be rid of imports, we must be rid of FFI. And that’s just one more motivation to avoid FFI.