Both "code rot" and "technical debt" are concepts that, unlike their real-world analogs, are only problematic in context of ever changing environment. I feel this is a crucial and unmentioned difference that makes the analogy bad.
Both "code rot" and "technical debt" are concepts that, unlike their real-world analogs, are only problematic in context of ever changing environment. I feel this is a crucial and unmentioned difference that makes the analogy bad.
It should be taken as a given that code (and everything else) exists in an ever changing environment. Computers are physical machines; they run down over time. Capacitors need to be replaced, and you've got to blow the dust out of your fans once in a while.
Especially in web development, the environment changes quickly. Who could have foreseen that the authors of the JavaScript spec would introduce their own "remove" function? Not me: I left my code unchanged, and it broke. Or, more technically, it rotted.
Maybe I should've put it in a different way: one of the biggest benefits of putting things in a digital form is that the digital form is immune to decay, as long as someone maintains the infrastructure for copying and reading that digital data. The default state of digital data - including code - is not rotting. We do a lot of extra work to make it rot. So the question should be, why are we doing it, and shouldn't we embrace this feature of permanence that we get for free? It's not impossible [0][1].
Version pinning and only doing updates in explicit, planned steps, is a start. Runtime environment can be virtualized and thus made to outlive hardware (virtualization is a way to turn hardware into software, to make the former immune to decay). Web folks have Babel, which today is used to evolve the language faster than the browsers can keep up with, but it could be used for the reverse - instead of compiling ES1234 into ES5, it could also be made to compile ES5 into whatever backwards-incompatible ES-whatever the browsers will be running 5 years from now. This is how you restore the pristine state of code undecaying. The nice thing about the digital medium is that it only requires maintenance at the boundaries of change, and we get to move those boundaries - we could opt to keep them concentrated in few places (like virtualization software, transpilers, hardware abstraction layers), instead of spreading them out everywhere and then saying that the code "rots".
--
[0] - Common Lisp has many warts that make it suboptimal for modern software development, but one of the best things about it is that CL code doesn't rot much. When you pull in a CL library that's 15-20 years old, you expect it to run without changes. With 25+ years codebase, you might need some fixes, mostly because the language wasn't standardized until 1994.
[1] - Maintaining backwards compatibility matters too. I can take a Windows .exe compiled 15 years ago and I expect it to run on a modern Windows machine just fine. Arguably, this is one of the main reason for success of Windows - Microsoft put in work to ensure old software doesn't break in new Windows versions.
All other things being equal, this is true, except for hardware issues where replacement parts may be very expensive or completely nonexistent.
This should be trivial on the small (just pin versions and disable automatic updates of your build tools / package repos), and with recent proliferation of cheap VMs and containers, it should be simple over time - you should be able to pull a 5 years old image full of old software and rebuild the original binary.
> There may well come a point where just getting the damn thing to build so you can release a version with whatever vulnerability patched can cost more than the remaining lifetime value of leaving it running. In that case, it's already dead, it just doesn't know it yet.
Vulnerabilities aren't sins, they are things that can be fine to leave unfixed. The software isn't dead, it'll just keep running with a known exploitable issue.
Yes, and in the not uncommon case where part of the build environment is left unspecified, the untouched code accrues debt over time. As you say, it's possible not to take on that debt by making a significant investment up front. This isn't an argument against the debt metaphor, it's an argument for it.
> Vulnerabilities aren't sins, they are things that can be fine to leave unfixed.
My point doesn't change if you s/vulnerability/sufficiently serious vulnerability/.
I agree the users of these stacks are often short sighted and you could call that bad engineering. However it's very much a feature of those platforms, not so much individuals decisions on then.
Personally I prefer ecosystems with large common libraries that are highly stable and cohesive to avoid those problems .. but the reality is so much software is built in fragile/high maintenance stacks these days, npm and react being the worst bit not only examples of extreme code rot from time decay of the ecosystem. Try updating a react app from two years ago to really understand..