Hacker News new | ask | show | jobs
by mattvanhorn 3821 days ago
tl;dr: "Conceptual debt" is what Ward Cunningham described as "technical debt". That thing you call "technical debt" is just a combination of bad habits, haste and apathy.
7 comments

Eh, I think terminology can evolve. Technical debt can also mean incidental complexity explicitly and consciously being introduced at the code level for very good reasons. And paying down the debt means code-level refactoring, introducing abstractions, unifying interfaces etc. It can also mean throwing the code out since the experiment was a failure. (One thing often overlooked on incurring tech debt is there are cases where you can just 'write it off', when the thing you thought was going to be important turned out not to be, so you can just kill it.) The opposite of incurring technical debt can be over-engineering, for example.

Personally I find it an improvement to have two terms that separate the concepts, if for no other reason that it underscores that 'conceptual debt' is a thing that matters a lot and isn't just 'the engineers can come in and clean it up later' type of deal, which technical debt often can be. Recognizing conceptual debt as something that all team members can contribute to, not just people writing code, is a profoundly different type of conversation than the ones you'll have today around tech debt where it's assumed a) stakeholders can't understand it and b) it's nobody's problem but the engineers: they create it, they pay it down.

The technical debt referred to in the article is inadvertent (i.e. bad) technical debt. Ideally a good code base should have none of that. Intentional technical debt on the other hand (imperfectly factored code produced with the purpose of getting something out the door now rather than later) is a totally different animal and is a "finance" instrument that can be used responsibly.
Conceptual debt arguably leads to a better understanding of the principal, as both technical and non-technical people can contribute to it.

I will certainly use the phrase.

That's how I've always understood technical debt as well[0]. Which database or programming language isn't quite it.

When a major customer needs a new feature, do you hack that feature into the codebase to save the account? Or do you risk the account in order to add the feature The Right Way?

http://martinfowler.com/bliki/TechnicalDebt.html

This. It's kind of sad to see a new term invented for what Ward called 'Technical Debt.'

I think that we arrived here specifically because we don't have a term for the effect of careless code change. 'Technical Debt' ended up being appropriated as a term for it.

Agree that 'technical debt' could encompass conceptual debt in its broader definition. But, at the companies I've worked in people often don't use the terminology technical debt to include conceptual design issues. Technical debt discussions often focus on the programming language/database issues. I've found it useful to have a shorthand for referring to unintuitive products and codebases that stem from poor product design choices rather than poor language/tool choices.
"Shipped is better than perfect"

As much as it hurts my engineering sensibilities, 9 times out of 10, being hasty is better than not existing.

Agree with the 'Shipped is better than perfect' and also the notion of isolating the dirty parts.

I've been adopting this rule of thumb that the first pass at a new product I can just dive in and treat it as a throwaway, since I probably don't understand the domain well enough to develop an ideal conceptual model anyways. The key here being to treat it as a throwaway and then return and do a rewrite from scratch once I have a better understanding of the problem.

I agree totally re your point of not understanding of the domain, it can be really hard to make good conceptual models until you've actually tried throwing some code at the walls.

I guess I'd rephrase your point about "one to treat as a throwaway" as saying that you should realistically expect to be moving back and forth between architecting the conceptual model and implementing it. I find it useful to first think about the conceptual model, then write some code for a while, then revisit the model and see what difficulties I've hit and/or what new good ideas I've thought of in the process, etc.

Definitely what you're saying. Thanks for adding even more deeper context. Accepting that back and forth: code, learn, code process.

And to your point too about first thinking about the conceptual model, agree that you should spend at least a bit of time before doing anything else. Thinking through your modeling is something that doesn't take that much time and has such huge payoffs in terms of avoiding pitfalls. But often times it's just funner to start writing code so people do that.

It's always saddening to see programmers just dive in and start coding without planning / thinking about the problem first.

That's often the best decision as long as everybody recognizes that it's debt, which has to be paid off. Just adding more and more debt leads to destruction.
> debt, which has to be paid off

Honestly, that's not quite true. If you told management of a source of funding that could fund a couple of developer salaries, and could borrow at zero percent interest, and pay back whenever so desired, then they would rightly point out that the optimal time to pay that debt off is "never."

The key point about technical debt is that quality metrics need to be tied to actual costs incurred, not just 'the software fails to meet my standards.' For example, 'our customer support forum hasn't been updated in years and has been hacked' is a valid technical debt since your staff is now spending time fixing the forum, at substantially greater cost than upgrading.

But maybe removing all the trailing whitespace and replacing all the tabs with spaces has no business related expense, and rewriting your Django app in Go because 'that's where the industry is heading' is paying off the cheap debt first.

It also depends on the lifecycle of the application. Some applications only exist for 2-3 years, just because of requirements changes; at that point, it's easier to "declare bankruptcy" by deprecating the old code base.

0% interest isn't the best analogy for technical debt, however, because technical debt often carries recurring costs that are analogous to interest. Every time you have to make changes or enhancements to a technically indebted system, the cost of those changes in time, effort, complexity, and bug hazard is higher than it would be in a clean system.

> 0% interest isn't the best analogy for technical debt, because technical debt often carries recurring costs that are analogous to interest.

My argument is simply that if there is no recurring cost, it's not technical debt. It's just imperfect software that still works without demonstrated problems.

I would only consider it debt if it's something that's likely to cost significant time later if not fixed. That sort of thing adds up after a while.
Some business situations demand haste and rushing things to market. Those situations are crappy for good engineers and extremely crapoy for those of us who are on the creative side. I would quit any job where the fate of the company depends on rushed delivery. It means the company is driven by low quality and high quantity output rather than the opposite which allows for engineers to improve and elevate their craft.

Speed and Quality need to be in balance.

Isolate the "dirty" parts. Write them down and make sure they're written somewhere.