> Oh hey, yeah. A bunch of small utilities that communicate and interoperate. I can see it working out. You could even have them communicate with each other via some sort of universal interface.
The key is to have that interface be narrow and well defined - something like gRPC. Allowing them to communicate via a huge, poorly specified, non-concurrency-safe swathe of shared state (filesystems with all their ad-hoc semantics, shared memory, signals, pipes, KAME sockets, namespaces, goodness knows what else two processes on a Unix system can do to fuck with each other) is a recipe for disaster.
> The key is to have that interface be narrow and well defined - something like gRPC.
You really can't use a mesh of unikernels for this then. You need an external system to enforce the types (like a compiler does for a single program).
At runtime, so far as the computer cares, there's really just arrays of bytes (or machine words depending on if your system is really byte-addressable or just faking it).
You can do input validation, but unix cli utilities can already do that. You'd need, rather than a bunch of unikernel utilities, an all encompassing environment that the utilities can register their constraints with, and the system would prevent them from being called if the constraints were not met.
Main contender is probably emacs, just because it's already ahead on the "all encompassing environment" part of this.
> At runtime, so far as the computer cares, there's really just arrays of bytes (or machine words depending on if your system is really byte-addressable or just faking it).
The problem isn't arrays of bytes. The problem is all the other semi-structured cruft that the OS has accumulated, the squillion different system calls you can make with almost-but-not-quite standardised effects.
> You can do input validation, but unix cli utilities can already do that. You'd need, rather than a bunch of unikernel utilities, an all encompassing environment that the utilities can register their constraints with, and the system would prevent them from being called if the constraints were not met.
Or you just don't give them the interfaces to mess with each other's internals. You have your hypervisor isolate them from each other except for a narrow communications channel obtainable in a narrowly specified way. Ideally the hypervisor also enforces that what you send/receive is well-formed gRPC (which is not hard), but that's not essential - the main benefit comes from just closing off all the other random OS-level ways that Unix processes communicate with each other.
The key is to have that interface be narrow and well defined - something like gRPC. Allowing them to communicate via a huge, poorly specified, non-concurrency-safe swathe of shared state (filesystems with all their ad-hoc semantics, shared memory, signals, pipes, KAME sockets, namespaces, goodness knows what else two processes on a Unix system can do to fuck with each other) is a recipe for disaster.