6 ms·
I think it could make more sense if it's rephrased to 'all code is a liability'. Then the equation is simpler. More code = more to maintain = more liability. I
by ljm 3y ago
I think it could make more sense if it's rephrased to 'all code is a liability'.
Then the equation is simpler. More code = more to maintain = more liability. It says nothing about the quality of the code, just the quantity.
Tech debt is a trade-off between near term and long term ambitions - it is literally impossible to build a successful project without accruing this kind of debt, simply because you cannot perfectly anticipate the future. In that sense, it's not so much debt as it is a maintenance overhead.
- code_biologist 3y agoI agree with the general sentiment but would generalize to "all corporate surface area is a liability" and that liability can be minimized in many ways. An illustrative example where more code is a lesser liability: I work on a product with an activity feed feature built in 2018-19. There was a political battle on whether to build it internally or use a third party "feed as a service" product. The build it internally folks won. The "FaaS" under consideration went under during the pandemic, so we dodged that bullet. We also have customized it in ways not possible with an off the shelf product, with no big rewrite necessary. On the flipside, we've never had time to implement things that are trivial with commercial FaaS like iOS and Android push notifications. Trade-offs are hard!
- opportune 3y agoAgreed, or similarly: all software has a carrying (maintenance, but I think that has connotations of not including full ongoing TCO) cost. Code is a liability in the sense that it has a non-zero carrying cost. The ideal software implementing a given functionality has as low of a carrying cost as possible. More code, in quantity and complexity, typically means more carrying costs. One of the appeals of SAAS is that this carrying cost is easy to quantify and predict. Going further, for high-quality OSS projects like the Linux Kernel, the carrying cost may be 0 or close to 0 for most users. But lower quality OSS or buggy SAAS has a carrying cost in the form of bugs (possibly affecting downstream users), patches, need for support + back and forth. In this analogy tech debt is a tradeoff for some short term benefit (like simplicity, time to market) at the expense of higher carrying costs down the line. But some carrying costs simply can’t be reduced - you can’t mooch off something like the Linux kernel, get your own carrying costs all the way to 0, or find a SAAS provider/vendor willing to give you the software for free. So in this model not all code is technical debt.
- anileated 3y ago> Code is a liability in the sense that it has a non-zero carrying cost. The under-appreciated corollary to that: tests are code, hence tests have non-zero carrying cost as well. > The ideal software implementing a given functionality has as low of a carrying cost as possible. More code, in quantity and complexity, typically means more carrying costs. You understress the complexity point. Higher quantity of code with high clarity and low complexity would have lower carrying cost. This is where DRY bites people: ill-suited or excessive abstractions can be worse than a little bit of copy-paste that are immediately visible to the eye. > In this analogy tech debt is a tradeoff for some short term benefit (like simplicity, time to market) at the expense of higher carrying costs down the line. In a general sense, doesn’t this hold for everything we do? If you really dig into it, is there an activity that is not a trade-off of short-term benefit for higher costs down the line (be it waste, pollution, something unknown or generally entropy)?
- mikermcneil 3y agoHear hear!!
- atoav 3y agoTests are indeed not free. But neither is having to spend two days to debug a weird bug you would have cought if you had them. Depending on the worst thing your software could be doing if it had a edge case mistake, writing tests is also just another take on trying to prevent them when they happen. Also: nothing prevents us from deleting tests and do as if they never existed, except the nagging voice of sunken cost.
- ljm 3y agoIf I've learned anything over my career, it's that tests are treated as write-only code and they forever accumulate. Not only are they a burden in terms of comprehension, they have a measurable cost as your CI/CD pipeline becomes ever slower or requires more parallelism. I've worked in so many places where a test suite suddenly takes a day to run with no parallelism, and requires 50 other machines to get it down to 20 minutes. And so many of the tests that waste so much time are down to them being pointless, or being stateful for no reason. I constantly advise people to stop writing obvious bullshit tests (e.g. the kind of test in Rails where you just assert that you wrote `belongs_to :some_model` in your model), or ones that are too heavily mocked. Focus on your business logic and the inputs and intended outputs, not how you used a framework or dependency.
- smallnamespace 3y ago'All code is a liability' is also not a particularly accurate application of finance jargon. A car or a house also have ongoing maintenance costs, but they would normally be classified as assets (because they generally produce value in excess of the maintenance, or because you can sell them in a secondary market). I think an accurate, useful, but not very catchy rephrasing is just 'working code requires ongoing maintenance'.
- Retric 3y ago‘All code is a liability’ some code is productive. Different domains have different jargon. Code doesn’t map very well to finance because the loan is also the productive asset. It’s easy for a deprecated function to exist which literally nothing calls and therefore it provides you zero benefits, but such cruft is still an ongoing cost. Meanwhile that exact same function was critical last week.
- Spivak 3y ago> working code requires ongoing maintenance I don't love this either because working code needs no maintenance whatsoever. After all it's already working. There's also no notion of "repairing" code because it isn't something that can just break suddenly. So really what we're talking about is that necessary changes to the codebase can arise from not just the stakeholders as we typically define them but also because the environment around the code changes. Someone who invested in shutters that can close instead of being purely decorative will be able to adapt more quickly and cheaply to a wind storm than someone who has to go out and buy wood to board them up.
- sowbug 3y agoChanges to the platform or dependencies break working code. This is increasingly hard to ignore when app stores stop vending your product to older versions of a platform, even if it's working fine. And working code, no matter how well it works, imposes a cost to implementing new features. A new feature might be a cinch to implement in a new app. But it can easily take much longer to implement the same feature in an existing app.
- andrewprock 3y agoAnd all code is an asset. Have we just reduced the conversation to: everything has a cost, and everything has a benefit?
- theendisney2 3y agoIf i had more time i would have written a shorter letter
- NateEag 3y ago> And all code is an asset. No - runnable programs are an asset. The code to produce those runnable programs is a liability. It's a necessary liability for a sustainable software business, as without the code fixing bugs is nigh-impossible (though not theoretically impossible - long-ago programmers wrote and read raw machine code). But, the code itself is not what produces value. That's the code's output. (Yes, you could be clever and say "but what about interpreted languages?" I'd respond by pointing out that it's pretty rare to distribute a pile of executable code files to end users. Front-end JS only producing UX if delivered as part of a website, and similar principles hold for other interpreted languages - they're effectively object files once deployed, as in any deployment they're being run by the interpreter, not read by a human.)
- Jensson 3y ago> No - runnable programs are an asset. > The code to produce those runnable programs is a liability. That is total nonsense. So you throw away all your code after you built the program binary to avoid the liability? Don't think so, that code is a massive asset and throwing it away would make continuing the project unfeasible most of the time. > It's a necessary liability for a sustainable software business, as without the code fixing bugs is nigh-impossible Ok, so you agree with me, the code is a massive asset since it is the code that lets you change the program. Code is there to help programmers do their work, that is valuable as you say. > But, the code itself is not what produces value. That's the code's output. Both produces value. The code is valuable since it makes it easier to inspect and change the program. That is value. It isn't uncommon to sell source code access for products, why would anyone pay for that if seeing the source code is a liability? No, of course it is an asset, people arguing otherwise have just gotten too hooked on the "code is bad" mantra and try to argue all code is bad even though code obviously is very valuable. Edit: And to be even more clear, throwing away the code and trying to work directly with a program binary creates technical debt, that is way worse debt than keeping the source code around. Code isn't inherently technical debt.
- jasonwatkinspdx 3y ago"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger." -- Dijkstra in 1998 (https://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/E...)
- empthought 3y agoThat was in 1988! For similar sentiments consider "Science and the Compulsive Programmer" from 1976. https://www.sac.edu/AcademicProgs/Business/ComputerScience/Pages/Hester_James/HACKER.htm https://www.sac.edu/AcademicProgs/Business/ComputerScience/P... "Programming systems can, of course, be built without plan and without knowledge, let alone understanding, of the deep structural issues involved, just as houses, cities, systems of dams, and national economic policies can be similarly hacked together. As a system so constructed begins to get large, however, it also becomes increasingly unstable. When one of its subsystems fails in an unanticipated way, it may be patched until the manifest trouble disappears. But since there is no general theory of the whole system, the system itself can be only a more or less chaotic aggregate of subsystems whose influence on one another’s behavior is discoverable only piecemeal and by experiment. The hacker spends part of his time at the console piling new subsystems onto the structure he has already built—he calls them “new features”—and the rest of his time in attempts to account for the way in which substructures already in place misbehave. That is what he and the computer converse about."
- jasonwatkinspdx 3y agoDoh! Yeah that was a typo. Sorry I can't edit now. Thanks for the correction. Even though I don't use any of his techniques, Dijkstra's "A Discipline of Programming" did affect the way I see things considerably.
- mirekrusin 3y agoIsn't this line of reasoning a bit like saying "life causes death"?