Technical debt is actually a really good analogy, precisely because non-technical finance people understand the tradeoff pretty intuitively. Sometimes incurring debt is the right thing to do, but you'll want to pay it down or you'll have to live with the interest. This is true of both monetary and technical debt. For extra credit, you might assign notional interest rates to your technical debt... if they're in the double digits I promise you they'll scare the finance guy.
Ehhh, the analogy doesn't hold totally because you might not have to pay it back. In that case you're ahead. FTA:
Call options are a better model than debt for cruddy code (without tests) because they capture the unpredictability of what we do. If I slap in an a feature without cleaning up then I get the benefit immediately, I collect the premium. If I never see that code again, then I’m ahead and, in retrospect, it would have been foolish to have spent time cleaning it up.
That's the home run point: you might not have to pay it back. That is exactly why the debt or credit card analogy doesn't hold. An uncovered call is exactly the correct metaphor. This isn't even high finance we're talking about, this is fundamental options stuff. I'm not sure I understand the resistance to using the uncovered call terminology as opposed to the highly innaccurate (but more Main Street comprehensible) "debt" analogy. Debt (aside from bankruptcy ALWAYS has to be repaid. Yet we all know that technical debt doesn't always have to be repaid. Debt is a terribly imprecise way of thinking about it.
> I'm not sure I understand the resistance to using the uncovered call terminology as opposed to the highly innaccurate (but more Main Street comprehensible) "debt" analogy.
Specifically, it is because the managers I am attempting to communicate with understand the concept of "debt" and do NOT understand the concept of "uncovered calls". I work at a bank and VERY few of the managers I need to explain things to would really understand uncovered calls. I would guess that people at other kinds of employers may find it even worse.
Debt doesn't always have to be repaid. It can be refinanced and carried indefinitely. People do it all the time with mortgages. I know people who have lived in the same house for 15 years, but due to frequent refinancing and cashing out equity they still have 29 years left on their mortgage.
I agree, the analogy is imperfect, because you don't pay interest unless you need to extend or maintain the code. It's only useful in a world where the codebase in question is under ongoing development, but those are the situations where I've used it. Naked calls work fine as an analogy in the case you describe.
Agreed. Startups have very high capital costs. Even a usurious credit card can look lo-cost. It's not very scary at all. It's like writing Little Red Riding Hood with a "big bad groundhog."
The counter also assumes all code lives in a vacuum - that cleaning that particular code will not impact any other parts of the code base. I find this to be very far from the truth. Often cleaning up one area will lead to abstractions that can have an effect far beyond the original code.
>Ehhh, the analogy doesn't hold totally because you might not have to pay it back. In that case you're ahead.
The analogy totally holds. If you don't pay back financial debts (e.g. airlines going through chapter 11 and shedding their pension obligations), then you ALSO come out ahead.
Calling it "selling insurance" is pretty good. People blank if you say "options", but selling insurance captures the immediate small upside with potential massive downside later
This is exactly the analogy I use with developers who tend to over-engineer.
In a perfect world, we'd be guaranteed that our code will never need to change. In this world, abstraction is worse than worthless - it is a cost with no benefit.
In the real world, there are risks. Bugs will be fixed, requirements may be changed, back end systems may be replaced or scaled, and so on.
Building things the "right way" is exactly like buying insurance against those future risks. Business-savvy developers know how to estimate the probability and cost of the risk this code will face over its lifetime, and weigh that against what it would cost to build in extra code to mitigate those risks right now.
Thus, choosing the right level of abstraction and engineering overhead to add to a particular feature should be a series of decisions and tradeoffs, not just a determination that it's always better to build the "right way".
In my experience, developers tend to be overly confident in their ability to predict and mitigate future risks, and suffer severely from hindsight bias. They rarely lament the extra abstraction layer they built and never needed, but are quick to point out when modifying a feature will cost more because of weak abstraction.
Even in those perfect conditions right level of abstraction may cause the system to be build with less code and faster.
That being said I agree that it's always a trade off; I actually did many refactorings where I threw an abstraction level out instead of adding more of them, resulting in faster and easier to maintain code. It's definitely not good to invest in abstraction blindly.
In a perfect immutable system, I'm still going to want my code to be as DRY as possible, because I don't like typing the same thing over and over again.
In this perfect hypothetical world, you wouldn't eschew abstraction; you'd just know exactly what abstractions to use to perfectly model the problem you're solving. Those ideal abstractions would be different, since the problem is immutable.
Ask yourself this: in this perfect world, would you code with a magnetized needle and a steady hand? Why not?
Not sure how the magnetized needle analogy applies here. The point of the hypothetical is to avoid developing your own extra layers of code for future reuse. Avoiding those that others have developed for you already would not make sense.
As to the rest of your point, yes. Anything in service of pure development speed would be desirable. If you could abstract and reuse something faster than you could implement it in some other way (eg copy/paste), then it would make sense to do so.
Well, with LedgerSMB (http://www.ledgersmb.org), we forked from an absolutely horrid codebase. The author has been described by Matt Trout as "The guy Matt's Scripting Archive would have fired for bad coding." I mean the codebase was a total mess. Total, total, total mess.
After 6 years of refactoring we now have a framework in place to start on the financial logic. It shouldn't take us more than 6 years to get the rest rewritten.
One of the hidden costs of bad code is that it is contagious. After staring at bad code, it is very hard to write very good code. So it takes several revisions to go from bad code to good code, to get the patterns right, etc.
>One of the hidden costs of bad code is that it is contagious.
That's why the debt analogy fits so well - because technical debt compounds. If your codebase is already heavily in technical debt, when developing new features or fixing bugs you are faced with three equally unpalatable options:
1) Do it properly (takes: 1 month)
2) Don't make it worse; don't make it better (takes: 1 week)
3) Just do a quick hack to work around all of the other hacks (takes: 30 minutes)
As a developer with a pushy boss who doesn't understand technical debt and a tight deadline, the rational choice is pretty obvious: take 3, go home at a reasonable hour to your family, still meet the deadline and drown your professional sorrows in alcohol.
But that isn't taking into effect the contagion issue. In theory your view is the way it works. In practice doing it "properly" comes out half-properly because you spent all your other time maintaining horrible code so that it infects your thought processes and design.
The problem is this. Let me put it clearly:
If you are maintaining bad code, it will take you several tries to come up with a good architecture to replace it. You will make better progress having someone entirely outside do the architecture themselves.
OTOH, if employers are going to use credit scores to decide whether to hire you, then technical debt may be an even better metaphor if you factor that in ;-)
Well, a 200k line codebase, maintaining it for current users. Yeah might have been better to start from scratch.
OTOH what one gets by going this way is a community of users, and therefore it will still beat Hurd 1.0 to completion. Starting an ERP from scratch without funding as a multi-vendor effort would lead to something that would never be released.
But you should see the legacy code. The code we forked from was a textbook of how not to write (secure, maintainable, bug-free, etc) software.
success of the business and good quality code does have a relation ship - it's just not an obvious one. Like reversing a car with a trailer, the direction you want to go can be difficult to control, but it doesn't mean your driving doesn't affect it.
That doesn't always get what you want, though. I've been working on a terrible project and even my managers know how bad it is, yet despite all their efforts to explain this to senior executives(need more people to work on it, more time to refactor, etc.), they simply don't want to hear it.
There's something to this – the emphasis on the optionality of 'technical debt' – but it's not quite 'unhedged'. There's not an 'unlimited downside', as there can be when writing a call on an asset that could appreciate boundlessly.
With tech projects there's almost always a de facto "abandon" option – if not for the firm then at least for the individual engineers. So whenever the cost of proceeding is higher than the expected value, you exit. That clips the downside, more like some sort of combined option position.
Or more like a specific kind of debt: nonrecourse loans secured by collateral. You get the money up front, but if it proves impossible to repay, you simply surrender the collateral. In this case, the collateral is the project itself: either the option to continue, or the IP rights, or the enclosing firm. And, in the event of failure, those may be worth nothing, so you aren't losing an unbounded amount.
For monetary debt, these fragmentary artifacts may in fact be surrendered to the creditors. In the case of metaphorical technical debt, you surrender up those hopes and dreams and mental (sunk) costs, to the reality that there won't ever be the time and budget to fix the system.
And so this leads to a different conclusion than the article, which ends with a near-religious stance against the inflexible evil of debt. Because the downside – project abandonment – is capped, sometimes technical debt is worth taking on, when acceleration-to-market (and thus market-feedback-learning) is of paramount importance. You're borrowing from the future, but you only pay it back (with interest) if there's wild success. If you fail for any other reason – perhaps things having nothing to do with the technical debt – you don't have to pay it off, you just surrender the (essentially worthless) collateral.
That's a hard thing for people with an aesthetic or craftsperson mentality to accept. And it still sucks when it's the technical debt itself – the cost of fixing old rushed choices – that occasionally makes a project no longer competitively viable. Your monetary credit report is unblemished, but your self-conception can take a hit.
Unlimited future downside? Really? I would like to know on which context this is possible.
I don't know in which context the writer is writing, I'm a developer and have been mostly working on startup-style projects. If you fail, you don't make a buck, the product does not work or does not sell. The downside is the lost time and money.
I have also known couple of startups, which have had really good engineers who have invested lots to testing, maintainability etc. In the end however the business hasn't succeeded selling the product, and all that investment was worth essentially nothing.
I was trying to make an ironic joke about the pitfalls of metaphors by using a metaphor. It didn't really have anything to do with the premise of the origīnal post. So I apologize for being off-topic - the opportunity was just too tempting :)
Actually, I think the commentator here assumed (as I did) that you were slightly off-topic talking about the use of metaphors in software programming. I feel a little bit silly now, FWIW.
There's also no unlimited downside in finance -- eventually you can't take out more debt, can't pay the interest, and default (creating counter party risk).
I suppose net across the system, you could inflict more downside to others exposed to your default, but it's not unlimited unless you can wipe out the entire planetary economy (financial and non financial) with your bet.
In the normal case of short selling (absent a large enough position to be subject to a short squeeze) future downside is not unlimited; your broker will close your position unless you put up enough capital.
While I agree with the overall message in this article, "unhedged call option" is not a phrase most people will get. "technical debt" is much easier to understand. "technical gambling" might be better, though i realize not as accurate as "call option".
the term "technical debt" is fairly clear; "technical credit" or 'technical lending" is fuzzier but also more descriptive. Maybe the compromise is "technical debt with interest"
actually, "technical trading" might be a good contender too. You might make out in the long run, or crash and burn. It's all about trade-offs anyway; not writing tests now means future you will have to write them. Sometimes this is fine, sometimes this is a truly horrible idea, and sometimes it could go either way.
I agree with you that "unhedged call option" is not a phrase most people will get, on the other hand software engineering needs a better vocabulary around tech debt. There is a very specific type of tech debt that I think this describes
So if you think we need better differentiation of technical debt (which I do) then finance is a good source of those differentiations[1]
Personally I've heard tech debt used to describe everything from tightly coupled UI/DB code, to design decisions the person disagreed with, to code without tests. Even though those are obviously 3 different problems. So I'm for increasing the size of our vocabulary
Why does it matter that "most" people don't get it. If we call an array a hash, that might be a more well known term, yet if it's innaccurate, what difference does it make? It's the wrong term. Using the wrong term to describe something simply because the wrong term is more well known doesn't make it a better term to use. As I mentioned in another comment, it isn't the term itself that matters, what matters is the meaning. "Technical debt" is the wrong paradigm because of the simple fact that it doesn't always have to be repaid and in fact making that "investment" could result in a higher return if it doesn't have to be repaid. Of course, it could result in a much lower return if it has to be repaid. With debt, you have a known interest rate and upfront, you are aware of the future cost. However, with technical debt we never know the future cost; thus the debt analogy is completely innaccurate.
And technical trading as a term is just completely wrong because the term technical trading already has a meaning; and it has nothing to do with understanding the unknown future benefit or gain. It has to do with making decisions (and predictions) based in extrapolating past results into the future. If anything we should be calling it fundamental trading since fundamental trading is making investment decisions based on a holistic view of the security in question. So, the decision to incur a technical "debt" is made with an understanding of the entire system and the cost-benefit analysis of paying "cash" now versus paying an unknown amount of cash later -- or not having to pay anything at all.
One could call it gambling, but a more accurate description would be risk management. Using a risk management decision matrix one could say that the risk of someone dying in a flood at a shopping mall would be catastrophic, however the likelihood is exceptionally low, so it wouldn't make sense to have life boats spaced every 10 meters. However, it could happen, but the shopping mall owner chose to incur that "debt" of not having lifeboats because they determined that the cost wasn't justified given the profile of the risk. A debt analogy would say that a shopping mall absolutely will be flooded eventually and the debt would exist until such day that the owner bought lifeboats.
The purpose of an analogy is to educate a concept using an approximation of another concept the person will understand. If the person in charge of risk management doesn't understand how risk accumulates in a codebase, they're far more likely to understand the model of technical debt than options calling.
The article ignores the risk of avoiding technical debt, YNGNI, where the `it` you're not gonna' need is the implementation of some set of future-proof architectural features. Or as Knuth put it:
Premature optimization is the root of all evil (or at least most of it) in programming.
The problem of making something worth maintaining has priority...and the software upon which it depends is often a second or third order priority. Facebook was built on PHP. That using PHP created technical debt was a nice problem to have on the way to the bank. None of which is to say that writing bad software is ok. It is to say that bad software includes software that wastes time trying to anticipate and solve the wrong problems at the wrong time for the sake of an ideal rather than current business needs.
The problem with the technical debt concept is that it implies there's this debt-free way of doing things. Like there's some sort of platonic form of "good" code that everything must aspire to, and good teams write code that doesn't have debt.
What I've actually seen in practice is that "technical debt" mostly means "things I wouldn't have written that way." It has very little to do with the code and more to do with the philosophical leanings of the commenter.
>Like there's some sort of platonic form of "good" code that everything must aspire to
There is:
1) Code that is covered by tests
2) DRY code
3) Loosely coupled code
4) Code that fails fast
5) Code that doesn't reinvent the wheel
Most technical debt I've seen violates one of the above principles. It is crystal fucking clear when you are paying it off and the benefits to paying it off are pretty obvious to those working on the code base.
It is impossible to avoid violating them completely, but low technical debt means small and rare violations, whereas high technical debt means large and extremely common violations.
>What I've actually seen in practice is that "technical debt" mostly means "things I wouldn't have written that way." It has very little to do with the code and more to do with the philosophical leanings of the commenter.
In practice I find that most people know terrible code when they see it, but if given the chance to rewrite from scratch most will end up digging themselves into the same hole.
Bad coders will not realize that they are doing it. Good coders can also end up doing it simply for expediency.
I find that the best way of paying off the technical debt is simply to work my way through fixing things 1-5, roughly in that order. It is a slow and largely thankless process.
I disagree. I have willfully acquired technical debt on many occasions by writing code in a hacky way which, given more time, I wouldn't have chosen.
Technical debt is a great metaphor for explaining this to non-tech stakeholders. They understand that choosing to rush a feature out now will lead to slower development (paying back the debt) later.
But to be fair, there's also the potential benefit of not having to pay that debt back. If the feature fails from a market perspective, you've actually saved money by incurring the debt. That's the whole concept behind the Lean Startup.
Yes, there is such a thing as 'good code' that people should aspire to, or at least good practices when it comes to writing code. There are good teams that write code that has no or very little debt. It's also not just bad code that leads to technical debt, but bad decisions when it comes to code-related things like architecture, tech stack, which version of libraries / languages to use, etc.
In startups, technical debt by your definition has more to do with not having enough time/resources to spend on the problem. Code philosophy is the first thing that goes out the door.
Selling a naked put - Integrating a 3rd party library for a feature vs building it yourself. Immediate benefits, and probably unlikely to go sideways, but if the framework turns out to suck you suddenly incur a large unexpected body of pain. However, unlike a naked call, there's understood limited downside, limited to the functionality the library provides.
Buying a put - Building in any kind of protection from "very low probability but high damage" events, such as provisioning a completely separate infrastructure in the case of a massive DC or network outage, or having a completely separate monitoring system in case the first goes down in the middle of fighting a separate fire.
Buying a call - Basically anytime you make an engineering bet that costs a bit of time and is unlikely to pan out but if it does, you win big. Like a spike to try some state of the art algorithm or bringing on a short term consultant to solve a really hard problem. If your whole team is always doing these in the long run you lose, but strategically doing these when they make sense in the long run can result in huge gains.
Selling a covered call - Focusing on consulting services vs building a product. Steady income, but in the unlikely case you build something that strikes gold, it won't be you who becomes rich overnight, it's the person who paid you to build it.
While I appreciate the interesting explanation of a naked call, I'm sorry to say that the category of good metaphors pretty much excludes any that require a lengthy exposition to understand.
I still like shoddy construction/shanty village as an analogy. People know what it is and it is tangible unlike debt or any other financial reference.
You can build a shanty village without a plan that supports a million people, but the first fire, storm, earthquake, etc destroys the whole thing. Also, for some reason when Bob flushes his toilet, the power goes out briefly in the capitol building. Nobody knows why, but routing power through the sewer last sprint to save time probably wasn't a good idea.
Seconded. The point is not that bad code is a necessary evil (it's really not), but that they are going to end up with it if they insist on doing things a certain way.
Another good one is, "Well, I can build you a 20,000-foot fire-breathing chicken made of balsamwood, if that's what you want, or if you just want me to parse a CSV file, I can do that too."
As a developer who has to hear the "tech debt" thing all the time from my co-workers, I really hate that concept. Metaphorically or otherwise, I don't like being in the position of a bank demanding high interest payments from a poor sap who didn't realize what he was getting into. That's not how I view myself in relation to my employers and clients.
I keep bumping into the notion of options in software development - there are (and I will try to hunt them down) a couple of well known papers on option pricing different features. It is interesting because if applied it would spread through the whole organisation using it - once one part uses options as it's decision making mechanism, all parts have to respond.
But anyway, I agree - naked call options is a much more accurate term. But it is a difficult term for folks to get their heads around (incurring debt is something the post Marx Brothers world has gotten used to. Outside specialised areas of finance, not so much with Options)
Read Harpo's autography for an amusing story about how he covered off a huge margin call in the wall street crash by doing private gigs for some gangster mates of chico
That's weird enough to be true ! I was thinking of the scene in A day at the Races, where the gangsters (the terrorists of the day) blocked the road with a car, and (Harpo?) on the escaped horse simply leaps and sails over it.
Chico exclaims "Did you see that - the horse cleared the car !"
Groucho - "well, I wish I could clear mine!"
And 80 years ago we have the consumer debt crisis still writ large.
It may be a more accurate analogy, but its a less useful metaphor for most audiences. Most people have a useful intuition about debt that the "technical debt" metaphor leverages.
Comparatively very few people have a useful intuition about "unhedged call options" that using it as a metaphor for poor code quality would leverage.
Also, I think predictable ongoing support cost is a big result of poor code quality in production systems, so that aspect of the debt metaphor isn't completely off-base (there are also unpredictable potential costs in the future, as well, so its not a perfect analogy.)
It isn't that complex. The idea behind the metaphor isn't to communicate what an uncovered call is, it's to illuminate what technical debt really means. It's a philosophical analysis describing that "debt" isn't an accurate metaphor for what techical debt really is. The fact that this way of thinking about techical debt "isn't widely known" is exactly the point. Most folks think about techical debt in terms of a thing that must eventually be repaid regardless of the future of the software while presenting it as an uncovered call is much more accurate as to what is actually happening: you're trading a now benefit for the future potential that it will cost you nothing or it could be so expensive that it might cost you everything. The decision to incur technical debt is actually an investment that the benefit now is more valuable than the future cost. Debt is completely different; debt implies that it must, eventually, one day be repaid with interest; however not all technical debt must actually be repaid-- for example if you build feature x in a sloppy but expeditious way, you've incurr d techical debt, however if feature x is eventually depreciated the you "won" because your overall cost of the feature is less than it would have been had you not incurred the techical debt. But, if feature x becomes the center of your product's world and everything else is blocked by the debt, then you lose greatly in comparison to the cost it would have taken to build it debt-free in the first place, thus the risk is theoretically unlimited and not just limited to the amount of technical debt incurred -- because other things are now being delayed because of that debt. So the goal, in my opinion is to manage risk, incur technical debt minimally and only when there's a high probability of that debt not ever having to be repaid. If you know, with a high degree of certainty that the debt will need to be repaid, it's cheaper not to incur it in the first place.
I think the uncovered call metaphor is a brilliant way of framing this issue. It doesn't matter if we know finance or not, it's the way of looking at the problem that provides us with a good framework with which to make development decisions. If we are aware of the unlimited downside and manage that risk, we can actually be more aware of when it makes sense to incur technical debt and when it doesn't. In my opinion, it, just like options trading, is all about risk management and certainly not about traditional debt management.
I totally understand this pain point before I began reading on options I was clueless, mystified but ultimately realized options are akin to trading stocks (buying low selling high) but with the added time restriction and ability to make money in any market.
Options are tricky to understand but essentially, think of it as just a piece of paper or a contract between you and the person buying it from you. It's a buy/sell market that exists on these "papers". Options trading essentially revolve around buying these papers which usually have an expiry date of between weeks to years and at what price you can buy the underlying good before the expiry date. The profit is made from the valuation of this paper going up and down based on the underlying value of what this paper represents. The paper can be contract about beef, corn, oil and share price of Apple. Just like the stock market, you want to pay cheap price for a paper and sell it when it goes high, but the beauty of options is since you don't actually trade the actual good itself, you can create a dizzying array of strategies and combinations to make money in any type of situation, but with the condition that you have to be right about what market we are in (trending up, down, sidways, volatility etc).
Writing an option is like selling a piece of paper that says the person buying your paper will have the ability to buy the stock at the price written on the paper. If the price is low and the stock price goes up, well you now have to buy X number of shares that was written on the paper at the high price to give to this guy, causing great deal of loss to you (since you sold the paper for some cash earlier).
If the stock price falls, then you could buy the shares at the low low price using the money you made from selling the paper and give it to the other guy, who most likely won't ask you to do this and just think about the time he paid you to write him a piece of paper that is now "expired" or worthless.
I worked at a place where the VPE would talk about technical debt as a mortgage. Yet they had a culture that abhorred paying down the debt through refactoring, and so it was more like one of those interest-only payment mortgages. They paid higher interest in the form of reduced productivity and speed, and ended up with the same amount of debt as when they started.
I've always liked this analogy in preference to the standard notion of debt, but if we find ourselves having to explain the analogy, is it such a good analogy in the first place?
So I think it needs to be judged in context - who are we trying to communicate with?
Not all code debt contains massive downsides. The key to using technical debt wisely is understanding the difference, and architecting a system that is loosely coupled to allow strategic debt to be taken on in places where it makes sense.
Technical debt is an elegant analogy. However, I find the majority of systems on which I work are not loosely coupled. And yet, judging from the notes left by my antecedents, "loosely coupled" was the ideal for which they were striving. Is there a metric, or at least a heuristic, that can be applied in this situation?
It's actually a really good example of the article - there's nothing wrong with debt denominated in a foreign currency, you can hedge against the currency risk.
The whole thing is about risk, if you hedge away all your risk financially there is generally no profit to be made (you're left with arbitrage), if you hedge away all your technical debt then you've essentially (re)implemented it properly.
I wish the dominant metaphors weren't so business-y--they end up framing the discussion in a way that we're stuck talking about what other business-y metaphors would be better.
Explaining that doing things "bad" creates "technical debt" or "unhedged call options" I think sets us up for not being taken all that seriously because these things themselves are abstractions that we have to work hard to reason about effectively.
Is it more useful if we say something tangible--that programming is like working on a house? Imagine you just started working on updating a house last month. The owner comes to you with a request that they be able to see what's going on in the kitchen from the living room; you _could_ just knock a hole in the wall. That would satisfy the basic requirements, but it's going to make a mess, it's going to look like shit, and it may disrupt the electricity/plumbing/hvac or even the stability of the house itself. But even if we make a proper window or door between the rooms without disrupting other systems in the house and clean up our mess, it's still possible we make a door or window that is a little different than all of the other doors and windows the past builders have put in the house.
In 2 or 10 or 20 years, after several maintainers have come and gone, the owner discovers that they're being bled dry by the house's energy inefficiency. The new maintainer may go measure a window twice and get the dimensions down precisely and then count all of the windows in the house that look the same. Then they go place an order for N new energy-efficient windows. When the windows arrive and they're getting ready to replace them, they come to the terrifying realization that every window in the house is actually custom, and only a few of the windows will fit. They install the windows that fit and try to return the others only to find out the vendor charges a healthy restocking fee. Down 40% of our budget for replacing the windows but only having actually replaced 15% of them, we no longer have enough money to replace the rest. The owner decides to just use the remaining 60% to cover the increased energy costs instead of fixing the issues.
The new maintainer goes to put the diagonal blinds back up on the windows that did get replaced and discovers the custom mounting hardware has gone missing in the shuffle, so the blinds get left in the corner with a note that someone needs to find a way to put them back up when there is time and money. It's the middle of the winter anyways; the sun is always under the horizon when the owners are home. Because this is a _funhouse_, these were of course the blinds with the greatest role in reflecting summer heat, and despite the improved window technology, total energy efficiency is going to be in the shitter come summertime. For now, perhaps quixotically, energy efficiency is buoyed by the extra solar heat; the owner seems happy enough with the updates, and the metrics all show good performance.
Houses need maintenance. Things on or in them break and can't be fixed because either the parts aren't made that way anymore or the knowledge of how to fix it has eroded. They end up with empty telephone nooks and doors that were sheet-rocked over instead of being removed. A major appliance stops working and you discover the house needs infrastructure updates before a contemporary version of the same can be installed. The maintainers want to add a floor and some new rooms and they need an architect and an engineer to make sure they aren't going to ruin the roof line, slab or overload a wall. Down the road it will have different rooms built in the fashion of three decades over a span of 80 years. Further down the road a room will get sealed off when the roof caves in and the owner doesn't have the funds to fix it.
Bad code is only one kind of "technical debt" and it's the worst kind. Technical debt could also be choosing not to add a feature. If you document the shortfall (say, your system won't scale beyond a single-node database, because you aren't going to need that for at least a year) and why it is there, you can mitigate the damage and make it possible for future users and maintainers to figure out what's going on.
Code quality problems are, as expressed in the OP, an unknown unknown. It's rare that anyone has a handle on just how bad things are, until it's too late. Also, there are sociological issues with legacy rescue projects that businesspeople, who'd rather think of programmers as fairly interchangeable, don't like to contend with: maintenance is only effective if done by high-quality programmers, but it's expensive and often hard as hell to motivate good people to do it. A pat on the back and a 10% bonus won't do it, because it doesn't come close to offsetting the career costs of doing undesirable work.
There is an apocryphal story about a trader buying chocolate santa futures and forgetting to sell them on. Eventually a truckload turned up at the Wall Street headquarters.
This has little to do with the subject itself, but this has actually happened, sort-of. Futures contracts usually don't include Wall Street as a delivery location, so it's not like the trader ends up taking physical delivery at the workplace. The contract will specify where one must make or take delivery, and most delivery locations are in the Midwest or Plains.
When a trader fucks up and has to make or take delivery, there are services that handle it, but it's expensive. If you get stuck taking delivery of, say, $500,000 worth of butter, you'll probably have to pay the agency 50 cents on the dollar, or $250,000, to handle the task of getting your surplus butter to a wholesaler. It hurts pretty bad.
Real debt has to be paid back. There is no requirement to ever pay down the technical debt. Therefore the analogy is misleading.
I also think that the call option is a bad analogy for similar reasons. In a call option you could be obliged to pay out. You never have to pay out with code. You can decide to get your developers to write code or not write code. No bailiffs will come knocking on the door.
Technical drag coefficient may be a better analogy.
For a car, the drag force increases as you speed increases.
For code, the more features you want to add, bug you want to fix, etc. (i.e. the bigger your velocity) the more the TDC will kick in to slow you down. It may put a speed limit entirely on what you can do until you put work in to reduce it.
Also you can write-off the car and invest in a new one. I have seen this many times of course - the 'new product' that is written that won't have all of the problems of the last one.
Real debt doesn't have to be paid down though. Eventually it compounds too far and the person/entity can't even meet the interest payments and goes bankrupt. There's plenty of analogies that can be made with technical debt.
To really stretch the analogy, those same people often then end up in (technical) debt again a few years later when they repeat the same mistakes.
Bad code is kind-of analogous to debt, but not perfectly. Hence the confusion.
In some ways it is worse than real debt - the compound interest rate is atrocious. Like a loan shark.
But in some ways it is not as bad - you never are required by another party to pay back the debt. If you stop making money from the product, the debt is cancelled to $0.
Real debt has to be paid down, unless there is collateral, but even then most lenders want to know when and how they are getting their money back.
Suppose an opportunity comes up, but the technical debt in your software makes it exceedingly hard to respond to it. Either you still respond to it (with an obvious high cost), or you let the opportunity pass (and you "pay" the opportunity cost). So in a sense you can be forced to pay back your technical debt, if you include the "cost" of missed opportunities. But you are right that you always have the choice between those two, unlike real debt.
The key idea behind the colloquial usage of the unhedged call option metaphor (or "writing naked calls") in financial circles, is the small chance of a catastrophic loss in return for a guaranteed small payout now. It is the idea of unfavourable non-linearity (asymmetry) in the reward/risk profile of a decision. It is mostly used pejoratively for any scenario which is superficially tempting but ultimately unattractive. I am not certain this is a good fit for the often reasonable decision to take shortcuts in software development, usually because the competitive landscape makes it very important to ship before competitors and land grab before others.
Moreover, in a startup context, both metaphors break down: you can walk away from your technical debt by shutting down. You can't walk away from your financial debts (or call option shorts) so easily.
This is such an excellent analogy and easy for me to understand as I am aware of how options work. Writing options is never a good act if it is naked (unlimited downside, limited profit). So what about buying a naked option (limited downside, unlimited profit) and what would that look like with code? A careful and well tested codebase to begin with that ends up paying off it's investment?
I don't like this kind of discussion. I don't believe technical debt is a thing and I think this idea if technical debt as really straining the metaphor. This is like bike shedding.
Code (or system design) that has potential issues that may or may not need to be resolved in the future, but the benefit of not doing it now outweighs the pain of doing it later.
Right. I know what technical debt is. The commenter I replied to said "I don't believe technical debt is a thing" and was hoping (s)he would elaborate.