Martin Fowler: Technical, Cognitive, and Intent Debt

(martinfowler.com)

71 points | by theorchid 3 hours ago ago

15 comments

  • hibikir an hour ago

    LLMs don't lack the virtue of laziness: it has it if you want it to, by just having a base prompt that matches intent. I've had good success convincing claude backed agents to aim for minimal code changes, make deduplication passes, and basically every other reasonable "instinct" of a very senior dev. It's not knowledge that the models haven't integrated, but one that many don't have on their forefront with default settings. I bet we've all seen the models that over-edit everything, and act like the crazy mid-level dev that fiddles with the entire codebase without caring one bit about anyone else's changes, or any risk of knowledge loss due to overfiddling.

    And on Jess' comments on validating docs vs generating them... It's a traditional locking problem, with traditional solutions. And it's not as if the agent cannot read git, and realize when one thing is done first, in anticipation of the other by convention.

    I'm quite senior: In fact, I have been a teammate of a couple of people mention in this article. I suspect that they'd not question my engineering standards. And yet I've no seen any of that kind of debt in my LLM workflows: if anything, by most traditional forms of evaluating software quality, the projects I work on are better than what they were 5, 10 years ago, using the same metrics as back then. And it's not magic or anything, but making sure there are agents running sharing those quality priorities. But I am getting work done, instead of spending time looking for attention in conferences.

    • marktani 7 minutes ago

      I agree with your sentiment here. However:

      > if anything, by most traditional forms of evaluating software quality, the projects I work on are better than what they were 5, 10 years ago, using the same metrics as back then.

      In this side sentence you're introducing so much vagueness. Can you share insights to get some validation on your claim? What metrics are you using and how is your code from 10, 5, 0 years performing?

      I feel throwing in a vague claim like that unnecessarily dilutes your message and distracts from the point. But, if you do have more to share I'd be curious to learn more.

    • dc_giant 26 minutes ago

      Mind sharing the instructions you give Claude to go for minimal code changes etc?

  • kvisner 2 hours ago

    I see what Martin is saying here, but you could make that argument for moving up the abstraction layers at any point. Assembly to Python creates a lot of Intent & Cognitive debt by his definition, because you didn't think through how to manipulate the bits on the hardware, you just allowed the interpereter to do it.

    My counter is that technical intent, in the way he is describing it, only exists because we needed to translate human intent into machine language. You can still think deeply about problems without needed to formulate them as domain driven abstractions in code. You could mind map it, or journal about it, or put post-it notes all over the wall. Creating object oriented abstractions isn't magic.

    • layer8 an hour ago

      Translating your intent into a formal language is a tool of thought in itself. It’s by that process that you uncover the ambiguities, the aspects and details you didn’t consider, maybe even that the approach as a whole has to be reconsidered. While writing in natural language can also be a tool of thought, there is an essential element in aligning one’s thought process with a formal language that doesn’t allow for any vagueness or ambiguity.

      It’s similar to how doing math in natural language without math notation is cumbersome and error-prone.

      • ah1508 39 minutes ago

        Agree: house architects have their language (architectural plans) to translate people needs in non ambiguous informations that will be useful for those who build the house. Musician uses musical notes, physician uses schemas to represent molecules, etc... And programmers use programming languages, when we write a line of code we don't hope that the compiler will understand what we write. Musical notes are a kind of abstraction: higher level than audio frequency but lower level than natural language. Same for programming language. Getting rid of all the formal languages take us back 2000 years ago.

        Using a formal language also help to enter in a kind of flow. And then details you did not think about before using the formal language may appear. Everything cannot be prompted, just like Alex Honnold prepared his climbing of El Capitan very carefully but it's only when he was on the rock that he took the real decisions. Same for Lindbergh when he crossed the Atlantic. The map is not the territory.

      • kvisner 20 minutes ago

        I agree, but that formal language doesn't need to be executable code.

        • ah1508 a few seconds ago

          So you need to find something better. In an article "How NASA writes 'perfect' software (1996) (fastcompany.com)" (comments on HN), the author explains that adding GPS support required 1500 pages of spec, and to avoid ambiguity the spec used pseudo code to describe expected features.

          If you invent a formal language that is easy to read and easy to write, it may look like Python... Then someone will probably write an interpreter.

          We have many languages, senior people who know how to use them, who enjoy coding and who don't have a "lack of productivity" problem. I don't feel the need to throw away everything we have to embrace what is supposed to be "the future". And since we need good devs to read and LLM generated code how to remain a good dev if we don't write code anymore ? What's the point of being up to date in language x if we don't write code ? Remaining good at something without doing it remains a mystery to me.

    • didericis an hour ago

      > you didn't think through how to manipulate the bits on the hardware, you just allowed the interpreter to do it

      If you are thinking through deterministic code, you are thinking through the manipulation of bits in hardware. You are just doing it in a language which is easier for humans to understand.

      There is a direct mapping of intent.

    • jdw64 an hour ago

      I like the word intent, but Martin Fowler’s essay made me think more carefully about it. When Thomas Kuhn talked about paradigm shifts, “paradigm” ended up carrying more than twenty different meanings. In the same way, I think intent has recently become one of the most polluted and overused words in programming. My own toy language project uses the word intent, so I am not really in a position to criticize others too harshly.

      Reading the Hacker News comments, I kept thinking that programming is fundamentally about building mental models, and that the market, in the end, buys my mental model.

      If we start from human intent, the chain might look something like this:

      human intent -> problem model -> abstraction -> language expression -> compilation -> change in hadrware

      But abstraction and language expression are themselves subdivided into many layers. How much of those layers a programmer can afford not to know has a direct effect on that programmer’s position in the market. People often think of abstraction as something clean, but in reality it is incomplete and contextual. In theory it is always clean; in practice it is always breaking down.

      Depending on which layer you live in, even when using the same programming language, the form of expression can become radically different. From that point of view, people casually bundle everything together and call it “abstraction” or “intent,” but in reality there is a gap between intent and abstraction, and another gap between abstraction and language expression. Those subtle friction points are not fully reducible.

      Seen from that perspective, even if you write a very clear specification, there will always be something that does not reduce neatly. And perhaps the real difference between LLMs and humans lies in how they deal with that residue.

      Martin frames the issue in a way that suggests LLM abstractions are bad, but I do not fully agree. As someone from a third-world country in Asia, I have seen a great deal of bad abstraction written in my own language and environment. In that sense, I often feel that LLM-generated code is actually much better than the average abstractions produced by my Asian peers. At the same time, when I look at really good programming from strong Western engineers, I find myself asking again what a good abstraction actually is.

      The essay talks about TDD and other methodologies, but personally I think TDD can become one of the worst methodologies when the abstraction itself is broken. If the abstraction is wrong, do the tests really mean anything? I have seen plenty of cases where people kept chasing green tests while gradually destroying the architecture. I have seen this especially in systems involving databases.

      The biggest problem with methodology is that it always tends to become dogma, as if it were something that must be obeyed. SOLID principles, for example, do not always need to be followed, but in some organizations they become almost religious doctrine. In UI component design, enforcing LSP too rigidly can actually damage the diversity and flexibility of the UI. In the end, perhaps what we call intent is really the ability to remain flexible in context and search for the best possible solution within that context.

      From that angle, intent begins to look a lot like the reward-function-based learning of LLMs.

      • layer8 37 minutes ago

        You are right in that the code (or the formal model) alone isn’t sufficient, in that it doesn’t specify the context, requirements, design goals and design constraints. The formal and the informal level complement each other. But that’s also why it’s necessary to think at both levels when developing software. Withdrawing to just the informal level and letting LLMs handle the mapping to the formal level autonomously doesn’t work.

        That being said, even model-based design (MBD) has largely been a failure, despite it being about mapping formal models to (formal-language) program code.

    • achierius an hour ago

      > Assembly to Python creates a lot of Intent & Cognitive debt by his definition, because you didn't think through how to manipulate the bits on the hardware, you just allowed the interpereter to do it

      I agree! You often see this realized when projects slowly migrate to using more and more ctypes code to try and back out of that pit.

      In a previous job, a project was spun up using Python because it was easier and the performance requirements weren't understood at that time. A year or two later it had become a bottleneck for tapeout, and when it was rewritten most of the abstract architecture was thrown out with it, since it was all Pythonic in a way that required a different approach in C++

  • brodouevencode an hour ago

    > ...to develop the powerful abstractions that then allow us to do much more, much more easily. Of course, the implicit wink here is that it takes a lot of work to be lazy

    This lines up with YAGNI, but most people believe the opposite, often using YAGNI to justify NOT building the necessary abstractions.

    • coldtea an hour ago

      The counter-argument is that people build abstractions they deem necessary but aren't, and then they're married to that premature architecture quite often. That's what YAGNI is there to advise against.

      I don't think what Fowler says here is in favor of saddling the early versions of your system with abstractions before you actually seen its use in practice, and its needs over time as requirements and conditions change.

      From this "Laziness drives us to make the system as simple as possible (but no simpler!) — to develop the powerful abstractions that then allow us to do much more, much more easily." it's clear that when he talks of abstractions he means of very basic, and as simple as possible, building blocks. Like having core, orthogonal, principles in the system.

      Not the kind of piling of software and pattern design abstractions e.g. the Java land in the past used to build.

  • PaulHoule an hour ago

    Hits the spot for me. I am always pushing back on AI to simplify and improve concision.