[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)