[HN Gopher] All code is technical debt
___________________________________________________________________
All code is technical debt
Author : j45
Score : 159 points
Date : 2023-12-19 10:46 UTC (1 days ago)
(HTM) web link (www.tokyodev.com)
(TXT) w3m dump (www.tokyodev.com)
| jeffrallen wrote:
| Hang out with mechanical engineers and it won't be long until you
| hear, "best part is no part".
|
| Best code is no code.
| sitzkrieg wrote:
| this is why deleting code is so great. a lot easier time than
| the MEs too
| adolph wrote:
| https://www.folklore.org/Negative_2000_Lines_Of_Code.html
|
| _Some of the managers decided that it would be a good idea
| to track the progress of each individual engineer in terms of
| the amount of code that they wrote from week to week. They
| devised a form that each engineer was required to submit
| every Friday . . . ._
|
| _Bill Atkinson, the author of Quickdraw and the main user
| interface designer, . . . was just putting the finishing
| touches on the optimization when it was time to fill out the
| management form for the first time. When he got to the lines
| of code part, he thought about it for a second, and then
| wrote in the number: -2000. . . . they stopped asking Bill to
| fill out the form, and he gladly complied._
| datadrivenangel wrote:
| The code without code is the eternal code.
|
| All other code requires updating dependencies.
| phpisthebest wrote:
| You mean a No Code Solution like PowerApps :)
| toppy wrote:
| https://github.com/kelseyhightower/nocode
| zoogeny wrote:
| Early in my career I worked with an engineer more senior than
| me who was responsible for performance optimization. He once
| told me "the fastest thing you can do is nothing at all" which
| was his way of saying it is better to find unnecessary steps to
| eliminate rather than making necessary steps execute faster.
| StayTrue wrote:
| Sure I sometimes say features are assets but code is a liability.
| Usually as part of an argument against complexity that some
| engineers favor to be ready for speculative future circumstances.
| pphysch wrote:
| I work with a FOSS product that has millions of lines of C. As a
| student, I would have been wowed by seeing these FOSS
| contributors each with +100,000 LOC in a single project. Now that
| I am more familiar how barely-functional the software is, with
| glaring architectural mistakes papered over by literally millions
| of LOC, I am more cynical.
|
| "Contributing" 100K LOC by implementing a bespoke http.c and
| mysql_client.c in 2020 is almost never something to be proud of
| from a SWE and product perspective. Great for ego/NIH and job
| security though.
|
| "Perfection is achieved, not when there is nothing more to add,
| but when there is nothing left to take away." -- Antoine de
| Saint-Exupery
| ravenstine wrote:
| That's the thing. Not making the problem _worse_ is fine and
| all, but most projects simply aren 't removing enough. It's
| amazing that today's software functions as well as it does, and
| programmers today are lucky they can hitch a free ride on
| decent hardware.
| pphysch wrote:
| Yeah. Refactors and rewrites (i.e. removing lots of code) are
| risky, but so is having critical CVEs and data loss events
| every year because of your insanely over-complicated
| architecture that has never been rethought in the past
| decade+.
|
| It's a cultural issue where we think major faults "just
| happen" and are not directly tied to prior product decisions,
| and therefore there isn't much accountability.
|
| But if you propose a major refactor, there is no question
| about (rightly) where the blame lies.
| ravenstine wrote:
| Modern software is so buggy, but it's considered the norm.
| I was talking to a non-technical person recently about
| that, and although they were at first puzzled by my view
| that most software is problematic, they realized that they
| experience the same bugs I complain about all the time.
| It's become so normal that people hardly notice it, but
| that doesn't make it better because bad software wastes
| human life time whether they realize it or not.
|
| > But if you propose a major refactor, there is no question
| about (rightly) where the blame lies.
|
| LOL Yep.
|
| Worse is when the blame lies on the semi-technical
| cofounder of your company who, granted, achieved quite a
| lot on their own, wrote a barely maintainable mess. Do you
| really want to be the one to indirectly point out that his
| code needs to be replaced? Haha I think a lot of developers
| would rather wait for the Dilbert Principle to kick in so
| that the cofounder gets out of the way enough for
| significant changes to finally be made.
| eichin wrote:
| In a thread elsewhere (mastodon, I think?) the idea of using
| a Copilot-like LLM as an assistant in _removing_ code was
| suggested as * a way to use an LLM with less discomfort about
| model provenance (since you wouldn 't be using anything it
| _generated_ ) * a way to get over some user cynicism (waves)
| about whether an LLM usefully "models" the code.
|
| Of course, at the time noone thought copilot could actually
| _do_ any of that, but it was a few weeks ago and things are
| moving quickly.
| tomxor wrote:
| > Technical debt, as originally coined by Ward Cunningham, is the
| idea that you can gain a temporary speed boost by rushing
| software development, at the cost of slowing down future
| development.
|
| No! Ward's blog post linked in this very paragraph [0] describes
| the original definition quite clearly, and it's not this.
|
| The term was originally intended to describe the delta between a
| programmer's _current_ understanding acquired through the process
| of developing the software, and the accumulated implementation
| which is based upon a combination of _past_ understanding.
| Because writing a program is often a process of discovery and
| learning about the problem and solution space, it 's not usually
| possible to write the ideal implementation up front.
|
| It's quite clear In Ward's 2nd paragraph where he describes the
| correction of this debt:
|
| > it was important to me that we accumulate the learnings we did
| about the application over time by modifying the program to look
| as if we had known what we were doing all along and to look as if
| it had been easy to do in Smalltalk.
|
| What the author is describing is the _modern_ definition that it
| has acquired independently, where by programmers knowingly take
| shortcuts... this is an entirely different phenomenon,
| intentionally writing code in a way that is less than ideal even
| based on current understanding. I find the original definition
| far more interesting and insightful, but the modern one is
| perhaps more reflective of the more common realities of the
| pressure developing software in a business today.
|
| [0] https://wiki.c2.com/?WardExplainsDebtMetaphor
|
| [edit]
|
| Despite this error, I do agree with the sentiment of the article,
| that too much code is a liability, that features can cost more
| than they are worth.
|
| Ward's definition of technical debt affects the cohesion and
| correctness of the code, the idea that if you could tear it all
| up every day and re-write it from scratch that it would always
| reflect the most up to date understanding, and for moving targets
| the most up to date problem, that it be absent of the weight of
| past misconceptions or solutions to past problems... aiming for
| minimal code makes achieving that state far more viable - these
| are complementary insights, so it's a shame the nuance of the
| original definition was lost.
| 0xdeadbeefbabe wrote:
| I had no idea Cunningham was so thoughtful about it. It's a
| term used by less thoughtful people in most of my experience.
| nirvdrum wrote:
| I think something similar happened with the term
| "refactoring." While it had been in use by a small community
| beforehand, Fowler's "Refactoring" book is what really opened
| it up to a wider audience. The book defines refactoring as:
|
| "Refactoring is the process of changing a software system in
| such a way that it does not alter the external behavior of
| the code yet improves its internal structure. It is a
| disciplined way to clean up code that minimizes the chances
| of introducing bugs. In essence when you refactor you are
| improving the design of the code after it has been written."
|
| The book then goes on to describe the methodology and runs
| through common refactorings step-by-step. Nowadays the term
| is used almost generically for code improvement. I'll see
| commit messages like "refactored the API", which violates the
| edict to not alter external behavior.
|
| Languages evolve and so on, but it's remarkable to me how
| quickly precisely defined terms (or even new words) change
| their meaning in tech. My cynical take is it's easier to get
| management to buy into "assuming technical debt" and
| addressing it with a "refactor" later than it is to "cut
| corners" and "rewrite" the code later. As long as everyone
| understands the new definition I guess there isn't even
| anything wrong with it, but it's a shame we've then lost a
| term for the original meaning.
| wavemode wrote:
| > Refactoring is the process of changing a software system
| in such a way that it does not alter the external behavior
| of the code yet improves its internal structure.
|
| That's the meaning of refactoring that I typically hear,
| tbh.
|
| I guess it just depends on what one means by "external
| behavior". Changing a function signature changes the
| external behavior of that function for callers of that
| function, but not for other modules. Changing the interface
| of a module changes its external behavior for other modules
| depending on it, but not for clients of the whole server.
| Changing an API changes the external behavior for the
| client, but not for the end user (to whom API changes are
| invisible and irrelevant).
|
| Traditionally, one might say "if the tests still pass, it
| was a refactor." Though nowadays that's probably not true
| either, as business code tends to contain a lot more
| internal testing than it used to (which is good! but also
| bad).
| nirvdrum wrote:
| Perhaps my initial selection was too short. I was trying
| to avoid copying out whole sections of the book. Overall,
| I think the book is less ambiguous than the one
| definition I presented shows. The entirety of the text
| reinforces different aspects of that definition.
|
| Fowler goes on to elaborate on the definition in chapter
| two, where he presents two context-dependent definitions
| (one a noun, the other a verb). The noun form is a
| specific type of change and the verb is the application
| of one or more of the nouns. E.g., "Move Method" and
| "Move Field" are types of refactorings. These are defined
| as changes made "without changing its observable
| behavior." To further qualify, he states "[o]nly changes
| to make the software easier to understand are
| refactorings." By way of example, he compares to
| performance optimization where he says: "A good contrast
| is performance optimization. Like refactoring,
| performance optimization does not usually change the
| behavior of a component (other than its speed); it only
| alters the internal structure."
|
| Maybe it's just the domain or languages I work with.
| Nowadays I never see anyone apply refactorings as
| described in the book. I'm sure devs implicitly apply
| several of them, perhaps without the rigor presented, and
| that's understandable. But, I often see "refactoring"
| just as a catch-all for any code change.
|
| While certainly there are some blurred lines in terms of
| what constitutes a refactoring or not, I think Fowler
| handles the product/API split fairly well. He adds:
|
| "The second thing I want to highlight is that refactoring
| does not change the observable behavior of the software.
| The software still carries out the same function that it
| did before. Any user, whether an end user or another
| programmer, cannot tell things have changed."
|
| By stating a programmer should not be able to tell things
| have changed, I think we can at least anchor public APIs
| as something that should not be adjusted in a
| refactoring. Such a change could improve the maintenance
| of the software or the quality of the product, but I
| don't think it fits the narrow definition of a
| refactoring. Admittedly, the part about the observable
| behavior of the software not changing can get murky. But,
| I think Fowler tries to scope this more at the code level
| than at the product level.
| wavemode wrote:
| Makes sense! I appreciate the clarification.
| burningChrome wrote:
| This is how the author starts his entire post.
|
| I would assume if he misinterpreted Cunningham's original idea,
| would it then follow that the rest of the article is suspect
| considering the original premise is so far off from what
| Cunningham originally intended?
| ska wrote:
| I agree with this history, but don't think the meaning was
| acquired independently so much as naturally grew. Ward presents
| it in a sort of "optimal development" context, where what we
| did last year was the right thing last year, but we know more
| now/things have changed and we know what the right thing would
| be today. This is definitely happens, but doesn't allow for a
| lot of other real-world reasons for this mismatch between the
| current and ideal state.
|
| The effect is the roughly the same though, there is an
| impedance mismatch between what you want to do to/with the
| system today, and what the system actual is today, and that has
| a cost. The work of reducing this impedance is real work, and
| can be thought of as "paying off debt".
| zoogeny wrote:
| > there is an impedance mismatch between what you want to do
| to/with the system today, and what the system actual is today
|
| This is a better conceptualization compared to the idea that
| tech-debt is the result of shortcuts or rushed code. Tech
| debt arises for a lot of reasons, including shortcuts but not
| exclusively because of shortcuts. I've seen tech debt arise
| because well-meaning engineers were trying to do things "the
| right way".
|
| I think it is just a kind of entropy thing that we have to
| fight against. A lot of confounding factors lead to code that
| is hard to maintain and extend. I think it is an unfair
| characterization to suggest it is solely because of laziness
| or negligence.
| ska wrote:
| I've used the entropy analogy also. In particular, entropy
| always wins in the end. But I do think it weakens the
| "debt" analogy to consider it the same thing, because I
| like the idea that this is sometimes transactional - a
| choice you make for benefit now which has amortized cost. I
| think this is a valuable idea that is separable from the
| problems of complexity growth, entropy, etc.
|
| I certainly don't agree with the idea that all technical
| debt is due to shoddy work, that's obviously silly. I
| suspect that people fall into it because it is easy to
| understand. The original framing is more nuanced and harder
| to think about but no less in effect.
| gav wrote:
| To generalize that idea a little, I think about technical
| debt being the accumulation of less-than-perfect decisions,
| if you consider the decision you made against the best
| possible decision that could have been made in hindsight.
|
| Sometimes that's not making things flexible enough, or too
| flexible, or not having all the requirements captured, or
| making technical bets that didn't pan out.
| tomxor wrote:
| > Ward presents it in a sort of "optimal development"
| context, where what we did last year was the right thing last
| year, but we know more now/things have changed and we know
| what the right thing would be today [...]
|
| Oh I suspect Ward's context was even more idealistic. That
| there was a problem to be solved, and there were few to no
| moving targets, the only differences over time were in the
| programmer's heads as they learned about the problem domain.
|
| This is not the only factor in software development today,
| which is mostly a moving target (although I kinda wish it
| was, it's my favourite form of development, a clear goal and
| end state to achieve - aiming for maintenance mode on 1st
| release, or pretending you are getting a bunch of discs
| stamped - and I really like trying to break real world
| problems into these types of mini projects, but that's
| another story). Perhaps this is why it was inevitable for the
| phrase to take on a new meaning, and honestly maybe "debt"
| wasn't the best analogy anyway, your "impedance mismatch" is
| probably already a lot better as the sibling commenter points
| out.
|
| > [...] but doesn't allow for a lot of other real-world
| reasons for this mismatch between the current and ideal
| state. The effect is the roughly the same though, there is an
| impedance mismatch between what you want to do to/with the
| system today, and what the system actual is today, and that
| has a cost. The work of reducing this impedance is real work,
| and can be thought of as "paying off debt".
|
| The effect may be similar, but I think it's useful to
| distinguish the forces at play. In particular I believe
| conceptual mismatches as per the original definition of
| technical debt are catalysts of the "other" debts... The
| original form of technical debt is the most common attribute
| I notice in the vast majority of source: code is accreted,
| existing code, existing decisions are rarely questioned with
| intention beyond what is necessary to make the next
| requirement on the todo list function, and this tends to
| result in a lot of unnecessary artificial work and code to
| work around the exiting code base - which of course only
| makes it even harder to change.
| juped wrote:
| I think this is right; the chaos of shifting or
| contradictory requirements can leave scars on the physical
| codebase reflecting this history, and so can attaining a
| better understanding of the problem from working on it, if
| one isn't careful to refactor (original sense) rather than
| adding new hacks on top. But the prescription for
| addressing each situation is pretty different.
| ska wrote:
| > This is not the only factor in software development
| today,
|
| I suspect it is a mistake to think that software
| development today is fundamentally different from how it
| was practised when he first wrote that. Possible
| application of recency bias..
| LargeWu wrote:
| Indeed, there's a significant portion of technical debt
| that's created with the full knowledge that it isn't the
| optimal approach and will incur a cost of maintenance or use,
| but might still be the correct tradeoff at the time.
| lysecret wrote:
| Indeed very insightful thanks for sharing.
| worldsayshi wrote:
| In other words, technical debt is when parts of the system does
| not yet implement the abstractions that align with the
| developers understanding of the problem?
|
| While I don't think we're there yet or maybe not even close, I
| kind of feel like this kind of technical debt would be
| something that an LLM should be able to help with. Why can't I
| point to a piece of code and say "Look at this new code I
| wrote, now go and refactor the rest of the code base to align
| with it." Or can I? I assume if I tried to implement something
| that did this I would hit the context size limit and that would
| be it.
| jahewson wrote:
| In hindsight Ward's choice of the word "debt" may not have been
| the right one. It feels more like "legacy code", in that there
| was nothing wrong with it at the time. Its impact on newer
| parts of the system is to create a "legacy burden".
|
| Of course if there was something wrong with the code at the
| time then it's more of a "proficiency debt" (or burden) where
| the shortcut taken was not in the coding but in not reading the
| docs and practicing the craft.
| nighthawk454 wrote:
| yeah sounds more like "design lag", where the software
| necessarily lags behind your ideal understanding by some
| amount
| tshaddox wrote:
| From what I can tell, the definition in the link you provided
| is precisely what you're saying it's not. He says this:
|
| > The explanation I gave to my boss, and this was financial
| software, was a financial analogy I called "the debt metaphor".
| And that said that if we failed to make our program align with
| what we then understood to be the proper way to think about our
| financial objects, then we were gonna continually stumble over
| that disagreement and that would slow us down which was like
| paying interest on a loan.
|
| So indeed, his definition of technical debt is explicitly that
| by rushing software development now you will slow down future
| development.
|
| The _specific_ software engineering task that caused him to
| develop the analogy was about rewriting some code to
| incorporate new learnings, but the analogy itself is clearly
| applicable to any software engineering task that could be
| deferred to the future (with a cost).
| turtlebits wrote:
| IME being in the operations space for along time, developers
| often oversimplify/ignore non-coding tasks, that is where I
| find most tech debt comes from, as the time/resources is not
| estimated/allocated ahead of time.
|
| Corner cutting == tech debt
|
| Ask any ops person and none of them will tell you they're
| content with the state of their infrastructure.
| cesarvarela wrote:
| Living is dying.
| ranting-moth wrote:
| You should write a 15 minute-reading blog post about that. Make
| sure to do a summary. I think you could use this linked blog
| post as a template.
| 0xbadcafebee wrote:
| Don't you just love clickbait blog articles that make no sense?
| HN sure does!
| metabagel wrote:
| Even if you disagree with the article, I feel like the comments
| here are insightful.
| ravenstine wrote:
| More code means more opportunities for things to go wrong, but I
| wouldn't go quite as far as saying that all code is tech debt,
| even though it makes for a good blog post title. Looking at all
| code in such a pessimistic light doesn't actually seem that
| useful. It might be one thing if there were adequate measures for
| "good code", but those hardly exist, or are dwarfed by inadequate
| measures that are entirely opinion-based. Less code than more
| might be as good as it gets, but I would rephrase the author's
| "To avoid technical debt, don't write code" as "To avoid
| technical debt, write _less_ code " (though perhaps "fewer codes"
| may be more grammatically accurate). Code is not bad, and tech
| debt isn't necessarily bad either. We code to accomplish things,
| and as much as I despise shitty codebases, even companies with a
| lot of tech debt often provide a lot of value to both customers
| and employees. In fact, I would say that tech debt in and of
| itself is no more a problem than monetary debt in real life,
| except when it's _not being paid off_ and is _collecting
| interest_. We could not only write less code but actually pay off
| our tech debts, yet the structure of incentives and most
| companies hardly facilitates that.
| ska wrote:
| I think the author is basically diluting the term "technical
| debt" to the point it becomes meaningless. Much of what they are
| talking about is the inherent difficulty of managing complexity,
| mixed with the difficulty of understanding requirements/defining
| features well.
|
| I think "technical debt" as a term is overused and sometimes
| misapplied, but the core idea resonates with many developers, at
| least the way it is most often used - which isn't exactly the
| original proposal as another commentpoints out. The key part of
| it is the analogy with an interest rate. I can decide do put 5k
| on the credit card for a last minute holiday, but for as long as
| I don't pay that off, I'm paying 20-something percent, every
| month, forever. Similarly for example a rush to add features to
| hit a demo deadline can introduce brittleness and abstraction
| failures into your codebase that you pay for every time you make
| changes, add features, do nearly anything. The analogy is that
| some of your development is going to be wasted "servicing the
| debt" going forward until you fix that (pay off the debt). That
| doesn't mean its the wrong move, for the same reasons that taking
| on debt can be the right move for a person or business.
| sorokod wrote:
| Yes, a bit silly this. Code is means to an end, it makes sence
| to think of code as liability (maintenance cost, inevitable
| bugs, etc .. ) but this must be contrasted with the value it
| provides within some reasonable timeframe.
| seadan83 wrote:
| I don't think the analogy breaks down per-say. Adding features
| is akin to adding a percentage interest rate. Some add more
| than others, but the cost of adding a feature is sometimes
| (often) dependent upon the existing features in the system.
|
| Coding & story-writing is a good analogy. If you are inserting
| a new scene into a large anthology, you need to make sure the
| new scene fits with everything else. OTOH, writing a brand new
| story does not have this constraint / cost.
|
| Which is all to say, software is an asset, code is a cost. The
| functionality of software is the valuable thing, all the code
| to do that is overhead. Thus, every line of code has a cost,
| and an ongoing cost that is forever then payed (which is
| exactly the interest; simply taking the time to scan/read over
| a line, to scan between 5 files vs 20, those are all ongoing
| costs)
| ska wrote:
| I disagree. Scaling things up has a cost, but not all costs
| are debt financed. I think the distinction is worth drawing.
| bgirard wrote:
| That's a good response. I can buy a house cash, I can buy a
| house with a 5% mortgage, or I could buy a house with a
| 20+% loan.
|
| Rushing out features with known bugs, poor architecture, no
| test and no documentation is akin to buying a house with a
| 20+% loan. You'll get your house sooner but you'll spend
| most of your resources servicing that debt until you can
| pay it down.
| JohnFen wrote:
| > I don't think the analogy breaks down per-say.
|
| Sorry for being "that guy", but I think you meant "per se".
| crazygringo wrote:
| Completely agreed.
|
| The idea that "all code is technical debt" because all
| requirements could hypothetically change someday, makes as much
| sense as saying "all currencies have no value" because 1,000
| years from now we might not be using any of them.
|
| Technical debt is not defined in terms of possible _future_
| requirements, it is defined in terms of _current_ requirements.
| Code that elegantly and concisely expresses current
| requirements is debt-free. Code that is a mix of elegantly
| expressing old requirements, with new requirements expressed in
| a hacky fast way, has debt.
|
| But trying to judge code in reference to _all possible future
| requirements_ is utterly nonsensical. You can 't measure that.
| It's literally meaningless.
|
| So no, all code is not technical debt. Technical debt is
| technical debt, and clean code is clean code. Trying to
| redefine words to mean their opposite helps no one. That way
| lies madness.
| posix86 wrote:
| But dept can only recognized if you're trying to implement
| something new, and notice that you have to pay interest.
| Poorly written code makes it very hard to implement new
| features & debug existing one, while well written code makes
| it easy. So the current dept can only be estimated with
| respect of features you are implementing in the future.
| majikandy wrote:
| Seems fair to assume that "current requirements" means
| current roadmap of requirements. Taken to extreme, if there
| are no future requirements at all, there is no technical
| debt.
| chuckadams wrote:
| My brother coined a term that I really love: "feature karma".
| He's an actual Buddhist, so he used the term "karma" not to
| mean a simple score with only positive connotations, but as
| something you're chained to and must work off should you at
| some point want to move past it.
| CSMastermind wrote:
| I often try to explain the concept of Technical Wealth as the
| other side of the spectrum from Technical Debt.
|
| Technical Wealth pays dividends; Tech Debt charges interest
| on which the payments will eventually become unwieldy.
|
| That doesn't mean you shouldn't take on Technical Debt, like
| many startups do with real money you can and should go into
| debt in order to get your business off the ground. But just
| like irresponsible financial management can kill your
| company, so can irresponsible technical management.
| Phiwise_ wrote:
| Absolutely agreed. Articles in this vein rather get my goat,
| especially because the analogy to real debt is _more_ clear: If
| someone wrote a consumer finance article like "All purchases
| of things other than cans of beans and Certificates of Deposit
| are like Mortgages, because what if your industry collapses
| tomorrow?" most people have the good sense to complain that the
| usually decent advice of saving a bit for a rainy day was being
| way exaggerated. And yet pieces that run something like "All
| programming of things other than washing machine
| microcontrollers are like technical debt, because what if your
| customer's needs suddenly change entirely?" get much more play.
| Sure, disasters _can_ happen, and it pays to reserve some
| resources to be ready for them, but it also pays to use
| resources when times are good to expand. It seems to me
| Cunningham 's point was to _encourage a move towards_ balance;
| headlines that don 't overshoot the mark.
| j45 wrote:
| Well said.
|
| Too often code is a proxy for complexity being added
| unnecessarily, consciously or unconsciously.
|
| Premature optimization or over-engineering or burning your
| innovation points on shiny object syndrome can create technical
| debt in a different way than just taking shortcuts.
| NoPicklez wrote:
| I agree and I can't stand it when people dilute terms to the
| point they become meaningless. I see it in other areas as well.
|
| It isn't a profound thought to take a term like "technical
| debt" and just say well that's just everything.
|
| Technical debt is absolutely that, adding something that incurs
| a level of interest, until you take the time to pay it off. In
| life, we often always have a level of interest to be paid.
|
| It's a good analogy
| rjzzleep wrote:
| Almost ten years ago I had the unfortunate opportunity to
| work with a master manipulator who was unfortunately more
| senior in the hierarchy.
|
| Most of his code was actually technical debt. The code that
| wasn't was external code he integrated. All of the code he
| wrote would eventually break down and until it did world
| force you to work around it, so it wouldn't fail from
| interfacing with it.
|
| In one of the standup's i used the term technical debt to
| argue for fixing one of these issues that broke later but
| which he discouraged everyone to fix.
|
| After that he integrated the term into his daily use to the
| point that it became meaningless. The people that believed
| this snake oil salesman thought that he had already carefully
| weighed his own decisions in advance.
|
| Needless to say the issue was not fixed before he left the
| company and cost millions and plenty of customer headaches.
| mmcnl wrote:
| What I don't like about "technical debt" is that it's usually
| interpreted as "technical" debt: it's only a problem for the
| developers, the techies. You immediately lose the business
| stakeholders once you start talking about technical debt. But
| the problem of technical debt if a problem for everyone, not
| just the devs, because it is reflected in quality and time-to-
| market. I feel having that conversation about time-to-market
| and quality with business stakeholders is incredibly important
| and is often skipped. This in turn alienates business
| stakeholders from the developers, which is counter-productive.
|
| So yes, the core idea of technical debt resonates with
| developers, but not with business stakeholders. So if you
| really think the business is going to be okay with "we're gonna
| slow down our time-to-market and say no to all your requests
| for a while because we need to pay back our technical debt"
| (which is something I see happening over and over again),
| you're just keeping them out of the loop and taking over their
| responsibilities without actually having their accountability.
| Developers shouldn't decide whether time and money should be
| invested in time-to-market and quality or feature delivery, but
| that's effectively what's happening when business is not
| involved in the tech debt discussion. This only leads to
| friction and suboptimal results.
|
| That's why I think we really need to be careful when using the
| words "technical debt" and not just label everything we don't
| really understand or think can be improved as "technical debt".
| Challenge yourself: what really is the problem with this piece
| of code, other than that we don't like it?
| convolvatron wrote:
| unless its a perfect shining jewel - every piece of existing
| code constrains future development, until progress
| asymptotically approaches zero and development cost
| asymptotically approaches infinity
| ljm wrote:
| 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 wrote:
| I 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 wrote:
| Agreed, 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.
| smallnamespace wrote:
| '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'.
| andrewprock wrote:
| And all code is an asset. Have we just reduced the
| conversation to: everything has a cost, and everything has a
| benefit?
| matheusmoreira wrote:
| I agree. Technical debt is a very useful concept and it's not
| helpful to dilute its meaning.
|
| Only a couple days ago I decided to change some data structure.
| It was needlessly hard because I had neglected to create an
| accessor function and was instead accessing it directly
| everywhere. Had to change every bit of code that accessed the
| structure's fields.
|
| _That 's_ technical debt: something the programmer should have
| done but for whatever reason didn't. I paid back the debt by
| doing it: I created the function. Now if I want to change the
| data structure I only have to update the function. If I hadn't
| paid it back, it would start accruing interest: it would be
| even harder in the future as more and more stuff accessed the
| fields.
| iraqmtpizza wrote:
| Please sign the rights to all your technical debt over to me.
| Thank you.
| anonporridge wrote:
| All wealth (negentropy/complexity) creation creates debt.
|
| Whenever we build, we use intelligence to rearrange things in
| more complex ways that don't naturally occur. Ideally, this
| creates value by unlocking things we want that we previously
| couldn't have.
|
| But this work always creates a burden on the future (debt) to
| maintain the complexity we built. This is especially true if the
| complexity doesn't gracefully degrade back to a more primitive
| state and the choices of people coming after you are "maintain"
| or "collapse and regress back further than your predecessor
| started, because you've forgotten the old ways".
|
| If you don't want to place this burden on the future, then the
| only surefire solution is to not build anything. Just be happy
| with maintaining what you have and hope that the environment
| doesn't change around you so much that what you have isn't good
| enough.
|
| But I don't think this is what we want. We need to build a LOT
| more for some of the existential goals we have as a civilization.
|
| Just know that every act of creation that sticks around
| intrinsically creates a burden on the future to maintain it.
|
| Acknowledge and respect that, but keep building.
| anonporridge wrote:
| Addendum;
|
| A concrete example of this conflict that I've been wrestling
| with recently. I've been considering going all in on home
| automation. Zigbee devices and sensors everywhere managed with
| custom rules on Home Assistant. I want to get to the point
| where I don't ever have to touch a light switch.
|
| However, I also recognize stories of others who have done this,
| and then died leaving their less technical spouse with an
| unmaintainable mess that gradually degrades and falls to
| Entropy. They eventually have to hire someone to rip it all out
| and revert to a dumb house.
|
| By going all in on home automation, I'm creating debt for
| future me and my partner to maintain it all. At the moment, I'm
| not convinced that this act of creation will actually create
| enough value to justified the debt incurred.
| flerchin wrote:
| This is exactly why I haven't automated my newest house. All
| the automation in my last one was net-negative to the buyer.
| captainkrtek wrote:
| I like to think of technical debt with a counter balance of a
| "credit score". Ie: as an organization, what is our ability and
| track record to manage complexity over time.
|
| It's not a perfect analogy, but the difference between a low
| interest rate mortgage and a high interest payday loan have
| parallels to the balance made in delivering software while
| limiting complexity. A developer that is a bit of a tornado,
| rapidly churning out new and exciting capabilities at the expense
| of reliability, brittleness, and complexity, will surely catch up
| with an organization sooner or later.
| jmduke wrote:
| I agree with many of this essay's points, but the flamboyant
| headline is a reductive way to view software (and a bit of a
| dangerous meme.)
|
| Your job as an engineer is, amongst other things, to identify the
| (sometimes rare!) instances in which code creates leverage beyond
| the business value it creates. Good abstractions are valuable
| assets!
| Ensorceled wrote:
| > So to give a quick recap, as adding more code to a product will
| slow down development, we should view all code as technical debt.
|
| Not a fan of this habit of taking a perfectly good technical term
| and redefining for another purpose; especially if there is
| already good, existing measures, such as code complexity.
|
| Rather, than calling all new code "technical debt", how about
| every planned feature, as part of it's total cost calculation,
| include the incremental costs of any increased code and/or
| architectural complexity it introduces.
| mjr00 wrote:
| The author is conflating a few different things.
|
| All code and features are _overhead_. It requires maintenance
| when it breaks, or requirements change. It increases complexity
| when working on other parts of the system, as other new features
| have to ask "how does this interact with existing features?",
| even if the answer to that is "it doesn't". At Amazon one of the
| VPs had a rule of thumb that if a dev or team worked full-time on
| a new feature, they would be at 50% of their capacity after the
| feature was "done" for 3-12 months due to ongoing maintenance.
|
| So yes, writing less code rather than more code for the same
| feature is good, generally. But all software requires _some_
| code, so the challenge is figuring out which code is necessary
| for which the maintenance and overhead costs are worth it.
|
| Technical debt is a bit different; the code is there, but
| something about it makes it challenging to maintain. There's lots
| of reasons this can happen. Sometimes the business requirements
| change and the domain concepts or abstractions no longer make
| sense. Sometimes the technical requirements change and decisions
| made at the time are no longer the right ones, if they were ever
| right at all.
|
| But the most common reason, in my experience, is that the
| _people_ have changed. New people have come in, looked at
| existing systems and code, and either don 't understand it or
| don't agree with how it was written from a personal stylistic
| point of view. Like a functional programming looking at a system
| that was designed with textbook OOP and calling that technical
| debt.
|
| As you move into more senior technical positions or engineering
| management one of the bigger challenges is determining what's
| "real" technical debt that's worth tackling, versus what's
| perceived technical debt that's based on personal opinions.
| metabagel wrote:
| And sometimes it can be difficult to tell when a complex
| solution is actually appropriate and not a candidate for being
| re-implemented.
| AndyPa32 wrote:
| In a similar vein I always try to convince colleagues that the
| best code is the one that is never written. As a close second the
| code that has been deleted. It has no bugs and doesn't need
| maintenance.
| abakker wrote:
| Put more directly: all choices are costs. Specifically, a choice
| is choosing to incur opportunity cost in order to realize some
| outcome.
|
| E.g. Buying a sandwich so you can eat it to be full is choosing
| not to spend that $10 on anything else.
|
| In durable and intellectual domains, choices can incur
| opportunity costs, but also lead to switching costs in the
| future. I've always understood technical debt to be the
| combination of opportunity costs and switching costs resultant
| from a specific choice that resulted in a durable physical or
| intellectual good.
|
| In this way, technical debt is not a particularly complicated
| topic. The issue is that switching costs can be very high, and to
| eliminate the accumulated opportunity cost and switching costs of
| a previous decision, it is necessary to incur a new set of costs
| going forward.
|
| There is no "debt", there is only cost. The idea that you can
| "owe" on a series of choices implies that you can "pay it back".
| This is false. You can make choices - some may be more costly
| than others both immediately and in the future - but all choices
| have costs always. To quote Rush, "if you choose not to decide,
| you still have made a choice".
| knodi wrote:
| If all code is tech debt then all employees are liabilities.
| marcod wrote:
| I mean I have definitely felt like a liability before :p
|
| "What do you mean, we have to pay health insurance for all of
| them?? Let's get the cheapest option available!"
| imhoguy wrote:
| Well, IT/Engineering as a cost center is everyday corporate
| life.
| ranting-moth wrote:
| Excuse my rule breaking, but holy shit this is crap.
| open-paren wrote:
| I prefer to say that "code is a liability, not an asset."
| Liabilities are useful and help achieve goals (want a house, get
| a mortgage), but the code is not the goal. Code is a mechanism
| that achieves that goal, but more code becomes a drag.
| indymike wrote:
| "I prefer my products to have less code in them." -- Can't
| remember what smarter person than I said it...
|
| Conceptually, I think every developer eventually realizes that
| every line of code ends up adding maintenance cost, and
| potentially constraints on the future. "Technical Debt" is one
| way to think about it - if you don't have the resources to
| maintain. Otherwise, it's just a cost as others have pointed out.
|
| Maintenance is harder than most people think: documentation,
| translations, tests, all are part of this cost.
| erikerikson wrote:
| The author should really read Peter Naur's "Programming as Theory
| Building".
|
| [0] https://pages.cs.wisc.edu/~remzi/Naur.pdf
| jrockway wrote:
| Code is inventory, not debt. Inventory is good and bad. If
| someone comes to your store and everything is out of stock, you
| will make $0. So you want some inventory. But if you have too
| much inventory and nobody is buying anything, then your inventory
| just rusts in storage and becomes worthless. Code is pretty much
| exactly the same. Most features are sitting in storage in the
| hopes that someone comes by to buy it. Sometimes they do!
| Sometimes they don't. If you were the guy with a toilet paper
| warehouse in March 2020 you did great.
| mmcnl wrote:
| Code is an asset. Assets need to be managed, maintained, or
| else they will degrade. Assets have costs.
| thiago_fm wrote:
| The correct term is "technical liability".
|
| I like to dive into a codebase the same way people do accounting
| for the finances of a company, the parallels always make sense.
| rqtwteye wrote:
| I always tell people that deleted code is the best code.
| alex201 wrote:
| Insightful articulation of the concept of technical debt
| (likening it to a financial loan) but it somewhat oversimplifies
| the nuanced and often non-linear nature of software development.
| I observe that technical debt is not always a straight trade-off
| between speed and future maintenance. Sometimes, what appears as
| debt could be a strategic decision aligned with evolving business
| goals or market demands. The article underestimates the dynamic
| nature of software projects where initial assumptions might
| change, making the so-called 'debt' a necessary step in the
| process of innovation and adaptation. This perspective fails to
| acknowledge that in certain scenarios, adhering too rigidly to
| best practices can lead to missed opportunities or an inability
| to pivot quickly in response to user feedback or changing market
| conditions.
| jfengel wrote:
| Conversely: "The things you own, end up owning you".
|
| A line of code is something you own. It makes you obligated to
| either maintain it or let it go. The only truly free development
| is greenfield development, where you can write whatever you want.
| And now you've got code you own, and you're in its debt.
|
| So yeah, we can all live wonderfully free lives by writing no
| code, but that does tend to up our other debts, i.e. student
| loans, mortgages, etc.
|
| Good code is not more code or less code but code that does what
| the customer actually wants it to do. The better we understand
| the customer's needs, the more we can write just the correct
| code. We can't always do that; often the customer themselves
| doesn't know what they need.
|
| Regardless, the way out of this conundrum is to stop counting
| code, technical debt, or other ways of trying to make the _human_
| problem into a _computer_ problem. The real problems are always
| out there, not in our repositories.
| fhars wrote:
| There is this old notion that you should think of "lines of code
| spent to solve a problem", not of "lines of code produced".
| veucast wrote:
| It's interesting to see someone putting a positive spin to
| technical debt. The level of technical debt you can afford taking
| on (technical risk) is heavily dependent on how you define
| technical debt at your company. You must understand how taking on
| a technical risk will have an impact in the current and future
| operation of the entire business/product/team. Not all technical
| debts are created equal, so to encourage people to see it as a
| positive thing or risk worth taking, without giving them this
| disclaimer is irresponsible.
| otabdeveloper4 wrote:
| Nah, some of it is an heirloom.
| equalsione wrote:
| This is a "when you think about it" argument. As in "humans are
| just tubes, when you think about it".
|
| Technical debt is a thorny issue already. Arguments like this
| don't help.
| wins32767 wrote:
| Code is best reasoned about as a depreciating asset, not
| technical debt.
| pyromaker wrote:
| Ultimately, everything can be debt. If code is technical debt, a
| HR system or a process that you implement for the company at that
| particular point in time is also a debt (process debt? HR debt?
| debt nonetheless).
|
| If we are trying to deliver fast by expediting software
| development and taking shortcuts (technical debt), another
| department can also do something similar (quick, our HR process
| is slow and cumbersome, implement that HR system) - which would
| solve the particular issues for the business at that particular
| point in time, but may not the needs of the business later on.
|
| For software, the issue is that we believe we can introduce
| technical debts, that is, it is permissible to introduce and talk
| about technical debts. We wouldn't necessarily talk about
| implementing a new HR system often.
|
| We think writing a line of code is fast (and define what "fast"
| means) but it isn't.
| csours wrote:
| Any code _having_side_effects_ is technical debt. Pure functional
| code is innocent of any sin.
| Nevermark wrote:
| Like quite a few people, I find the word "debt" to carry a lot of
| connotations that don't seem apply to building non-ideal code.
|
| For me, "technical debt" would be shipping a product that is
| going to predictably require regular investment just to keep
| going. Like a distributed database that needs manual work to fix
| regular corruptions.
|
| In contrast, writing code without care for future work is not
| some original emergent issue of software development that we
| should need to navel gaze about. It is a universally understood,
| common sense problem for any foundation work: in design,
| engineering, construction, book stacking, whatever.
|
| It already has 1000 names: "Building on Sand", "Ticking
| Timebombs", "Bandaid Solutions", "Cutting Corners", "Short Term
| Fixes", "Playing Jenga", "Putting Lipstick on a Pig", "Haste
| Makes Waste", etc. I suggest: "Shoddy Foundations".
|
| Essay Title: _All Living Code is a Foundation_
|
| Essay Body: _Don 't build shoddy foundations._
|
| There! That's it. Nothing more to say. No new terminology. You
| don't even need strategies for how to translate it for the non-
| techies.
|
| Tell your CEO they can get those enormous features yesterday,
| they just need to attach their name to a "shoddy foundation"
| signoff. Informally by email is fine. You are ready to unleashed
| the troops from responsibility for future mishaps! All you need
| is that little written record! Then presto! The coders are
| standing by, breathless, ready to party! (And preparing their
| resumes.)
| jrochkind1 wrote:
| Whether it is exactly the same concept as actual technical debt
| or not...
|
| This makes a lot of sense to me, and explains why you always
| think "I can do better than that monster", and it _does_ always
| feel better at first, then then inevitably grows to feel like a
| monster where it 's hard to make any changes.
|
| Especially when we are thinking about _tools for developers_ ,
| where developers are the users, libraries or web frameworks and
| such. Or even languages/ecosystems. A bunch of existing
| libraries/frameworks/platforms/ecosystems _are_ a mess... surely
| we can do better! let 's make a new thing!
|
| This explains why we are always hopping to the new thing, and
| always convinced the new thing is better...
|
| And the new thing is better and so much easier to work with, even
| though it doesn't have all the features the old thing did, but
| okay, we just need to keep building it out to encompass those
| features, using our _much_ better sense of architecture and
| usability that we 've proven we have because look how clean and
| simple and usable our first draft is!
|
| Now, there is such a thing as better or worse designed, as the OP
| admits, poorly implemented or beautifully implemented. But...
| comparing the new thing that only has the most basic features and
| seems really elegant to the old thing that covers all the edge
| cases... isn't actually a good comparison to tel you which is
| better implemented. That new thing is going to get cruftier when
| you cover the edges, _always_.
|
| And it shows that if you want to keep your thing feeling smooth
| and elegant and easy to work with.. you have to keep it as small
| as possible and resist all feature requests!
|
| > For a feature to add value to your product, it needs to be
| useful to users. Features can have a negative value when the
| technical debt they add to your product outweighs the value they
| add to it.
|
| Thinking of tools for developers where developers are the
| users... _oh yeah_ it 's true.
|
| > A technique for reducing technical debt when adding a new
| feature is to work within the constraints of existing
| assumptions, rather than adding new ones
|
| I would describe that as limiting the number of "concepts" inside
| your code... and definitely applies to libraries/frameworks/tools
| for developers.
| mjw_byrne wrote:
| Taking a useful concept and stretching it to an extreme in order
| to generate a counterintuitive-but-plausible soundbite is not the
| same thing as wisdom.
|
| Other examples that come to mind are "a complete rewrite is
| always a mistake" (no, it just has different risks/rewards), "if
| you are reading this part of the docs, you are trying to be too
| clever" (your API is too much for my puny brain is it?) and "all
| functions are APIs" (no, my two-line string quoting func is not
| an API, actually).
| lnxg33k1 wrote:
| I personally consider tech debt code that is hard to reason
| about, change, understand or not covered by unit test. I think
| the author just wanted to say something nonsense to go viral and
| get share/increase klout, but if the concept of code is
| symmetrical to the one of tech debt then the concept of tech debt
| is useless and we need something else to scope code that is hard
| to be worked on, and back to square one
___________________________________________________________________
(page generated 2023-12-20 23:00 UTC)