As for the phrase "technical debt": While I like the metaphor, in my experience, most people use it as a synonym for "bad code", so I recommend making sure everyone agrees on the same definition before using it.
As for the phrase "technical debt": While I like the metaphor, in my experience, most people use it as a synonym for "bad code", so I recommend making sure everyone agrees on the same definition before using it.
No, it is not. For consistency, you'd have to start thinking of everything you own as a liability, and only use "asset" to refer to a problem solved by something you own. This would be confusing to everyone you talk with about assets and liabilities. On a day when you didn't drive anywhere, you'd point at your car and say "I got no assets from this liability today." (There would be some truth in that statement, but your listeners would definitely be confused.)
EDIT: I should add, I believe Dijkstra was using hyperbole to make a point with the "lines spent" part of https://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD103...
It doesn't sound like hyperbole to me. "lines of code" without context is a liability, more is not better. The correct side of the ledger is being stated as liability, if we're to consider lines of code at all.
I'm not in the industry so can't say, but the weight of parts is always a liability as it contributes to fuel consumption. Parts also require maintenance (but not necessarily by weight).
An operational plane as a whole is certainly an asset. Perhaps this is how we should handle software, the whole is an asset, the quantity of parts that need maintenance are liabilities.
Doesn't more lines == more features == more value.
How is that not better?
More lines of code do not always mean more features.
More features do not always mean more value.
To my knowledge researchers have not found a single metric that correlates with bug count other than total lines of code. Unit testing, developer experience, none of it is predictive of bug count, only size of code base has a correlation.
Counting lines is a terrible metric for software. It lacks any sort of useful context.
first 6 months: more LoC => more features next 6 months: more LoC => less features next 6 months: more LoC => 1 feature next 6 months: more LoC => some existing features not working well
and so on
because a new feature is not only adding code but changing code.
and the more code you have the more you have to change it.
Everything I own is a liability -- and an asset at the same time.
Some things are net assets, some things net liabilities.
The distinction matters a lot.
Writing less code minimizes the liability side. Combined with a "YAGNI" stance, you can minimize your codebase total liability while writing the least amount of code required to do the job.
Rushing out poorly architected and implemented software systems means that the asset depreciates at a much greater rate than otherwise, just like a crappy vacuum cleaner.
Since we’re mainly in the business of building a single self-updating vacuum cleaner per business we’re fully capable of taking a cheap design and a cheap implementation and making it better over time… at a cost!
We've got an asset account, and a couple of expense accounts, depreciation and maintenance. So the depreciation transactions are from some kind of assessment of the asset's value over the full lifetime (read: will anyone still use this Android app in 10 years?) while the maintenance transactions are from the actual costs to keep the asset operational.
Depreciation isn't really about quality or value, rather lifetime expectation. As a consumer buying a cheap vacuum cleaner you are knowingly buying a product that depreciates at a higher rate. You can maintain that vacuum cleaner for a lifetime if you wish but those are separate expenses.
So in terms of software, if you should be rushing something out the door in order to try and find product-market fit, do so with the knowledge that you are creating an asset with a shortened expected lifetime, ie, that depreciates at a higher rate. As you transition from prototype to a more robust system you adjust the rate the depreciation to match.
You can choose to keep maintaining the prototype but the costs of doing so are probably more than the enhancement costs that are offset by increased capitalization. But again, do you expect anyone to be using your Android app in 10 years?
The accounting practices in software are much different than thinking about a widget factory so I do get the sense we could using some innovation in the field.
In my view yes. I often find it frustrating how much code people will generate to solve a problem that occurs extremely rarely and the consequences are not severe anyway. All of that code is now a liability and must continue to cope with any future changes to the system. No matter how elegantly you think you write code, the easiest code to change is the code that doesn't exist at all.
it's not the lines of code that costs, but time. It may be OK to use lines of code as proxy for time spent - but that sort of assumes that each line took similar amounts of time to write. I am not sure that's really the case, but even if it is, hiring somebody more competent will get more lines in less time!
Therefore, why not just measure the time directly?
Your perspective just needs a shift from negative to positive.
Yes. I love to code and I love that metaphor. One day while browsing Reddit/TIFU, a post jumped at me: "TIFU by creating and releasing a Reddit plugin for Firefox/Chrome, because I'll have to maintain it for my whole life."
It's so funny, true and enlightening at the same time.
> most people use it as a synonym for "bad code"
For me, "tech debt" is the suboptimal solution you shoehorned in the last minute because you don't have any alternative course at that moment (time, brain fog, etc.), which can boil to bad code, in general.
Presence of code itself is not the technical debt itself.
Nowadays it’s even easier with LLMs, they can help you point to the right direction, then it’s easy to validate with some search engines.
Software rots too, if for no other reason then due to Lehman's 1st law [1]. Difference is that with code we have more choices.
[1] https://en.wikipedia.org/wiki/Lehman%27s_laws_of_software_ev...
The teams who were fastidious with their unit and automation testing saw the code as an asset. It was generally reliable and not risky to change.
The teams with little to no unit or automation testing saw their code as an ever growing liability as complexity increased ultimately culminating in the great rewrite every few years.
Damn! I'm fortunate to have never experienced this. In my entire career, only once have I seen a project suffer from a complete rewrite, even with projects that did no unit testing.
Code should
1. Function as needed 2. Be clear to read and understand 3. Perform well enough
Possibly even in the order listed. Performance is the trickiest one of course. Sometimes it's not negotiable and messes with #2. But one should always benchmark and profile to see what needs to actually be done before sacrificing clarity and cleanness.
Architectural decisions may very well result in technical debt, but an architectural decision to go with a vertically scaling solution doesn't have to be a bad decision or bad code. It's only really a problem once you get enough users that you need to start scaling horizontally. At that point though it would very much be considered a technical debt since it was originally trading development time with future scalability.
It's not even that. There are certainly low-effort projects that take a lot of lines of code, and there are high-effort projects that take few.
I don't like these rules of thumb that when taking literally screws us. Some manager is going to want to minimize locs now.
Code suckiness per feature is a qualitative measurement. I don't think there should be any allusion of absolute numerical scores for that property.
"Cognitive load" has to be normalized by "stuff done".
I mean the unit is something like: (stuff done by app) / (code stuff) where 'code stuff' is really really fuzzy. I mean dependencies count into that measure, even though they are zero loc written by you. Etc.
Few things are 50/50--those cases rather tend to be "no one really knows yet".
My phrasing is "you'll know good code when it's shown to you" where "you" is myself for my own work.
But... if you do the same thing in fewer lines, by writing terser code, that may be harder to understand and therefore maintain, and that's also a liability - maybe more of a liability.
If lines of code are a liability, some lines of code are much more so, because they are hard to understand, overengineered, badly designed, brittle, or probably several other reasons. Code is a liability; bad code is far more so. Get the most assets - functionality - with the least cost - lines of code plus "things that make code more expensive".
Can't be done without it, but it can definitely get in the way.
In the same way a factory should be accounted for as a liability. You spend to build the factory, then it depreciates to zero value, so all you've done is lose your original capital. It's not possible to ever get ahead.
That's just a very bad understanding of basic accounting.
Code is a capital asset. Getting value from it over the long term requires maintenance and repairs, improvements and replacements. "Technical debt" is a complete misnomer in terms of accounting principles.
That is, yes. Code is a liability. This does not keep it from being an asset, as well.
If we're thinking in these terms, code is clearly both an asset and a liability.
I don't think of code in those terms at all, though. I think of code in terms of change. Changing code brings risk and expense, and that's why the rule of thumb is to never touch an existing line of code without careful consideration and a very good reason to do so.
Just as "real" assets depreciate, capabilities/functionality can as well. Require both maintenance and has a operation cost (also beyond hardware cost).
If you measure cost by lines of code, you'll get programs like this: https://www.youtube.com/watch?v=a9xAKttWgP4&t=402s
I like the garden analogy. We want a garden to be pleasant and nice, but we'd also like it to be easy to maintain. A successful garden is about finding that balance between plants that mostly take care of themselves and a few unique things that might take a bit more care but make the garden special. Daffodils require no maintenance at all but they only appear briefly and everyone has them. A garden full of daffodils isn't special.
Software is there to be useful, to provide some business value. But it can't all be boring old daffodils. There has to be something your business is doing that is different from any other business, otherwise why are you even writing software? So, yes, there is a liability in the sense that you need to tend to whatever garden you decide to grow, but there is a definite asset in the sense that it is delivering value to the business. It's all about trying to manage the size of the liability given the size of the asset.