Your #1 is so true. The lesson I learned was that the guy who was there before me almost always developed what he did under the gun and took on technical debt to make it happen.
Now I just put a mental crosshair on the code I want changed and come back to it.
> The lesson I learned was that the guy who was there before me almost always developed what he did under the gun and took on technical debt to make it happen.
The number of times I've spotted some terrible bit of code then go through the version control system to try to find out more of why that moron did what he did only to discover that I wrote the code is embarrassingly large.
Ditto. Not only that, but when working with a large codebase, design decisions that seem unfathomable at first glance often turn out to be reasonable or necessary once you understand the code and its use cases.
I think people mistake the source of frustration. It’s not that the other guy took on tech debt. It’s that he kept saying “we’ll fix that later” and never did. Corner cutting isn’t fatal. Often it’s not even all that painful, if I’m perfectly honest.
In my experience, the person adding the technical debt usually had every intention of going back to fix it, but they were never given the time to actually do it. :)
The road to hell is paved with good intentions. That's the delusional part of the problem. You won't look at it because admitting you have a problem is the hardest part. "I'll do it later." is the primary failure mode we have for personal improvement across just about everything. Diet, personal finance, interpersonal relationships. There's a whole category of aphorisms dedicated to this.
Nobody is going to schedule time for integrity on the project roadmap. That's not how integrity works. You can find some or lose some, but on any given day you have it or you don't.
I’ve become more aware (again?) lately of the differences between ugly code and debtful code.
When hunting down a bug in bad code every method you read becomes a honey trap. It could be here, so you have to stop and grok this messy pile and that mental gymnastics removes parts of the todo list from your working memory.
You pingpng around and when you find the problem you can’t remember why you were looking for it.
Then there’s code where you say “ugh”, take a breath and keep going.
If the smell doesn’t rise to the point of potential confusion about the purpose or goals of the code, if it’s a small inefficiency you can’t (yet) spot in the flame charts, then move on to bigger issues.
That said, I’ve paired to debug with people who defend their bad variable naming choices and the source of their problem was that their own code (and bad naming) confused them. You make them rename and they see the problem immediately.
There are so many things that could go wrong in delivering a piece of code. Just the ones I've seen enough times to build rules of thumb about exceeds my own powers of recall. And some people reliably trip over certain failure modes, while others avoid them subconsciously, never even realizing there was a hazard to begin with.
My new motto is: filter out the reversible decisions and worry about the rest. When something in the former set breaks, make it a teachable moment.
technical debt is not always a "bad thing". Sometimes it makes sense to rapidly iterate until you understand what it is that needs to live on. If the risk for not getting the code out exceeds the risk for whatever technical metric is going to be improved by addressing the technical debt, then by all means iterate.
Or, to stick with the analogy more closely; what is interest? It's the cost of servicing a debt. Technical debt has a low cost to the extent that it Just Works. If it has to be constantly propped up, then it's high interest.
Now I just put a mental crosshair on the code I want changed and come back to it.