I think there's too much being conflated to make such a statement.
For example, microservices tend to communicate via strings of bytes (e.g. containing HTTP requests with JSON payloads, or whatever). We could do a similar thing with `void` in C, or `byte[]` in Java, etc.
Languages which support 'separate compilation' only need to recompile modules which have changed; if all of our modules communicate using `void` then only the module containing our change will be recompiled.
It's also easy to share a `void` between modules written in different languages, e.g. using a memory-mapped file, a foreign function interface, etc.
It's also relatively* easy to hook such systems into a network; it introduces headaches regarding disconnection, packet loss, etc. but those are all standard problems with anything networked. The actual logic would work as-is (since all of the required parsing, validation, serialisation, etc. is already there, for shoehorning our data in and out of `void*`).
If these benefits were so clear, I would expect to see compiled applications moving in this direction. Yet instead I see the opposite: stronger, more elaborate contracts between modules (e.g. generic/parametric types, algebraic data types, recursive types, higher-kinded types, existential types, borrow checkers, linear types, dependent types, etc.)
For example, microservices tend to communicate via strings of bytes (e.g. containing HTTP requests with JSON payloads, or whatever). We could do a similar thing with `void` in C, or `byte[]` in Java, etc.
Languages which support 'separate compilation' only need to recompile modules which have changed; if all of our modules communicate using `void` then only the module containing our change will be recompiled.
It's also easy to share a `void` between modules written in different languages, e.g. using a memory-mapped file, a foreign function interface, etc.
It's also relatively* easy to hook such systems into a network; it introduces headaches regarding disconnection, packet loss, etc. but those are all standard problems with anything networked. The actual logic would work as-is (since all of the required parsing, validation, serialisation, etc. is already there, for shoehorning our data in and out of `void*`).
If these benefits were so clear, I would expect to see compiled applications moving in this direction. Yet instead I see the opposite: stronger, more elaborate contracts between modules (e.g. generic/parametric types, algebraic data types, recursive types, higher-kinded types, existential types, borrow checkers, linear types, dependent types, etc.)