if we could rethink packages, versioning, (and maybe even linking) from the ground up.
The simple and elegant solution is static linking for all user code, and only use dynamic linking as the interface to the operating system (instead of syscalls), and for plugin-systems (for plugins WASM/WASI is the better technology though). E.g. every application and tool should be a single, self-contained executable, maybe even including all application data (those data sections would only be mapped into memory when needed, kinda like a memory-backed virtual filesystem).
The biggest problem of dynamic linking isn’t versioning, but that a DLL represents an optimization barrier. First, dead-code-elimination doesn’t work for DLLs. It may well be that a single shared instance of a DLL loaded into memory takes up more memory than as if each process would statically link the library, since unused code is either not linked in the first place, or removed during LTO. And second, DLL functions cannot be inlined and further reduced and optimized. E.g. it may be that a large function body may be reduced to almost nothing after inlining.
Linux distro package maintainers hate this simple trick though
(since when a security issue is found in a library, all packages that use a specific library must be rebuilt instead of only one package).
PS: A ‘new way’ of linking could be some sort of ‘shared static’ linking. E.g. an executable could have specific pieces of code and read-only data in separate executable sections, identified by a hash-key. The executable loader would keep track of those sections, and if other executables have sections with the same checksum, they could be shared in memory (the exe loader must not just trust the checksum of course, but make sure that the sections are byte-by-byte identical).
This would fix “DLL version hell”, since each executable is still fully self-contained, but the operating system will still be able to eliminate multiple copies of the same code and data in memory. The downside is that such executable sections would still be an optimization barrier. And if the executable only places actually used library code into such sections, then it’s much less likely that those sections can be shared with other processes.
…yeah, the more I think about this weird static/dynamic hybrid the less sense it makes. Static linking is actually fine 