For the most part, the output object/exe size should be the realm of the tooling, not the programmer's concern -- a dependency-walking package-manager, linker or loader -- and in dynamic languages, unused code should never be JITed. Of course, surrounding issues such as choosing bad or incompatible libraries, etc., is another matter.
There’s no way a linker, no matter how smart, can give us back the object size and performance of the ‘90s.
For starters, there’s 64-bits. Pointers were a quarter of the size in the ‘90s.
Then, there is Unicode. All programs need ICU (http://userguide.icu-project.org/icudata). Even if you dynamically link it, many of its symbols (or entry point IDs) end up in your executable.
Unicode isn’t an exception, though. Every library choice you make adds a bit more in size and takes a bit more in performance than the solution from the ‘90s would have.
For example, the moment you decide to use json, you get its entire feature set (arbitrarily nested arrays, a multi-line string parser, ability to read fields in arbitrary order, etc), even if all you need to do is pass two integers and get one back.
A parser generator that generates code for the json subset you need would help here, but would mean extra work for the programmer and the overhead typically isn’t that large, so why bother? It all adds up, though.
Even if you can’t remove some code, you still could optimize memory layout to move code you expect will rarely run into separate code pages so that it likely will never be mapped into memory, but that’s serious work.
And of course there’s all that argument checking/buffer overflow protection people do nowadays that ‘wasn’t necessary’ in the ‘90s.
The article clearly focuses size due to the use of libraries.
As for pointer size, personally I agree -- most processes can get by just fine with their own 32bit address space, so I'm not sure why we need to double the working-set size of all pointer-based data-structures.
> so I'm not sure why we need to double the working-set size of all pointer-based data-structures.
If your data structures can fit in a 32-bit address space, you can just place them in an arena w/ 32-bit indexes. You do need to use a custom allocator for every element of that data structure, but other than that it ought to be feasible. Link/pointer-based data structures should be used with caution anyway, due to their poor cache performance